-
-
[分享]混淆、加密、反沙箱概念介绍
-
发表于: 5天前 594
-
前言
在实际的应用场景中淆、加密、反沙箱这几个技术几乎是无处不在,常见于恶意代码、驱动保护、软件加壳、逆向对抗等场景,所以了解是十分必要的
混淆(Obfuscation)
本质就是把原本清晰的代码变得难以理解,但不改变功能
目的是为了防止逆向工程(IDA / Ghidra)、提高分析成本、隐藏关键逻辑
常见手段
1. 控制流混淆
把正常代码结构打乱,例如:
if (a > b) {
func1();
} else {
func2();
}
变成类似:
goto LABEL1;
LABEL2:
func2();
goto END;
LABEL1:
if (a <= b) goto LABEL2;
func1();
END:
在分析时比较难看出逻辑结构,但其实没啥用,因为是体力活可以交给ai
2. 字符串混淆
例如:"CreateFileA" 变成 char s[] = {0x23, 0x12, 0x99...};
也是为了防直接在ida中搜索到,同样也用处不大,是很老的加密技术
3. API混淆(动态解析)
不直接调用CreateFileA(...),而是GetProcAddress(GetModuleHandle("kernel32.dll"), "CreateFileA");
避免静态分析发现调用关系,但也是老套路了,人尽皆知...
4. 垃圾代码(Dead Code)
插入无用代码:
int x = 123;
x ^= 456;
增加分析噪音,这种方式用的多会拖慢程序速度
比如经典的 OLLVM
就提供了如下功能:
- 控制流平坦化(Flattening)
- 虚假分支(Bogus Control Flow)
- 指令替换(Substitution)
目的就是让反编译结果非常难读
加密(Encryption / Packing)
本质就是把代码或数据加密,运行时再解密执行
目的是防止静态分析(直接看文件)以及隐藏真实代码
常见形式
壳(Pack)
程序在磁盘上是加密的:[壳代码] + [加密payload]
运行流程为:壳运行、解密payload、跳转执行
比如:UPX、Themida、VMProtect
分段加密
这种比较高级一些,特点是不一次解密全部代码而是用到哪解密哪,常用于对抗内存dump
反沙箱(Anti-Sandbox)
本质是为了检测当前环境是否是:虚拟机、沙箱(杀软分析环境)、调试器
为什么要做这个?因为杀毒软件流程通常为把程序丢进沙箱、运行观察行为、判断是否恶意
反沙箱就是骗过这一步
常见检测方法
例如检测 MAC 地址和设备名,
以及检测进程否存在vmtoolsd.exe、vboxservice.exe、wireshark.exe
检测CPU/硬件特征例如 cpuid 来判断是否是虚拟 CPU ,但其实可以用vt过掉
检测时间异常(这个很常用)
其实就是检测延迟,因为往往虚拟机延迟会比较大,例如:
start = GetTickCount();
Sleep(10000);
end = GetTickCount();
if (end - start < 10000) {
//
}
还有一些检测用户行为来判断有没有真实用户,例如:有没有鼠标移动、没有键盘输入
以及还可以检测内存/磁盘大小,因为沙箱通常资源很小:if (RAM < 2GB) exit(0);
还有一些常用的检测,检测调试器(反调试)IsDebuggerPresent()、PEB->BeingDebugged、NtQueryInformationProcess来判断是不是在调试环境
做这一切都是在增加调试成本
赞赏
- [分享]混淆、加密、反沙箱概念介绍 595
- [分享]手动映射sys到内核 681
- [分享]Minifilter简易文件访问监控 569
- [分享]内核逆向开发阶段评测方法 598
- [分享]游戏网络封包解析可行性分析 774