Writing Data

Writing Memory

%n will deference a pointer from the stack and write the number of bytes written so far to it.

int namelength;
printf("%s%n", name, &namelength);
printf("The name was %d bytes long!", namelength);

Why is this bad?

%n requires a pointer to where we want to write. But:

  1. If our buffer is on the stack (and we can put a valid pointer into it), we can use that!
  2. %7$n (and other offsets) let us use different pointers on the stack.
  3. Frame pointers point to each other!

|700

  1. We can target ebp1 for %n and modify ebp2, then target ebp2.

This lets us operate independently of the stack ASLR!

Writing Memory Using Your Own Format String Attack

If our format string is on the stack: |700

This means that we can reference values in our format string using %[]$n. How do we figure out the []?

Writing Memory - Cont.

Problem: %n writes 4 bytes.

Solution:

  • %ln
  • %hn
  • %hhn

Problem: How do we control what to write?

Solution:

char buf[4];
printf("1145258561x%1$n", buf);

This writes “ABCD”, (with a shit ton of whitespace to the prefix) to buf!

Demo:


Problem: How do we limit the output amount?

Solution:

char buf[4];
printf("%65x%1hhn%c%2$hhn%c%3$hhn%c%4$hhn", buf, buf+1, buf+2, buf+3);

This writes “ABCD” to buf, but with lower cost! How can we write “DCBA”?

Copying Memory

One more thing: %*10c%11$n

* specifies a dynamic padding size. This will:

  1. Get the 10th parameter.
  2. Use it as the padding size of a single character.
  3. Print that many bytes.
  4. Write the number of bytes printed to memory pointed to by the 11th parameter. This results in a copy.

Problem: Not realistic for large values, too much output.