c-格式化字符串攻击



我有一个小的C程序要利用。我也理解了要实施的攻击背后的逻辑。然而,尽管我尝试了很多,但它对我来说并不奏效

#include <stdio.h>
#include <stdlib.h>
#define SECRET1 0x44
#define SECRET2 0x55
int main(int argc, char *argv[]) {
char user_input[100];
int *secret;
int int_input;
int a, b, c, d; /* other variables, not used here.*/
/* The secret value is stored on the heap */
secret = (int *) malloc(2*sizeof(int));
/* getting the secret */
secret[0] = SECRET1; secret[1] = SECRET2;
printf("Please enter a decimal integern");
scanf("%d", &int_input);  /* getting an input from user */
printf("Please enter a stringn");
scanf("%s", user_input); /* getting a string from user */
printf(user_input);
printf("n");
/* Verify whether your attack is successful */
printf("The original secrets: 0x%x -- 0x%xn", SECRET1, SECRET2);
printf("The new secrets:      0x%x -- 0x%xn", secret[0], secret[1]);
return 0;
}

我只需要使用格式字符串"printf(user_input);"打印secret[0]的地址和值

我试过给出一些类似"\x6e\xaf\xff\xx%x%x%x%s"的内容。但它不起作用。如有任何建议,我们将不胜感激。非常感谢。

这看起来像是一个类的练习,所以我将提供一些指针,但没有实际的解决方案。

您正试图通过提供不受信任的输入来利用此程序进行攻击。这里有两个相当明显的bug;一种是使用%sscanf(),因为您可以使缓冲区溢出并覆盖堆栈。另一个是格式字符串漏洞。在函数返回之前,重写堆栈可能不会让您做任何有趣的事情。根据"验证您的攻击是否成功"部分,您可能想在此之前利用该漏洞,所以我猜这应该是一个格式字符串漏洞。

根据验证部分,您需要覆盖secret指向的内存。使printf写入内存中受控位置的唯一方法是使用%n格式说明符,它写入给定的指针。

现在的诀窍是找出如何在堆栈中遍历,直到找到合适的指针。方便的是,在堆栈上的指针前面有一个用户控制的整数。因此,我们输入一个具有易于识别模式的数字(可能是65535,十六进制中的ffff),并使用一个包含大量%x的格式字符串来查看堆栈上的内容。一旦我们发现,堆栈上的下一个东西应该是指针。

嗯。我刚试过这个,结果发现并不是那么简单。堆栈框架的确切布局实际上与声明的顺序无关;对我来说,不同系统之间的指针不同。相反,我必须使用大量的%lxs,以及开头的一个众所周知的字符串,并添加一行打印出实际的指针,这样我就知道什么时候找到了它。然后用%n替换相应的%lx来写入该指针。最简单的方法可能是尝试20个左右的%lx,然后用%n逐个替换,直到您成功覆盖该指针。

无论如何,希望这足以让你开始。如果你有任何问题,请告诉我。

最新更新