moectf2023 - feedback
文件分析
下载feedback
, 保护全开
ghidra分析为64位程序
缓冲区没有溢出,所以没法利用栈溢出等,因为可以访问stdout等,故利用_IO_FILE
本题是我第一次做_IO_FILE
,详细写写
前置知识
_IO_FILE
中存在_flags
,各标志位含义如下
1 | /* Magic numbers and bits for the _flags field. |
pwn中常用0xfbad1800
puts, sprintf, printf等包装函数,最后都会调用write,可以对stdout结构体进行修改,
实现leak;其中结构体中的_chain
,在stdout中会指向stdin;在执行包装输出函数前,
会打印_IO_write_base
到_IO_write_ptr
范围内的字符;初始化后_IO_write_*
会指向结构体中的_shortbuf
,通过覆盖最后一个字节,可以将base指向_chain
tips
一开始在我本地上跑的时候,flag是无法写入的:
read函数返回-1(val of rax),使用p *__errno_location()
查询errno得知,
14: Bad Address,本身读入的地址就没有w权限
后来发现zip包里含有ld和libc, 可以patchelf(这里我把这两各文件放在./libs下)
Arch Linux可以直接pacman(yay)安装patchelf哦
gdb中要重启程序不需要q,先kill再run/start即可
1 | patchelf --set-interpreter ./libs/ld-2.31.so --replace-needed libc.so.6 ./libs/libc-2.31.so feedback |
patch后gdb调试发现这时flag就会放到一个匿名内存段,不会崩溃了
解题思路
反汇编后得知,flag放在比puts
高0x16d2e0的地址,而puts
的地址是随机化的,
因此可以获取libc中的任意地址然后偏移取得flag地址
在vuln函数中要输入数组索引,而索引被限定为小于4;观察.bss段布局可知,
stdout地址比feedback_list
低,将索引输入为-8,就可以覆盖stdout写入
gdb调试后可以知道stdin与flag位置的差值
EXPLOIT
1 | from pwn import * |
Done.
- 标题: moectf2023 - feedback
- 作者: RocketDev
- 创建于 : 2023-09-27 12:00:00
- 更新于 : 2024-07-30 10:28:00
- 链接: https://rocketmadev.github.io/2023/09/27/feedback/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。