can't calculate TCP checksum and get the result as in wireshark - networking

I am trying to calculate the checksum of a tcp packet and I can't get the same value as in the packet captured with wireshark
the original captured packet is:
"6c f0 49 e8 a3 0d 24 b6 fd 52 40 cb 08 00 45 00 00 28 02 22 40 00 80 06 00 00 00 0a 2a 00 1c 1f 0d 5a 24 ca 7d 01 bb 3f 44 f8 6e 6c 83 75 20 50 10 01 02 83 91 00 00"
As I saw in wireshark:
The first 14 bytes are ETH.
After that (in the IP part) there are 12 bytes of "header length",'DSCP','total length,'identification','fragment offset','TTL','protocol','header checksum'.
and then there are 4 bytes of IP-src and 4 bytes of IP-dst (which are the only one in the IP header that are important for the calculation).
we are left with 20 bytes of TCP header (no data).
I created the new packet for the calculation with the pseudo header in the form:
IPsrc/IPdst/reserved(0x00)/protocol(0x06)/TCP-length(0x0014)/TCP-header
Which got me:
"0a 2a 00 1c 1f 0d 5a 24 00 06 00 14 ca 7d 01 bb 3f 44 f8 6e 6c 83 75 20 50 10 01 02 83 91 00 00"
Zeroing the tcp checksum field (the 0x8391 according to wireshark) gets:
"0a 2a 00 1c 1f 0d 5a 24 00 06 00 14 ca 7d 01 bb 3f 44 f8 6e 6c 83 75 20 50 10 01 02 00 00 00 00"
calculating checksum on the new packet got me the value: 0xcc45 which is differen than the one in the original packet (0x8391)
data="0a 2a 00 1c 1f 0d 5a 24 00 06 00 14 ca 7d 01 bb 3f 44 f8 6e 6c 83 75 20 50 10 01 02 00 00 00 00"
def carry_around_add(a, b):
c = a + b
return (c & 0xffff) + (c >> 16)
def checksum(msg):
s = 0
for i in range(0, len(msg), 2):
w = ord(msg[i]) + (ord(msg[i+1]) << 8)
s = carry_around_add(s, w)
return ~s & 0xffff
data = data.split()
data = map(lambda x: int(x,16), data)
data = struct.pack("%dB" % len(data), *data)
print ' '.join('%02X' % ord(x) for x in data)
print "Checksum: 0x%04x" % checksum(data)
What am I doing wrong?

Your total test data length is 55 bytes, it should be 14 (ETH) + 20 (IP) + 20 (TCP). It's not that it's just one byte too long since that would not match with the 0x8391 checksum. But, the IP Protocol byte (0x06 - TCP) at IP offset 9 is stil in place. The IP source address seems rather unlikely though: 0.10.40.0.
The 'which got me' part starts with '0a 2a' which are the 2nd and 3rd byte of the IP source address. So let's assume the three zero bytes before this address should actually be two zero bytes. If that's correct, we're still on the right track.
The 12 byte TCP pseudo-header is: IPsrc/IPdst/0x00/0x06/TCP-length(0x0014) (without the TCP header), so far so good. The TCP checksum is calculated over: pseudo-header + TCP header + TCP data. But your test data uses only the pseudo-header and the TCP header data, the TCP data itself is missing.
I didn't really check your Python code but I don't see any obvious problems. The main issue seems to be the lack of the TCP payload data in the calculation.

Related

Can anyone advise how I can get the TCP / IP packet checksums verified?

I have a packet that I have manually created for a SYN/ACK but I get no reply from the server.
This is all wireless/GSM stuff so I cannot use a sniffer.
I have calculated the TCP and the IP header checksums manually a few times and they seem correct but I really need a 3rd party method to be sure.
I had several endian issues but I think I have it right now. But who knows...
I only found an online parser but it does not test/verify the checksums.
Does anyone have an easy idea for me?
Just in case someone has suitable access to a test method, and feels like pasting it in for me, here is the packet:
45 10 00 3C 00 02 00 00 64 06 E8 1F 0A AA 61 43 51 8A B1 13
01 BB 01 BB 00 00 00 0A 00 00 00 00 50 02 00 00 3D D8 00 00
Regards
berntd
I've creating a pcap from your hex data using Net::PcapWriter:
use strict;
use warnings;
use Net::PcapWriter;
my $w = Net::PcapWriter->new('test.pcap');
my $ip = pack('H*','4510003C000200006406E81F0AAA6143518AB11301BB01BB0000000A00000000500200003DD80000');
$w->packet($w->layer2prefix('1.1.1.1').$ip);
Loading it into Wireshark shows both the IP checksum and the TCP checksum as correct, so it is probably not a problem of the checksum calculation.
But tcpdump says that the length is wrong:
IP truncated-ip - 20 bytes missing! 10.170.97.67.443 > 81.138.177.19.443: Flags [S], seq 10:30, win 0, length 20
This is because you've set the total length in the IP header to 60 bytes (00 3C) but the IP header + TCP header is only 40 bytes in total and your packet does not have any payload, i.e. the total length should be 40 and not 60 bytes.
Here is what I came up with to do it the manual way:
Put packet into a text file like so:
45 10 00 3C 00 02 00 00 64 06 E8 1F 0A AA 61 43 51 8A B1 13
01 BB 01 BB 00 00 00 0A 00 00 00 00 50 02 00 00 3D D8 00 00
add addressing offsets and group into 16 byte lines as in a hex dump:
000000 45 10 00 3C 00 02 00 00 64 06 E8 1F 0A AA 61 43
000010 51 8A B1 13 01 BB 01 BB 00 00 00 0A 00 00 00 00
000020 50 02 00 00 3D D8 00 00
Save it (source).
Now run ext2pcap.exe -e 0x800 source dest
The dest file can now be imported as a PCAP file into wireshark for decoding.
Multiple packets can be converted byt starting the address offset for each new packet at 000000 again in the source file.
text2pcap.exe seems to come with wireshark.
Tedious but works.
Cheers

Dota2 packet analysis uknown wiretype for proto message

I am trying to gain access to in game chat information from dota2 packets. I knew this used to possible since there were multiple projects that intercepted dota2 network traffic and translated chat text to print out on an overlay over dota2. Right now I am using wireshark with protobuf addon installed. I can see a few packets here and there to valve servers outside the USA and can see the protobuf addon for wireshark working on these packets but I get an unknown wiretype error for 95% of the packets I believe to be related to dota. In almost all of these packets the UDP data payload starts off with 56 53 30 31
here is an example hex dump from wireshark. Are these 4 bytes some sort of header and then the proto messages start?
0000 c8 a7 0a a4 63 ed 6c fd b9 4b 6e 16 08 00 45 00
0010 00 70 58 db 40 00 40 11 85 1a c0 a8 01 f5 d0 40
0020 c9 a9 9e 96 69 89 00 5c 72 7c **56 53 30 31** 30 00
0030 06 00 00 02 00 00 00 1d fe 11 11 10 00 00 d7 0a
0040 00 00 01 00 00 00 11 10 00 00 30 00 00 00 24 fd
0050 37 3c b4 30 a5 48 fa 3d ea 30 1a 1f d8 a9 41 e0
0060 e0 6c 44 ba bb 4e ba fc e7 ac ed f9 40 19 86 20
0070 84 71 52 5d b3 1f da 36 40 d9 b6 2e e1 e5
That is ascii code for "VS01", so yes, it might be some kind of version identifier.

unable to decrypt 3DES with SessionKey

I'm developing a C project to read/write Desfire Contactless Cards.
Right now I achieved to authenticate and I'm able to read data from the card, but it's encrypted with 3DES.
I want to decrypt next message:
EB 54 DF DD 07 6D 7C 0F BD D6 D1 D1 90 C6 C7 80 92 F3 89 4D 6F 16 7C BF AA 3E 7C 48 A8 71 CF A2 BD D0 43 07 1D 65 B8 7F
My SessionKey (generated in Authentication step) is:
44 E6 30 21 4A 89 57 38 61 7A B8 7C A9 91 B2 C0
I know the IV={ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
With this information, I can go here and choosing 3DES, CBC mode, I can decrypt the message and I have means to know that it's right.
It should be, decrypted:
10 1a 01 31 32 ae 03 de 39 b0 00 97 7f 65 e9 43 93 89 53 5c 9e 04 a9 3f 95 71 24 0f 0a 9b f7 ee d4 5b 1b c6 78 7a f4 36
Anyhow, I tried to implement the C code using OpenSSL des library and I find the next difficulty:
I need 3 Keys of 8 bytes each, but I have 1 SessionKey of 16 bytes
long.
I tried to split SessionKey into Key1/Key2/Key1 without success.
I have read so much about it, the only clue i found is that I have to generate those 3 keys from my 16byte SessionKey (taking it as a password) but I feel it is too advanced for me.
If this is the only way, is there any tutorial about ossl key derivation (evp_bytestokey)? Is there any other way?
Thanks
Edit:
So, right now I'm in a very weird spot. As noted by many of you, I had already taken first 8 bytes from Session Key as Key 3 (that's what I referred to with Key1/Key2/Key1). Anyway it seemed to not work, but slightly it did, which is what puzzles me.
I get:
Decrypted : 11 1B 00 30 33 AF 02 DF DE 01 00 00 00 01 01 00 14 C1 26 8F 03 20 20 41 00 30 39 01 00 00 00 00 00 00 00 00 00 00 75 B1
When
Expected : 10 1a 01 31 32 ae 03 de de 01 00 00 00 01 01 00 14 c1 26 8f 03 20 20 41 00 30 39 01 00 00 00 00 00 00 00 00 00 00 75 b1
So I get the expected result XORing first 8 bytes with 01. Does that make any sense?? As in OSSL docu it says: Note that there is both a DES_cbc_encrypt() and a DES_ncbc_encrypt() in libcrypto. I recommend you only use the ncbc version (n stands for new). See the BUGS section of the OpenSSL DES manpage and the source code for these functions.
But I have access only to older version... Could it be the problem??
Perhaps the encryption is two-key 3DES, in that case repeat the first 8-bytes , bytes 0-7 as bytes 16-23: 44 E6 30 21 4A 89 57 38 61 7A B8 7C A9 91 B2 C0 44 E6 30 21 4A 89 57 38.
Some 3DES implementations will do this automatically, some you must do it yourself.
If this does not work you will need to provide more information in the question.
Size of session key
Since you refer to MIFARE DESFire and you are using a 16 byte session key, you probably use 2-key triple DES. This means that the 16 byte session key is actually two keys (8 bytes, or actually 56 bits, each with 8 unused "parity" bits).
In order to map this to 3DES with 3 keys, you simply need to append the first 8 bytes to the end of your session key, so that you get
+-------------------------+-------------------------+
16 byte session key: | 8 bytes | 8 bytes |
| 44 E6 30 21 4A 89 57 38 | 61 7A B8 7C A9 91 B2 C0 |
+-------------------------+-------------------------+-------------------------+
24 byte 3DES key: | 8 bytes | 8 bytes | 8 bytes |
| 44 E6 30 21 4A 89 57 38 | 61 7A B8 7C A9 91 B2 C0 | 44 E6 30 21 4A 89 57 38 |
+-------------------------+-------------------------+-------------------------+
First block of decrypted plaintext
If the first 8 bytes of the decrypted plaintext differ from the expected value but the remaining bytes match, this is a clear indication that you are using an incorrect initialization vector for CBC mode.
Have a look at how CBC mode works:
So for the first block, the plaintext is calculated as
P0 = DecK(C0) XOR IV
For the remaining blocks, the plaintext is calculated as
Pn = DecK(Cn) XOR Cn-1
This means that only the decryption of the first block depends on the IV. The decryption of the remaining blocks depends on the preceding ciphertext instead.
Since you assumed the IV to be all zeros, the XOR operation does nothing. Hence, in your case, the plaintext of the first block is calculated as
P0 = DecK(C0) XOR {0} = DecK(C0) = '10 1A 01 31 32 AE 03 DE'
As this expected value deviates from the actual value that you get ('11 1B 00 30 33 AF 02 DF'). This most likely means that you used an incorrect IV for decryption:
P0 = DecK(C0) = '10 1A 01 31 32 AE 03 DE'
P'0 = DecK(C0) XOR IV = '11 1B 00 30 33 AF 02 DF'
You can calculate the IV that you used by XORing the two values:
P'0 = P0 XOR IV
P'0 XOR P0 = IV
IV = '11 1B 00 30 33 AF 02 DF' XOR '10 1A 01 31 32 AE 03 DE'
= '01 01 01 01 01 01 01 01'
As this IV differs in exactly the LSB of each byte being set to one, I wonder if you accidentally used the method DES_set_odd_parity() on the IV. This would explain why the LSB (i.e. the parity bit if the value was a DES key) was changed.
It's possible that you don't need 3 keys of 32bits, but only one of 3*32bits, with the bytes in the good order
Best regards

What is this bittorrent network flow? [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I've recorded some network traffic in my home that only appear up while running BitTorrent or uTorrent.
I've been reading the bittorrent protocol descriptions, but I am stuck trying to figure out a particular network flow.
Can someone help me identify what the following bittorrent network traffic is exactly?
It lasts quite a long time, even after stopping downloads.
All packets are in one direction - from my local machine running Bittorrent to a remote machine.
Here is data payload of one packet (copied from Wireshark):
00000000 60 00 00 00 00 00 3b 15 20 01 00 00 9d 38 6a b8 `.....;. ....8j.
00000010 04 b9 18 bf 9c 90 d8 81 20 01 00 00 9d 38 6a b8 ........ ....8j.
00000020 20 5a 01 45 bd 13 b1 65 01 04 44 4a e7 d5 04 04 Z.E...e ..DJ....
00000030 01 00 00 00 05 02 ea cf ........
All the packets in the network flow are similar, here are two more:
00000038 60 00 00 00 00 00 3b 15 20 01 00 00 9d 38 6a b8 `.....;. ....8j.
00000048 04 b9 18 bf 9c 90 d8 81 20 01 00 00 9d 38 6a b8 ........ ....8j.
00000058 20 5a 01 45 bd 13 b1 65 01 04 08 8e 35 9f 04 04 Z.E...e ....5...
00000068 01 00 00 00 05 02 ea cf ........
00000070 60 00 00 00 00 00 3b 15 20 01 00 00 9d 38 6a b8 `.....;. ....8j.
00000080 04 b9 18 bf 9c 90 d8 81 20 01 00 00 9d 38 6a b8 ........ ....8j.
00000090 20 5a 01 45 bd 13 b1 65 01 04 12 3e ba 6c 04 04 Z.E...e ...>.l..
000000A0 01 00 00 00 05 02 ea cf ........
These bittorrent packets are typically several seconds apart, and this flow seems to go on indefinitely. Which one of the bittorrent protocols describes this network flow?
I just sent a response to you on our mailing list, but I'm gonna post here too in case anyone else stumbles across it and finds it useful.
They're Teredo packets (with no payload). Wireshark can decode these
but it doesn't do so without coercion.
http://en.wikipedia.org/wiki/IPv6_packet
http://en.wikipedia.org/wiki/Teredo_tunneling
One of your packets dissected:
IP Version: 6
Traffic Class: 0 0
Flow Label: 0 00 00
Payload Length: 00 00
Next Header: 3b (indicates that there is no payload present)
Hop Limit: 15
Source: 20 01 00 00 9d 38 6a b8 04 b9 18 bf 9c 90 d8 81
Destination: 20 01 00 00 9d 38 6a b8 20 5a 01 45 bd 13 b1 65
The source and destination also encode the source and destination
public ipv4 addresses and ports.
The hop-by-hop options header (in type-length-value format) follows in
this case. The possible types can be found here:
http://www.iana.org/assignments/ipv6-parameters/ipv6-parameters.xml
So we have this:
01 04: c3 ae 60 38 ("PadN", random bytes)
04 04: 01 00 00 00 ("Tunnel Encapsulation Limit")
05 02: ea cf ("Router Alert")
No clue what the value of the router alert field is here. I would
expect it to be listed here:
http://www.iana.org/assignments/ipv6-routeralert-values/ipv6-routeralert-values.xml
But it looks like either that's out of date or the Teredo
implementation you're using is doing something non-standard (or
there's something I've missed).
Anyways, these are clearly keep-alive packets. We're not directly
triggering them in the client as far as I know. I believe they're sent
by your Teredo driver to keep your tunnels open.

IPv4 header frame

I need to sort out something about the IPv4 header. For example the following frame with an Ethernet-II frame with an IPv4 packet starting at the fifteenth byte.
0000: 08 00 20 7c 94 1c 00 00 - 39 51 90 37 08 00 45 00
0010: 00 3e 36 00 00 00 80 11 - da 4f 82 eb 12 7f 82 eb
0020: 12 0a 04 01 00 35 00 2a - ee 6a 00 01 01 00 00 01
0030: 00 00 00 00 00 00 06 67 - 65 6d 69 6e 69 03 6c 64
0040: 63 02 6c 75 02 73 65 00 - 00 01 00 01
I need to sort somethings out:
What does the 0000 & 0010 & 0020 & 0030 on the left stands for?
I just cant sort it out is 1 pair for example the first one 08 two bits or?
And if the IPv4 starts at fifteenth byte(1 byte = 8 bits) where does it start then, have problems to understand this because i dont get number 2.
Thank you for your time.
”45” in your first line of hexdump is the 1st byte of the ip header (15th byte of the ethernet frame). Each line is 16 bytes.
Also, in the beginning of each line has an offset like e.g. ”0010: ” (in hex) means the starting offset from the start of the whole dump.
Your first line would be, (total 16 bytes),
dmac(6)+smac(6)+etype(2)+ first2byte_of_ip(2)
and your first byte of ip is hex ”45”, you can lookup the detail ip header field in wikipedia.
It would be nice if you can read wireshark user's guide on your own. Anyway, to answer your question,
1) What does the 0000 & 0010 & 0020 & 0030 on the left stands for?
It stands for hexdump offset. You can refer to this page.
2) I just cant sort it out is 1 pair for example the first one 08 two bits or?
It is (part of ) destination MAC address. Entire MAC address should be 08 00 20 7c 94 1c.
3) since Q2 is now answered, this should not be problem for you.

Resources