4

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

4

3 回答 3

9

我建议阅读关于利用缓冲区溢出漏洞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;
}
于 2010-03-08T16:49:36.970 回答
1

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

以下文章更关注堆溢出:

于 2010-03-09T15:57:14.267 回答
0

如果不了解应用程序的更多信息,这有点难以了解,但首先想到的是堆喷射

于 2010-03-08T16:42:02.637 回答