格式字符串攻击

我有一个小的C程序可以被利用。 而且我也理解了要执行的攻击背后的逻辑。 但是,尽管我尝试过,但这对我来说并不适用。

#include  #include  #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 integer\n"); scanf("%d", &int_input); /* getting an input from user */ printf("Please enter a string\n"); 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%x\n", SECRET1, SECRET2); printf("The new secrets: 0x%x -- 0x%x\n", secret[0], secret[1]); return 0; } 

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

我试过给出类似“\ x6e \ xaf \ xff \ xff%x%x%x%x%s”的东西。 但它不起作用。 任何建议将不胜感激。 非常感谢。

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

您试图通过提供不受信任的输入来利用此程序。 这里有两个相当明显的错误; 一个是使用%sscanf() ,因为你可以溢出缓冲区并覆盖堆栈。 另一种是格式字符串漏洞。 在函数返回之前,覆盖堆栈可能不会让你做任何有趣的事情。 基于“validation您的攻击是否成功”部分,您可能希望在此之前利用此漏洞,因此我猜它应该是格式字符串漏洞。

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

现在的诀窍是弄清楚如何在堆栈中找到适当的指针。 方便的是,在堆栈上的指针之前有一个用户控制的整数。 因此,我们输入一个带有易于点模式的数字(可能为65535,hex为ffff ),并使用带有大量%x s的格式字符串来查看堆栈中的内容。 一旦我们找到了,堆栈上的下一件事应该是指针。

嗯。 我刚试过这个,结果发现它并不那么简单。 堆栈帧的确切布局实际上与声明的顺序无关; 它对我来说在不同系统之间有所不同。 相反,我必须使用很多%lx s,以及开头的一个众所周知的字符串,并添加一行来打印实际的指针,所以我知道我何时找到它。 然后用%n替换相应的%lx以通过该指针进行写入。 最简单的方法是尝试20左右的%lx s,并用%n逐个替换,直到你设法覆盖该指针。

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