网络安全 频道

sh3llc0de开发测试中dumpbin的使用

    当然,基于MSF(Metasploit Framework)的shellcode开发简单的已经几乎用不着你自己去了解编程上的东西(细节请参考本人编写的MSF中文手册),但是对于初学而又喜欢探索底层的人来说,自己动手编程也是件不错的事情。嗯...本文面向像我一样在系统探索上的初学者,如果您是这方面的高手,这篇文章让您见笑了。

    首先,了解一下dumpbin。
    这个工具在微软的几乎所有的tool kits里都有,像VS,MASM...
在VS里没找到dumpbin?好吧,把路径切换到..\WINDOWS\System32\,尝试以下命令:
link.exe /dump /headers /exports kernel32.dll >E:\log
记事本打开E盘下的log文件,看到了什么...实际效果和:
dumpbin /headers /exports kernel32.dll >E:\log
是一样的。

    稍微解释一下dumpbin的参数.
    把dumpbin放进一个环境变量指向的路径里(方便随时随地启动dumpbin),命令行输入dumpbin:

    Microsoft (R) COFF Binary File Dumper Version 6.00.8168
    Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

    usage: DUMPBIN [options] [files]

    options:
    /ALL
    /ARCH
    /ARCHIVEMEMBERS
    /DEPENDENTS
    /DIRECTIVES
    /DISASM
    /EXPORTS
    /FPO
    /HEADERS
    /IMPORTS
    /LINENUMBERS
    /LINKERMEMBER[:{1|2}]
    /LOADCONFIG
    /OUT:filename
    /PDATA
    /RAWDATA[:{NONE|BYTES|SHORTS|LONGS}[,#]]
    /RELOCATIONS
    /SECTION:name
    /SUMMARY
    /SYMBOLS

    挑我们需要的,/HEADERS,/EXPORTS,/OUT,其他的参数可以参考微软的MSDN,地址如下:
    http://msdn2.microsoft.com/zh-cn/library/c1h23y6c(VS.80).aspx

    /HEADERS显示文件头和每节的头,这里有个比较重要的信息就是文件在内存中的加载地址,也就是OPTIONAL HEADER VALUES里的Image Base;/EXPORTS显示从可执行文件或 DLL 导出的所有定义,这里我们需要的是函数的相对偏移地址;/OUT指定输出的 filename。默认情况下,DUMPBIN 将信息显示到标准输出(DOS窗口中),一般我不太喜欢用这个参数,我用管道>代替,而且如果是追加信息的话可以用>>。

    然后,我们实际运用一把,随便到网上抓个shellcode,如下:

    CODE:
    #include <stdio.h>

    unsigned char beepsp[] =
    "\x55\x89\xE5\x83\xEC\x18\xC7\x45\xFC"
    "\x77\x7A\x83\x7C"               //Address \x77\x7A\x83\x7C = SP2
    "\xC7\x44\x24\x04"
    "\xD0\x03"                     //Length \xD0\x03 = 2000 (2 seconds)
    "\x00\x00\xC7\x04\x24"
    "\x01\x0E"                     //Frequency \x01\x0E = 3585
    "\x00\x00\x8B\x45\xFC\xFF\xD0\xC9\xC3";

    int main()
    {
    void (*function)();
    *(long*)&function = (long)beepsp;
    function();
    }  
    [Copy to clipboard]

    这段代码我已经修改过了,在我的机器上运行是没问题的。用VC编译之后执行,会听到主板的“滴---”声,实际上是调用了kernel32.dll里的beep函数。
如代码中给出的:
    "\x77\x7A\x83\x7C"               //Address \x77\x7A\x83\x7C = SP2
这个代码在XP SP2下才会正常执行,而且就算是SP2的系统,也会因为系统补丁导致类似krnel32.dll等这些系统dll在内存中的加载地址的不同,这样Address \x77\x7A\x83\x7C (实际上是7C837A77,注意小端排列)也就指向了错误的地方。

    那么,怎么取得自己机器上的合理地址呢?
    首先,用dumpbin取得dll的加载地址,比如要引用kernel32.dll中的beep函数,我们需要先得到kernel32.dll在本机内存中的加载地址,方法如下:

    C:\Documents and Settings\Administrator>cd C:\WINDOWS\System32

    C:\WINDOWS\system32>dumpbin /headers kernel32.dll > E:\log.txt

    打开log.txt,找到如下信息:
    OPTIONAL HEADER VALUES
    7C800000 image base
       
    这里,7C800000就是kernel32.dll的本机加载地址。
    知道了基址,我们就要查找beep函数在kernel32.dll内存映射的什么地方,方法如下:

    C:\WINDOWS\system32>dumpbin /exports kernel32.dll >> E:\log.txt

    我们在Dump of file kernel32.dll里查找函数beep:
    28   1B 00019805 BasepCheckWinSaferRestrictions
    29   1C 00037A77 Beep
    30   1D 0006FC7B BeginUpdateResourceA
    其中,00037A77就是beep函数相对于基址的偏移地址,我们把两个地址相加,即得到beep函数在内存中的真实地址:
    7C800000 + 00037A77 =7C837A77
    以小端排列,得到:\x77\x7A\x83\x7C
    这样在shellcode里修改:
    "\x77\x7A\x83\x7C"               //Address \x77\x7A\x83\x7C = SP2
    即可正常运行测试程序。

    思路就这样简单,如果是kernel基址的通用获取,就需要其他技术了,超出本文范围,不做讨论。
Have Fun!

    附:
    1.kernel32.dll
    C:\WINDOWS\system32>dumpbin /headers /exports kernel32.dll >     E:\kernel_log.txt

    2.ntdll.dll
    C:\WINDOWS\system32>dumpbin /headers /exports ntdll.dll > E:\ntdll_log.txt

    3.msvcrt.dll
    C:\WINDOWS\system32>dumpbin /headers /exports msvcrt.dll > E:\msvcrt_log.txt

    4.ws2_32.dll (网络编程)
    C:\WINDOWS\system32>dumpbin /headers /exports ws2_32.dll > E:\ws2_log.txt

0
相关文章