Ethereal-dev: [Ethereal-dev] ntlmssp decoding
Note: This archive is from the project's previous web site, ethereal.com. This list is no longer active.
From: Devin Heitmueller <dheitmueller@xxxxxxxxxxx>
Date: 05 Jul 2002 23:30:35 -0400
I now have a newfound appreciation for how much work goes into writing dissectors. I have made a few changes to further decode the DCERPC bind message to show ntlmssp fields. It has taken me about four hours to add three or four fields. I suspect this is either because I am doing something seriously wrong, or I am still in the learning curve. Would it be possible for someone to review my attached changes, and provide feedback? In particular, I am interested in knowing if I am using the correct primitives to decode the various data types, etc (for example, I still can't figure out how to display strings). I am very interested in going further, but I would appreciate a sanity check on what I have done thus far, so my patches do not get rejected. Any feedback would be greatly appreciated. Thanks, -- Devin Heitmueller Senior Software Engineer Netilla Networks Inc
Index: packet-dcerpc.c
===================================================================
RCS file: /cvsroot/ethereal/packet-dcerpc.c,v
retrieving revision 1.64
diff --unified -r1.64 packet-dcerpc.c
--- packet-dcerpc.c 2002/06/24 09:23:39 1.64
+++ packet-dcerpc.c 2002/07/06 03:21:26
@@ -99,6 +99,34 @@
{ 0, NULL }
};
+static const value_string ntlmssp_message_types[] = {
+ { 1, "NTLMSSP_NEGOTIATE" },
+ { 2, "NTLMSSP_CHALLENGE" },
+ { 3, "NTLMSSP_AUTH" },
+ { 4, "NTLMSSP_UNKNOWN" }
+};
+
+/*
+ * NTLMSSP negotiation flags
+ * Taken from Samba-TNG rpc_ntlmssp.h
+ */
+#define NTLMSSP_NEGOTIATE_UNICODE 0x00000001
+#define NTLMSSP_NEGOTIATE_OEM 0x00000002
+#define NTLMSSP_REQUEST_TARGET 0x00000004
+#define NTLMSSP_NEGOTIATE_SIGN 0x00000010
+#define NTLMSSP_NEGOTIATE_SEAL 0x00000020
+#define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080
+#define NTLMSSP_NEGOTIATE_00000100 0x00000100
+#define NTLMSSP_NEGOTIATE_NTLM 0x00000200
+#define NTLMSSP_NEGOTIATE_00000400 0x00000400
+#define NTLMSSP_NEGOTIATE_00001000 0x00001000
+#define NTLMSSP_NEGOTIATE_00002000 0x00002000
+#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000
+#define NTLMSSP_NEGOTIATE_NTLM2 0x00080000
+#define NTLMSSP_NEGOTIATE_TARGET_INFO 0x00800000
+#define NTLMSSP_NEGOTIATE_128 0x20000000
+#define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000
+
/*
* Protection levels.
*/
@@ -381,6 +409,25 @@
static int hf_dcerpc_fragment_multiple_tails = -1;
static int hf_dcerpc_fragment_too_long_fragment = -1;
static int hf_dcerpc_fragment_error = -1;
+static int hf_dcerpc_auth_ntlmssp = -1;
+static int hf_ntlmssp_message_type = -1;
+static int hf_dcerpc_ntlmssp_negotiate_flags = -1;
+static int hf_dcerpc_ntlmssp_negotiate_flags_01 = -1;
+static int hf_dcerpc_ntlmssp_negotiate_flags_02 = -1;
+static int hf_dcerpc_ntlmssp_negotiate_flags_04 = -1;
+static int hf_dcerpc_ntlmssp_negotiate_flags_10 = -1;
+static int hf_dcerpc_ntlmssp_negotiate_flags_20 = -1;
+static int hf_dcerpc_ntlmssp_negotiate_flags_80 = -1;
+static int hf_dcerpc_ntlmssp_negotiate_flags_100 = -1;
+static int hf_dcerpc_ntlmssp_negotiate_flags_200 = -1;
+static int hf_dcerpc_ntlmssp_negotiate_flags_400 = -1;
+static int hf_dcerpc_ntlmssp_negotiate_flags_1000 = -1;
+static int hf_dcerpc_ntlmssp_negotiate_flags_2000 = -1;
+static int hf_dcerpc_ntlmssp_negotiate_flags_8000 = -1;
+static int hf_dcerpc_ntlmssp_negotiate_flags_80000 = -1;
+static int hf_dcerpc_ntlmssp_negotiate_flags_800000 = -1;
+static int hf_dcerpc_ntlmssp_negotiate_flags_20000000 = -1;
+static int hf_dcerpc_ntlmssp_negotiate_flags_40000000 = -1;
static gint ett_dcerpc = -1;
static gint ett_dcerpc_cn_flags = -1;
@@ -390,6 +437,7 @@
static gint ett_dcerpc_pointer_data = -1;
static gint ett_dcerpc_fragments = -1;
static gint ett_dcerpc_fragment = -1;
+static gint ett_dcerpc_negotiate_flags = -1;
fragment_items dcerpc_frag_items = {
&ett_dcerpc_fragments,
@@ -1298,6 +1346,89 @@
}
static int
+dissect_dcerpc_ntlmssp_negotiate (tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *dcerpc_tree,
+ e_dce_cn_common_hdr_t *hdr)
+{
+ guint32 negotiate_flags;
+ proto_tree *negotiate_flags_tree = NULL;
+ proto_item *tf = NULL;
+
+ // NTLMSSP Negotiate Flags
+ negotiate_flags = tvb_get_letohs (tvb, offset);
+ tf = proto_tree_add_uint (dcerpc_tree,
+ hf_dcerpc_ntlmssp_negotiate_flags,
+ tvb, offset, 4, negotiate_flags);
+ negotiate_flags_tree = proto_item_add_subtree (tf, ett_dcerpc_negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_01, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_02, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_04, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_10, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_20, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_80, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_100, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_200, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_400, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_1000, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_2000, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_8000, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_80000, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_800000, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_20000000, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_40000000, tvb, offset, 4, negotiate_flags);
+
+ offset +=4;
+
+
+ return offset;
+}
+
+static int
+dissect_dcerpc_ntlmssp_challenge (tvbuff_t *tvb, int offset, packet_info *pinfo,
+ proto_tree *dcerpc_tree,
+ e_dce_cn_common_hdr_t *hdr)
+{
+ guint32 negotiate_flags;
+ proto_tree *negotiate_flags_tree = NULL;
+ proto_item *tf = NULL;
+
+ // Skip over the two unknown fields
+ offset += 8;
+
+ // NTLMSSP Negotiate Flags
+ negotiate_flags = tvb_get_letohs (tvb, offset);
+ tf = proto_tree_add_uint (dcerpc_tree,
+ hf_dcerpc_ntlmssp_negotiate_flags,
+ tvb, offset, 4, negotiate_flags);
+ negotiate_flags_tree = proto_item_add_subtree (tf, ett_dcerpc_negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_01, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_02, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_04, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_10, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_20, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_80, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_100, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_200, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_400, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_1000, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_2000, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_8000, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_80000, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_800000, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_20000000, tvb, offset, 4, negotiate_flags);
+ proto_tree_add_boolean (negotiate_flags_tree, hf_dcerpc_ntlmssp_negotiate_flags_40000000, tvb, offset, 4, negotiate_flags);
+
+ offset +=4;
+
+ proto_tree_add_text (dcerpc_tree, tvb, offset, 8, "NTLM Challenge");
+ offset += 8;
+ proto_tree_add_text (dcerpc_tree, tvb, offset, 8, "Reserved");
+ offset += 8;
+
+ return offset;
+}
+
+static int
dissect_dcerpc_cn_auth (tvbuff_t *tvb, packet_info *pinfo, proto_tree *dcerpc_tree,
e_dce_cn_common_hdr_t *hdr, int *auth_level_p)
{
@@ -1339,8 +1470,22 @@
offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
hf_dcerpc_auth_ctx_id, NULL);
- proto_tree_add_text (dcerpc_tree, tvb, offset, hdr->auth_len, "Auth Data");
+ // proto_tree_add_text (dcerpc_tree, tvb, offset, hdr->auth_len, "Auth Data");
+ // djh debug
+ /* NTLMSSP constant (skip over the string) */
+ offset += 8;
+
+ // NTLMSSP Message Type
+ hdr->ntlmssp_message_type = tvb_get_letohs (tvb, offset);
+ offset = dissect_dcerpc_uint32 (tvb, offset, pinfo, dcerpc_tree, hdr->drep,
+ hf_ntlmssp_message_type, NULL);
+
+ if (hdr->ntlmssp_message_type == 1)
+ offset = dissect_dcerpc_ntlmssp_negotiate (tvb, offset, pinfo, dcerpc_tree, &hdr);
+ else if (hdr->ntlmssp_message_type == 2)
+ offset = dissect_dcerpc_ntlmssp_challenge (tvb, offset, pinfo, dcerpc_tree, &hdr);
+
/* figure out where the auth padding starts */
offset = hdr->frag_len - (hdr->auth_len + 8 + auth_pad_len);
if (offset > 0 && auth_pad_len) {
@@ -3427,6 +3572,46 @@
{ &hf_dcerpc_fragment_error,
{ "Defragmentation error", "dcerpc.fragment.error", FT_NONE, BASE_NONE, NULL, 0x0, "Defragmentation error due to illegal fragments", HFILL }},
+ { &hf_dcerpc_auth_ntlmssp,
+ { "NTLMSSP identifier", "dcerpc.auth_ntlmssp", FT_STRING, BASE_NONE, NULL, 0x0, "NTLMSSP Identifier", HFILL }},
+
+ { &hf_ntlmssp_message_type,
+ { "NTLM Message Type", "dcerpc.ntlmssp.messagetype", FT_UINT32, BASE_HEX, VALS(ntlmssp_message_types), 0x0, "", HFILL }},
+
+ { &hf_dcerpc_ntlmssp_negotiate_flags,
+ { "NTLM SSP Negotiate Flags", "dcerpc.negotiateflags", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
+ { &hf_dcerpc_ntlmssp_negotiate_flags_01,
+ { "Negotiate UNICODE", "dcerpc.ntlmssp.negotiateunicode", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_UNICODE, "", HFILL }},
+ { &hf_dcerpc_ntlmssp_negotiate_flags_02,
+ { "Negotiate OEM", "dcerpc.ntlmssp.negotiateoem", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_OEM, "", HFILL }},
+ { &hf_dcerpc_ntlmssp_negotiate_flags_04,
+ { "Request Target", "dcerpc.ntlmssp.requesttarget", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_REQUEST_TARGET, "", HFILL }},
+ { &hf_dcerpc_ntlmssp_negotiate_flags_10,
+ { "Negotiate Sign", "dcerpc.ntlmssp.negotiatesign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SIGN, "", HFILL }},
+ { &hf_dcerpc_ntlmssp_negotiate_flags_20,
+ { "Negotiate Seal", "dcerpc.ntlmssp.negotiateseal", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SEAL, "", HFILL }},
+ { &hf_dcerpc_ntlmssp_negotiate_flags_80,
+ { "Negotiate Lan Manager Key", "dcerpc.ntlmssp.negotiatelmkey", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_LM_KEY, "", HFILL }},
+ { &hf_dcerpc_ntlmssp_negotiate_flags_100,
+ { "Negotiate 0x00000100", "dcerpc.ntlmssp.negotiate00000100", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000100, "", HFILL }},
+ { &hf_dcerpc_ntlmssp_negotiate_flags_200,
+ { "Negotiate NTLM key", "dcerpc.ntlmssp.negotiatentlm", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM, "", HFILL }},
+ { &hf_dcerpc_ntlmssp_negotiate_flags_400,
+ { "Negotiate 0x00000400", "dcerpc.ntlmssp.negotiate00000400", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000400, "", HFILL }},
+ { &hf_dcerpc_ntlmssp_negotiate_flags_1000,
+ { "Negotiate 0x00001000", "dcerpc.ntlmssp.negotiate00001000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00001000, "", HFILL }},
+ { &hf_dcerpc_ntlmssp_negotiate_flags_2000,
+ { "Negotiate 0x00002000", "dcerpc.ntlmssp.negotiate00002000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00002000, "", HFILL }},
+ { &hf_dcerpc_ntlmssp_negotiate_flags_8000,
+ { "Negotiate Always Sign", "dcerpc.ntlmssp.negotiatealwayssign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_ALWAYS_SIGN, "", HFILL }},
+ { &hf_dcerpc_ntlmssp_negotiate_flags_80000,
+ { "Negotiate NTLM2 key", "dcerpc.ntlmssp.negotiatentlm2", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM2, "", HFILL }},
+ { &hf_dcerpc_ntlmssp_negotiate_flags_800000,
+ { "Negotiate Target Info", "dcerpc.ntlmssp.negotiatetargetinfo", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_TARGET_INFO, "", HFILL }},
+ { &hf_dcerpc_ntlmssp_negotiate_flags_20000000,
+ { "Negotiate 128", "dcerpc.ntlmssp.negotiate128", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_128, "", HFILL }},
+ { &hf_dcerpc_ntlmssp_negotiate_flags_40000000,
+ { "Negotiate Key Exchange", "dcerpc.ntlmssp.negotiatekeyexch", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_KEY_EXCH, "", HFILL }},
};
static gint *ett[] = {
&ett_dcerpc,
@@ -3437,6 +3622,7 @@
&ett_dcerpc_pointer_data,
&ett_dcerpc_fragments,
&ett_dcerpc_fragment,
+ &ett_dcerpc_negotiate_flags,
};
module_t *dcerpc_module;
Index: packet-dcerpc.h
===================================================================
RCS file: /cvsroot/ethereal/packet-dcerpc.h,v
retrieving revision 1.18
diff --unified -r1.18 packet-dcerpc.h
--- packet-dcerpc.h 2002/06/24 00:03:18 1.18
+++ packet-dcerpc.h 2002/07/06 03:21:26
@@ -48,6 +48,7 @@
guint16 frag_len;
guint16 auth_len;
guint32 call_id;
+ guint32 ntlmssp_message_type;
} e_dce_cn_common_hdr_t;
typedef struct _e_dce_dg_common_hdr_t {
- Follow-Ups:
- Re: [Ethereal-dev] ntlmssp decoding
- From: Ronnie Sahlberg
- Re: [Ethereal-dev] ntlmssp decoding
- From: Tim Potter
- Re: [Ethereal-dev] ntlmssp decoding
- Prev by Date: Re: [Ethereal-dev] How to cd to non-8.3 dirs in Win2K?
- Next by Date: [Ethereal-dev] User Info (0x10 == 16) is an ACB struct.
- Previous by thread: Re: [Ethereal-dev] How to cd to non-8.3 dirs in Win2K?
- Next by thread: Re: [Ethereal-dev] ntlmssp decoding
- Index(es):





