【问题标题】:For buffer overflows, what is the stack address when using pthreads?对于缓冲区溢出,使用 pthread 时的堆栈地址是什么?
【发布时间】:2010-03-08 16:30:57
【问题描述】:

我正在学习计算机安全课程,并且有一个额外的学分分配将可执行代码插入缓冲区溢出。我有我正在尝试操作的目标程序的 c 源代码,并且我已经到了可以成功覆盖当前函数堆栈帧的 eip 的地步。但是,我总是遇到分段错误,因为我提供的地址总是错误的。问题是当前函数位于 pthread 内部,因此,堆栈的地址似乎总是在程序的不同运行之间发生变化。是否有任何方法可以在 pthread 中查找堆栈地址(或用于估计 pthread 中的堆栈地址)? (注意:pthread_create 的第二个参数为空,所以我们没有手动分配堆栈地址)

【问题讨论】:

    标签: c pthreads stack memory-address buffer-overflow


    【解决方案1】:

    我建议阅读关于利用缓冲区溢出漏洞的优秀文章/教程(如果有点过时)Smashing The Stack For Fun And Profit

    这里有一个简短的摘录:

    问题是我们不知道内存空间在哪里 我们试图利用代码(以及后面的字符串)的程序 它)将被放置。一种解决方法是使用 JMP 和 CALL 操作说明。 JMP 和 CALL 指令可以使用 IP 相对寻址, 这意味着我们可以在不需要的情况下跳转到当前 IP 的偏移量 知道我们要跳转到内存中的确切地址。


    您可以通过一些内联汇编来检索堆栈指针的当前值。 Smashing The Stack For Fun And Profit 中的所有示例都溢出了main 中的缓冲区,但是您可以轻松地使用相同的技术在从 pthread 调用的函数中溢出缓冲区。下面的代码基于文章 (overflow1.c) 中的示例构建,以显示相同的技术可以使用 pthreads 工作。您将使用的实际技术将取决于您尝试利用的目标程序。

    
    /* get value of sp off the stack - not essential to example */
    unsigned long get_sp()
    {
       __asm__("movl %esp,%eax"); /* equiv. of 'return esp;' in C */
    }
    
    int foo()
    {
       char buffer[96];
    
       /* overflow buffer to overwrite return address */
       /* and place code to be executed into buffer. */
       ...
    
       return 0;
    }
    
    void *thread(void *arg)
    {
       printf("thread stack 0x%x\n", get_sp()); 
    
       foo();   
    
       return NULL;
    }
    
    int main(int argc, char **argv) 
    {
       printf("main stack 0x%x\n", get_sp());   
    
       pthread_t t;
       pthread_create(&t, NULL, thread, NULL);
       pthread_join(t, NULL);
    
       return 0;
    }
    

    【讨论】:

    • 我实际上正在阅读那篇文章。我得再研究一遍,但那句话不是指在缓冲区内获取“/bin/sh”的地址吗?难道我们还不需要覆盖eip,让它指向初始的跳转指令吗?
    • 使用strcpy() 建立的摘录示例溢出了字符缓冲区。溢出会覆盖堆栈上的返回地址(保存的 IP),使其指向缓冲区内的 JMP 指令。 JMP 指令跳转到调用execve()execve() 的CALL 指令,该指令已全部作为shellcode 复制到缓冲区中。后面的文章建议用 NOP 指令填充溢出缓冲区的前面,这样返回地址只需要指向 NOP 中的某个位置。
    • 感谢 jschmier 的所有回复。我的助教提到,通过使用 pthread,程序可以有效地执行堆栈随机化,作为防止缓冲区溢出的预防技术。 JMP 和 CALL 指令的方法仅在返回地址更改为指向缓冲区中的代码后才有效。但是由于程序使用的是pthreads,所以不知道用什么内存地址来覆盖返回地址。
    【解决方案2】:

    除了我之前的回答,您可能还想阅读以下内容:

    以下文章更侧重于堆溢出:

    【讨论】:

      【解决方案3】:

      如果不了解该应用程序的更多信息,有点难以了解,但首先想到的是heap spraying

      【讨论】:

        猜你喜欢
        • 2021-11-02
        • 2010-11-10
        • 2015-12-31
        • 2014-12-09
        • 1970-01-01
        • 2017-02-23
        • 2011-04-23
        • 1970-01-01
        • 2019-01-05
        相关资源
        最近更新 更多