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。
    接下来要确认下字节序,简单说是输入11111111222222223333333344444444\x08\x04\x84\x7d,还是输入11111111222222223333333344444444\x7d\x84\x04\x08。

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

    构造输入字符串

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

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

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

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


posted on 2017-03-05 22:29  20145339顿珠  阅读(224)  评论(0编辑  收藏  举报