P1sec / pycrate

A Python library to ease the development of encoders and decoders for various protocols and file formats; contains ASN.1 and CSN.1 compilers.
GNU Lesser General Public License v2.1
381 stars 132 forks source link

bug fixes in IKEv2 #187

Closed edhinard closed 2 years ago

edhinard commented 2 years ago

Hi, here are three little fixes in pycrate_crypto/IKEv2.py.

I am trying to decode and build ISAKMP payloads with pycrate_crypto/IKEv2. The code would look like :

import pycrate_crypto.IKEv2

# decoding a received payload
obj1 = pycrate_crypto.IKEv2.IKEv2()
obj1.from_bytes(bytes.fromhex(hexpayload))

# creating a payload to send
obj2 = pycrate_crypto.IKEv2.IKEv2(val=dictpayload)

assert obj1.to_bytes().hex() == obj2.to_bytes().hex()

The proposed merge request makes the code running OK with the following values :

hexpayload = 'a9a3a51a00000000000000000000000021202208000000000000010c2200002c0000002801010004030000080100000b03000008030000020300000802000002000000080400000128000068000100007bb0426834a6fe0b8e93ca3598f8dfa33bb2ef81ba98363c406b815b73b833a9fa5343370c70435d691f957767db1be68d71cbc7a456ec09a37bab5150c7b6291b2022230d11ba38f7a05fd97a6807001807cbfb7889201e711d4631d71b792b29000024d40968e6987bc8e1d40968e6987bc8e1d40968e6987bc8e1d40968e6987bc8e12900001c00004004e0b68417870334bf5e671f3c89a4f25e633c56d00000001c0000400562a3794153bfafbf0ea3207908abb2ea963e2341'

dictpayload = {
    'Header': {'SPIInitiator': b'\xa9\xa3\xa5\x1a\x00\x00\x00\x00',
               'SPIResponder': b'\x00\x00\x00\x00\x00\x00\x00\x00',
               'VersMaj': 2,
               'VersMin': 0,
               'ExchType': 34,
               'Flags': {'undef': 0, 'R': 0, 'V': 0, 'I': 1},
               'MID': 0},
    'Payloads': [{'C': 0,
                  'SA': [{'ProtID': 1,
                          'SPI': b'',
                          'Transforms': [{'Type': 1, 'ID': 11, 'Attributes': []},
                                         {'Type': 3, 'ID': 2, 'Attributes': []},
                                         {'Type': 2, 'ID': 2, 'Attributes': []},
                                         {'Type': 4, 'ID': 1, 'Attributes': []}]}],
                  'Type': 33},
                 {'C': 0,
                  'KE': {'DHGroup': 1,
                         'Data': b'{\xb0Bh4\xa6\xfe\x0b\x8e\x93\xca5'
                         b'\x98\xf8\xdf\xa3;\xb2\xef\x81\xba\x986<@k\x81['
                         b's\xb83\xa9\xfaSC7\x0cpC]i\x1f\x95wg\xdb\x1b\xe6'
                         b'\x8dq\xcb\xc7\xa4V\xec\t\xa3{\xabQP\xc7\xb6)'
                         b'\x1b "#\r\x11\xba8\xf7\xa0_\xd9zh\x07\x00'
                         b'\x18\x07\xcb\xfbx\x89 \x1eq\x1dF1\xd7\x1by+'},
                  'Type': 34},
                 {'C': 0,
                  'NONCE': {'Data': b'\xd4\th\xe6\x98{\xc8\xe1\xd4\th\xe6'
                            b'\x98{\xc8\xe1\xd4\th\xe6\x98{\xc8\xe1'
                            b'\xd4\th\xe6\x98{\xc8\xe1'},
                  'Type': 40},
                 {'C': 0,
                  'N': {'ProtID': 0,
                        'Type': 16388,
                        'SPI': b'',
                        'Data': b'\xe0\xb6\x84\x17\x87\x034\xbf^g\x1f<'
                        b'\x89\xa4\xf2^c<V\xd0'},
                  'Type': 41},
                 {'C': 0,
                  'N': {'ProtID': 0,
                        'Type': 16389,
                        'SPI': b'',
                        'Data': b'b\xa3yAS\xbf\xaf\xbf\x0e\xa3 y\x08\xab\xb2\xea'
                        b'\x96>#A'},
                  'Type': 41}]
}
edhinard commented 2 years ago

I am now facing a problem with 'SK' payloads. For example :

>>> import pycrate_crypto.IKEv2
>>> hexpayload = 'a9a3a51a00000000330d0eddfff255582e20230800000001000000a5230000892f00000c01000000220e00972900000c0100000000010000210000080000400a2c000028000000240103040300000064030000080100000b030000080300000200000008050000002d00001801000000070000100001ffff00000000ffffffff0000001801000000070000100001ffff00000000ffffffff00c1ef31fd646e38d7abd689b0'
>>> obj1 = pycrate_crypto.IKEv2.IKEv2()
>>> obj1.from_bytes(bytes.fromhex(hexpayload))
>>> print(obj1.show())
### IKEv2 ###
 ### Header ###
  <SPIInitiator : 0xa9a3a51a00000000>
  <SPIResponder : 0x330d0eddfff25558>
  <Next : 46>
  <VersMaj : 2>
  <VersMin : 0>
  <ExchType : 35 (IKE_AUTH)>
  ### Flags ###
   <undef : 0x0>
   <R : 0>
   <V : 0>
   <I : 1>
   <undef : 0x0>
  <MID : 0x00000001>
  <Len : 165>
     ### Payloads ###
>>> 

The PayEncr (Next=46) class is not decoding at all as we can see in the result of show() above. Can you tell me what should be done to decode such payloads. I can manage the encryption/decryption myself later. I just want to retrieve IV and Data. Among the questions that I ask myself, there is that of the determination of the length of the IV field. I understand that the length is automatically computed when the encryption algorithm is known. But how to set the ALG_ENCR value before decoding the payload ?

p1-bmu commented 2 years ago

Yep, IKEv2 implementation was quite unfinished... I just pushed commit 1a6d4d6ab8b61e0ef4ea9314ac07facfdd10f785, which addresses the few fixes you did in this PR, plus additional fixes and enhancements for proper decoding of packets.

For encrypted payload, you need to configure the algorithm suite you have selected, in order to get the correct IV and ICS size. You can do this by calling the following class method with the appropriate algorithm identifiers:

PayEncr.set_alg(IKEv2TransENCR.ENCR_AES_CBC, IKEv2TransAUTH.AUTH_HMAC_SHA1_96)

From here, decoding of encrypted payloads should be fine. I am missing unit tests for this protocol, so in case you have pcap / traces for full IKEv2 negotiations, if possible with keys, that would enable to set them cleanly.

edhinard commented 2 years ago

Thank you for the update and the help. I can now go further and the request can be closed. I do have an IKEv2 pcap trace with keys, coming from a N3IWF setup, that I can share with you. Unfortunately github does not allow for private messages.

p1-bmu commented 2 years ago

You can send me an email to benoit.michau@p1sec.com, having such a trace would be helpful for further development.