解码 Cookie
解码并验证现有 Flask Cookie伪造 Cookie
生成有效的签名 Flask Cookie工作原理
Flask 使用 itsdangerous 库以 HMAC 对会话 Cookie 进行签名。Cookie 格式为三个以点分隔的 base64url 段:PAYLOAD.TIMESTAMP.SIGNATURE。密钥派生方式为 HMAC-{algo}(key=secret, msg=salt)——派生密钥再用于计算 HMAC-{algo}(key=derived, msg=PAYLOAD.TIMESTAMP)。本工具解码并可选验证任意 Flask 会话 Cookie,然后允许伪造新的——全部在服务器端 PHP 中完成,不存储任何输入。
- 1. Get the cookie: 在 Burp Suite 或浏览器 DevTools 中拦截目标请求并复制会话 Cookie 值。
- 2. Decode: 粘贴 Cookie 以在无需密钥的情况下显示 JSON 载荷——Flask Cookie 是签名的,而非加密的。
- 3. 获取 SECRET_KEY: 在目标应用配置、泄露的 .env、git 历史中查找,或从已知签名中破解。
- 4. Modify & forge: 修改 JSON 载荷(例如设置 user_id 或 is_admin),输入 SECRET_KEY 并伪造新的有效签名 Cookie。
- 5. Inject: 替换请求中的会话 Cookie 并重新发送。
什么是 Flask 会话 Cookie?
Flask 将整个会话字典直接存储在浏览器 Cookie 中——默认情况下没有服务器端会话存储。会话对象经 JSON 序列化、可选 zlib 压缩、base64url 编码,并使用应用的 SECRET_KEY 以 HMAC 签名。签名防止篡改,但由于载荷未加密,任何人无需密钥即可读取会话数据。这使得 Flask 会话 Cookie 成为 CTF 网络挑战中的常见目标。
payload
base64url 编码的 JSON 对象(若有点号前缀则为 zlib 压缩)。包含会话数据——user_id、角色、CSRF 令牌等。
timestamp
打包进 base64url 的 4 字节大端序 Unix 时间戳。存在于有时间戳的 Cookie(URLSafeTimedSerializer)中。用于 Cookie 过期检查。
signature
base64url(HMAC-{algo}(derived_key, PAYLOAD.TIMESTAMP))。派生密钥 = HMAC-{algo}(secret_key, salt)。默认 salt 为 "cookie-session"。
compression
当压缩能节省空间时,itsdangerous 使用 zlib deflate 压缩载荷。压缩载荷在 base64url 编码前以点号为前缀。
常见问题
这会将我的 Cookie 或 SECRET_KEY 发送到任何地方吗?
不会。所有解码和签名均在服务器端 PHP 中进行。不存储、不记录、不向第三方传输任何数据。
我能在没有 SECRET_KEY 的情况下读取载荷吗?
可以——Flask Cookie 是签名的,而非加密的。无需密钥粘贴 Cookie 即可立即查看 JSON 会话数据。只有在验证或伪造有效签名时才需要 SECRET_KEY。
itsdangerous 的密钥派生是如何工作的?
itsdangerous 将签名密钥派生为 HMAC-{algo}(key=secret_key, msg=salt)。签名随后为 HMAC-{algo}(key=derived_key, msg=PAYLOAD.TIMESTAMP)。这与直接 HMAC 不同——salt 在同一秘密密钥的不同使用场景之间增加了域隔离。
伪造时应选择哪种算法?
HMAC-SHA1 是 Flask/itsdangerous 的默认算法。仅在目标应用明确配置时才使用 HMAC-SHA512。可在解码时同时尝试两种算法来检测——本工具先尝试 sha1,再尝试 sha512。
解码失败或签名无效——为什么?
确保粘贴的是未经 URL 编码(%3D 等)的原始 Cookie 值。本工具会自动处理 URL 编码的输入。对于签名验证,请检查 SECRET_KEY 是否正确且 salt 与目标应用匹配(默认为 "cookie-session")。