zoukankan      html  css  js  c++  java
  • 20145339顿珠达杰 《网络对抗技术》 逆向与Bof基础

     

    目的

    • 通过一些方法,使能够运行本不该被运行的代码部分,或得到shell的使用:
      • 将正常运行代码部分某处call后的目标地址,修改为另一部分我们希望执行、却本不应该执行的代码部分首地址(这需要我们有一定的权限修改可执行文件)
      • 通过缓冲区溢出:输入数据,使其超出缓冲区大小,并覆盖住返回地址(新的返回地址为另一部分我们希望执行、却本不应该执行的代码部分首地址)
      • ......

    基础知识

    • objdump -d test :反汇编test
    • more : more命令和cat的功能一样都是查看文件里的内容,但有所不同的是more可以按页来查看文件的内容,还支持直接跳转行等功能
    • nop : 空操作指令,执行指令使程序计数器PC加1,占用一个机器周期
    • ebp esp : 寄存器ebp指向当前的栈帧的底部(高地址),寄存器esp指向当前的栈帧的顶部(低址地)
    • bp : 16位 ebp :32位 rbp :64位
    • info r :info registers , 查看寄存器的情况
    • 缓冲区溢出攻击:是指当计算机向缓冲区内填充数据位数时超过了缓冲区本身的容量,溢出的数据覆盖在合法数据上,当覆盖到堆栈中的返回地址时,将会引起程序错误或运行其他程序
    • call : call指令的机器代码表示为4字节(IA32的ATT格式),0x80 ** ** **,后3个字节为跳转到的指令地址到目前下一条指令的地址的偏移量,即 :
      • 后3个字节的值 + eip(目前所运行的call指令的下一条指令的地址) = 新eip(要跳转到的指令的地址)

     

    测试可执行代码,发现成功运行了getshell代码

    1 逆向及Bof基础实践说明

    1.1 实践目标

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

    三个实践内容如下:

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

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

    • 知识要求:Call指令,EIP寄存器,指令跳转的偏移计算,补码,反汇编指令objdump,十六进制编辑工具
    • 学习目标:理解可执行文件与机器指令
    • 进阶:掌握ELF文件格式,掌握动态技术
    • 下面就修改可执行文件,将其中的call指令的目标地址由d7ffffff变为c3ffffff。

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

      下载目标文件pwn1,执行

      反汇编。

      先看第12行,"call 8048491 "是汇编指令,是说这条指令将调用位于地址8048491处的foo函数;其对应机器指令为“e8 d7ffffff”,e8即跳转之意。本来正常流程,此时此刻EIP的值应该是下条指令的地址,即80484ba,但一解释e8这条指令呢,CPU就会转而执行 “EIP + d7ffffff”这个位置的指令。“d7ffffff”是补码,表示-41,41=0x29,80484ba +d7ffffff= 80484ba-0x29正好是8048491这个值,
      main函数调用foo,对应机器指令为“ e8 d7ffffff”,那我们想让它调用getShell,只要修改“d7ffffff”为,"getShell-80484ba"对应的补码就行。用Windows计算器,直接 47d-4ba就能得到补码,是c3ffffff。
      下面我们就修改可执行文件,将其中的call指令的目标地址由d7ffffff变为c3ffffff。

      root@KaliYL:~# cp pwn1 pwn2
      root@KaliYL:~# vi pwn2
      以下操作是在vi内
      1.按ESC键
      2.输入如下,将显示模式切换为16进制模式
      :%!xxd
      3.查找要修改的内容
      /e8d7
      4.找到后前后的内容和反汇编的对比下,确认是地方是正确的
      5.修改d7为c3
      6.转换16进制为原格式
      :%!xxd -r
      7.存盘退出vi
      :wq

      以上编辑操作也可以在图形化的16进制编程器中完成。实测可用。

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

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

      运行下改后的代码,会得到shell提示符#

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

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




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

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

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

      getShell的内存地址,在未启用ALSR的主机上是固定不变的,通过反汇编时可以看到,即0804847d。
      接下来要确认下字节序,简单说是输入11111111222222223333333344444444x08x04x84x7d,还是输入11111111222222223333333344444444x7dx84x04x08。

      对比之前 ==eip 0x34333231 0x34333231== ,正确应用输入 ==11111111222222223333333344444444x7dx84x04x08==。

      构造输入字符串

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

      root@KaliYL:~# perl -e 'print "11111111222222223333333344444444x7dx84x04x08x0a"' > input

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

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


  • 相关阅读:
    python-模块-tkinter
    Linux-命令-基本-反引号``或$()
    Linux-命令-基本-time,ctime,atime
    Linux-命令-基本-find-exec
    Linux-命令-cp,mkdir
    Linux-命令-setup,ifup,ls,cd,touch重定向
    Linux-Buffer和Cache
    给Access数据库文件减肥
    GPT转MBR怎么转?
    Windows XP解决显示桌面图标消失的问题
  • 原文地址:https://www.cnblogs.com/dj20145339/p/6507172.html
Copyright © 2011-2022 走看看