CookieMonster 是一款命令行工具和 API,用于解码和修改来自多种不同框架的漏洞会话 Cookie。它设计用于自动化流水线,这些流水线必须能够高效处理大量此类 Cookie,以便快速发现漏洞。此外,CookieMonster 是可扩展的,可以轻松支持新的 Cookie 格式。
需要强调的一点是,CookieMonster 发现的是框架使用者(而非框架本身)的漏洞。这些使用者可以通过配置框架使用强密钥来解决 CookieMonster 发现的漏洞。
| 框架 | 支持情况 | 备注 |
|---|---|---|
| JSON Web Tokens | ✅ | HS256、HS384、HS512 |
| Django | ✅ | 常见算法 |
| Flask | ✅ | 常见算法 |
| Rack | ✅ | 常见算法 |
| Express (cookie-signer) | ✅ | 常见算法 |
| Laravel | ✅ | AES-CBC-128/256(GCM 尚未支持) |
| itsdangerous | ✅ | URLSafeSerializer/URLSafeTimedSerializer(默认盐值) |
| 其他 | ❌ | 目前还不支持! |
要安装 CookieMonster,请先安装 Go,然后安装 CLI:
go install github.com/iangcarroll/cookiemonster/cmd/cookiemonster@latest
CookieMonster 只需要两样核心内容:一个要尝试签名验证的 Cookie,以及一个要使用的词表。如果您没有词表,CookieMonster 附带了来自 Flask-Unsign 项目的默认词表。CookieMonster 的词表略有不同:每一行都必须经过 base64 编码。这是因为 Python 项目特别随意地在这些密钥中插入垃圾字节,我们需要能够正确处理它们。
下面是一个使用静态 Cookie 或 URL 使用 CLI 的示例:
% ./cookiemonster -cookie "gAJ9cQFYCgAAAHRlc3Rjb29raWVxAlgGAAAAd29ya2VkcQNzLg:1mgnkC:z5yDxzI06qYVAU3bkLaWYpADT4I"
🍪 CookieMonster 1.3.0
ℹ️ CookieMonster 已加载默认词表;共有 38919 条条目。
✅ 成功!我使用 django 解码器发现了此 Cookie 的密钥,密钥为 "changeme"。
% ./cookiemonster -url "https://httpbingo.org/cookies/set?abc=gAJ9cQFYCgAAAHRlc3Rjb29raWVxAlgGAAAAd29ya2VkcQNzLg:1mgnkC:z5yDxzI06qYVAU3bkLaWYpADT4I"
🍪 CookieMonster 1.3.0
⚠️ 从该 URL 返回的状态码不是 200,而是 302。
ℹ️ CookieMonster 已加载默认词表;共有 38919 条条目。
✅ 成功!我使用 django 解码器发现了此 Cookie 的密钥,密钥为 "changeme"。
CookieMonster 能够支持由 cookie-session(在 Express 中常见)签名的 Cookie。然而,它有一些奇怪的地方,需要小心才能使用此工具。cookie-session 应用程序的常见响应如下所示:
set-cookie: session=eyJhbmltYWxzIjoibGlvbiJ9
set-cookie: session.sig=Vf2INocdJIqKWVfYGhXwPhQZNFI
要将其传递给 CookieMonster,您必须同时包含 Cookie 名称和签名 Cookie。在这个例子中,您应该这样调用 CookieMonster:cookiemonster -cookie session=eyJhbmltYWxzIjoibGlvbiJ9^Vf2INocdJIqKWVfYGhXwPhQZNFI(注意分隔符 ^ 和前缀的 Cookie 名称)。API 在 monster.NewCookie 中接受相同的格式。
CookieMonster 对使用 -resign 标志对已签名验证的 Cookie 进行重新签名提供了有限的支持。这包括修改 Cookie 的主体以匹配您的输入,然后使用我们发现的密钥重新计算签名。目前,您可以对 Django 解码的 Cookie 执行此操作;请确保使用 -cookie 传递原始 Cookie,并使用 -resign 传递您希望放入 Cookie 中的未编码字符串文本。CookieMonster 将正确编码您的输入,然后重新签名 Cookie。
CookieMonster 公开了 pkg/monster,允许其他应用程序轻松利用它。如果您要测试大量 Cookie,这比启动 CLI 性能更高。下面是一个使用示例。
import (
"github.com/iangcarroll/cookiemonster/pkg/monster"
"errors"
)
var (
//go:embed wordlists/my-wordlist.txt
monsterWordlist string
wl = monster.NewWordlist()
)
func init() {
if err := wl.LoadFromString(monsterWordlist); err != nil {
panic(err)
}
}
func MonsterRun(cookie string) (success bool, err error) {
c := monster.NewCookie(cookie)
if !c.Decode() {
return false, errors.New("could not decode")
}
if _, success := c.Unsign(wl, 100); !success {
return false, errors.New("could not unsign")
}
return true, nil
}
CookieMonster 的构建灵感来源于多个来源,并附带了优秀的 Flask-Unsign 词表。