参考书目:0day安全:软件漏洞分析技术
相关工具使用:OD,IDA Pro,VC++6.0,UltraEdit
最近需要做课堂演习,就选了缓冲区溢出的实践。主要参考0day安全这本书,一面一句话很经典:
To be the apostrophe which changed Impossible into I’m possible!
直接步入正题:
1. 反汇编修改程序
在实现缓冲区溢出之前,简单熟悉一下反汇编重用的两个软件,OD和IDA,用OD修改程序代码实例。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
代码就是简单验证输入密码是否正确,首先用IDA打开编译生成的应用程序。看到这样一个图(好像每次打开生成的东西都不太一样~)
如果看不到地址可以在Options->General在Line prefixes前打钩以及将Number of opcode bytes设置为6就可以了。这样就可以找到代码中相应的跳转部分,然后用OD打开对应的EXE文件,看到下图:
找到004010D5这条命令就是对应的判断地方了,对应的汇编命令为:
- 1
- 1
于是将JE改成JNE,再运行程序,这时发现原来正确的密码不正确,原来错误密码都可以通过!用OD还可以对程序保存,一个简单的破解就完成了。(OD保存软件不会的话可以网上搜一下,我当时没搞懂还是请教的大神)
2. 缓冲区溢出漏洞修改邻接变量
还是刚刚的类似程序,假如程序员一不小心或者因为要在其他地方使用字符串,加了个strcpy函数,验证函数如下所示:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
看似还是正常的一个程序却会发生不可思议的事情,不信运行程序输入qqqqqqqq试试,发现没,通过验证了!这是为什么呢?来看看栈里面数据的存放:
啊,原来是这样啊,输入qqqqqqqq,或者输入其他8位也行(11111111不行,自己探索吧)在strcmp的时候auth确实是1,但是在进行strcpy之后,buffer里面的数据太长了,占了auth的位置,将auth从1改成了0。
看来下次写程序要注意点了!
3. 修改程序执行流程
是看了上面的原理图,是不是懂了点什么!EBP和返回地址是啥?不禁心生恶意,我要是再长点,是不是把返回地址给换了???还有那个EBP啥东西???
事实上,EBP是PE文件执行时候在函数调用时函数调用前栈底指针,在函数调用时会重新生成一个比较小的栈,此新栈为调用的函数所用,因此需要将之前栈的栈底入栈。在调用新的子程序的时候,也需要将子函数的返回地址入栈,不然子函数执行完了,计算机就不知道下一步执行什么了~
搞懂了这点知识,我们就可以利用这个来修改程序的执行流程了,具体实验可以自己做。
4 代码植入
之前例子的缓冲区较小,正常的函数中如果使用的话,缓冲区可能是比较大的,下面用新的例子来测试缓冲区溢出中的代码植入,完整的代码见上传的文件。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
此次的实验中由于控制台输入的限制性,将输入流改为文本。实验的目的是利用缓冲区溢出漏洞植入代码,代码内容为弹出一个新的窗口。
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
上面是MessageBox的四个参数,如果弹出标题和内容都是hellobug的串,四个参数分别为:
NULL, “hellobug”, “hellobug”, NULL
根据MessageBox得到应该执行的汇编代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
最后的Address是MessageBoxA地址,对应的机器码如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
因为缓冲区有44个字节,而四个字节一组,因此有11组,加上原来的auth,EBP和返回地址,一共14组,每组4个字节。新建一个这样的文件。
我在执行的过程中最后部分0018FD44就是Buff的起始地址。
接下来的问题就是buff的起始地址以及MessageBox的入口地址怎么找到呢?
首先是buff的起始地址,这个比较简单,将该文件写为14组1234,然后在OD里面跑一遍之后可以看到内存里面的数据,这个数据区的起始地址就是就是buff的起始地址。
然后是MessageBox的入口地址,在0Day安全这本书中有计算过程,我按照这个过程没有实现,因此我自己找了一个方法,有兴趣的同学可以按照书上的计算一下~
我的试验工程就是新建一个工程,只允许Messagebox然后通过OD查看其入口地址
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
写这样一个简单的程序用OD打开以下就好啦
找到MessageBox回车之后就进入了,从这个图可以看出入口地址是768EFD1E
然后整个文件就制作完成了,运行一下看看吧
以上就是一个简单的缓冲区溢出的实例了,不过在植入代码这个过程中电机确定之后~~就挂了,因为一些参数没有设置好,慢慢再深入研究吧。