来源:安全中国
Image File Execution Options,说熟悉又陌生,一年来大家谈起的映像劫持,都是它的Debugger键值的问题。实现IFEO劫持,只是在注册表写一个键而已,轻松到没技术含量。然而,系统到底是怎么识别的呢,或者说,系统的这个功能,是怎么使它自己走入圈套的呢?
早前给电脑报写了一篇简单谈IFEO的文章,当时托大家找了些资料,TK翻到MSDN里的相关描述,明确指出“当父进程不是作用子进程的调试器时,CreateProcess在其用户态部分检测Image File Execution Options项”。当时就想在文章最后说一下这点,以及为什么那些系统关键进程是不会被IFEO影响的。但是一来自己当时太菜,根本不懂得去看CreateProcess的代码来调试,所以也自己确认不了。同时那篇文章也是给一般用户看的,无谓说些让他们坠入迷雾的东西,所以就作罢了。
而最近这两三天里,由于前一篇blog里提到的看shellcode的xor加密代码的激励,突然对汇编逆向调试感兴趣了,于是整天盯着OD看反汇编代码。今天又遇到一个求助者,他不慎将D盘在资源管理器下隐藏了,于是教他从组策略里改回来。最后随口说了一句“系统应该是在FindFirstFile和FindNextFile的用户态部分检查这个键值,以隐藏驱动器吧,不至于到调用NATIVE API甚至进ring0时才检测,就像CreateProcess在用户态检测IFEO一样”。
于是突然有想法,何不确认一下?
自己写个小程序,button的onclick里就简单地CreateProcess。 打开注册表编辑器,将SREngPS.exe给IFEO劫持到cmd.exe。
OD载入运行,忽略所有异常,开工。 先看了CreateProcessA、WinExec、ShellExecuteA这几个函数,果然全都是内部调用了CreateProcessInternalA来完成,而后者又调用了其UNICODE版本,即CreateProcessInternalW,来完成实际的工作。 在CreateProcessInternalW出口处下断,断到了,一路跟下去。这次的重点在于找出“系统判断父进程是否为子进程的调试器,是则检测IFEO项”的相应代码。 也就是说,要找到系统对dwCreationFlags进行检测并决定是否进入IFEO检测的代码。
父进程成为子进程的调试器的dwCreationFlags参数有两个: DEBUG_PROCESS = 1; DEBUG_ONLY_THIS_PROCESS = 2;
找了半天,这函数要做的步骤还真不是一般的多,调用NATIVE API创建进程对象的顺序就不仔细看了,留待以后吧,现在重点不是这些。最后终于柳暗花明:

用断点的红色标示的这两句,其中byte ptr [ebp+20]正是传入的dwCreationFlags,与3进行test,如dwCreationFlags中包含1或2,则结果非零(ZF=0),这时就跳走,绕过下面的检测。 这里我们用了0参数,所以当F8到jnz的时候,会发现提示窗口写着“跳转未实现”。 而下面这个检测,就是跳到ntdll.dll导出的LdrQueryImageFileExecutionOptions函数中了,看看它是怎么检测的:

进入那个call中,又是冗长的一大堆,看得头痛,拣其中一些:
 IFEO项的地址,IFEO的路径所为字符串常量保存在ntdll.dll中。
 进行完这两个mov,esi中是指向SREngPS.exe的全路径的地址,注意这时已经是UNC标准的UNICODE(前面有\??\)
 循环,eax初始值指向全路径地址末尾,每次向前推进,直到找到"\",再跳出循环到最后这一行。 跳出循环到最后这一行时,eax保存的便是指向相对路径("SREngPS.exe“)开头的地址,而[ebp-2d4]里的则是前面的文件夹路径的长度。 。。。。
 调用ZwOpenKey去访问键值了。 回到LdrQueryImageFileExecutionOptions中test得到的eax值(已传到esi),然后就 7C93D36D /0F8D CD900100 jge 7C956440 ; 存在则读其键值
看下这个7C956440: 7C956440 FF75 1C push dword ptr [ebp+1C] 7C956443 FF75 18 push dword ptr [ebp+18] 7C956446 FF75 14 push dword ptr [ebp+14] 7C956449 FF75 10 push dword ptr [ebp+10] 7C95644C FF75 0C push dword ptr [ebp+C] 7C95644F FF75 08 push dword ptr [ebp+8] 7C956452 E8 14000000 call 7C95646B 7C956457 FF75 08 push dword ptr [ebp+8] 7C95645A 8BF0 mov esi, eax 7C95645C E8 2571FDFF call ZwClose 7C956461 ^ E9 0D6FFEFF jmp 7C93D373
[1] [2] 下一页 |