章节大纲

  • 本实验中使用的易受攻击的程序名为 stack.c,位于 code 文件夹内。 此程序存在缓冲区溢出漏洞,并且您的任务是利用该漏洞并获得 root 权限。代码已去除一些非本质的信息,所以它与您从 Labsetup 文件中获取的内容略有不同。

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    /* 更改此大小将更改堆栈布局 */
    #ifndef BUF_SIZE
    #define BUF_SIZE 100
    #endif
    
    int bof(char *str)
    {
        char buffer[BUF_SIZE];
    
        /* 下面的语句具有缓冲区溢出问题 */ 
        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\n");
        return 1;
    }

    上述程序存在缓冲区溢出漏洞。它首先从名为 badfile 的文件读取输入,然后将此输入传递给函数中的另一个缓冲区 bof()。原始输入的最大长度为 517 字节,但 bof() 中的缓冲区大小仅为 BUF_SIZE 字节,且小于 517。 因为 strcpy() 不检查边界,所以会发生缓冲区溢出。由于此程序是 root 所拥有的 setuid 程序,如果普通用户能够利用这个缓冲区溢出漏洞,则可能能够获得一个 root shell。 请注意,该程序从名为 badfile 的文件中获取输入。此文件由用户控制。现在我们的目标是创建 badfile 文件的内容,当易受攻击的程序将这些内容复制到其缓冲区时,可以启动一个 root shell。

    要编译上述易受攻击的程序,请不要忘记使用 -fno-stack-protector 和 "-z execstack" 选项来禁用 StackGuard 和不可执行栈保护。 编译完成后,我们需要将程序设置为 root 所拥有的 setuid 程序。我们可以通过首先更改程序的所有权(行 ①)到根,然后将权限更改为 4755 以启用 setuid 比特(行 ②)。请注意,在设置 setuid 比特之前必须更改所有权,因为所有权更改会关闭此位。

    $ gcc -DBUF_SIZE=100 -m32 -o stack -z execstack -fno-stack-protector stack.c
    $ sudo chown root stack   ①
    $ sudo chmod 4755 stack   ②

    编译和设置命令已包含在 Makefile 中,所以我们只需键入 make 执行这些命令。变量 L1, ..., L4 在 Makefile 中被设置;它们将在编译过程中使用