zoukankan      html  css  js  c++  java
  • 20155321 《网络攻防》 Exp1 PC平台逆向破解(5)M

    20155321 《网络攻防》 Exp1 PC平台逆向破解(5)M

    实践目标

    • 本次实践的对象是linux的可执行文件
    • 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串
    • 该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode

    实践内容

    • 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数
    • 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数
    • 注入一个自己制作的shellcode并运行这段shellcode

    实践思路

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

    关于指令

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

    实践一:直接修改程序机器指令,改变程序执行流程

    • 第一步:通过objdump -d pwn1_20155321对文件进行反汇编

    • 第二步:主要看以下三个地方

      • 因此根据课上内容可知需要修改d7c3,计算过程为d7-(91-7d)=c3,计算均为十六进制计算
    • 第三步:通过命令vi pwn1_20155321编辑文件,通过命令:%! xxd把文件转为十六进制编辑模式,通过命令/d7ff找到需要修改的地方,最后输入i进入编辑模式,即把d7c3

    • 第四步:改完后输入命令:%! xxd -r将文件转回至二进制形式,再输入:wq保存并退出

    • 第五步:由此可发现程序已从原来跳转至foo函数变为跳转至getshell函数

    • 第六步:运行改后的程序

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

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

      • 触发getshell函数
      • 该可执行文件正常运行是调用如下函数foo,这个函数有Buffer overflow漏洞
      • 这里读入字符串,但系统只预留了__字节的缓冲区,超出部分会造成溢出,我们的目标是覆盖返回地址
      • 上面的call调用foo,同时在堆栈上压上返回地址值:80484ba
    • 确认输入字符串哪几个字符会覆盖到返回地址

      • 通过命令gdb pwn2_20155321进行调试,通过命令r进行运行,通过命令info r可查看各寄存器的值,其中主要关注EIP寄存器的值(EIP寄存器读取即将要执行的指令)
      • 由可知此1234这四个数最终会覆盖到堆栈上的返回地址,进而CPU会尝试运行这个位置的代码。因此只要把这四个字符替换为getShell的内存地址,输给pwn1pwn1就会运行getShell
    • 确认用什么值来覆盖返回地址

      • getShell的内存地址,通过反汇编时可以看到,即0804847d
      • 接下来要确认下字节序,即确认是大端方式还是小端方式,简单说是输入11111111222222223333333344444444x08x04x84x7d,还是输入11111111222222223333333344444444x7dx84x04x08
      • 对比之前EIP寄存器显示的值0x34333231,因此此处应输入11111111222222223333333344444444x7dx84x04x08
    • 构造输入字符串

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

    实践三:注入Shellcode并执行

    • 准备一段Shellcode

      • 通常这段机器指令的目的是为获取一个交互式的shell,所以这段机器指令被称为shellcode
      • 在实际的应用中,凡是用来注入的机器指令段都通称为shellcode,像添加一个用户、运行一条指令
    • 准备工作

      • 输入命令execstack -s pwn1设置堆栈可执行,但是一开始执行此命令的时候会遇到找不到命令这个问题,因此要先安装
      • 依次输入如下图所示的各个命令即可
    • 构造要注入的payload

      • Linux下有两种基本构造攻击buf的方法
        • retaddr+nop+shellcode
        • nop+shellcode+retaddr
      • 因为retaddr在缓冲区的位置是固定的,shellcode要不在它前面,要不在它后面,缓冲区小就把shellcode放后边,缓冲区大就把shellcode放前边,使用nops+shellcode+retaddr,nop一为是了填充,二是作为“着陆区/滑行区”
      • 若猜的返回地址只要落在任何一个nop上,自然会滑到我们的shellcode
      • 输入攻击命令(cat input_shellcode;cat) | ./pwn3_20155321
      • 打开另一个终端,进行gdb调试
        • 找到进程号:2437
        • 输入命令gdb进行调试
        • 通过设置断点,来查看注入buf的内存地址
        • 所以计算出地址应为0xffffd2f0
        • 因此将地址改为0xffffd2f0
        • 再次攻击,成功!
  • 相关阅读:
    HDU4529 郑厂长系列故事——N骑士问题 —— 状压DP
    POJ1185 炮兵阵地 —— 状压DP
    BZOJ1415 聪聪和可可 —— 期望 记忆化搜索
    TopCoder SRM420 Div1 RedIsGood —— 期望
    LightOJ
    LightOJ
    后缀数组小结
    URAL
    POJ3581 Sequence —— 后缀数组
    hdu 5269 ZYB loves Xor I
  • 原文地址:https://www.cnblogs.com/rafell/p/8527231.html
Copyright © 2011-2022 走看看