概述
虽然我是一只Web菜狗,还要渗透测试实习,但是怎么能不去了解逆向溢出呢。So,先了解Windows XP 溢出好了。
目标代码
|
|
步骤
它的运行时这样的:

假如name[] 的字符串变长 ,例如:
|
|
就会发生溢出,vc6.0 就会报错:

可见后面的值溢出,覆盖了之后的值。
如果name[]的值是这样:
|
|
则会调用cmd命令

至于jmp esp的地址是怎么来的,一般网上都有,或者。
用如下程序寻找
|
|

上述程序中是在user32.dll中寻找jmp esp的机器码FFE4,会查找到很多的结果,选择其中的一个就可以。
这里需要特别说明的是,不同的计算机不同的操作系统版本,所找到的jmp esp的地址可能会不一样,就是说jmp esp的地址往往并不是通用的。
当然,也会有几个地址是跨版本的,这个在这里不讨论。
这次我们选择其中的一个地址——0x7e490b40。由于是小 端显示,所以应当在“OPQR”的位置反向书写,即400b497e。
当然这里不能够直接用类似于记事本这样的软件进行编辑,而是需要用十六进制代码编辑 器操作。
至于shellcode如何得出,请继续往下看
比如下面这个程序就可以完成开DOS窗口的功能,大家详细看下注释:
|
|
程序中用GetProcAddress函数获得System的真实地址,但地址究竟是多少,如何查看呢?
如下图断点,然后调试

按alt + 8 以及alt+ 5,出现如下界面

按F10 运行到如下位置

EAX变为77c293c7,说明在我的机器上System( )函数的地址是0x77c293c7。
为什么EAX就是System( )函数的地址呢?那是因为函数执行的返回值,在汇编下通常是放在EAX中的,这算是计算机系统的约定吧,所以GetProcAddress(”System”)的返回值(System函数的地址),就在EAX中,为0x77c293c7。
如下是调用cmd代码
|
|
首先来验证一下,在VC中可以用__asm关键字插入汇编,我们把System(“Command.com”)用我们写的汇编替换,LoadLibrary先不动,然后执行,成功!弹出了我们想要的DOS窗口。
|
|

同样的道理,LoadLibrary(“msvcrt.dll”)也仿照上面改成汇编,注意LoadLibrary可以用如下程序查找。
|
|

可以看到地址为0x7c801d7b
把两段汇编合起来,将其编译、链接、执行,也成功了!
|
|

有了上面的工作,提取ShellCode就只剩下体力活了。
我们对刚才的全汇编的程序,按F10进入调试,接着按下Debug工具栏的Disassembly按钮,点右键,在弹出菜单中选中Code Bytes,就出现汇编对应的机器码。
因为汇编可以完全完成我们的功能,所以我们把汇编对应的机器码原封不动抄下来,就得到我们想要的ShellCode了。

提取出来的ShellCode如下。
|
|
最后要验证提取出来的ShellCode能否完成我们的功能。
在以前的文章中已经说过方法,只需要新建一个工程和c源文件,然后把ShellCode部分拷下来,存为一个数组,最后在main中添上( (void(*)(void)) &shellcode )(),如下:
|
|
( (void(*)(void)) &shellcode )()这句话是关键,它把ShellCode转换成一个参数为空,返回为空的函数指针,并调用它。
执行那句就相当于执行ShellCode数组里的那些数 据。如果ShellCode正确,就会完成我们想要的功能,出现一个DOS窗口。
我们亲自编写的第一个ShellCode成功完成!
