Pergunta

Eu tenho um código C C ++ que recebe uma estrutura sobre a rede, a partir deste formulário:

struct DataStruct
{
int DataLen;
BYTE* Data;
}

O código que eu atropela Data em um loop de DataLen horários e processa os dados.

...O problema:

Depois que o código chegou a especialistas em segurança para testes de penetração, eles prepararam um aplicativo falso que envia esta estrutura com DataLen maior que o tempo real de Data. Isso causa, é claro, uma exceção de violação de acesso.

Então, a questão é - como posso validar o comprimento real do recebido Data? É possível sem alterar a estrutura?

Desde já, obrigado.

Foi útil?

Solução

Bom especialistas em segurança! Eu gostaria que minha empresa tivesse um departamento como esse.

Sempre que os dados são recebidos da rede, a rede IO relata o número de bytes realmente escritos para o buffer, se você usou read(2), recv(2), ou boost::asio::async_read ou qualquer outra coisa que eu já vi. Caso de uso típico quando há um "número de bytes a seguir" no cabeçalho da sua estrutura de dados, é chamar repetidamente de leitura/RECV/etc até que muitos bytes fossem recebidos (ou até que o erro ocorra) e somente então ele deve construir e retorne seu DataStruct (ou erro de relatório).

Outras dicas

Você sabe quanto bytes você recebeu, então compare -o com DataLen.

É impossível sem alterar a estrutura. Os dados recebidos do soquete TCP/IP são fluxo simples. Logicamente, ele não é dividido em pacotes. O pacote físico pode conter uma ou mais instâncias de dados de dados, uma instância de dados pode ser dividida em dois ou mais pacotes físicos. A estrutura de informações atual pode ser usada apenas se não houver erros de comunicação ou pacotes inválidos.

A corrupção é fácil se você não tiver nenhuma limitação intrínseca.

Alguns mecanismos de proteção seriam:

  • Tente realloc() o buffer, dentro de algum tamanho aceitável (se Data é dinâmico)
  • Exceções são Amigos: Use SIGSEGV dentro signal(2), signal(7) e setjmp(2) Para fazer alguns tente/capturar estrutura de código. Ver Combinando setjmp ()/longjmp () e manuseio de sinal Para uma introdução rápida sobre este tópico. Usar sigaction(2) ir mais fundo (obtendo o endereço defeituoso;).
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top