IFEO(Image File Execution Options )是设置在Windows注册表中,创建IFEO注册表项的目的是让开发人员可以选择调试他们的软件,是为了开发人员可以使用注册表项将任何程序附加到任何可执行文件,但是很多被利用了去实现进程注入。很多只知道ring3的部分机制,但是并不知道完整的机制,今天们就来分析下它的ring3到ring0的整个过程的机理。
开发一个小的test.exe解析命令行,为了方便上调试器调试加上Messagebox 弹框
编译后,我们可以修改注册表演示下IFFO
**HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\{name of the executable}**
加个notepad.exe的项目然后添加Debugger的keyvalue
“Debugger”=”{full path to the debugger}”
然后我们在windows左下角搜索框输入notepad
然后启动notepad.exe,这时我们的test.exe就会被启动了
今天的目的就是来分析下这种机制的原理。
把上述代码继续改造的MessageBox去掉,加直接启动notepad.exe的启动参数里的进程
然后上ollydbg调试运行。
启动后对CreatPorcessW下断点输入命令: bp CreatPorcessW
断点停下来
继续F8 然后F7进入
**775F1054 |. E8 22010100 CALL kernel32.CreateProcessInternalW**
通过IDA
查看CreateProcessInternalW前面基本都是一些字符串拷贝的动作
在Ollydbg开始阶段就直接F8单步运行过去
接着就是创建环境
这些也直接单步走过,当我们单步到这里的时候
调试器在这里下断点
然后F8
发现
NtCreateUserProcess(&Process, &ThreadHandle, 0x2000000, 0x2000000, v188, v189, v64, 1, v60, &v194, &v347)
函数的eax的返回值是0xC0000039,也就是说这里调用内核去创建的时候是直接失败的,
返回值是STATUS_OBJECT_PATH_INVALID
意识就是说路径对象无效,通过分析第九个参数结构体的数据发现路径确实没有任何问题
我们可以做个对比实验,把IFEO的对应注册表Debugger删除后再运行调试
下面是正常情况下把注册表删除了后的运行
参数基本一模一样,然后直接F8 单步运行,结果出现了返回值eax == 0
也就是STATUS_SUCCES,没有debugger注册表键值的时候NtCreateUserProcess内核返回值是0
,现在我们大致可以猜测内核里也对这个IFEO位置的注册表键值做了处理,为了搞清楚内核如何处理,直接上windbg用虚拟机进行双机调试,调试内核。
接下来在NtCreateUserProcess上下断点,当Ollydbg里执行NtCreadtUserProcess
时windbg里断点停下来
有个最简单的方法就是不断的尝试单步进入函数后单步Call返回值为0xC0000039的函数,最后经过反复的实现发现NtCreateUserProcess内在调用**PspAllocateProcess**
函数时返回0xC0000039
在fffff800`0412651f 出下断点
运行后断下
调试器停在了call nt!PspAllocateProcess (fffff8000412852c)
,F10 后查看eax值r eax
,显示
也就是说在这个函数里可能会涉及处理注册表的过程,用ida打开ntkrnlmap.exe的内核文件,慢慢查看会发现有这么一段代码
在这段代码里判断IFEOKEY 是否有对应Debugger注册表设置,往上面翻会发现IFEOKey打开的就是当前进程名的IFEOKey的注册表
RtlpOpenImageFileOptionsKey
调用了RtlpOpenBaseImageFileOptionsKey
,RtlpOpenBaseImageFileOptionsKey
会ZwOpenKey IFEO
注册表
为了验证我们的结果,在RtlQueryImageFileKeyOption
函数下断点
进入 RtlQueryImageFileKeyOption
函数单步执行到ZwQueryValueKey
时,F10后
查看rsi里的值
会发现此时读取到Debugger的设置注册表,然后返回到调用之前的下面一句指令:
判断eax是否是0,此时函数返回值就是0,然后就进入了
mov r12d,0xC00000039h
最后把 r12d 赋值给了eax返回
就是最后我看到创建进程失败了,错误号0xC00000039
当前者失败后,ring3 层就进入了
76B4F75F . FF15 5006B176 CALL DWORD PTR DS:[<&ntdll.LdrQueryImageFileKeyOption>] ; ntdll.LdrQueryImageFileKeyOption
函数去读取IFEO的Debugger注册表
获取了数据后,解析参数成功后就把当前进程的路径加载Debugger对应的进程后面作为一个参数组合成一个启动进程参数
在上图可以看到两个路径被加到一起。构造的的新参数就是
UNICODE "C:\Users\Administrator\Desktop\test.exe C:\Windows\System32\notepad.exe"
最后goto LABEL_87
重新组建进程参数环境去执行新的进程,又会进入NtCreateUserProcess
,但这时启动的是test.exe
这时返回值就是0了,创建成功
至此整个过程就分析完毕了,微软的IFEO机制本来是给开发人员调试程序用的,后来慢慢被恶意软件用来镜像劫持,在微软的官方msdn里有一段描述说使用DEBUG_ONLY_THIS_PROCESS和DEBUG_PROCESS方式 CreateProcess时是不会读取注册表去劫持的,而实际测试时确实如此,具体原理读者可以自行分析。
特别申明:逆向分析调试是一种武器,切莫用于非法途径。
来源:freebuf.com 2020-08-06 22:25:34 by: 浪子_三少
请登录后发表评论
注册