Thanks to visit codestin.com
Credit goes to github.com

Skip to content

API em Rust intencionamente vulneravel a vazamento de dados sensiveis via vazamento de memoria não inicializada.

fguisso/http-echo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🚨 Echo Desatento

🎯 O Desafio

Este é um desafio de desenvolvimento seguro que demonstra uma vulnerabilidade real de vazamento de memória não inicializada em uma API Rust. O cenário simula um serviço de echo de alta performance que implementou um padrão de reutilização de buffers para otimização, mas falhou na execução segura.

Contexto Técnico

A API utiliza um padrão comum em sistemas de alta performance: reutilização de buffers. Para evitar alocações constantes de memória, a equipe implementou um sistema que reutiliza buffers pré-alocados. O erro fatal foi assumir que poderia simplesmente resetar o tamanho do buffer para sua capacidade máxima sem limpar adequadamente o conteúdo anterior, causando vazamento de dados sensíveis.

Impacto

  • Exposição de Dados de Sessão: Tokens JWT e IDs de usuário
  • Vazamento de Informações de Autenticação: Dados de login e permissões
  • Informações de Sistema: Dados residuais de operações anteriores
  • Violação de Confidencialidade: Acesso não autorizado a dados privados de outros usuários

Narrativa

Você é um pentester contratado para avaliar a segurança de uma nova API de echo. O cliente suspeita que há uma vulnerabilidade que pode expor dados sensíveis. Sua missão é identificar e explorar essa falha para demonstrar o impacto real.

📋 Sua Missão

  1. Reconhecimento: Entender como a API funciona
  2. Identificação: Descobrir a vulnerabilidade de vazamento
  3. Exploração: Fazer requisições que maximizem o vazamento
  4. Extração: Decodificar os bytes vazados para encontrar dados sensíveis
  5. Documentação: Registrar o processo e impacto

🚀 Começando

Pré-requisitos

  • Docker
  • curl
  • Conhecimento básico de HTTP

1. Preparar o Ambiente

Opção 1: Setup Automático (Recomendado)

# Clonar o repositório
git clone https://github.com/seu_usuario/echo_desatento.git
cd echo_desatento

docker build -t desafio-rust .

# Executar o container
docker run -p 8080:8080 --rm desafio-rust
Opção 2: Setup com Rust Direto
# Clonar o repositório
git clone https://github.com/seu_usuario/echo_desatento.git
cd echo_desatento

# Executar diretamente (requer Rust instalado)
cargo run

A API estará disponível em http://localhost:8080

2. Endpoints Disponíveis

  • GET /health - Verificar status da API
  • POST /echo - Endpoint vulnerável (aceita JSON)

🔍 Explorando como um Pentester

Teste Inicial

Vamos começar com uma requisição normal para entender o comportamento da API:

curl -s http://localhost:8080/echo \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{"message":"test"}' | ./decode_curl_output.sh

Nota: A resposta vem como um array de bytes. Usamos o script decode_curl_output.sh para torná-la legível.

Teste removendo alguns Headers

Agora vamos tentar uma requisição deixando alguns headers em branco:

curl -s http://localhost:8080/echo \
  -X POST \
  -H "Content-Type: application/json" \
  -H "User-Agent:" \
  -d '{"message":"x"}' | ./decode_curl_output.sh

🔎 O que Procurar

Analise as respostas procurando por:

  • Tokens JWT de sessão
  • IDs de usuário e dados de autenticação
  • Fragmentos de dados de sessão anteriores
  • Padrões de dados que não deveriam estar na resposta

💡 Dicas para a Correção

Dica Nível 1: Onde está o problema? A vulnerabilidade está na forma como o comprimento (`len`) do buffer de resposta é definido após os dados da requisição serem copiados para ele. Examine a função `handle_request_with_reused_buffer` no arquivo `src/main.rs`.
Dica Nível 2: Qual é o contrato quebrado? Examine o bloco `unsafe`. O método `set_len` tem um contrato de segurança muito estrito: você, o programador, garante a Rust que todos os bytes até o novo comprimento estão devidamente inicializados. Esse contrato está sendo cumprido?
Dica Nível 3: O que acontece com a memória não inicializada? Quando você define `buffer.set_len(MAX_BUFFER_SIZE)`, mas só copiou `bytes_to_copy` bytes, o que acontece com os bytes restantes? Eles contêm dados residuais de operações anteriores na memória.

✅ Soluções Possíveis

Solução 1: Corrigindo o Bloco unsafe

Se o uso de unsafe fosse absolutamente necessário por motivos de performance, a correção seria garantir que o len do buffer reflita exatamente a quantidade de bytes que foram inicializados.

Correção: Mude buffer.set_len(MAX_BUFFER_SIZE); para buffer.set_len(bytes_to_copy);.

Por quê? Assim, garantimos o contrato do set_len. Rust agora sabe o tamanho real dos dados válidos e não irá ler a memória não inicializada adjacente.

Solução 2: A Forma Idiomática e Segura (Sem unsafe)

Como discutido, o uso de unsafe deve ser a última alternativa. Em 99% dos casos, existe uma forma segura e quase tão performática de se atingir o mesmo objetivo. Neste cenário, a melhor solução é abandonar a otimização manual e deixar o Rust gerenciar a memória.

Correção Ideal: A função handle_request_with_reused_buffer pode ser reescrita sem unsafe algum, simplesmente criando um Vec<u8> a partir dos dados de entrada.

fn handle_request_safely(input_data: &[u8]) -> Vec<u8> {
    // Deixa Rust fazer o que faz de melhor: gerenciar memória de forma segura.
    // O compilador otimiza isso muito bem.
    input_data.to_vec()
}

Benefícios:

  • Elimina completamente a classe do bug
  • Código mais legível e manutenível
  • Performance similar (o compilador otimiza muito bem)
  • Segurança garantida pelo sistema de tipos do Rust

🎯 Próximos Passos

  1. Experimente diferentes tamanhos de entrada
  2. Teste com diferentes headers HTTP
  3. Analise como a vulnerabilidade se comporta
  4. Implemente as correções sem quebrar o funcionamento da API
  5. Compare o comportamento antes e depois da correção
  6. Desafio Extra: Implemente ambas as soluções e compare a performance

⚠️ Aviso Importante

ATENÇÃO: Este projeto é APENAS para fins educacionais. A vulnerabilidade foi intencionalmente implementada para demonstrar conceitos de segurança. Nunca use este código em produção ou em sistemas reais.

About

API em Rust intencionamente vulneravel a vazamento de dados sensiveis via vazamento de memoria não inicializada.

Topics

Resources

Stars

Watchers

Forks