Uma vez, antes de defender outro trabalho de laboratório, eles me fizeram uma pergunta: quais campos de um pacote IP podem ser usados para acolchoados? Eu não sabia e apenas dei de ombros. Mas logo ainda decidi estudar esse assunto.
Abaixo, você encontrará o estudo de cabeçalhos de pacotes IP, o próprio utilitário de ping do Python e várias maneiras de transferir dados sem chamar a atenção.
Conteúdo
- Estrutura de pacotes IP
- Configuração do ambiente
- Ping: opção fácil
- Ping: opção difícil
- Melhorias?
Estrutura de pacotes IPv4

Selecione os campos, cuja alteração não afetará muito o pacote:
O DIH pode variar de 5 a 15.
O campo
ToS é usado para priorizar as notificações de tráfego e congestionamento sem descartar pacotes. Na maioria das vezes, esse campo é 0. Teoricamente, ele pode ser usado para transmitir um byte inteiro de informações.
O comprimento do pacote é um excelente campo para transmitir números de 20 a 65535.
TTL pode transmitir até 7 bits de informação. Você precisa saber o número de saltos para o host e levar isso em consideração.
Configuração do ambiente
Para repetir o experimento, você precisará de duas máquinas com Python e a estrutura scapy.
Você pode instalá-lo seguindo as
instruções da documentação . No meu caso, foram duas gotículas no DO com a rede local ativada. Para testar a operacionalidade do estegano, foram escolhidas duas rotas: através da rede local para 1 salto e via Internet para 2 hop.
Ping: opção fácil
Primeiro, implementamos o sender.py, que enviará pacotes ICMP sem mensagens ocultas.
from scapy.all import *
O Scapy preencherá os campos restantes com os valores padrão antes do envio e calculará a soma de verificação.
No lado do recebimento, escreva listener.py, que escutará e exibirá todos os pacotes ICMP recebidos.
from scapy.all import *
Saída do ouvinte ###[ Ethernet ]### dst = hh:hh:hh:hh:hh:hh src = gg:gg:gg:gg:gg:gg type = 0x800 ###[ IP ]### version = 4 ihl = 5 tos = 0x0 len = 28 id = 24923 flags = frag = 0 ttl = 64 proto = icmp chksum = 0x4364 src = 10.0.0.1 dst = 10.0.0.2 \options \ ###[ ICMP ]### type = echo-request code = 0 chksum = 0xf7ff id = 0x0 seq = 0x0 ###[ Padding ]### load = '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
O cabeçalho do pacote IP possui um campo identificador. Preencha com os símbolos "A" e "B":
payload = ord("A") * 0x100 + ord("B") pkt = IP(src="10.0.0.1", dst="10.0.0.2", id = payload) / ICMP(type = 8)
Além disso, no cabeçalho do ICMP, existe exatamente o mesmo campo no qual dois bytes também podem ser carregados.
Mude o ouvinte para exibir os dados recebidos:
from scapy.all import * import sys packets = sniff(filter="icmp", timeout = 10, count = 100, iface="eth0") for pkt in packets: if pkt[ICMP].type != 8: continue
Na imagem e na semelhança, você pode preencher praticamente qualquer campo que foi anotado anteriormente como adequado para acolchoado.
Ping: opção difícil
A transferência de dados do parágrafo anterior não foi a mais óbvia, mas podemos torná-la ainda mais óbvia. Você pode ocultar os dados no campo da soma de verificação. De acordo com a
RFC1071, uma soma de verificação é (de repente!) Uma inversão bit a bit de uma soma aritmética um pouco mais complexa.
Explicação com um exemploSuponha que tenhamos um cabeçalho para o qual queremos calcular a soma de verificação. No momento do cálculo, o campo de soma de verificação é redefinido.
4500 003c 000a 0000 8001 [checksum] c0a8 000d c0a8 000d
1. Adicione todas as palavras de 16 bits, lembrando a transferência da ordem superior:
4500 + 003c + 000a + 0000 + 8001 + [checksum=0000] + c0a8 + 000d + c0a8 + 000e = = (2) 46b2
2. Adicione o resultado com transferências:
46b2 + 2 = 46b4
3. Inverter:
~(46b4) = b94b
b94b é a soma de verificação que estamos
procurando . Para verificação, você pode substituir no cabeçalho e executar as etapas 1 e 2. Se você obtiver FFFF, a quantidade encontrada estará correta.
Verificação:
1. 4500 + 003c + 000a + 0000 + 8001 + [checksum=b94b] + c0a8 + 000d + c0a8 + 000e = = (2) FFFD 2. FFFD + 2 = FFFF
Sabemos que a soma de verificação de um pacote muda à medida que os nós passam pela rede, à medida que o TTL muda. Além disso, ao passar pelo NAT no pacote, o "endereço de origem" é substituído, o que também afeta a soma de verificação. E quanto TTL diminuirá ao alcançar nosso ouvinte ... A cereja no bolo é que a testemunha do "identificador" coincide com a testemunha da soma de verificação. Esse fato nos permite influenciar a soma de verificação e alterá-la para qualquer valor da área de definição. Como a soma de verificação (carga útil) será calculada apenas ao passar o último nó na rota, é importante levar em consideração tudo o que pode ser alterado no pacote durante a rota durante o cálculo.
O algoritmo para encontrar o "identificador", que nos dará a soma de verificação desejada:
- Configuramos o pacote como quando passamos pelo último nó (IP, TTL, etc)
- No "identificador", escreva a carga
- Nós calculamos a soma de verificação
- O resultado deve ser escrito no "identificador" do pacote enviado
Escreveremos uma função que formará um pacote pelo número de esperanças, IPs atrás do NAT e dois bytes de carga útil.
Melhorias?
- Os campos chksum, seq, id no cabeçalho do protocolo ICMP também podem ser usados para transmitir dados
- O ToS pode ser usado para identificar pacotes "próprios" e ignorar a solicitação de eco de outras pessoas.