From b89efa188810bf95a9d245e69e2961b5721c3b0f Mon Sep 17 00:00:00 2001 From: imarom Date: Mon, 21 Mar 2016 16:03:47 +0200 Subject: scapy python 2/3 --- .../scapy-2.3.1/python3/scapy/contrib/ikev2.py | 362 +++++++++++++++++++++ 1 file changed, 362 insertions(+) create mode 100644 scripts/external_libs/scapy-2.3.1/python3/scapy/contrib/ikev2.py (limited to 'scripts/external_libs/scapy-2.3.1/python3/scapy/contrib/ikev2.py') diff --git a/scripts/external_libs/scapy-2.3.1/python3/scapy/contrib/ikev2.py b/scripts/external_libs/scapy-2.3.1/python3/scapy/contrib/ikev2.py new file mode 100644 index 00000000..fd38b80c --- /dev/null +++ b/scripts/external_libs/scapy-2.3.1/python3/scapy/contrib/ikev2.py @@ -0,0 +1,362 @@ +#!/usr/bin/env python + +# http://trac.secdev.org/scapy/ticket/353 + +# scapy.contrib.description = IKEv2 +# scapy.contrib.status = loads + +from scapy.all import * +import logging + + +## Modified from the original ISAKMP code by Yaron Sheffer , June 2010. + +import struct +from scapy.packet import * +from scapy.fields import * +from scapy.ansmachine import * +from scapy.layers.inet import IP,UDP +from scapy.sendrecv import sr + +# see http://www.iana.org/assignments/ikev2-parameters for details +IKEv2AttributeTypes= { "Encryption": (1, { "DES-IV64" : 1, + "DES" : 2, + "3DES" : 3, + "RC5" : 4, + "IDEA" : 5, + "CAST" : 6, + "Blowfish" : 7, + "3IDEA" : 8, + "DES-IV32" : 9, + "AES-CBC" : 12, + "AES-CTR" : 13, + "AES-CCM-8" : 14, + "AES-CCM-12" : 15, + "AES-CCM-16" : 16, + "AES-GCM-8ICV" : 18, + "AES-GCM-12ICV" : 19, + "AES-GCM-16ICV" : 20, + "Camellia-CBC" : 23, + "Camellia-CTR" : 24, + "Camellia-CCM-8ICV" : 25, + "Camellia-CCM-12ICV" : 26, + "Camellia-CCM-16ICV" : 27, + }, 0), + "PRF": (2, {"PRF_HMAC_MD5":1, + "PRF_HMAC_SHA1":2, + "PRF_HMAC_TIGER":3, + "PRF_AES128_XCBC":4, + "PRF_HMAC_SHA2_256":5, + "PRF_HMAC_SHA2_384":6, + "PRF_HMAC_SHA2_512":7, + "PRF_AES128_CMAC":8, + }, 0), + "Integrity": (3, { "HMAC-MD5-96": 1, + "HMAC-SHA1-96": 2, + "DES-MAC": 3, + "KPDK-MD5": 4, + "AES-XCBC-96": 5, + "HMAC-MD5-128": 6, + "HMAC-SHA1-160": 7, + "AES-CMAC-96": 8, + "AES-128-GMAC": 9, + "AES-192-GMAC": 10, + "AES-256-GMAC": 11, + "SHA2-256-128": 12, + "SHA2-384-192": 13, + "SHA2-512-256": 14, + }, 0), + "GroupDesc": (4, { "768MODPgr" : 1, + "1024MODPgr" : 2, + "1536MODPgr" : 5, + "2048MODPgr" : 14, + "3072MODPgr" : 15, + "4096MODPgr" : 16, + "6144MODPgr" : 17, + "8192MODPgr" : 18, + "256randECPgr" : 19, + "384randECPgr" : 20, + "521randECPgr" : 21, + "1024MODP160POSgr" : 22, + "2048MODP224POSgr" : 23, + "2048MODP256POSgr" : 24, + "192randECPgr" : 25, + "224randECPgr" : 26, + }, 0), + "Extended Sequence Number": (5, {"No ESN": 0, + "ESN": 1, }, 0), + } + +# the name 'IKEv2TransformTypes' is actually a misnomer (since the table +# holds info for all IKEv2 Attribute types, not just transforms, but we'll +# keep it for backwards compatibility... for now at least +IKEv2TransformTypes = IKEv2AttributeTypes + +IKEv2TransformNum = {} +for n in IKEv2TransformTypes: + val = IKEv2TransformTypes[n] + tmp = {} + for e in val[1]: + tmp[val[1][e]] = e + IKEv2TransformNum[val[0]] = (n,tmp, val[2]) + +IKEv2Transforms = {} +for n in IKEv2TransformTypes: + IKEv2Transforms[IKEv2TransformTypes[n][0]]=n + +del(n) +del(e) +del(tmp) +del(val) + +# Note: Transform and Proposal can only be used inside the SA payload +IKEv2_payload_type = ["None", "", "Proposal", "Transform"] + +IKEv2_payload_type.extend([""] * 29) +IKEv2_payload_type.extend(["SA","KE","IDi","IDr", "CERT","CERTREQ","AUTH","Nonce","Notify","Delete", + "VendorID","TSi","TSr","Encrypted","CP","EAP"]) + +IKEv2_exchange_type = [""] * 34 +IKEv2_exchange_type.extend(["IKE_SA_INIT","IKE_AUTH","CREATE_CHILD_SA", + "INFORMATIONAL", "IKE_SESSION_RESUME"]) + + +class IKEv2_class(Packet): + def guess_payload_class(self, payload): + np = self.next_payload + logging.debug("For IKEv2_class np=%d" % np) + if np == 0: + return conf.raw_layer + elif np < len(IKEv2_payload_type): + pt = IKEv2_payload_type[np] + logging.debug(globals().get("IKEv2_payload_%s" % pt, IKEv2_payload)) + return globals().get("IKEv2_payload_%s" % pt, IKEv2_payload) + else: + return IKEv2_payload + + +class IKEv2(IKEv2_class): # rfc4306 + name = "IKEv2" + fields_desc = [ + StrFixedLenField("init_SPI","",8), + StrFixedLenField("resp_SPI","",8), + ByteEnumField("next_payload",0,IKEv2_payload_type), + XByteField("version",0x20), # IKEv2, right? + ByteEnumField("exch_type",0,IKEv2_exchange_type), + FlagsField("flags",0, 8, ["res0","res1","res2","Initiator","Version","Response","res6","res7"]), + IntField("id",0), + IntField("length",None) + ] + + def guess_payload_class(self, payload): + if self.flags & 1: + return conf.raw_layer + return IKEv2_class.guess_payload_class(self, payload) + + def answers(self, other): + if isinstance(other, IKEv2): + if other.init_SPI == self.init_SPI: + return 1 + return 0 + def post_build(self, p, pay): + p += pay + if self.length is None: + p = p[:24]+struct.pack("!I",len(p))+p[28:] + return p + + +class IKEv2_Key_Length_Attribute(IntField): + # We only support the fixed-length Key Length attribute (the only one currently defined) + name="key length" + def __init__(self, name): + IntField.__init__(self, name, "0x800E0000") + + def i2h(self, pkt, x): + return IntField.i2h(self, pkt, x & 0xFFFF) + + def h2i(self, pkt, x): + return IntField.h2i(self, pkt, struct.pack("!I", 0x800E0000 | int(x, 0))) + + +class IKEv2_Transform_ID(ShortField): + def i2h(self, pkt, x): + if pkt == None: + return None + else: + map = IKEv2TransformNum[pkt.transform_type][1] + return map[x] + + def h2i(self, pkt, x): + if pkt == None: + return None + else: + map = IKEv2TransformNum[pkt.transform_type][1] + for k in keys(map): + if map[k] == x: + return k + return None + +class IKEv2_payload_Transform(IKEv2_class): + name = "IKE Transform" + fields_desc = [ + ByteEnumField("next_payload",None,{0:"last", 3:"Transform"}), + ByteField("res",0), + ShortField("length",8), + ByteEnumField("transform_type",None,IKEv2Transforms), + ByteField("res2",0), + IKEv2_Transform_ID("transform_id", 0), + ConditionalField(IKEv2_Key_Length_Attribute("key_length"), lambda pkt: pkt.length > 8), + ] + +class IKEv2_payload_Proposal(IKEv2_class): + name = "IKEv2 Proposal" + fields_desc = [ + ByteEnumField("next_payload",None,{0:"last", 2:"Proposal"}), + ByteField("res",0), + FieldLenField("length",None,"trans","H", adjust=lambda pkt,x:x+8), + ByteField("proposal",1), + ByteEnumField("proto",1,{1:"IKEv2"}), + FieldLenField("SPIsize",None,"SPI","B"), + ByteField("trans_nb",None), + StrLenField("SPI","",length_from=lambda x:x.SPIsize), + PacketLenField("trans",conf.raw_layer(),IKEv2_payload_Transform,length_from=lambda x:x.length-8), + ] + + +class IKEv2_payload(IKEv2_class): + name = "IKEv2 Payload" + fields_desc = [ + ByteEnumField("next_payload",None,IKEv2_payload_type), + FlagsField("flags",0, 8, ["critical","res1","res2","res3","res4","res5","res6","res7"]), + FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4), + StrLenField("load","",length_from=lambda x:x.length-4), + ] + + +class IKEv2_payload_VendorID(IKEv2_class): + name = "IKEv2 Vendor ID" + overload_fields = { IKEv2: { "next_payload":43 }} + fields_desc = [ + ByteEnumField("next_payload",None,IKEv2_payload_type), + ByteField("res",0), + FieldLenField("length",None,"vendorID","H", adjust=lambda pkt,x:x+4), + StrLenField("vendorID","",length_from=lambda x:x.length-4), + ] + +class IKEv2_payload_Delete(IKEv2_class): + name = "IKEv2 Vendor ID" + overload_fields = { IKEv2: { "next_payload":42 }} + fields_desc = [ + ByteEnumField("next_payload",None,IKEv2_payload_type), + ByteField("res",0), + FieldLenField("length",None,"vendorID","H", adjust=lambda pkt,x:x+4), + StrLenField("vendorID","",length_from=lambda x:x.length-4), + ] + +class IKEv2_payload_SA(IKEv2_class): + name = "IKEv2 SA" + overload_fields = { IKEv2: { "next_payload":33 }} + fields_desc = [ + ByteEnumField("next_payload",None,IKEv2_payload_type), + ByteField("res",0), + FieldLenField("length",None,"prop","H", adjust=lambda pkt,x:x+4), + PacketLenField("prop",conf.raw_layer(),IKEv2_payload_Proposal,length_from=lambda x:x.length-4), + ] + +class IKEv2_payload_Nonce(IKEv2_class): + name = "IKEv2 Nonce" + overload_fields = { IKEv2: { "next_payload":40 }} + fields_desc = [ + ByteEnumField("next_payload",None,IKEv2_payload_type), + ByteField("res",0), + FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4), + StrLenField("load","",length_from=lambda x:x.length-4), + ] + +class IKEv2_payload_Notify(IKEv2_class): + name = "IKEv2 Notify" + overload_fields = { IKEv2: { "next_payload":41 }} + fields_desc = [ + ByteEnumField("next_payload",None,IKEv2_payload_type), + ByteField("res",0), + FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+4), + StrLenField("load","",length_from=lambda x:x.length-4), + ] + +class IKEv2_payload_KE(IKEv2_class): + name = "IKEv2 Key Exchange" + overload_fields = { IKEv2: { "next_payload":34 }} + fields_desc = [ + ByteEnumField("next_payload",None,IKEv2_payload_type), + ByteField("res",0), + FieldLenField("length",None,"load","H", adjust=lambda pkt,x:x+6), + ShortEnumField("group", 0, IKEv2TransformTypes['GroupDesc'][1]), + StrLenField("load","",length_from=lambda x:x.length-6), + ] + +class IKEv2_payload_IDi(IKEv2_class): + name = "IKEv2 Identification - Initiator" + overload_fields = { IKEv2: { "next_payload":35 }} + fields_desc = [ + ByteEnumField("next_payload",None,IKEv2_payload_type), + ByteField("res",0), + FieldLenField("length",None,"load","H",adjust=lambda pkt,x:x+8), + ByteEnumField("IDtype",1,{1:"IPv4_addr", 11:"Key"}), + ByteEnumField("ProtoID",0,{0:"Unused"}), + ShortEnumField("Port",0,{0:"Unused"}), +# IPField("IdentData","127.0.0.1"), + StrLenField("load","",length_from=lambda x:x.length-8), + ] + +class IKEv2_payload_IDr(IKEv2_class): + name = "IKEv2 Identification - Responder" + overload_fields = { IKEv2: { "next_payload":36 }} + fields_desc = [ + ByteEnumField("next_payload",None,IKEv2_payload_type), + ByteField("res",0), + FieldLenField("length",None,"load","H",adjust=lambda pkt,x:x+8), + ByteEnumField("IDtype",1,{1:"IPv4_addr", 11:"Key"}), + ByteEnumField("ProtoID",0,{0:"Unused"}), + ShortEnumField("Port",0,{0:"Unused"}), +# IPField("IdentData","127.0.0.1"), + StrLenField("load","",length_from=lambda x:x.length-8), + ] + + + +class IKEv2_payload_Encrypted(IKEv2_class): + name = "IKEv2 Encrypted and Authenticated" + overload_fields = { IKEv2: { "next_payload":46 }} + fields_desc = [ + ByteEnumField("next_payload",None,IKEv2_payload_type), + ByteField("res",0), + FieldLenField("length",None,"load","H",adjust=lambda pkt,x:x+4), + StrLenField("load","",length_from=lambda x:x.length-4), + ] + + + +IKEv2_payload_type_overload = {} +for i in range(len(IKEv2_payload_type)): + name = "IKEv2_payload_%s" % IKEv2_payload_type[i] + if name in globals(): + IKEv2_payload_type_overload[globals()[name]] = {"next_payload":i} + +del(i) +del(name) +IKEv2_class.overload_fields = IKEv2_payload_type_overload.copy() + +split_layers(UDP, ISAKMP, sport=500) +split_layers(UDP, ISAKMP, dport=500) + +bind_layers( UDP, IKEv2, dport=500, sport=500) # TODO: distinguish IKEv1/IKEv2 +bind_layers( UDP, IKEv2, dport=4500, sport=4500) + +def ikev2scan(ip): + return sr(IP(dst=ip)/UDP()/IKEv2(init_SPI=RandString(8), + exch_type=34)/IKEv2_payload_SA(prop=IKEv2_payload_Proposal())) + +# conf.debug_dissector = 1 + +if __name__ == "__main__": + interact(mydict=globals(), mybanner="IKEv2 alpha-level protocol implementation") -- cgit 1.2.3-korg