C 对于缓冲区溢出,使用pthreads时堆栈地址是什么?

C 对于缓冲区溢出,使用pthreads时堆栈地址是什么?,c,pthreads,stack,memory-address,buffer-overflow,C,Pthreads,Stack,Memory Address,Buffer Overflow,我修了一门计算机安全课程,有一个额外的学分分配,可以将可执行代码插入缓冲区溢出。我有我试图操作的目标程序的c源代码,我已经达到了可以成功覆盖当前函数堆栈帧的eip的程度。但是,我总是遇到分段错误,因为我提供的地址总是错误的。问题在于当前函数位于pthread内部,因此,堆栈地址似乎总是在程序的不同运行之间发生变化。是否有任何方法可以在pthread中查找堆栈地址(或估计pthread中的堆栈地址)?(注意:pthread_create的第2个参数为null,因此我们不是手动分配堆栈地址)如果不了

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

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

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

以下是一个简短的摘录:

问题是我们不知道内存空间中 我们正在尝试利用代码(以及后面的字符串 它)将被放置。一种解决方法是使用JMP和调用 指示JMP和CALL指令可以使用IP相对寻址, 这意味着我们可以跳转到当前IP的偏移量,而无需 要知道我们要跳转到内存中的确切地址


可以使用一点内联程序集检索堆栈指针的当前值。中的所有示例都会使
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指令跳转到调用指令,该指令调用
/bin/sh
execve()
,该指令已作为外壳代码复制到缓冲区中。本文稍后建议用NOP指令填充溢出缓冲区的前端,这样返回地址只需要指向NOP中的某个位置。谢谢你的回复,jschmier。我的TA提到,通过使用pthreads,程序可以有效地执行堆栈随机化,作为防止缓冲区溢出的一种技术。JMP和CALL指令的方法只有在返回地址被更改为指向缓冲区中的代码时才起作用。但是,由于程序使用pthreads,我不知道使用什么内存地址来覆盖返回地址。