Ethereal-dev: [Ethereal-dev] PATCH: ESP transport null encyption decode (v2)
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Mark Phillips <msp@xxxxxxxxxxxxxxxxxx>
Date: Wed, 27 Oct 2004 15:02:00 +0100 (BST)
Hi, The attached patch adds the, optional, ability to decode transport ESP packets which are using NULL encryption. Please checkin or propose fixes! Background ========== It is normally hard to decode IP Security ESP protocol packets because they are encrypted (ie. when used to form a secure VPN tunnel into a corporate network). BUT, there are applications where ESP is just used to authenticate the data with no encryption (aka. NULL encryption). In particular the application we are developing uses transport mode ESP with NULL encyption and either SHA1 or MD5 authentication. The proposed patch adds the (by default disabled), capability to attempt decode of packets contained in NULL encypted ESP transport packets. The authentication information is displayed, but not checked. Patch breakdown =============== epan/dissectors/packet-ipsec.c ------------------------------ Add/register g_esp_enable_null_encryption_decode_heuristic option (default FALSE). Add/register new packet fields hf_esp_pad and hf_esp_protocol. If g_esp_enable_null_encryption_decode_heuristic is true, attempts to decode the ESP packet contents:- The code assumes that if this is a transport ESP NULL encrypted packet it will contain a 12 byte (ie. SHA1 or MD5) authentication trailer, prefixed with the ESP pad and payload type fields, which in turn will specify the payload type. Decode is attempted based on this type and if this fails, the payload is displayed as raw data. If g_esp_enable_null_encryption_decode_heuristic is false (default), it will decode the packet in the same way as it used to be (ie. raw data). epan/dissectors/packet-udp.c ---------------------------- Fix UDP length calculation in decode_udp_ports. The code did not correctly allow for the UDP header which means that if there is additional data AFTER the UDP (ie. the ESP authentication field), its length will be included in the length passed to the protocol contained within the UDP packet. Cheers Mark Phillips -- Mark S. Phillips mob. 07903 559147 mark.phillips@xxxxxxxxxx Tel. 01279 441124 Old Nortel address (til 3rd Dec 2004) ESN 742 2461 msp@xxxxxxxxxxxxxxxxxx Tel. +44 1279 402461
--- ethereal-2004-10-27/epan/dissectors/packet-ipsec.c.orig 2004-10-27 14:02:18.170499000 +0100 +++ ethereal-2004-10-27/epan/dissectors/packet-ipsec.c 2004-10-27 14:02:57.580806000 +0100 @@ -38,6 +38,8 @@ /* Place AH payload in sub tree */ static gboolean g_ah_payload_in_subtree = FALSE; +/* Default ESP payload decode to off (only works if payload is NULL encrypted) */ +static gboolean g_esp_enable_null_encryption_decode_heuristic = FALSE; static int proto_ah = -1; static int hf_ah_spi = -1; @@ -45,6 +47,8 @@ static int proto_esp = -1; static int hf_esp_spi = -1; static int hf_esp_sequence = -1; +static int hf_esp_pad = -1; +static int hf_esp_protocol = -1; static int proto_ipcomp = -1; static int hf_ipcomp_flags = -1; static int hf_ipcomp_cpi = -1; @@ -214,6 +218,9 @@ * (ie none) */ if(tree) { + int len, pad, encapsulated_protocol; + int auth_decode_ok = 0; + ti = proto_tree_add_item(tree, proto_esp, tvb, 0, -1, FALSE); esp_tree = proto_item_add_subtree(ti, ett_esp); proto_tree_add_uint(esp_tree, hf_esp_spi, tvb, @@ -222,9 +229,43 @@ proto_tree_add_uint(esp_tree, hf_esp_sequence, tvb, offsetof(struct newesp, esp_seq), 4, (guint32)g_ntohl(esp.esp_seq)); - call_dissector(data_handle, - tvb_new_subset(tvb, sizeof(struct newesp), -1, -1), - pinfo, esp_tree); + + if(g_esp_enable_null_encryption_decode_heuristic) + { + len = tvb_length_remaining(tvb, 0); /* Get length of whole ESP packet. */ + pad = tvb_get_guint8(tvb, len - 14); + encapsulated_protocol = tvb_get_guint8(tvb, len - 13); + + if(dissector_try_port(ip_dissector_table, + encapsulated_protocol, + tvb_new_subset(tvb, + sizeof(struct newesp), + -1, + len - sizeof(struct newesp) - 14 - pad), + pinfo, + esp_tree)) + { + auth_decode_ok = 1; + } + } + + if(auth_decode_ok) + { + proto_tree_add_uint(esp_tree, hf_esp_pad, tvb, + len - 14, 1, + pad); + proto_tree_add_uint(esp_tree, hf_esp_protocol, tvb, + len - 13, 1, + encapsulated_protocol); + proto_tree_add_text(esp_tree, tvb, len - 12, 12, + "Authentication Data"); + } + else + { + call_dissector(data_handle, + tvb_new_subset(tvb, sizeof(struct newesp), -1, -1), + pinfo, esp_tree); + } } } @@ -299,6 +340,12 @@ "", HFILL }}, { &hf_esp_sequence, { "Sequence", "esp.sequence", FT_UINT32, BASE_DEC, NULL, 0x0, + "", HFILL }}, + { &hf_esp_pad, + { "Pad Length", "esp.pad", FT_UINT8, BASE_DEC, NULL, 0x0, + "", HFILL }}, + { &hf_esp_protocol, + { "Next Header", "esp.protocol", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }} }; @@ -317,6 +364,7 @@ }; module_t *ah_module; + module_t *esp_module; proto_ah = proto_register_protocol("Authentication Header", "AH", "ah"); proto_register_field_array(proto_ah, hf_ah, array_length(hf_ah)); @@ -338,6 +386,12 @@ "Whether the AH payload decode should be placed in a subtree", &g_ah_payload_in_subtree); + esp_module = prefs_register_protocol(proto_esp, NULL); + prefs_register_bool_preference(esp_module, "enable_null_encryption_decode_heuristic", + "Attempt to detect/decode NULL encrypted ESP payloads", +"Assumes a 12 byte auth (SHA1/MD5) and attempts decode based on the ethertype 13 bytes from packet end", + &g_esp_enable_null_encryption_decode_heuristic); + register_dissector("esp", dissect_esp, proto_esp); register_dissector("ah", dissect_ah, proto_ah); } --- ethereal-2004-10-27/epan/dissectors/packet-udp.c.orig 2004-09-29 01:52:45.000000000 +0100 +++ ethereal-2004-10-27/epan/dissectors/packet-udp.c 2004-10-27 14:02:57.580844000 +0100 @@ -85,10 +85,10 @@ /* This is the length from the UDP header; the payload should be cut off at that length. XXX - what if it's *greater* than the reported length? */ - if (uh_ulen < len) - len = uh_ulen; - if (uh_ulen < reported_len) - reported_len = uh_ulen; + if ((uh_ulen - offset) < len) + len = (uh_ulen - offset); + if ((uh_ulen - offset) < reported_len) + reported_len = (uh_ulen - offset); } next_tvb = tvb_new_subset(tvb, offset, len, reported_len);
- Follow-Ups:
- Re: [Ethereal-dev] PATCH: ESP transport null encyption decode (v2)
- From: Guy Harris
- Re: [Ethereal-dev] PATCH: ESP transport null encyption decode (v2)
- References:
- [Ethereal-dev] PATCH: ESP transport null encyption decode
- From: Mark Phillips
- [Ethereal-dev] PATCH: ESP transport null encyption decode
- Prev by Date: [Ethereal-dev] Re: make errors
- Next by Date: Re: [Ethereal-dev] range preference type
- Previous by thread: Re: [Ethereal-dev] PATCH: ESP transport null encyption decode
- Next by thread: Re: [Ethereal-dev] PATCH: ESP transport null encyption decode (v2)
- Index(es):