
Decodifica e remove a assinatura de cookies de sessão vulneráveis dos frameworks Django, Flask, Laravel, Express e JWT. Suporta decodificadores baseados em HMAC, listas de palavras base64 e pipelines de automação para descoberta rápida de vulnerabilidades.
CookieMonster é uma ferramenta de linha de comando e API para decodificar e modificar cookies de sessão vulneráveis de vários frameworks diferentes. Foi projetado para ser executado em pipelines de automação que precisam processar eficientemente uma grande quantidade desses cookies para descobrir vulnerabilidades rapidamente. Além disso, CookieMonster é extensível e pode suportar facilmente novos formatos de cookie.
Vale ressaltar que CookieMonster encontra vulnerabilidades em usuários dos frameworks, geralmente não nos próprios frameworks. Esses usuários podem resolver as vulnerabilidades encontradas via CookieMonster configurando o framework para usar uma chave secreta forte.
| Framework | Suportado | Observações |
|---|---|---|
| JSON Web Tokens | ✅ | HS256, HS384, HS512 |
| Django | ✅ | Algoritmos comuns |
| Flask | ✅ | Algoritmos comuns |
| Rack | ✅ | Algoritmos comuns |
| Express (cookie-signer) | ✅ | Algoritmos comuns |
| Laravel | ✅ | AES-CBC-128/256 (GCM ainda não suportado) |
| itsdangerous | ✅ | URLSafeSerializer/URLSafeTimedSerializer (salt padrão) |
| Outros | ❌ | Ainda não! |
Para instalar o CookieMonster, instale o Go e depois instale a CLI:
go install github.com/iangcarroll/cookiemonster/cmd/cookiemonster@latest
CookieMonster precisa apenas de dois itens essenciais: um cookie para tentar remover a assinatura e uma wordlist para usar. Se você não tiver uma wordlist, CookieMonster vem com uma wordlist padrão do projeto Flask-Unsign. As wordlists do CookieMonster são um pouco diferentes: cada linha deve ser codificada com base64. Isso ocorre porque os projetos em Python são especialmente liberais ao inserir bytes de lixo nessas chaves, e precisamos ser capazes de lidar com elas adequadamente.
Um exemplo de uso da CLI com um cookie estático ou com uma URL:
% ./cookiemonster -cookie "gAJ9cQFYCgAAAHRlc3Rjb29raWVxAlgGAAAAd29ya2VkcQNzLg:1mgnkC:z5yDxzI06qYVAU3bkLaWYpADT4I"
🍪 CookieMonster 1.3.0
ℹ️ CookieMonster loaded the default wordlist; it has 38919 entries.
✅ Success! I discovered the key for this cookie with the django decoder; it is "changeme".
% ./cookiemonster -url "https://httpbingo.org/cookies/set?abc=gAJ9cQFYCgAAAHRlc3Rjb29raWVxAlgGAAAAd29ya2VkcQNzLg:1mgnkC:z5yDxzI06qYVAU3bkLaWYpADT4I"
🍪 CookieMonster 1.3.0
⚠️ I got a non-200 status code from this URL; it was 302.
ℹ️ CookieMonster loaded the default wordlist; it has 38919 entries.
✅ Success! I discovered the key for this cookie with the django decoder; it is "changeme".
CookieMonster é capaz de suportar cookies assinados com cookie-session, que é comum no Express. No entanto, ele faz várias coisas estranhas que exigem cuidado para usar esta ferramenta. Uma resposta comum de uma aplicação cookie-session se parece com isso:
set-cookie: session=eyJhbmltYWxzIjoibGlvbiJ9
set-cookie: session.sig=Vf2INocdJIqKWVfYGhXwPhQZNFI
Para passar isso para o CookieMonster, você deve incluir tanto o nome do cookie quanto o cookie de assinatura. Neste exemplo, você chamaria o CookieMonster assim: cookiemonster -cookie session=eyJhbmltYWxzIjoibGlvbiJ9^Vf2INocdJIqKWVfYGhXwPhQZNFI (observe o delimitador ^ e o nome do cookie prefixado). A API aceita o mesmo formato em monster.NewCookie.
CookieMonster tem suporte limitado para re-assinar um cookie depois que a assinatura foi removida, com a flag -resign. Isso envolve modificar o corpo do cookie para corresponder à sua entrada e, em seguida, recalcular a assinatura com a chave que descobrimos. Atualmente, você pode fazer isso para cookies decodificados do Django; certifique-se de passar o cookie original para -cookie e passar para -resign uma string de texto não codificada que você deseja que esteja dentro do cookie. O CookieMonster codificará corretamente sua entrada e então re-assinará o cookie.
CookieMonster expõe pkg/monster, que permite que outros aplicativos aproveitem facilmente. Isso é muito mais eficiente do que iniciar a CLI se você estiver testando muitos cookies. Um exemplo de uso está abaixo.
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 é construído com inspiração de várias fontes e vem com as excelentes wordlists do Flask-Unsign.