Zuletzt aktiv 6 months ago

go prog to extract EXE from GIF as Trojan-Ransom.Win32.Foreign did

gifExeExtract.go Originalformat
1## see also https://0x41414141.de/blog/2017-03-30-trojan-ransom.win32.foreign-hides-payload-exe-in-gif-file/
2#
3package main
4
5import (
6 "bufio"
7 "bytes"
8 "container/ring"
9 "encoding/hex"
10 "flag"
11 "fmt"
12 "io/ioutil"
13 "log"
14 "os"
15)
16
17var inFile string
18
19func init() {
20 flag.StringVar(&inFile, "in", "", "path to input file")
21}
22
23func check(err error) {
24 if err != nil {
25 log.Fatal(err)
26 }
27}
28
29func main() {
30 // parse flags
31 flag.Parse()
32 // check if inputFile is given
33 if inFile == "" {
34 err := fmt.Errorf("no input file given")
35 check(err)
36 }
37 // determine fileSize of inputFile
38 var fileSize int64
39 file, err := os.Open(inFile)
40 check(err)
41 fi, err := file.Stat()
42 check(err)
43 fileSize = fi.Size()
44
45 var offset int64
46 var bytesRead int
47
48 // extract XOR key
49 keyBuf := make([]byte, 256)
50 offset, err = file.Seek(10, 0)
51 check(err)
52 bytesRead, err = file.Read(keyBuf)
53 check(err)
54 log.Printf("read %d at offset %d into keyBuf\n", bytesRead, offset)
55 log.Println("Key extracted is:")
56 d := hex.Dumper(os.Stdout)
57 defer d.Close()
58 d.Write(keyBuf)
59 err = ioutil.WriteFile("key", keyBuf, 0755)
60 check(err)
61 log.Printf("key was written to the file 'key'\n")
62
63 // extract encrypted EXE from inFile
64 encBlockSize := fileSize - 10 - 256 - 266
65 encBlockBuf := make([]byte, encBlockSize)
66 offset, err = file.Seek(266, 0)
67 check(err)
68 bytesRead, err = file.Read(encBlockBuf)
69 check(err)
70 log.Printf("read %d at offset %d into encBlockBuf\n", bytesRead, offset)
71
72 // extract last block from inFile
73 lastBlockBuf := make([]byte, 266)
74 offset, err = file.Seek(-532, 2)
75 check(err)
76 bytesRead, err = file.Read(lastBlockBuf)
77 check(err)
78 log.Printf("read %d at offset %d into lastBlock\n", bytesRead, offset)
79 // xor encBlockBuf with XOR key
80 decBlock := XOR(encBlockBuf, keyBuf)
81 // decBlock = append(decBlock, lastBlockBuf)
82 var exeBuf bytes.Buffer
83 w := bufio.NewWriter(&exeBuf)
84 w.Write(decBlock)
85 w.Write(lastBlockBuf)
86 w.Flush()
87 // write exe file out
88 err = ioutil.WriteFile("exe", exeBuf.Bytes(), 0755)
89 check(err)
90 log.Printf("wrote output to file 'exe'\n")
91}
92
93// XOR implements a rolling xor where the key size is allowed not to be the same size as the data
94func XOR(data, key []byte) []byte {
95 // setup ring buffer with key data
96 r := ring.New(len(key))
97 for i := 0; i < r.Len(); i++ {
98 r.Value = key[i]
99 r = r.Next()
100 }
101 // do the actual xor operation
102 for i := 0; i < len(data); i++ { // foreach byte of data
103 data[i] = r.Value.(byte) ^ data[i] // xor data byte with current ring element
104 r = r.Next() // move ring forward
105 }
106 return data
107}
108