格式字符串攻击

时间:2012-11-16 02:27:56

标签: c buffer-overflow format-string fortify-source

我有一个小的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 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”的内容。但它不起作用。任何建议将不胜感激。非常感谢。

1 个答案:

答案 0 :(得分:8)

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

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

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

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

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

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