格式字符串漏洞,意外结果

时间:2016-04-05 13:51:40

标签: c string security unix exploit

我试图在64位Linux上实现C中格式字符串漏洞的简单示例。这是我的源代码:

void not_called() {
    printf("Exploited\n");
}

int main(int argc, char **argv) {

    // Buffer overflow vulnerability
    char buffer[256];
    gets(buffer);

    // User may input the format string
    printf(buffer);
}

我输入以下字符串给程序

AAAABBBB-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x-%x

结果是

AAAABBBB-8608002c-f458fe00-fbad2288-78252d78-252d7825-5e5c51a8-0-41414141-2d78252d-78252d78-252d7825-2d78252d

我可以将AAAA视为41414141而不是BBBB跟随我的预期,因为它是缓冲区中相同输入字符串的组成部分。

这是某种保护机制还是我误解了什么?我的目标是覆盖返回地址,我需要读取8个字节(AAAABBBB),因为我在64位机器上工作。

漏洞利用字符串的伪代码看起来像这样

RETRNPTR%[decimal address of not_called - 8]u%[offset of RETRNPTR]$n

RETRNPTR是存储当前堆栈帧中返回地址的内存地址。

所以我最关心的是,8个字节的RETRNPTR似乎并不像我期望的那样在内存中持续存在。第二个问题是,%n是int-pointer,意味着只写入4个字节。我也很困惑,AAAA之前的那些价值来自哪里。

1 个答案:

答案 0 :(得分:2)

首先,您要问的是具有未定义行为的代码;代码的行为确实应该被一个临时的C程序员认为是未定义的大部分内容。

现在,为什么你没有看到{{each ChildProduct where ChildProduct.ParentID === $index}} 。我认为这是因为你在x86-64系统上运行这个程序。调用约定是对堆栈上的值进行64位推送;但是BBBB打印一个32位%x; 64位堆栈值的32个最低有效位。要打印64位int值,请使用long

(另外,在x86-64的System-V API上,6个第一个整数/指针参数根本不在堆栈上;它们位于%lxRDI,{{1} },RSIRDXRCX寄存器。)

例如我输入了:

R8

并获得输出

R9