Ethereal-dev: [Ethereal-dev] PATCH: ESP transport null encyption decode
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: Fri, 22 Oct 2004 13:44:46 +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 decode TCP or UDP packets contained in NULL encypted ESP transport packets. The authentication information is displayed, but not checked.
Patch breakdown --------------- epan/dissectors/packet-ip.c epan/dissectors/packet-ip.hMake dissect_icmp public so we can call it to decode any enacapsulated ICMP packets.
epan/dissectors/packet-tcp.c epan/dissectors/packet-tcp.h Make dissect_tcp public so we can call it to decode any enacapsulated TCP packets. epan/dissectors/packet-udp epan/dissectors/packet-udp.c Make dissect_udp public so we can call it to decode any enacapsulated UDP packets.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.
epan/dissectors/packet-ipsec.c Include the ip/udp/tcp headersAdd/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 field, which in turn will specify the payload as being ICMP/UDP/TCP. If a reasonable payload type is found the the payload is passed to the appropriate dissector. If not the payload is displayed as raw data. If g_esp_enable_null_encryption_decode_heuristic is false (default), will decode the packet in the same was as it used to be (ie. raw data). Cheers Mark Phillips -- Mark S. Phillips mob. 07903 559147 mark.phillips@xxxxxxxxxx Tel. 01279 441124
--- ethereal-2004-10-22/epan/dissectors/packet-ip.c.orig 2004-09-29 01:52:45.000000000 +0100 +++ ethereal-2004-10-22/epan/dissectors/packet-ip.c 2004-10-22 12:59:03.281893000 +0100 @@ -54,8 +54,6 @@ static int ip_tap = -1; -static void dissect_icmp(tvbuff_t *, packet_info *, proto_tree *); - /* Decode the old IPv4 TOS field as the DiffServ DS Field */ static gboolean g_ip_dscp_actif = TRUE; @@ -1300,7 +1298,7 @@ * RFC 1256 for router discovery messages. * RFC 2002 and 3012 for Mobile IP stuff. */ -static void +void dissect_icmp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *icmp_tree; --- ethereal-2004-10-22/epan/dissectors/packet-ip.h.orig 2004-07-18 19:06:47.000000000 +0100 +++ ethereal-2004-10-22/epan/dissectors/packet-ip.h 2004-10-22 12:59:03.291887000 +0100 @@ -45,4 +45,6 @@ /* Export the DSCP value-string table for other protocols */ extern const value_string dscp_vals[]; +void dissect_icmp(tvbuff_t *, packet_info *, proto_tree *); + #endif --- ethereal-2004-10-22/epan/dissectors/packet-ipsec.c.orig 2004-09-29 01:52:45.000000000 +0100 +++ ethereal-2004-10-22/epan/dissectors/packet-ipsec.c 2004-10-22 13:22:32.421615000 +0100 @@ -35,9 +35,14 @@ #include <epan/addr_resolv.h> #include <epan/ipproto.h> #include <epan/prefs.h> +#include "packet-udp.h" +#include "packet-tcp.h" +#include "packet-ip.h" /* Place AH payload in sub tree */ static gboolean g_ah_payload_in_subtree = FALSE; +/* Assume ESP contains NULL encrypted data */ +static gboolean g_esp_enable_null_encryption_decode_heuristic = FALSE; static int proto_ah = -1; static int hf_ah_spi = -1; @@ -45,6 +50,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 +221,9 @@ * (ie none) */ if(tree) { + int len, pad, encapsulated_protocol; + int auth_decode_ok = 1; + 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 +232,57 @@ 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); + + switch(encapsulated_protocol) + { + case IP_PROTO_ICMP: + dissect_icmp(tvb_new_subset(tvb, sizeof(struct newesp), -1, + len - sizeof(struct newesp) - 14 - pad), + pinfo, esp_tree); + break; + case IP_PROTO_UDP: + dissect_udp(tvb_new_subset(tvb, sizeof(struct newesp), -1, + len - sizeof(struct newesp) - 14 - pad), + pinfo, esp_tree); + break; + case IP_PROTO_TCP: + dissect_tcp(tvb_new_subset(tvb, sizeof(struct newesp), -1, + len - sizeof(struct newesp) - 14 - pad), + pinfo, esp_tree); + break; + default: + auth_decode_ok = 0; + break; + } + } + else + { + auth_decode_ok = 0; + } + + 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 +357,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 +381,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 +403,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 decodes as TCP/UDP/ICMP based on 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-22/epan/dissectors/packet-tcp.c.orig 2004-10-11 09:12:34.000000000 +0100 +++ ethereal-2004-10-22/epan/dissectors/packet-tcp.c 2004-10-22 12:59:03.321899000 +0100 @@ -2533,7 +2533,7 @@ } } -static void +void dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { guint8 th_off_x2; /* combines th_off and th_x2 */ --- ethereal-2004-10-22/epan/dissectors/packet-tcp.h.orig 2004-07-18 19:06:47.000000000 +0100 +++ ethereal-2004-10-22/epan/dissectors/packet-tcp.h 2004-10-22 12:59:03.321936000 +0100 @@ -93,4 +93,6 @@ guint32 dport, proto_tree *tree, proto_tree *tcp_tree); +extern void dissect_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); + #endif --- ethereal-2004-10-22/epan/dissectors/packet-udp.c.orig 2004-09-29 01:52:45.000000000 +0100 +++ ethereal-2004-10-22/epan/dissectors/packet-udp.c 2004-10-22 12:59:03.321974000 +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); @@ -145,7 +145,7 @@ } -static void +void dissect_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *udp_tree; --- ethereal-2004-10-22/epan/dissectors/packet-udp.h.orig 2004-07-18 19:06:47.000000000 +0100 +++ ethereal-2004-10-22/epan/dissectors/packet-udp.h 2004-10-22 12:59:03.322011000 +0100 @@ -35,6 +35,7 @@ address ip_dst; } e_udphdr; +extern void dissect_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree); extern void decode_udp_ports(tvbuff_t *, int, packet_info *, proto_tree *, int, int, int);
- Follow-Ups:
- Re: [Ethereal-dev] PATCH: ESP transport null encyption decode
- From: Guy Harris
- [Ethereal-dev] PATCH: ESP transport null encyption decode (v2)
- From: Mark Phillips
- Re: [Ethereal-dev] PATCH: ESP transport null encyption decode
- Prev by Date: RE: [Ethereal-dev] please help
- Next by Date: [Ethereal-dev] Problem with pinfo->cinfo in dissector
- Previous by thread: Re: [Ethereal-dev] ipseckey RR
- Next by thread: Re: [Ethereal-dev] PATCH: ESP transport null encyption decode
- Index(es):