前言
最近知道创宇NDR安全团队在对APT32针对国内的攻击研究过程发现一些比较有意思的混淆样本。APT32混淆也不是什么新鲜事,前几年包括近几年攻击活动中都有使用过。
网上关于APT32组织使用的混淆技术介绍分析文章比较少,提及最多的也就是《Deobfuscating APT32 Flow Graphs with Cutter and Radare2 Research by: Itay Cohen》这篇文章,根据APT32近两年的混淆更新情况来看那篇文章已经没法准确的去除混淆而且存在部分问题。
刚好趁着这两天分析的APT32情况来介绍一下APT32最近的混淆技术。
Research by: NDR-NaN
混淆分析
废话不多说,直接来看APT32样本混淆情况。简单来说APT32混淆所采用的方式主要包含两类:
· 污点块或垃圾块
· 流混淆
污点分析
APT32采用添加垃圾代码或者干扰块等方式从而扰乱IDA迭代加深搜索,但根据实际测试情况来看IDA 7.5及以上版本基本上能跳过(7.5以下版本未经测试)如图一所示,但存有少数干扰使IDA无法正常分析如图二所示。
图一 IDA跳过污点
图二 中间存在无效引用
流混淆分析
流混淆包含两种方式:
· 硬编码Sign比较跳转
· 寄存器条件跳转
流混淆流程控制机制
Opcode r/m,imm
Opcode: CMP TEST
r/m: r/m8 r/m16 r/m32
imm: imm8 imm16 imm32
jn jnz jo jns
硬编码Sign比较跳转
跳转方式包括不限于溢出跳转、非零跳转、非负跳转等方式
寄存器条件跳转
解决思路
污点块或垃圾块解决方式
此类混淆处理方式相对简单也较为统一,一般来说分为三步进行处理,处理流程为:首先定位JMP跳转指令定位后判断后续两条指令是否存在它指引用,如果不存在,将清除JMP后条指令至JMP imm地址空间内的垃圾数据。
· 定位JMP指令
· 后条指令是否存在引用
· 清除后条指令至JMP IMM地址空间内数据
注:建议在清除前添加一步判断操作可能会存在向上JMP
去混淆后VS去混淆前
流混淆解决方式
APT32所采用的流混淆并不是特别复杂基本上为Compares operand with immediate jump,处理此类问题方法很多,此处列举两种方式均可解决此类流混淆方式。
方式一 模拟比较
通过计算CMP TEST结果模拟填充Flags,根据不同跳转条件判断是否跳转。
方式二 内联汇编
通过内联汇编直接运算,运算完成后设置异常,之后通过异常处理获取_EXCEPTION_POINTERS->ContextRecord->ContextFlags数据,再根据跳转条件判断是或否跳转。
根据结果如果跳转则直接JMP反之NOP跳转指令修剪分支。最终去混淆执行效果如下:
脚本执行日志
永跳转执行结果
去混淆后VS去混淆前
永不跳转执行结果
去混淆后VS去混淆前
去混淆后函数数量
去混淆后VS去混淆前
去混淆后伪代码结果对比
去混淆后VS去混淆前
总结
APT32组织混淆相较而言并非异常复杂,同样可以进行去混淆,编写脚本应注意几个问题:大小端问题、有符号数处理、如果编写模拟程序还需考虑进位、借位等问题。关于寄存器判断跳转问题静态方式处理起来难度较大,可能根据情况编写OD、XDBG动态脚本原理类似。
如若转载,请注明原文地址