Como validar a duração da matriz de bytes recebida, que não é encerrada?
-
25-09-2019 - |
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.
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 (seData
é dinâmico) - Exceções são Amigos: Use
SIGSEGV
dentrosignal(2)
,signal(7)
esetjmp(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. Usarsigaction(2)
ir mais fundo (obtendo o endereço defeituoso;).