类似标签:映像劫持、(Image File Execution Options)、“Image Hijact"
"如果我想在双击程序‘notepad.exe‘ 程序时,系统执行的确是 ‘cmd.exe‘ ,该怎么实现?”
我们应该先探索一下 当我们点击了 ‘notepad.exe‘时,发生了什么:我们双击了‘notepad.exe‘,系统判断‘notepad.exe‘是一个可执行体,然后为程序申请内存空间/加载程序/执行程序。
不对,其实在为程序申请内存空间之前,系统还对‘notepad.exe‘进行了一项是否IFEO判定(我们暂且这么称呼),具体操作就是:打开注册表“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options”键,然后查找该键下是否有与执行程序同名,即‘notepad.exe’,的子健, 如果不存在(你很幸运),则真正运行‘notepad.exe‘程序; 如果存在名为‘notepad.exe‘的子健,系统便会查找该子健中名为‘Debugger‘的项,且恰好’Debugger‘项的项值为‘cmd.exe’,那么系统真正运行的会是‘Debugger‘项值中的‘cmd.exe‘程序,而原本的程序‘notepad.exe‘只会作为一个参数传给‘cmd.exe‘。即最后执行的’cmd.exe notepad.exe‘。
既然有这么大一个漏洞,它为什么还存在啊?
IFEO注册表键是干什么的?
原来,在Windows NT时代,系统使用一种早期的堆(Heap,由应用程序管理的内存区域)管理机制,使得一些程序的运行机制与现在的不同,而后随着系统更新换代,厂商修改了系统的堆管理机制,通过引入动态内存分配方案,让程序对内存的占用更为减少,在安全上也保护程序不容易被溢出,但是这些改动却导致了一些程序从此再也无法运作,为了兼顾这些出问题的程序,微软以“从长计议”的态度专门设计了“IFEO”技术,它的原意根本不是“劫持”,而是“映像文件执行参数”!
比如,当你想运行一个使用了旧的堆管理机制程序“a.exe”时,在新的系统上是无法正常运行的。这时,你打开注册表,在“HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options”下新建一个“a.exe"子健,然后在该子健内新建一个一个字符串注册表项"DisableHeapLookAside",值为1. 保存注册表后,再次运行”a.exe"是不是unx成功了?(还没有?那出错原因就不是IFEO能够管的范围了...或者尝试搭配下其它参数使用)。
IFEO是不仅仅只有“Debugger"这一个参数的,下面都是IFEO的参数:
ApplicationGoo
Debugger
PageHeapFlags
DisableHeapLookAside
DebugProcessHeapOnly
PageHeapSizeRangeStart
PageHeapSizeRangeEnd
PageHeapRandomProbability
PageHeapDllRangeStart
PageHeapDllRangeEnd
GlobalFlag
BreakOnDllLoad
ShutdownFlags
但是造成”映像劫持“的罪魁祸首,只是”Debugger".
因为”Debugger“参数的优先权是高于所有其它参数的!!!
当系统查找到IFEO中某一子健时,会首先判断是否使用了“Debugger"参数!!
为什么”Debugger"会存在呢?
或许微软当初的用意是便于程序员能够通过双击某个设置了IFEO控制列表的执行体文件来直接调用调试器对其进行调试,而不用再通过繁琐的打开调试器再进行文件载入来实现调试,提高了工作效率。
下面附图:
拓展阅读:映像劫持-百度百科
代码Demo:
1 #include "stdafx.h" 2 #include <Windows.h> 3 4 #pragma comment(lib, "Advapi32.lib") 5 6 int _tmain(int argc, _TCHAR* argv[]) 7 { 8 LONG lRst; 9 HKEY hKey; 10 if(ERROR_SUCCESS != RegCreateKeyEx( 11 HKEY_LOCAL_MACHINE, 12 L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\notepad.exe", 13 0L, 14 NULL, 15 REG_OPTION_NON_VOLATILE, 16 KEY_ALL_ACCESS, 17 NULL, 18 &hKey, 19 NULL)) 20 { 21 wprintf(L"RegCreateKeyEx failed.\n"); 22 return 0; 23 } 24 25 lRst = RegSetValueEx(hKey, L"Debugger", 0L, REG_SZ, (CONST BYTE*)L"cmd.exe", sizeof(L"cmd.exe")); 26 if (ERROR_SUCCESS != lRst) 27 { 28 wprintf(L"RegSetValueEx failed.\n"); 29 } 30 31 RegCloseKey(hKey); 32 return 0; 33 }