Solução para “Check It Out” Packet Challenge

Dando uma olhada nos feeds de notícias sobre Forensics, encontrei mais um desafio interessante no blog I smell packets, mantido pelo instrutor do SANS, Chris Christianson. O blog trata, basicamente, do tema Network Forensics e frequentemente publica desafios sobre este assunto.

Assim como já demonstrado aqui, existem outros sites de desafios similares disponíveis na rede, caso tenha interesse, destaco aqui alguns.

Uma breve descrição deste desafio é a seguinte: dado um pacote IP, calcule o checksum do cabeçalho desse pacote. Apesar de simples, o desafio envolve a identificação do cabeçalho do protocolo envolvido, bem como o cálculo do checksum, algo não tão trivial para muitos. Eis aqui uma oportunidade de conhecer um pouco mais sobre este processo.

O texto completo do desafio está aqui, entretanto, destaco abaixo somente o conteúdo do pacote em hexadecimal, conforme constante no site:

4500 0527 0001 4000 4006 0000 c0a8 0102
c0a8 0101 2b67 0014 0000 006f 0000 006f
5018 0200 aa32 0000 ffd8 ffe0 0010 4a46
4946 0001 0200 0064 0064 0000 ffec 0011
4475 636b 7900 0100 0400 0000 0a00 00ff
ee00 0e41 646f 6265 0064 c000 0000 01ff
db00 8400 1410 1019 1219 2717 1727 3226
1f26 322e 2626 2626 2e3e 3535 3535 353e
4441 4141 4141 4144 4444 4444 4444 4444
4444 4444 4444 4444 4444 4444 4444 4444
4444 4444 0115 1919 201c 2026 1818 2636
2620 2636 4436 2b2b 3644 4444 4235 4244
4444 4444 4444 4444 4444 4444 4444 4444
4444 4444 4444 4444 4444 4444 4444 4444
4444 4444 44ff c000 1108 004f 004f 0301
2200 0211 0103 1101 ffc4 0075 0000 0203
0101 0000 0000 0000 0000 0000 0000 0401
0305 0602 0101 0000 0000 0000 0000 0000
0000 0000 0000 1000 0201 0204 0403 0308
0b00 0000 0000 0001 0203 0011 2131 1204
4151 6105 8122 1371 9132 a1b1 e142 5262
72d2 c1d1 8292 a233 7393 1415 0611 0100
0000 0000 0000 0000 0000 0000 0000 00ff
da00 0c03 0100 0211 0311 003f 00ec e8a2
8a08 a5e7 df6d f6e4 2cd2 2213 c198 0aa7
72cf 3c83 6d19 2a00 0d23 2e76 37b2 8ea6
c71e 0075 156c 1b28 36ea 4468 0039 9e27
da4e 2683 da6e 6274 f515 d4a0 cd81 b8af
50cc 93a0 9232 191b 222b 13bf 47b5 dbed
a57f 8257 52ab a0e9 2c7a 81f1 0e77 bd87
2a5b fe65 a6dc 6d2c 252a aacc 2c14 13cf
337e 7ca8 3a9a 2926 dbce b8c7 31bf 2915
48f9 029a 9837 4598 c530 d122 8d59 f948
e6a7 e7e4 7c2e 0e51 5153 4054 1c2a 6b27
be6f 7fc6 db32 a8bc 8e19 5074 b5d8 f82d
cfb7 0a05 e0ef 1b78 e52a f706 521e ff00
56ed 8229 e44a a83e 3577 fb19 774d e96c
d6ce 3095 e41e 58cf d9fb cc39 0c38 deb8
5ee6 026f 24c0 140f 80e8 b97b c575 bff3
bbaf 5142 31b9 2194 fe28 ec2f e28c bfbb
eda0 d28f b444 11c4 a4c9 2480 abc8 ff00
158f 2fb2 3a0a 3b3f 6c1d b213 0ab6 abb1
6bda d4de eb72 bb58 ccaf 7205 be11 7389
b655 306e 239d 03c6 da94 d05d 58bd fe29
1a38 de00 0cca fa50 3006 faf0 e387 5f0a
d2dc eee2 db0d 5230 5be4 389f 60cc f852
d0c7 26e6 513c ca51 13f9 4873 b916 2cc3
81b6 0070 c49c 6d60 bbb7 c524 5085 9459
b3d3 7be9 e97e 9f45 3945 1405 5524 4925
8b00 48bd ae39 e06d ed15 6d14 1c07 77ed
13a3 8529 e41e 5f58 02c0 afd5 d400 2750
1e53 cec0 df9e b765 edfb 8450 ea74 841a
53d4 4b6b d56b 9b5f 5016 0a01 cce2 4819
5753 4506 5b4c 2571 b4dd 2697 61a9 0a9f
29d3 63e5 3810 c33e 99dc d67c 9db2 4138
8a19 003a 492e cbe6 0320 d704 5df8 5f97
c57c 2ecf 7585 f73b adbc 31b9 423d 472c
83cc a2d6 cfad edf2 d7a6 ed02 02bb 8819
9a74 fad2 393a c715 3c05 f9db 038d 031b
2ed3 06d0 eb03 5ca7 e295 f162 7f47 8568
d2db 3dca ee63 f517 0372 aca7 3561 983d
47d3 4cd0 1451 4501 4514 5015 141a cc59
7773 ab59 3d33 6c14 f3ea d8df f657 a5e8
16d9 6ecc 9dc2 60c3 062d 1c67 fa5a 6e3d
ec4f 8568 c339 79a5 85f0 29a1 97f0 b0fc
c1ab 9e48 f7bd b1e3 32a0 941f 2974 c717
7b9b 5ed6 66be 937c f020 e62b 5f60 93bc
cdb8 dc80 8ccb a123 e3a6 f7bb 75e8 3e1f
1a0f 7b70 21df 4a83 2915 2523 8061 e53e
fb0f 7569 d677 6f53 297d d3e7 21d2 8392
2e5e 24dc 9f6d 68d0 1451 4501 4514 5015
54d2 a408 6490 e955 cc9a b694 dec3 14d1
6995 b4ad d7cd 7b63 7f2e 7867 6fd5 40af
aafb e68f 446e b12b eb2e f65d 416f 6b2d
f562 6c71 030a 6771 0c8d 224b 115b a061
66fb d6e5 ecaf 036f ba53 e59c 11f7 e204
ff00 0b27 cd53 e9ee f8c9 1ff6 cfe7 a0ce
2dbc d90d 2b8a 8bb6 95b3 d85f ecd9 1ac3
a5cf 4ad0 da6e de56 f4e5 02e5 43a3 21ba
ba9e 38d8 8e17 1ee2 6978 f692 068c 34cb
e507 4e85 b310 73c4 b361 e1cb 2a6b 670e
da2b 8db9 5370 326d 474e 36e2 70ce dc28
1da2 8a28 3fff d9

Existem mil maneiras de preparar Neston resolver este desafio. Abordaremos apenas duas delas, com o intuito de tornar este post um pouco mais didático.

A maneira mais simples trata da identificação do cabeçalho IP no conteúdo do pacote  e da aplicação do cálculo do checksum. Para tanto, basta procurar por ocorrências da string “45” no conteúdo do pacote, assumindo que não se trata de um pacote IPv6 (muito menos IPv4.1!). O valor 45 representa os 2 campos iniciais de um pacote IP (v4) comum: versão e tamanho do cabeçalho.

Neste primeiro byte do pacote, “4” representa a versão do protocolo IP, já “5” representa o número de palavras de 32 bits referente ao tamanho do cabeçalho. Para facilitar, multiplique este valor por 4 para obter o valor em bytes. Neste caso, verifica-se que o tamanho compreende 20 bytes, tamanho do cabeçalho de um pacote IP comum, sem opções.

Assumindo que o conteúdo apresentado já se inicia com a string que procuramos, tem-se o cabeçalho do pacote IP no seguinte intervalo:

4500 0527 0001 4000 4006 0000 c0a8 0102
c0a8 0101

Antes de mapear os valores, apenas para ficar mais claro, segue abaixo a estrutura do cabeçalho IP (v4):

Assim, os seguintes valores são obtidos a partir do conteúdo do pacote:

  • Version: 4
  • IHL: 5 (5×4 = 20 bytes)
  • ToS: 00
  • Total Lenght:  1319 bytes (0x0527)
  • Identification: 1 (0001)
  • Flags: dont’ fragment (0x40)
  • Frag Offset: 0
  • TTL: 64 (0x40)
  • Protocol: TCP (6)
  • Header Checksum: 0000
  • Source IP: 192.168.1.2
  • Destination IP: 192.168.1.1

Percebe-se que o valor do campo header checksum está zerado, o que é completamente aceitável, dado que o autor do desafio espera que este valor seja calculado. Na verdade, de acordo com a especificação do protocolo, para efetuar a validação adequadamente, o dispositivo receptor sempre assume valor igual a zero para esse campo.

Agora, com os valores dos campos referentes ao cabeçalho, basta aplicarmos a fórmula para obtenção do checksum, a qual resume-se ao complemento de 1 da soma de todos os campos do cabeçalho IP e opções (inexistentes aqui) agrupados em fatores de 2 bytes (16 bits). Mais detalhes sobre o cálculo do checksum podem ser obtidos no famoso RFC 791.

Sendo assim, a conta fica da seguinte forma:

Fatores (2 bytes cada)
--------
4500
0527
0001
4000
4006
0000
c0a8
SubTotalA = 0x18AD6 = 11000101011010110 (extrapola 1 bit) => 1000101011010111 (16 bits)
0102
c0a8
0101
SubTotalB = 0xC2AB = 1100001010101011
Total = SubTotalA + SubTotalB = 10100110110000010 (17 bits) => 0100110110000011
Complemento de 1 = 1011001001111100

Ao final, tem-se o valor em hexadecimal igual a B27C.

Outra abordagem trata da transformação do conteúdo do pacote (ASCII), publicado no desafio, em algo que possa ser lido por um analisador de PCAPs (binário), como o Wireshark. Desta forma, o cálculo, por meio de uma notificação de erro, é gerado pela própria ferramenta, nos restando apenas a importação do arquivo de captura do pacote para o Wireshark.

Eis a fórmula da lambança:

Copie e cole o conteúdo do pacote em um arquivo qualquer, chamarei de “challenge.txt”;

Execute o comando abaixo para formatar o conteúdo de forma que este seja corretamente interpretado pelo comando “text2pcap”:

perl -ne 'print "00000 " if $.==1; s/\s+//g; s/(..)/\1 /g; print' < challenge.txt > bazinga

O que isso faz, basicamente, é alinhar offsets (em hexa) de acordo com o conteúdo de cada linha. Mais fácil jogar tudo em uma só. Existem outras mil maneiras de fazer o mesmo;

Em seguida, há duas opções para que o frame torne-se facilmente interpretado pelo Wireshark; preencher o início do frame com um cabeçalho Ethernet fake ou mesmo em um raw IP packet. Neste caso, optei pelo último:

text2pcap -d -l 12 bazinga challenge.pcap
Input from: bazinga
Output to: challenge.pcap
Start new packet
Wrote packet of 1319 bytes at 0

Agora, basta abrir o arquivo (binário) gerado no Wireshark:

Pode-se perceber que o próprio Wireshark alerta sobre o checksum incorreto.

Enfim, existem várias maneiras de se chegar ao mesmo resultado (utilizando scapy, por exemplo) ou mesmo outro analisador de protocolo. Acredito que já deu para ter uma idéia das possibilidades, certo?

3 thoughts on “Solução para “Check It Out” Packet Challenge

Comments are closed.