zoukankan      html  css  js  c++  java
  • 20145234黄斐《网络对抗技术》实验一,逆向及Bof基础实践

    实践内容

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

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

      

      该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。

    实践方法

    1. 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
    2. 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。

         这几种思路,基本代表现实情况中的攻击目标

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

    实践要求

    1. 掌握NOP,JNE,JE,JMP,CMP汇编指令的机器码

    2. 掌握反汇编与十六进制编程器

    3. 能正确修改机器指令改变程序执行流程

    4. 能正确构造payload进行bof攻击

    5. Optional:进阶,Shellcode编程与注入

    实践基础知识

    • (1)NOP指令即“空指令”(机器码:90)。执行到NOP指令时,CPU什么也不做,仅仅当做一个指令执行过去并继续执行NOP后面的一条指令。所以NOP指令自然也会占用执行一个指令的CPU时间片。
    • (2)JNE是一个条件转移指令(机器码:75)。当ZF=0,转至标号处执行。
    • (3)JE是一个条件转移指令(机器码:74)。如果相等则跳转。
    • (4)JMP是无条件转移指令。段内直接短转Jmp short(机器码:EB)段内直接近转移Jmp near(机器码:E9)段内间接转移Jmp word(机器码:FF)段间直接(远)转移Jmp far(机器码:EA)
    • (5)CMP为比较指令,功能相当于减法指令,只是对操作数之间运算比较,不保存结果(机器码:39)。cmp指令执行后,将对标志寄存器产生影响。其他相关指令通过识别这些被影响的标志寄存器位来得知比较结果。

    实践过程

    方法一 直接修改可执行文件的机器指令

    • 键入指令objdump -d hf0145234 | more
    • 找到程序关键函数(即去除运行所添加的各种库函数), getShell , foo , main
    • 从图中可以看出该程序正常运行顺序是从main函数入口开始进行执行,而后调用foo函数,并没有对getShell函数进行调用,而我们可以通过修改main函数中call指令来将原本程序对于foo函数的调用改为对getShell函数的调用。

    • 首先我们要了解call指令是通过修改eip寄存器的值来实现对于函数的调用的,因为eip寄存器永远指向下一条指令的地址,call指令的汇编代码与机器指令间的关系为 0x8048491 = 0x80484ba + 0xd7ffffff,其中 0x80484ba是原本下一条指令的地址, 0x8048491 为经过call指令修改后下一条指令的地址,机器指令中的 e8 是call指令的机器码
    • 因此想要调用getShell,只要修改 d7ffffff 为, getShell-80484ba 对应的补码 c3ffffff 就行了。

    • 接下来输入 vi hf20145234 打开可执行文件hf20145234;
    • 输入 :%!xxd 将文件转换成16进制显示
    • 输入 /e8 d7 搜索查询需要修改的机器码位置,锁定位置后按 i 进入插入模式进行将 e8 d7 修改为 e8 c3 (04b0行)
    • 输入 :%!xxd -r取消16进制显示,并输入 :wq 对文件的修改进行保存并退出(注:若不退出16进制显示直接保存,运行文件会出错
    • 再次使用反汇编指令objdump -d pwnx | more进行查看 发现call 后发生了变化
    • 键入 ./hf20145234 查看运行结果

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

    • 第一步依旧是输入反汇编指令objdump -d hf2 | more进行分析,内容同上

    • 第二步,确认输入字符串中哪几个字符会覆盖到返回地址
      • 输入指令 gdb hf2 调试程序,
      • 如果输入字符串1111111122222222333333334444444412345678,那 1234 那四个数最终会覆盖到堆栈上的返回地址,进而CPU会尝试运行这个位置的代码。那只要把这四个字符替换为 getShell 的内存地址,输给pwn1,pwn1就会运行getShell。
    • 第三步,确认用什么值来覆盖返回地址
      • getShell的内存地址,在未启用ALSR的主机上是固定不变的,通过反汇编时可以看到,即 0x804847d 。接下来要确认下字节序,简单说是输入 11111111222222223333333344444444x08x04x84x7d ,还是输入 11111111222222223333333344444444x7dx84x04x08 。
      • 对比之前 eip 0x34333231 0x34333231 ,正确应用输入11111111222222223333333344444444x7dx84x04x08
    • 第四步,构造输入字符串
      • 由为我们没法通过键盘输入 x7dx84x04x08 这样的16进制值,所以先生成包括这样字符串的一个文件。x0a表示回车,如果没有的话,在程序运行时就需要手工按一下回车键。
      • 利用Perl构建input文件进行输入,键入指令 perl -e 'print "11111111222222223333333344444444x7dx84x04x08x0a"' > input
      • 使用16进制查看指令xxd查看input文件的内容是否如预期
      • 然后将input的输入,通过管道符“|”,作为pwn1的输入。
  • 相关阅读:
    flask 文件上传(单文件上传、多文件上传)--
    flask 自定义验证器(行内验证器、全局验证器) --
    flask 使用宏渲染表单(包含错误信息) --
    flask 在模板中渲染错误消息 --
    flask 在视图函数中验证表单 --
    flask 处理表单数据 --
    flask 在模板中渲染表单 --
    flask 使用Flask-WTF处理表单 --
    flask 表单
    iPad适合写作吗
  • 原文地址:https://www.cnblogs.com/taigenzhenjun/p/6505895.html
Copyright © 2011-2022 走看看