20155326 2017-2018-1 《信息安全系统设计基础》第5周课上习题及缓冲区溢出漏洞实验

一、实验简介

缓冲区溢出是指程序试图向缓冲区写入超出预分配固定长度数据的情况。这一漏洞可以被恶意用户利用来改变程序的流控制,甚至执行代码的任意片段。这一漏洞的出现是由于数据缓冲器和返回地址的暂时关闭,溢出会引起返回地址被重写。

二、实验过程

  • 实验楼提供的是64位Ubuntu linux,而本次实验为了方便观察汇编语句,我们需要在32位环境下作操作,因此实验之前输入命令安装一些用于编译32位C程序的东西:

  • 终端显示实验楼无法进入32位linux环境。

  • Ubuntu和其他一些Linux系统中,使用地址空间随机化来随机堆(heap)和栈(stack)的初始地址。关闭地址空间随机化,以使猜测准确内存地址变得简单。

  • 此外,为了进一步防范缓冲区溢出攻击及其它利用shell程序的攻击,许多shell程序在被调用时自动放弃它们的特权。因此,即使你能欺骗一个Set-UID程序调用一个shell,也不能在这个shell中保持root权限,这个防护措施在/bin/bash中实现。

linux系统中,/bin/sh实际是指向/bin/bash或/bin/dash的一个符号链接。为了重现这一防护措施被实现之前的情形,我们使用另一个shell程序(zsh)代替/bin/bash。

在输入ln -S zsh sh命令,进行zsh程序的设置时一直出错,查找资料后将-S改为-s错误消失。

  • 接下来设置漏洞程序。输入stack.c,编译且设置SET-UID。GCC编译器有一种栈保护机制来阻止缓冲区溢出,所以我们在编译代码时需要用 –fno-stack-protector 关闭这种机制。

  • 而 -z execstack 用于允许执行栈。

  • 我们的目的是攻击刚才的漏洞程序,并通过攻击获得root权限,把以下代码保存为“exploit.c”文件

  • 现在我们要得到shellcode在内存中的地址

  • 结果如下:

  • 通过i r $esp找到str地址0xffffd350。

  • 再根据语句 strcpy(buffer+100,shellcode);计算shellcode的地址为 0xffffd350(十六进制)+100(十进制)=0xffffd3b4(十六进制)

  • 然后,编译exploit.c程序

  • 先运行攻击程序exploit,再运行漏洞程序stack,可见,通过攻击,获得了root权限!

  • 通过命令”sudo sysctl -w kernel.randomize_va_space=2“打开系统的地址空间随机化机制,重复用exploit程序攻击stack程序,观察能否攻击成功,能否获得root权限。

攻击不成功,不能获得root权限

  • 将/bin/sh重新指向/bin/bash(或/bin/dash),观察能否攻击成功,能否获得root权限。

尝试后发现未获得root权限,因为当没有关闭内存随机化机制时,攻击不成功,不能获得root权限。

实验中遇到的问题

  • 问题一及解决办法: 在我做这个实验之前我的室友在自己的虚拟机里面做了这个实验然后虚拟机就不能正常运行了。所以我在实验楼的机器上做了。

  • 问题二及解决办法: 在一开始设置32位环境时,输入"linux32"一直显示出错。

一开始我怀疑是sudo apt-get update出了错,重新输了一遍后反而有更多错误了。

于是我重新做了一遍实验,忽略它继续前进。

  • 问题三及解决办法: 在输入ln -S zsh sh命令,进行zsh程序的设置时一直出错,查找资料后将-S改为-s错误消失。

实验总结

通过本次实验,了解到缓冲区溢出是一种在各种操作系统、应用软件中广泛存在普遍且危险的漏洞,利用缓冲区溢出攻击可以导致程序运行失败、系统崩溃等后果。在实验过程中我也遇到了很多问题,比如说在准备阶段linux32、以及后面zsh的设置。

参考资料