kbandla / dpkt

fast, simple packet creation / parsing, with definitions for the basic TCP/IP protocols
Other
1.08k stars 270 forks source link

dpkt.ah.AH misinterprets the payload length field #596

Closed ttmapr closed 2 years ago

ttmapr commented 2 years ago

Describe the bug RFC 4302, section 2.2 describes how the payload length field of IPsec's authentication header is to be interpreted. But dpkt.ah.AH.unpack only takes the value directly as the length of the ICV (auth) field. Example: if the payload length has a value of 4, the ICV field would have to be interpreted as (payloadLen+2)*4-12 = 12 bytes, but dpkt.ah.AH.unpack directly uses 4 bytes. Besides a wrong ICV length and thus a wrong ICV value, this behaviour also results in a wrong offset for the next protocol's header, and the encapsulated TCP or UDP will have wrong port numbers and so on.

To Reproduce

>>> import dpkt, binascii
>>> dpkt.ethernet.Ethernet(binascii.unhexlify("01020304050601020408102008004500004c65ab4000013344f0c0a8002ac0a8001706040000914094af0000cad8509d3d4b91d2decac76991b330395ba0a3a83399dab531e5801000221dc000000101080af200284e00188dd2"))

Expected behavior Ethernet(dst=b'\x01\x02\x03\x04\x05\x06', src=b'\x01\x02\x04\x08\x10 ', data=IP(len=76, id=26027, off=16384, ttl=1, p=51, sum=17648, src=b'\xc0\xa8\x00*', dst=b'\xc0\xa8\x00\x17', opts=b'', data=AH(nxt=6, len=4, spi=2436928687, seq=51928, auth=b'P\x9d=K\x91\xd2\xde\xca\xc7i\x91\xb3', data=TCP(sport=12345, dport=23456, seq=2745709465, ack=3669307877, off=8, flags=16, win=34, sum=7616, opts=b'\x01\x01\x08\n\xf2\x00(N\x00\x18\x8d\xd2'))))

Actual behavior Ethernet(dst=b'\x01\x02\x03\x04\x05\x06', src=b'\x01\x02\x04\x08\x10 ', data=IP(len=76, id=26027, off=16384, ttl=1, p=51, sum=17648, src=b'\xc0\xa8\x00*', dst=b'\xc0\xa8\x00\x17', opts=b'', data=AH(nxt=6, len=4, spi=2436928687, seq=51928, auth=b'P\x9d=K', data=TCP(sport=37330, dport=57034, seq=3345584563, ack=809065376, off=10, flags=168, win=13209, sum=55989, urp=12773, opts=b'\x80\x10\x00"\x1d\xc0\x00\x00\x01\x01\x08\n\xf2\x00(N\x00\x18\x8d\xd2'))))

Details