Linux 基础
实验 <缓冲区溢出漏洞实验>
作业所属课程 | <2020-2021-1Linux内核原理与分析> |
---|---|
作业要求 | <2020-2021-1Linux内核原理与分析第一周作业> |
作业目标 | <缓冲区溢出漏洞实验> |
作业正文 | 2020-2021-1 20209308《Linux内核原理与分析》第十周作业 |
1.实验简介
缓冲区溢出是指程序试图向缓冲区写入超出预分配固定长度数据的情况。这一漏洞可以被恶意用户利用来改变程序的流控制,甚至执行代码的任意片段。这一漏洞的出现是由于数据缓冲器和返回地址的暂时关闭,溢出会引起返回地址被重写。
2.实验过程
输入命令安装一些用于编译 32 位 C 程序的软件包
sudo apt-get update
sudo apt-get install -y lib32z1 libc6-dev-i386 lib32readline6-dev
sudo apt-get install -y python3.6-gdbm gdb
2.1初始设置
Ubuntu 和其他一些 Linux 系统中,使用地址空间随机化来随机堆(heap)和栈(stack)的初始地址,这使得猜测准确的内存地址变得十分困难,而猜测内存地址是缓冲区溢出攻击的关键。因此本次实验中,我们使用以下命令关闭这一功能:
$ sudo sysctl -w kernel.randomize_va_space=0
此外,为了进一步防范缓冲区溢出攻击及其它利用 shell 程序的攻击,许多shell程序在被调用时自动放弃它们的特权。因此,即使你能欺骗一个 Set-UID 程序调用一个 shell,也不能在这个 shell 中保持 root 权限,这个防护措施在 /bin/bash 中实现。
sudo su
cd /bin
rm sh
ln -s zsh sh
exit
2.2shellcode
一般情况下,缓冲区溢出会造成程序崩溃,在程序中,溢出的数据覆盖了返回地址。而如果覆盖返回地址的数据是另一个地址,那么程序就会跳转到该地址,如果该地址存放的是一段精心设计的代码用于实现其他功能,这段代码就是 shellcode。
#include <stdio.h>
int main()
{
char *name[2];
name[0] = "/bin/sh";
name[1] = NULL;
execve(name[0], name, NULL);
}
2.3漏洞程序
cd /tmp
vim stack.c
/* stack.c */
/* This program has a buffer overflow vulnerability. */
/* Our task is to exploit this vulnerability */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int bof(char *str)
{
char buffer[12];
/* The following statement has a buffer overflow problem */
strcpy(buffer, str);
return 1;
}
int main(int argc, char **argv)
{
char str[517];
FILE *badfile;
badfile = fopen("badfile", "r");
fread(str, sizeof(char), 517, badfile);
bof(str);
printf("Returned Properly\n");
return 1;
}
编译该程序,并设置 SET-UID
sudo su
gcc -m32 -g -z execstack -fno-stack-protector -o stack stack.c
chmod u+s stack
exit
2.4攻击程序
在 /tmp 目录下新建一个 exploit.c 文件,输入如下内容,之后输入命令进入 gdb 调试
esp 中就是 str 的起始地址,所以我们在地址 0x080484ee 处设置断点。
接着修改exploit.c文件
2.5结果
3.遇到的问题
3.1ubuntu中zsh的安装
参考此博客(https://www.jianshu.com/p/4fde9ae77922)
3.2str地址计算未加偏移量出错
esp 中就是 str 的起始地址,所以我们在地址 0x080484ee 处设置断点。最后获得的这个 0xbffff440 就是 str 的地址。根据语句 strcpy(buffer + 100,shellcode); 我们计算 shellcode 的地址为 0xbffff440 + 0x64 = 0xbffff4a4。