Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

FeedsContatoPrivacidade© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
AfterLife — Laboratório de detecção de persistência de revogação: quando a redefinição de senha é bem-sucedida, mas o atacante nunca vai embora. Reproduz o bug de revogação condicional do Strapi CVE-2026-22706, sua correção, um pacote de detecção com três regras e a regra ingênua que não o detecta. | Kitploit
Ferramentas/GitHubGitHub/het-p301204/afterlife
Ferramentas DefensivasAnálise de VulnerabilidadesSegurança WebAutenticaçãoAprendizado e EducaçãoRed TeamingResposta a IncidentesLabs e Prática
GitHubhet-p301204/afterlife

AfterLife

Ver Repositório
35há 1 mêsAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →

Sobre

Laboratório de detecção de persistência de revogação: quando a redefinição de senha é bem-sucedida, mas o atacante nunca vai embora. Reproduz o bug de revogação condicional do Strapi CVE-2026-22706, sua correção, um pacote de detecção com três regras e a regra ingênua que não o detecta.

Compartilhar

AFTERLIFE

Laboratório de Detecção de Persistência de Revogação

Quando a redefinição de senha é bem-sucedida, mas o atacante nunca vai embora.

Um laboratório local red/blue para uma classe de vulnerabilidade: a credencial que sobrevive ao evento que deveria eliminá-la. Ele entrega o exploit, a causa raiz, a correção, um pacote de detecção com três regras, uma auditoria de estado para o que as regras estruturalmente não conseguem ver, um console forense — e a regra de detecção que não funciona, mantida no repositório para ser demonstrada falhando.

CI tests python rules OWASP CWE license

Início rápido · A descoberta · Por que a detecção ingênua falha · O pacote de regras · Console · A correção · Matriz · Testes · Documentação


O mesmo ataque contra ambas as implementações. Uma barra por credencial, da emissão à morte, agrupadas em linhagens. A linha tracejada é a troca de senha. No modo vulnerável, cinco barras a cruzam e continuam; no modo corrigido, toda barra na linhagem roubada para ali.

O mesmo ataque. As mesmas requisições. Uma diferença. Gerado por scripts/figures.py a partir do mesmo payload que o console desenha — regenerado e comparado por diff na CI, para que uma figura não possa divergir do código.


A ação de contenção que não contém```text

09:00 alice logs in ┐ refresh credential rt-001 │ the attacker steals rt-001 ┘

10:00 alice changes her password ← the one thing a victim can do alone HTTP 200 · password changed · fresh session issued

10:00:03 attacker: POST /refresh rt-002 → HTTP 200 new access credential at-004, issued 10:00:03

10:01:00 attacker: GET /me at-004 → HTTP 200 {"username": "alice", "authenticated": true}

Sem erro. Sem anomalia. Sem autenticação falhada para contar. A credencial de acesso do atacante tem *três segundos de vida* e foi emitida pelo servidor, a pedido, após o reset.

Eis a vulnerabilidade completa:```python
def _revoke_for_security_change(self, user, kind, device_id):
    if device_id:
        revoke_credentials(user, device_id=device_id)   # ← the finding

Leia isso como um revisor leria. A lógica de revogação está bem ali. Ela chama a função correta com o escopo correto. O endpoint ao redor atualiza o hash da senha, retorna 200 e emite uma nova sessão — todo comportamento observável de uma troca de senha correta está presente.

E se o chamador omitir device_id, nada é revogado, e o endpoint ainda relata sucesso.

Isso não é hipotético. É CVE-2026-22706 no Strapi ≤ 5.33.2, onde a etapa de invalidação do refresh-token era condicional a um deviceId fornecido pelo chamador. Pontuado como 2.1, Low. Discutido abaixo.


Por que isso importa

A pontuação é baixa porque o atacante já tinha acesso — essa é a condição de entrada, e este bug não concede nada novo. O que ele concede é duração, e o faz quebrando o único controle que a vítima pode operar por conta própria.

  • Todo runbook de account-takeover começa com redefina a senha. Todo produto diz a mesma coisa ao usuário.
  • Quando isso falha silenciosamente, a vítima é informada de que o problema foi resolvido e para de procurar — o que desliga o sinal de detecção que mais importa em account takeover: o usuário perceber.
  • A janela de persistência é o tempo de vida da credencial de refresh: 30 dias por padrão, renovável indefinidamente por rotação. test_persistence_lasts_as_long_as_the_refresh_credential percorre sete dias de tempo simulado para demonstrar isso.
  • Não há uma segunda ação que o usuário possa tomar. Uma segunda troca de senha faz exatamente o mesmo que a primeira.

Um bug com pontuação Low em um caminho de contenção custa mais do que um bug com pontuação Low em um caminho de funcionalidade, porque o custo é pago durante um incidente, quando ninguém está lendo advisories.


O detector ingênuo

A regra que você escreve primeiro:```text IF credential.issued_at < credential_change.timestamp: ALERT

Não é uma regra estúpida. É barata, precisa de um campo, lê-se como a definição
do problema, e está **correta quanto ao caso simples** — um atacante que use um
token de *acesso* roubado após o reset é apanhado.
`test_the_naive_rule_catches_the_simple_case` afirma que funciona.

Ambas as regras fazem a mesma pergunta sobre a mesma credencial. Leem campos
diferentes para responder, e os dois campos discordam:

![Duas linhas, uma por campo. credential.issued_at lê 10:00:03, três segundos após a alteração, e conclui que a credencial parece limpa. lineage.root_issued_at lê 09:00:00, uma hora antes da alteração, e alerta.](https://raw.githubusercontent.com/het-p301204/afterlife/main/docs/figures/two-fields.svg)

**Três segundos depois, ou uma hora antes — a mesma credencial, no mesmo
instante.** A regra ingénua pergunta a um campo que o atacante controla, e um
`POST /refresh` reinicia-o.

Executa-a sobre o registo de pedidos, que é onde esta consulta é realmente escrita,
porque os registos de pedidos são o que tens:```text
NAIVE DETECTOR (NAIVE-001), over the request log

  Result: NO ALERT

  Six requests were served to the attacker after the reset. Every one of them
  carried at-004, minted at 10:00:03 -- three seconds *after* the password
  change. By its own timestamp it is the newest credential on the account.

Seria fácil parar por aí, e desonesto, então o laboratório também executa a versão mais justa da regra ingênua — ampliada para observar também o endpoint de refresh:```text NAIVE DETECTOR, widened to include POST /refresh

1 alert at 2026-09-11T10:00:03.000Z: the credential presented to /refresh was rt-002, issued 2026-09-11T09:30:00.000Z. Then it goes blind. 6 events follow that hop and it flags none of them, because every credential from there on carries a post-reset timestamp. Its incident covers 1 accepted request; the lineage rule's covers all of them.

And look at what the alert names: NAIVE-001 revoke rt-002 -- rotated away and already dead at 10:00:03 AFTERLIFE-001 revoke lin-001 -- the live thing every future credential descends from

Essa é a diferença que importa às 3 da manhã. A regra ingênua captura o único
instante em que a cadeia cruza a fronteira, e então perde o rastro pelos 29 dias
restantes — e a credencial que ela nomeia *já foi rotacionada e revogada
pelo servidor*. Revogá-la não resolve nada. `lin-001` é o objeto que você
precisa eliminar.
Baixar ferramenta