6

I have a small C program to be exploited. And I also understood the logic behind the attack to be performed. However, as much as I try, it is just not working for me.

#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;
}

I just need to print the address and value of secret[0] using the format string "printf(user_input);"

I have tried giving something like "\x6e\xaf\xff\xff%x%x%x%x%s". but it is not working. Any suggestions will be appreciated. Thanks a lot.

4

1 回答 1

9

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

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

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

现在的诀窍是弄清楚如何在堆栈中向上走,直到找到合适的指针。方便的是,在堆栈指针之前有一个用户控制的整数。因此,我们输入一个易于识别的数字(可能是 65535,它是ffff十六进制),并使用带有很多%xs 的格式字符串来查看堆栈中的内容。一旦我们发现,堆栈上的下一个东西应该是指针。

唔。我刚刚尝试了这个,结果发现它并不是那么简单。堆栈帧的确切布局实际上与声明的顺序无关;对我来说,不同的系统之间有所不同。取而代之的是,我不得不使用很多%lxs,以及开头的一个众所周知的字符串,并添加一行来打印出实际的指针,这样我就会知道什么时候找到它。然后将对应的替换为%lx%n通过该指针写入。尝试 20 左右可能是最简单%lx的,然后用 逐个替换%n,直到您设法覆盖该指针。

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

于 2012-11-16T05:10:04.937 回答