对抗启发式代码仿真检测技术分析part2
对抗启发式代码仿真检测技术分析part2
本文发表于2年前
4 通过INT 6 的手段:
cpu 如果发现无效指令运行则int 6h 中断总是会被调用的。这个方法非常相似于INT 1 中断的手段。我们设置一个INT 6h中断的handler,然后执行一个条我们故意使用的无效指令,同时返回解密密钥。如果我们不想陷入无穷尽的循环当中,就要修改返回时的偏移。
mov ax, 3506h ;get int vector 6, so we can restore it later
int 21h ;not really necessary, but a little bit saver
mov int6_segm, es
mov int6_offs, bx
mov ax, 2506h ;set int vector 6 to our own routine
mov dx, offset int6_handler
int 21h
dw 0FFFFh ;an invalid opcode, will call our int 6
mov decrypt_key, ax ;handler, which returns the decryption key
mov ax, 2506h ;restore the original int 6 handler
mov dx, cs:int6_offs
mov ds, cs:int6_segm
int 21h
[...]
int6_handler:
mov ax, key
mov bx, sp
add word ptr ss:[bx], 2 ;modify return address - very important!
;2 is the size of our invalid opcode.
iret
请记住,这一方式并不能工作在window系统下的dos窗口程序中,因为window会率先截获一个无效的opcode,并给出错误消息(thanks to Z0MBiE for that tip)。所以如果你想使你的DOS virus兼容window,那么不要用此方法,尽管破坏引导区的virus实在是很美妙的。
5 感染COM文件及FAR JUMP方式:
我不喜欢delta offsets方式,所有我开始尝试用far jump方式来感染com文件(当然,还是要加上些代码用来重定位的):
mov ax, cs ;Relocate far Jump
add [offset com_seg], ax
JMP SHORT $Content$2 ;Clear prefetch queue
db 0EAh ;OP-Code far Jump
dw offset start ;Offset
com_seg dw 0 ;Segment (length of com file in paragraphs)
;pad filesize to even paragraph!
这段代码可以非常稳定地运行,我很惊讶,这种感染方式可以阻止AVP和Tbscan的来发现文件已被感染的检测方式。如果想看全部的virus欺骗技巧,再一次提醒您,可以查找我写 PR.H!- virus。
6 初始化寄存器方式:
大多是DOS版本的系统,在程序开始时的寄存器值是下面这样的:
AX=BX=0000h (if the first/second command line parameter contain a illegal
drive letter, AL/AH are set to 0FFh)
CX=00FFh
DX=DS=ES=PSP segment address
SI=IP
DI=SP
BP=91Ch/912h depending on DOS/Windows version.
如果你知道这些,你就可以利用这些值来加密你的virus了---- 一些AVs并不能正确的仿真这些值,因为这些大部分是undocumented。例如,我是用91h(BP shr 4)来加密/解密我的病毒体,可以非常好的欺骗TBAV, DrWeb, f-prot v2.27 and Ikarus这些AVs,但是不能很好的对抗AVP和NOD。
当然除了BP你还可选择其它寄存器来做这样的事情,保存加密密钥到指向EXE头部的堆栈处指针。例如,设置正确的堆栈在程序开始或解密代码处使用DI,或者在加密/解密处使用cx做异或操作。这些可激发你足够的想象力。但请记住,这些undocumented的技巧并在所有dos版下都一样。例如,freedos则在程序开始时设置所有通用寄存器都为0值。如果你想使用这一技巧,就要有心里准备,你的virus崩溃在这些系统的环境中了。
因此你必选结合起来其它的欺骗方式来对抗所有AVs,正如我刚才所说的,它们不是非常强大,基于这个理由,我并不是非常喜欢这种欺骗方式,但无论如何都要感谢bfr0vrfl0为这一方式所创造的灵感。
7 ENDLESS LOOPS:
这是个很古老的手段了。它不同于这篇文章中介绍的其它技术,但当我测试时才惊讶的发现,它非常的棒,可以骗过Thunderbyte, Dr. Web and Ikarus。这一想法的出发点是,那些启发式的扫描器,仅仿真了最开始处的一些指令,然后停止,以此加快扫描速度。因此,我们可以在病毒体开始处设置一个很长的循环,下面是一经典的模式:
mov cx, 0FFFFh
loop_head:
jmp short over_it
mov ax, 4C00h ;actually this isn’t needet, but it’s the
int 21h ;"classic" implementation of this trick.
over_it:
loop loop_head
你还可以使用不同类型的循环,或者像Opic’s Odessa-B virus那样的手法,非常长的一个解密循环。
这篇文章所公布的这些anti heuristic 技术目前为止都可以正常运行。当然AVs也可能改进它们的一些不足,在未来使这些方式失效。随时欢迎把这些技巧加入到你virus当中。使它们作为AVs无法检测出的地狱,展示给那些愚蠢的AV看他们所谓的”保护“。(译完)
可以看出此篇文章的作者对AV产品中,初期的启发式技术研究的非常深入,目标明确,知晓启发式检测的很多弱点。怎奈时代变换,多态变形病毒已经产量稀少,启发式技术整体上进步缓慢。上面提及的技术虽然已经不能造成多大危害,但基于代码仿真的启发式检测仍有很多个方面会受到技术上的挑战。
1 利用SEH方式:
虽然启发式的仿真器会模拟SEH异常处理,但解决这一对抗性问题却并非像实现一个SEH识别器那样简单。比如virus在解密的过程中洒下随机代码,建立异常处理,随后迫使处理器出错,进入virus的异常处理函数,进而再跳向另一个解密引擎中执行代码。如果AV不能处理这样的异常,病毒的代码也就无从执行,那么和谈检测呢。最大的问题就是仿真环境无法完美的处理某条指令引发的引发的特定异常。
2 慢随机执行方式:
可以利用任何程序开始执行时的随机数据来决定是否进行解密及感染,随机时间也好,日期也好都行,或者像win95下利用FS:[0ch]指向的TIB数据(在win 9x下该处数据随机)。目的只有一个,即便被模拟运行,也无法使AV得到100%的检测率,这也是我以前曾提到过的,仿真器应该具有指令预分析的功能。
3 利用多线程:
多线程的模拟并非高不可攀,关键的难点在于线程间的同步。这一点上没什么可说,仍然是AV今后要努力解决的问题。
4 RDA 方式:
病毒体解密代码可以不知道加密时的密钥,而是通过RDA(随机解密算法)方式来获得,目的只有一个,真实环境下解密部分可以很快运行完,但仿真环境下却会很慢,暴力搜索密钥算法,可能会产生很多个大循环,以此来迫使仿真器退出执行环境。
5 EOP 方式:
仿真器不会很有耐心地执行完程序的每一条指令,只要你的病毒所在宿主程序入口点足够的靠后,那你就胜利了一半,仿真器会因失去耐心而丢下你不管的。此时我想到了ExitProcess,聪明的你肯定明白了接下来将要干什么了,当然,当你知道这样做的时候,AV已经开始行动了,但关键是我们已经找到了一种对抗的思路了。
6 分析执行逻辑方式:
这一点是从xyzreg那里学到的,考虑到程序真实的运行与仿真环境的差别,也就知道如何对抗了。指令预取反跟踪也属于这一思路的范畴。下面是xyzreg给出的代码:
DWORD fpid,epid;
void VMM()
{
PROCESSENTRY32 pe;
HANDLE hkz=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
pe.dwSize=sizeof(PROCESSENTRY32);
if (Process32First(hkz,&pe))
{
do
{
if (pe.th32ProcessID==GetCurrentProcessId())
{
fpid=pe.th32ParentProcessID;
}
if (stricmp(pe.szExeFile,"explorer.exe")==0)
{
epid=pe.th32ProcessID;
}
}
while(Process32Next(hkz,&pe));
}
}
void main()
{
if(fpid!=epid)
return 0;
}
即便是一向作风严谨AVP也会有此疏漏,且在仿真的执行环境中与正常执行相悖的逻辑还有很多处,如GetModuleFileName。所以仿真的启发式检测远没有达到十分完善的地步。
还有一些对抗技巧如利用MMX指令或利用API传递控制等,但因这些技巧本身不会对启发式检测构成绝对威胁此处不再一一举例。启发是虽是对抗virus的利器,但我更感觉越是复杂高级的检测技术反而越加脆弱,脆弱的原因就是太过于复杂,所谓智者千虑必有一失吧。在没有加密、多态病毒出现前,特征匹配技术对待病毒可谓一剑封喉。或许越是简单的技术越是无懈可击。一次偶然间发现NOD可以仅用高级侦测模式,检测出被感染的文件,并精确的给出病毒名。或许启发式检测加适量的特征应该是对抗virus的最好武器吧。
附参考文献:
[1] Black Jack . 《Anti heuristic techniques》原文出处 http://vx.netlux.org/lib/vbj01.html
[2] Peter Szor . 《The Art of Computer Virus Research and Defense 》
[3] xyzreg. 《可怜的高级虚拟机启发式查毒》www.xyzreg.net/blog/read.php?39
这篇为批量导入文章,以下为之前站内评论!
- 夜风冷发表于 2年前