20145313张雪纯网络攻防第一次实验
实验目的
本次实验用到的代码pwn1有两个函数foo、getShell。其中,foo的作用是简单回显用户输入的字符,getShell的作用是返回一个可用shell。程序正常运行时调用的是foo函数。在这次实验中,我们的目的是通过不同方式使得程序运行本不该运行的代码、调用getShell函数。
实验过程及原理
方法一 直接修改程序机器指令,改变程序执行流程
原程序的运行结果是回显用户输入字符,如图。
对程序进行反汇编
黑色一行表示下一条将调用位于地址8048491处的foo函数。其对应机器指令为“e8 d7ffffff”,e8即跳转之意。本来正常流程,此时此刻EIP的值应该是下条指令的地址,即80484ba,但一解释e8这条指令呢,CPU就会转而执行 “EIP + d7ffffff”这个位置的指令。“d7ffffff”是补码,表示-41,41=0x29,80484ba +d7ffffff= 80484ba-0x29正好是8048491这个值,main函数调用foo,对应机器指令为“ e8 d7ffffff”,那我们想让它调用getShell,只要修改“d7ffffff”为,"getShell-80484ba"对应的补码就行。用Windows计算器,直接 47d-4ba就能得到补码,是c3ffffff。
用vim打开文件,是ascii码,转换为16进制后,搜索到该条指令,进行直接修改。注意:修改完毕后需要再次转换为ascii码,否则程序无法正常运行。
修改后运行该程序,显示出shell符号#。
对修改后的程序进行反汇编,原来调用foo函数的指令变为了调用getShell函数。
方法二 通过构造输入参数,造成BOF攻击,改变程序执行流
对原程序进行反汇编
发现其foo函数对用户输入的字符串存储的缓冲区长度是有限的。如果我们输入的字符串超出其长度,就会产生缓冲区溢出。若缓冲区溢出数据进入eip寄存器,我们就可以修改下一步运行的指令。
先进行测试,字符串的第多少位会覆盖eip寄存器。输入长字符串1111111122222222333333334444444455555555,通过gdb调试,查看eip寄存器数值
可知现在eip中数值为5的ascii码。那么,下一步,对5进行编号,输入字符串1111111122222222333333334444444412345678,通过gdb调试,查看eip寄存器数值
可知是1~4位覆盖了eip。只要把这四个字符替换为 getShell 的内存地址,下一个指令就会调用getShell的函数。
getShell的内存地址,在未启用ALSR的主机上是固定不变的,通过反汇编时可以看到,即0804847d。小端法,低位在前,可知我们应输入的字符串是11111111222222223333333344444444\x7d\x84\x04\x08。
由于我们无法直接通过键盘输入十六进制的地址,所以我们利用管道符输入该值。
运行后,我们即可使用ls命令测试是否已经调用getShell函数。
问题
在方法二中,如何在gdb中追踪修改后的eip寄存器数值呢?
- 这个问题在实验拓展中已解决。http://www.cnblogs.com/entropy/p/6505905.html