2 * Routines for NTLM Secure Service Provider
3 * Devin Heitmueller <dheitmueller@netilla.com>
5 * $Id: packet-ntlmssp.c,v 1.36 2003/03/11 22:51:52 guy Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@ethereal.com>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #include <epan/packet.h>
33 #include "packet-smb-common.h"
34 #include "asn1.h" /* XXX - needed for subid_t */
35 #include "packet-gssapi.h"
36 #include "packet-frame.h"
38 #include "crypt-rc4.h"
39 #include "crypt-md4.h"
40 #include "crypt-des.h"
41 #include "packet-ntlmssp.h"
45 #define NTLMSSP_NEGOTIATE 1
46 #define NTLMSSP_CHALLENGE 2
47 #define NTLMSSP_AUTH 3
48 #define NTLMSSP_UNKNOWN 4
50 static const value_string ntlmssp_message_types[] = {
51 { NTLMSSP_NEGOTIATE, "NTLMSSP_NEGOTIATE" },
52 { NTLMSSP_CHALLENGE, "NTLMSSP_CHALLENGE" },
53 { NTLMSSP_AUTH, "NTLMSSP_AUTH" },
54 { NTLMSSP_UNKNOWN, "NTLMSSP_UNKNOWN" },
59 * NTLMSSP negotiation flags
62 #define NTLMSSP_NEGOTIATE_UNICODE 0x00000001
63 #define NTLMSSP_NEGOTIATE_OEM 0x00000002
64 #define NTLMSSP_REQUEST_TARGET 0x00000004
65 #define NTLMSSP_NEGOTIATE_00000008 0x00000008
66 #define NTLMSSP_NEGOTIATE_SIGN 0x00000010
67 #define NTLMSSP_NEGOTIATE_SEAL 0x00000020
68 #define NTLMSSP_NEGOTIATE_DATAGRAM_STYLE 0x00000040
69 #define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080
70 #define NTLMSSP_NEGOTIATE_NETWARE 0x00000100
71 #define NTLMSSP_NEGOTIATE_NTLM 0x00000200
72 #define NTLMSSP_NEGOTIATE_00000400 0x00000400
73 #define NTLMSSP_NEGOTIATE_00000800 0x00000800
74 #define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED 0x00001000
75 #define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED 0x00002000
76 #define NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL 0x00004000
77 #define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000
78 #define NTLMSSP_CHAL_INIT_RESPONSE 0x00010000
79 #define NTLMSSP_CHAL_ACCEPT_RESPONSE 0x00020000
80 #define NTLMSSP_CHAL_NON_NT_SESSION_KEY 0x00040000
81 #define NTLMSSP_NEGOTIATE_NTLM2 0x00080000
82 #define NTLMSSP_NEGOTIATE_00100000 0x00100000
83 #define NTLMSSP_NEGOTIATE_00200000 0x00200000
84 #define NTLMSSP_NEGOTIATE_00400000 0x00400000
85 #define NTLMSSP_CHAL_TARGET_INFO 0x00800000
86 #define NTLMSSP_NEGOTIATE_01000000 0x01000000
87 #define NTLMSSP_NEGOTIATE_02000000 0x02000000
88 #define NTLMSSP_NEGOTIATE_04000000 0x04000000
89 #define NTLMSSP_NEGOTIATE_08000000 0x08000000
90 #define NTLMSSP_NEGOTIATE_10000000 0x10000000
91 #define NTLMSSP_NEGOTIATE_128 0x20000000
92 #define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000
93 #define NTLMSSP_NEGOTIATE_80000000 0x80000000
96 static int proto_ntlmssp = -1;
97 static int hf_ntlmssp = -1;
98 static int hf_ntlmssp_auth = -1;
99 static int hf_ntlmssp_message_type = -1;
100 static int hf_ntlmssp_negotiate_flags = -1;
101 static int hf_ntlmssp_negotiate_flags_01 = -1;
102 static int hf_ntlmssp_negotiate_flags_02 = -1;
103 static int hf_ntlmssp_negotiate_flags_04 = -1;
104 static int hf_ntlmssp_negotiate_flags_08 = -1;
105 static int hf_ntlmssp_negotiate_flags_10 = -1;
106 static int hf_ntlmssp_negotiate_flags_20 = -1;
107 static int hf_ntlmssp_negotiate_flags_40 = -1;
108 static int hf_ntlmssp_negotiate_flags_80 = -1;
109 static int hf_ntlmssp_negotiate_flags_100 = -1;
110 static int hf_ntlmssp_negotiate_flags_200 = -1;
111 static int hf_ntlmssp_negotiate_flags_400 = -1;
112 static int hf_ntlmssp_negotiate_flags_800 = -1;
113 static int hf_ntlmssp_negotiate_flags_1000 = -1;
114 static int hf_ntlmssp_negotiate_flags_2000 = -1;
115 static int hf_ntlmssp_negotiate_flags_4000 = -1;
116 static int hf_ntlmssp_negotiate_flags_8000 = -1;
117 static int hf_ntlmssp_negotiate_flags_10000 = -1;
118 static int hf_ntlmssp_negotiate_flags_20000 = -1;
119 static int hf_ntlmssp_negotiate_flags_40000 = -1;
120 static int hf_ntlmssp_negotiate_flags_80000 = -1;
121 static int hf_ntlmssp_negotiate_flags_100000 = -1;
122 static int hf_ntlmssp_negotiate_flags_200000 = -1;
123 static int hf_ntlmssp_negotiate_flags_400000 = -1;
124 static int hf_ntlmssp_negotiate_flags_800000 = -1;
125 static int hf_ntlmssp_negotiate_flags_1000000 = -1;
126 static int hf_ntlmssp_negotiate_flags_2000000 = -1;
127 static int hf_ntlmssp_negotiate_flags_4000000 = -1;
128 static int hf_ntlmssp_negotiate_flags_8000000 = -1;
129 static int hf_ntlmssp_negotiate_flags_10000000 = -1;
130 static int hf_ntlmssp_negotiate_flags_20000000 = -1;
131 static int hf_ntlmssp_negotiate_flags_40000000 = -1;
132 static int hf_ntlmssp_negotiate_flags_80000000 = -1;
133 static int hf_ntlmssp_negotiate_workstation_strlen = -1;
134 static int hf_ntlmssp_negotiate_workstation_maxlen = -1;
135 static int hf_ntlmssp_negotiate_workstation_buffer = -1;
136 static int hf_ntlmssp_negotiate_workstation = -1;
137 static int hf_ntlmssp_negotiate_domain_strlen = -1;
138 static int hf_ntlmssp_negotiate_domain_maxlen = -1;
139 static int hf_ntlmssp_negotiate_domain_buffer = -1;
140 static int hf_ntlmssp_negotiate_domain = -1;
141 static int hf_ntlmssp_ntlm_challenge = -1;
142 static int hf_ntlmssp_reserved = -1;
143 static int hf_ntlmssp_challenge_domain = -1;
144 static int hf_ntlmssp_auth_username = -1;
145 static int hf_ntlmssp_auth_domain = -1;
146 static int hf_ntlmssp_auth_hostname = -1;
147 static int hf_ntlmssp_auth_lmresponse = -1;
148 static int hf_ntlmssp_auth_ntresponse = -1;
149 static int hf_ntlmssp_auth_sesskey = -1;
150 static int hf_ntlmssp_string_len = -1;
151 static int hf_ntlmssp_string_maxlen = -1;
152 static int hf_ntlmssp_string_offset = -1;
153 static int hf_ntlmssp_blob_len = -1;
154 static int hf_ntlmssp_blob_maxlen = -1;
155 static int hf_ntlmssp_blob_offset = -1;
156 static int hf_ntlmssp_address_list = -1;
157 static int hf_ntlmssp_address_list_len = -1;
158 static int hf_ntlmssp_address_list_maxlen = -1;
159 static int hf_ntlmssp_address_list_offset = -1;
160 static int hf_ntlmssp_address_list_server_nb = -1;
161 static int hf_ntlmssp_address_list_domain_nb = -1;
162 static int hf_ntlmssp_address_list_server_dns = -1;
163 static int hf_ntlmssp_address_list_domain_dns = -1;
164 static int hf_ntlmssp_verf = -1;
165 static int hf_ntlmssp_verf_vers = -1;
166 static int hf_ntlmssp_verf_body = -1;
167 static int hf_ntlmssp_verf_unknown1 = -1;
168 static int hf_ntlmssp_verf_crc32 = -1;
169 static int hf_ntlmssp_verf_sequence = -1;
170 static int hf_ntlmssp_decrypted_payload = -1;
172 static gint ett_ntlmssp = -1;
173 static gint ett_ntlmssp_negotiate_flags = -1;
174 static gint ett_ntlmssp_string = -1;
175 static gint ett_ntlmssp_blob = -1;
176 static gint ett_ntlmssp_address_list = -1;
177 static gint ett_ntlmssp_decrypted_tree = -1;
179 /* Configuration variables */
180 static char *nt_password = NULL;
182 #define MAX_BLOB_SIZE 256
183 typedef struct _ntlmssp_blob {
185 guint8 contents[MAX_BLOB_SIZE];
188 /* Used in the conversation function */
189 typedef struct _ntlmssp_info {
192 rc4_state_struct rc4_state_peer1;
193 rc4_state_struct rc4_state_peer2;
194 guint32 peer1_dest_port;
195 int rc4_state_initialized;
196 ntlmssp_blob ntlm_response;
197 ntlmssp_blob lm_response;
201 * GMemChunk from which ntlmssp_info structures are allocated.
203 static GMemChunk *ntlmssp_info_chunk;
204 static int ntlmssp_info_count = 10;
206 /* If this struct exists in the payload_decrypt, then we have already
208 typedef struct _ntlmssp_packet_info {
211 guint8 *decrypted_payload;
213 gboolean payload_decrypted;
214 gboolean verifier_decrypted;
215 } ntlmssp_packet_info;
218 * GMemChunk from which ntlmssp_packet_info structures are allocated.
220 static GMemChunk *ntlmssp_packet_info_chunk;
221 static int ntlmssp_packet_info_count = 10;
224 * GSlist of decrypted payloads.
226 static GSList *decrypted_payloads;
229 Generate a challenge response, given an eight byte challenge and
230 either the NT or the Lan Manager password hash (16 bytes).
231 Returns output in response, which is expected to be 24 bytes.
233 static int ntlmssp_generate_challenge_response(guint8 *response,
234 const guint8 *passhash,
235 const guint8 *challenge)
237 guint8 pw21[21]; /* Password hash padded to 21 bytes */
239 memset(pw21, 0x0, sizeof(pw21));
240 memcpy(pw21, passhash, 16);
242 memset(response, 0, 24);
244 crypt_des_ecb(response, challenge, pw21, 1);
245 crypt_des_ecb(response + 8, challenge, pw21 + 7, 1);
246 crypt_des_ecb(response + 16, challenge, pw21 + 14, 1);
251 /* Create an NTLMSSP version 1 key.
252 * password points to the ANSI password to encrypt, challenge points to
253 * the 8 octet challenge string, key128 will do a 128 bit key if set to 1,
254 * otherwise it will do a 40 bit key. The result is stored in
255 * sspkey (expected to be 16 octets)
258 create_ntlmssp_v1_key(const char *nt_password, const guint8 *challenge,
259 int use_key_128, guint8 *sspkey)
261 unsigned char lm_password_upper[16];
262 unsigned char lm_password_hash[16];
263 guint8 lm_challenge_response[24];
265 guint8 pw21[21]; /* Password hash padded to 21 bytes */
268 unsigned char lmhash_key[] =
269 {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
271 memset(lm_password_upper, 0, sizeof(lm_password_upper));
273 /* Create a Lan Manager hash of the input password */
274 if (nt_password[0] != '\0') {
275 password_len = strlen(nt_password);
276 /* Truncate password if too long */
277 if (password_len > 16)
279 for (i = 0; i < password_len; i++) {
280 lm_password_upper[i] = toupper(nt_password[i]);
284 crypt_des_ecb(lm_password_hash, lmhash_key, lm_password_upper, 1);
285 crypt_des_ecb(lm_password_hash+8, lmhash_key, lm_password_upper+7, 1);
287 /* Generate the LanMan Challenge Response */
288 ntlmssp_generate_challenge_response(lm_challenge_response,
289 lm_password_hash, challenge);
291 /* Generate the NTLMSSP-v1 RC4 Key.
292 * The RC4 key is derived from the Lan Manager Hash.
293 * See lkcl "DCE/RPC over SMB" page 254 for the algorithm.
295 memset(pw21, 0xBD, sizeof(pw21));
296 memcpy(pw21, lm_password_hash, sizeof(lm_password_hash));
298 /* Only the first eight bytes of challenge_reponse is used */
299 crypt_des_ecb(rc4key, lm_challenge_response, pw21, 1);
300 crypt_des_ecb(rc4key + 8, lm_challenge_response, pw21 + 7, 1);
301 crypt_des_ecb(rc4key + 16, lm_challenge_response, pw21 + 14, 1);
303 /* Create the SSP Key */
304 memset(sspkey, 0, sizeof(sspkey));
306 /* Create 128 bit key */
307 memcpy(sspkey, rc4key, 16);
310 /* Create 40 bit key */
311 memcpy(sspkey, rc4key, 5);
319 /* dissect a string - header area contains:
322 four byte offset of string in data area
323 The function returns the offset at the end of the string header,
324 but the 'end' parameter returns the offset of the end of the string itself
325 The 'start' parameter returns the offset of the beginning of the string
328 dissect_ntlmssp_string (tvbuff_t *tvb, int offset,
329 proto_tree *ntlmssp_tree,
330 gboolean unicode_strings,
331 int string_hf, int *start, int *end)
333 proto_tree *tree = NULL;
334 proto_item *tf = NULL;
335 gint16 string_length = tvb_get_letohs(tvb, offset);
336 gint16 string_maxlen = tvb_get_letohs(tvb, offset+2);
337 gint32 string_offset = tvb_get_letohl(tvb, offset+4);
338 const char *string_text = NULL;
342 *start = (string_offset > offset+8 ? string_offset : offset+8);
343 if (0 == string_length) {
346 proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
351 bc = result_length = string_length;
352 string_text = get_unicode_or_ascii_string(tvb, &string_offset,
353 unicode_strings, &result_length,
357 tf = proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
358 string_offset, result_length, string_text);
359 tree = proto_item_add_subtree(tf, ett_ntlmssp_string);
361 proto_tree_add_uint(tree, hf_ntlmssp_string_len,
362 tvb, offset, 2, string_length);
364 proto_tree_add_uint(tree, hf_ntlmssp_string_maxlen,
365 tvb, offset, 2, string_maxlen);
367 proto_tree_add_uint(tree, hf_ntlmssp_string_offset,
368 tvb, offset, 4, string_offset);
371 *end = string_offset + string_length;
375 /* dissect a generic blob - header area contains:
378 four byte offset of blob in data area
379 The function returns the offset at the end of the blob header,
380 but the 'end' parameter returns the offset of the end of the blob itself
383 dissect_ntlmssp_blob (tvbuff_t *tvb, int offset,
384 proto_tree *ntlmssp_tree,
385 int blob_hf, int *end, ntlmssp_blob *result)
387 proto_item *tf = NULL;
388 proto_tree *tree = NULL;
389 guint16 blob_length = tvb_get_letohs(tvb, offset);
390 guint16 blob_maxlen = tvb_get_letohs(tvb, offset+2);
391 guint32 blob_offset = tvb_get_letohl(tvb, offset+4);
393 if (0 == blob_length) {
394 *end = (blob_offset > ((guint)offset)+8 ? blob_offset : ((guint)offset)+8);
396 proto_tree_add_text(ntlmssp_tree, tvb, offset, 8, "%s: Empty",
397 proto_registrar_get_name(blob_hf));
402 tf = proto_tree_add_item (ntlmssp_tree, blob_hf, tvb,
403 blob_offset, blob_length, FALSE);
404 tree = proto_item_add_subtree(tf, ett_ntlmssp_blob);
406 proto_tree_add_uint(tree, hf_ntlmssp_blob_len,
407 tvb, offset, 2, blob_length);
409 proto_tree_add_uint(tree, hf_ntlmssp_blob_maxlen,
410 tvb, offset, 2, blob_maxlen);
412 proto_tree_add_uint(tree, hf_ntlmssp_blob_offset,
413 tvb, offset, 4, blob_offset);
416 *end = blob_offset + blob_length;
418 if (result != NULL) {
419 result->length = blob_length;
420 memset(result->contents, 0, MAX_BLOB_SIZE);
421 if (blob_length < MAX_BLOB_SIZE)
422 tvb_memcpy(tvb, result->contents, blob_offset, blob_length);
430 dissect_ntlmssp_negotiate_flags (tvbuff_t *tvb, int offset,
431 proto_tree *ntlmssp_tree,
432 guint32 negotiate_flags)
434 proto_tree *negotiate_flags_tree = NULL;
435 proto_item *tf = NULL;
438 tf = proto_tree_add_uint (ntlmssp_tree,
439 hf_ntlmssp_negotiate_flags,
440 tvb, offset, 4, negotiate_flags);
441 negotiate_flags_tree = proto_item_add_subtree (tf, ett_ntlmssp_negotiate_flags);
444 proto_tree_add_boolean (negotiate_flags_tree,
445 hf_ntlmssp_negotiate_flags_80000000,
446 tvb, offset, 4, negotiate_flags);
447 proto_tree_add_boolean (negotiate_flags_tree,
448 hf_ntlmssp_negotiate_flags_40000000,
449 tvb, offset, 4, negotiate_flags);
450 proto_tree_add_boolean (negotiate_flags_tree,
451 hf_ntlmssp_negotiate_flags_20000000,
452 tvb, offset, 4, negotiate_flags);
453 proto_tree_add_boolean (negotiate_flags_tree,
454 hf_ntlmssp_negotiate_flags_10000000,
455 tvb, offset, 4, negotiate_flags);
456 proto_tree_add_boolean (negotiate_flags_tree,
457 hf_ntlmssp_negotiate_flags_8000000,
458 tvb, offset, 4, negotiate_flags);
459 proto_tree_add_boolean (negotiate_flags_tree,
460 hf_ntlmssp_negotiate_flags_4000000,
461 tvb, offset, 4, negotiate_flags);
462 proto_tree_add_boolean (negotiate_flags_tree,
463 hf_ntlmssp_negotiate_flags_2000000,
464 tvb, offset, 4, negotiate_flags);
465 proto_tree_add_boolean (negotiate_flags_tree,
466 hf_ntlmssp_negotiate_flags_1000000,
467 tvb, offset, 4, negotiate_flags);
468 proto_tree_add_boolean (negotiate_flags_tree,
469 hf_ntlmssp_negotiate_flags_800000,
470 tvb, offset, 4, negotiate_flags);
471 proto_tree_add_boolean (negotiate_flags_tree,
472 hf_ntlmssp_negotiate_flags_400000,
473 tvb, offset, 4, negotiate_flags);
474 proto_tree_add_boolean (negotiate_flags_tree,
475 hf_ntlmssp_negotiate_flags_200000,
476 tvb, offset, 4, negotiate_flags);
477 proto_tree_add_boolean (negotiate_flags_tree,
478 hf_ntlmssp_negotiate_flags_100000,
479 tvb, offset, 4, negotiate_flags);
480 proto_tree_add_boolean (negotiate_flags_tree,
481 hf_ntlmssp_negotiate_flags_80000,
482 tvb, offset, 4, negotiate_flags);
483 proto_tree_add_boolean (negotiate_flags_tree,
484 hf_ntlmssp_negotiate_flags_40000,
485 tvb, offset, 4, negotiate_flags);
486 proto_tree_add_boolean (negotiate_flags_tree,
487 hf_ntlmssp_negotiate_flags_20000,
488 tvb, offset, 4, negotiate_flags);
489 proto_tree_add_boolean (negotiate_flags_tree,
490 hf_ntlmssp_negotiate_flags_10000,
491 tvb, offset, 4, negotiate_flags);
492 proto_tree_add_boolean (negotiate_flags_tree,
493 hf_ntlmssp_negotiate_flags_8000,
494 tvb, offset, 4, negotiate_flags);
495 proto_tree_add_boolean (negotiate_flags_tree,
496 hf_ntlmssp_negotiate_flags_4000,
497 tvb, offset, 4, negotiate_flags);
498 proto_tree_add_boolean (negotiate_flags_tree,
499 hf_ntlmssp_negotiate_flags_2000,
500 tvb, offset, 4, negotiate_flags);
501 proto_tree_add_boolean (negotiate_flags_tree,
502 hf_ntlmssp_negotiate_flags_1000,
503 tvb, offset, 4, negotiate_flags);
504 proto_tree_add_boolean (negotiate_flags_tree,
505 hf_ntlmssp_negotiate_flags_800,
506 tvb, offset, 4, negotiate_flags);
507 proto_tree_add_boolean (negotiate_flags_tree,
508 hf_ntlmssp_negotiate_flags_400,
509 tvb, offset, 4, negotiate_flags);
510 proto_tree_add_boolean (negotiate_flags_tree,
511 hf_ntlmssp_negotiate_flags_200,
512 tvb, offset, 4, negotiate_flags);
513 proto_tree_add_boolean (negotiate_flags_tree,
514 hf_ntlmssp_negotiate_flags_100,
515 tvb, offset, 4, negotiate_flags);
516 proto_tree_add_boolean (negotiate_flags_tree,
517 hf_ntlmssp_negotiate_flags_80,
518 tvb, offset, 4, negotiate_flags);
519 proto_tree_add_boolean (negotiate_flags_tree,
520 hf_ntlmssp_negotiate_flags_40,
521 tvb, offset, 4, negotiate_flags);
522 proto_tree_add_boolean (negotiate_flags_tree,
523 hf_ntlmssp_negotiate_flags_20,
524 tvb, offset, 4, negotiate_flags);
525 proto_tree_add_boolean (negotiate_flags_tree,
526 hf_ntlmssp_negotiate_flags_10,
527 tvb, offset, 4, negotiate_flags);
528 proto_tree_add_boolean (negotiate_flags_tree,
529 hf_ntlmssp_negotiate_flags_08,
530 tvb, offset, 4, negotiate_flags);
531 proto_tree_add_boolean (negotiate_flags_tree,
532 hf_ntlmssp_negotiate_flags_04,
533 tvb, offset, 4, negotiate_flags);
534 proto_tree_add_boolean (negotiate_flags_tree,
535 hf_ntlmssp_negotiate_flags_02,
536 tvb, offset, 4, negotiate_flags);
537 proto_tree_add_boolean (negotiate_flags_tree,
538 hf_ntlmssp_negotiate_flags_01,
539 tvb, offset, 4, negotiate_flags);
546 dissect_ntlmssp_negotiate (tvbuff_t *tvb, int offset, proto_tree *ntlmssp_tree)
548 guint32 negotiate_flags;
553 /* NTLMSSP Negotiate Flags */
554 negotiate_flags = tvb_get_letohl (tvb, offset);
555 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
558 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
559 hf_ntlmssp_negotiate_domain,
560 &start, &workstation_end);
561 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
562 hf_ntlmssp_negotiate_workstation,
563 &start, &domain_end);
565 /* XXX - two blobs after this one, sometimes? */
567 return MAX(workstation_end, domain_end);
572 dissect_ntlmssp_address_list (tvbuff_t *tvb, int offset,
573 proto_tree *ntlmssp_tree,
576 guint16 list_length = tvb_get_letohs(tvb, offset);
577 guint16 list_maxlen = tvb_get_letohs(tvb, offset+2);
578 guint32 list_offset = tvb_get_letohl(tvb, offset+4);
579 guint16 item_type, item_length;
581 proto_item *tf = NULL;
582 proto_tree *tree = NULL;
584 /* the address list is just a blob */
585 if (0 == list_length) {
586 *end = (list_offset > ((guint)offset)+8 ? list_offset : ((guint)offset)+8);
588 proto_tree_add_text(ntlmssp_tree, tvb, offset, 8,
589 "Address List: Empty");
594 tf = proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_address_list, tvb,
595 list_offset, list_length, FALSE);
596 tree = proto_item_add_subtree(tf, ett_ntlmssp_address_list);
598 proto_tree_add_uint(tree, hf_ntlmssp_address_list_len,
599 tvb, offset, 2, list_length);
601 proto_tree_add_uint(tree, hf_ntlmssp_address_list_maxlen,
602 tvb, offset, 2, list_maxlen);
604 proto_tree_add_uint(tree, hf_ntlmssp_address_list_offset,
605 tvb, offset, 4, list_offset);
608 item_offset = list_offset;
609 item_type = tvb_get_letohs(tvb, item_offset);
611 item_length = tvb_get_letohs(tvb, item_offset);
619 /* Strings are always in unicode regardless of the negotiated
622 text = get_unicode_or_ascii_string(tvb, &item_offset,
623 TRUE, &result_length,
626 if (!text) text = ""; /* Make sure we don't blow up below */
630 proto_tree_add_string(tree, hf_ntlmssp_address_list_server_nb,
631 tvb, item_offset, item_length, text);
634 proto_tree_add_string(tree, hf_ntlmssp_address_list_domain_nb,
635 tvb, item_offset, item_length, text);
638 proto_tree_add_string(tree, hf_ntlmssp_address_list_server_dns,
639 tvb, item_offset, item_length, text);
642 proto_tree_add_string(tree, hf_ntlmssp_address_list_domain_dns,
643 tvb, item_offset, item_length, text);
646 item_offset += item_length;
647 item_type = tvb_get_letohs(tvb, item_offset);
649 item_length = tvb_get_letohs(tvb, item_offset);
653 *end = list_offset + list_length;
658 dissect_ntlmssp_challenge (tvbuff_t *tvb, packet_info *pinfo, int offset,
659 proto_tree *ntlmssp_tree)
661 guint32 negotiate_flags;
662 int item_start, item_end;
663 int data_start, data_end;
664 ntlmssp_info *conv_ntlmssp_info;
665 conversation_t *conversation;
666 gboolean unicode_strings = FALSE;
667 guint8 sspkey[16]; /* NTLMSSP cipher key */
668 guint8 ssp_key_len; /* Either 8 or 16 (40 bit or 128) */
670 /* need to find unicode flag */
671 negotiate_flags = tvb_get_letohl (tvb, offset+8);
672 if (negotiate_flags & NTLMSSP_NEGOTIATE_UNICODE)
673 unicode_strings = TRUE;
676 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, unicode_strings,
677 hf_ntlmssp_challenge_domain,
678 &item_start, &item_end);
679 data_start = item_start;
682 /* NTLMSSP Negotiate Flags */
683 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
686 /* NTLMSSP NT Lan Manager Challenge */
687 proto_tree_add_item (ntlmssp_tree,
688 hf_ntlmssp_ntlm_challenge,
689 tvb, offset, 8, FALSE);
692 * Store the flags and the challenge with the conversation, as they're
693 * needed in order to dissect subsequent messages.
695 conversation = find_conversation(&pinfo->src, &pinfo->dst,
696 pinfo->ptype, pinfo->srcport,
698 if (!conversation) { /* Create one */
699 conversation = conversation_new(&pinfo->src, &pinfo->dst, pinfo->ptype,
700 pinfo->srcport, pinfo->destport, 0);
703 if (!conversation_get_proto_data(conversation, proto_ntlmssp)) {
704 conv_ntlmssp_info = g_mem_chunk_alloc(ntlmssp_info_chunk);
705 /* Insert the flags into the conversation */
706 conv_ntlmssp_info->flags = negotiate_flags;
707 /* Insert the challenge into the conversation */
708 tvb_memcpy(tvb, conv_ntlmssp_info->challenge, offset, 8);
710 /* Between the challenge and the user provided password, we can build the
711 NTLMSSP key and initialize the cipher */
712 if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_128) {
713 create_ntlmssp_v1_key(nt_password, conv_ntlmssp_info->challenge,
718 create_ntlmssp_v1_key(nt_password, conv_ntlmssp_info->challenge,
722 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_peer1, sspkey, ssp_key_len);
723 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_peer2, sspkey, ssp_key_len);
724 conv_ntlmssp_info->peer1_dest_port = pinfo->destport;
725 conv_ntlmssp_info->rc4_state_initialized = 1;
727 conversation_add_proto_data(conversation, proto_ntlmssp, conv_ntlmssp_info);
731 /* Reserved (function not completely known) */
733 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_reserved,
734 tvb, offset, 8, FALSE);
738 * The presence or absence of this field is not obviously correlated
739 * with any flags in the previous NEGOTIATE message or in this
740 * message (other than the "Workstation Supplied" and "Domain
741 * Supplied" flags in the NEGOTIATE message, at least in the capture
742 * I've seen - but those also correlate with the presence of workstation
743 * and domain name fields, so it doesn't seem to make sense that they
744 * actually *indicate* whether the subsequent CHALLENGE has an
747 if (offset < data_start) {
748 offset = dissect_ntlmssp_address_list(tvb, offset, ntlmssp_tree, &item_end);
749 data_end = MAX(data_end, item_end);
752 return MAX(offset, data_end);
756 dissect_ntlmssp_auth (tvbuff_t *tvb, packet_info *pinfo, int offset,
757 proto_tree *ntlmssp_tree)
759 int item_start, item_end;
760 int data_start, data_end = 0;
761 guint32 negotiate_flags;
762 gboolean unicode_strings = FALSE;
763 ntlmssp_info *conv_ntlmssp_info;
764 conversation_t *conversation;
767 * Get flag info from the original negotiate message, if any.
768 * This is because the flag information is sometimes missing from
769 * the AUTHENTICATE message, so we can't figure out whether
770 * strings are Unicode or not by looking at *our* flags.
772 conv_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
773 if (conv_ntlmssp_info == NULL) {
775 * There isn't any. Is there any from this conversation? If so,
776 * it means this is the first time we've dissected this frame, so
777 * we should give it flag info.
779 conversation = find_conversation(&pinfo->src, &pinfo->dst,
780 pinfo->ptype, pinfo->srcport,
782 if (conversation != NULL) {
783 conv_ntlmssp_info = conversation_get_proto_data(conversation, proto_ntlmssp);
784 if (conv_ntlmssp_info != NULL) {
786 * We have flag info; attach it to the frame.
788 p_add_proto_data(pinfo->fd, proto_ntlmssp, conv_ntlmssp_info);
792 if (conv_ntlmssp_info != NULL) {
793 if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_UNICODE)
794 unicode_strings = TRUE;
798 * Sometimes the session key and flags are missing.
799 * Sometimes the session key is present but the flags are missing.
800 * Sometimes they're both present.
802 * This does not correlate with any flags in the previous CHALLENGE
803 * message, and only correlates with "Negotiate Unicode", "Workstation
804 * Supplied", and "Domain Supplied" in the NEGOTIATE message - but
805 * those don't make sense as flags to use to determine this.
807 * So we check all of the descriptors to figure out where the data
808 * area begins, and if the session key or the flags would be in the
809 * middle of the data area, we assume the field in question is
813 /* Lan Manager response */
814 data_start = tvb_get_letohl(tvb, offset+4);
815 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
816 hf_ntlmssp_auth_lmresponse,
818 conv_ntlmssp_info == NULL ? NULL :
819 &conv_ntlmssp_info->lm_response);
820 data_end = MAX(data_end, item_end);
823 item_start = tvb_get_letohl(tvb, offset+4);
824 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
825 hf_ntlmssp_auth_ntresponse,
827 conv_ntlmssp_info == NULL ? NULL :
828 &conv_ntlmssp_info->ntlm_response);
829 data_start = MIN(data_start, item_start);
830 data_end = MAX(data_end, item_end);
833 item_start = tvb_get_letohl(tvb, offset+4);
834 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
836 hf_ntlmssp_auth_domain,
837 &item_start, &item_end);
838 data_start = MIN(data_start, item_start);
839 data_end = MAX(data_end, item_end);
842 item_start = tvb_get_letohl(tvb, offset+4);
843 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
845 hf_ntlmssp_auth_username,
846 &item_start, &item_end);
847 data_start = MIN(data_start, item_start);
848 data_end = MAX(data_end, item_end);
851 item_start = tvb_get_letohl(tvb, offset+4);
852 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
854 hf_ntlmssp_auth_hostname,
855 &item_start, &item_end);
856 data_start = MIN(data_start, item_start);
857 data_end = MAX(data_end, item_end);
859 if (offset < data_start) {
861 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
862 hf_ntlmssp_auth_sesskey,
864 data_end = MAX(data_end, item_end);
867 if (offset < data_start) {
868 /* NTLMSSP Negotiate Flags */
869 negotiate_flags = tvb_get_letohl (tvb, offset);
870 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
874 return MAX(offset, data_end);
878 dissect_ntlmssp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
880 guint32 ntlmssp_message_type;
881 volatile int offset = 0;
882 proto_tree *volatile ntlmssp_tree = NULL;
883 proto_item *tf = NULL;
885 /* Setup a new tree for the NTLMSSP payload */
887 tf = proto_tree_add_item (tree,
889 tvb, offset, -1, FALSE);
891 ntlmssp_tree = proto_item_add_subtree (tf,
896 * Catch the ReportedBoundsError exception; the stuff we've been
897 * handed doesn't necessarily run to the end of the packet, it's
898 * an item inside a packet, so if it happens to be malformed (or
899 * we, or a dissector we call, has a bug), so that an exception
900 * is thrown, we want to report the error, but return and let
901 * our caller dissect the rest of the packet.
903 * If it gets a BoundsError, we can stop, as there's nothing more
904 * in the packet after our blob to see, so we just re-throw the
908 /* NTLMSSP constant */
909 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth,
910 tvb, offset, 8, FALSE);
913 /* NTLMSSP Message Type */
914 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_message_type,
915 tvb, offset, 4, TRUE);
916 ntlmssp_message_type = tvb_get_letohl (tvb, offset);
919 if (check_col(pinfo->cinfo, COL_INFO))
920 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
921 val_to_str(ntlmssp_message_type,
922 ntlmssp_message_types,
923 "Unknown message type"));
925 /* Call the appropriate dissector based on the Message Type */
926 switch (ntlmssp_message_type) {
928 case NTLMSSP_NEGOTIATE:
929 offset = dissect_ntlmssp_negotiate (tvb, offset, ntlmssp_tree);
932 case NTLMSSP_CHALLENGE:
933 offset = dissect_ntlmssp_challenge (tvb, pinfo, offset, ntlmssp_tree);
937 offset = dissect_ntlmssp_auth (tvb, pinfo, offset, ntlmssp_tree);
941 /* Unrecognized message type */
942 proto_tree_add_text (ntlmssp_tree, tvb, offset, -1,
943 "Unrecognized NTLMSSP Message");
946 } CATCH(BoundsError) {
948 } CATCH(ReportedBoundsError) {
949 show_reported_bounds_error(tvb, pinfo, tree);
954 * Get the encryption state tied to this conversation. cryptpeer indicates
955 * whether to retrieve the data for peer1 or peer2.
957 static rc4_state_struct *
958 get_encrypted_state(packet_info *pinfo, int cryptpeer)
960 conversation_t *conversation;
961 ntlmssp_info *conv_ntlmssp_info;
963 conversation = find_conversation(&pinfo->src, &pinfo->dst,
964 pinfo->ptype, pinfo->srcport,
966 if (conversation == NULL) {
967 /* We don't have a conversation. In this case, stop processing
968 because we do not have enough info to decrypt the payload */
972 /* We have a conversation, check for encryption state */
973 conv_ntlmssp_info = conversation_get_proto_data(conversation,
975 if (conv_ntlmssp_info == NULL) {
976 /* No encryption state tied to the conversation. Therefore, we
977 cannot decrypt the payload */
981 /* We have the encryption state in the conversation. So return the
982 crypt state tied to the requested peer
984 if (cryptpeer == 1) {
985 return &conv_ntlmssp_info->rc4_state_peer1;
987 return &conv_ntlmssp_info->rc4_state_peer2;
995 * See page 45 of "DCE/RPC over SMB" by Luke Kenneth Casson Leighton.
998 decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
999 packet_info *pinfo, proto_tree *tree)
1001 proto_tree *decr_tree = NULL;
1002 proto_item *tf = NULL;
1003 conversation_t *conversation;
1004 rc4_state_struct *rc4_state;
1005 rc4_state_struct *rc4_state_peer;
1006 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
1008 ntlmssp_info *conv_ntlmssp_info = NULL;
1009 ntlmssp_packet_info *packet_ntlmssp_info = NULL;
1010 int decrypted_offset = 0;
1012 packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1013 if (packet_ntlmssp_info == NULL) {
1014 /* We don't have data for this packet */
1017 if (!packet_ntlmssp_info->verifier_decrypted) {
1018 conversation = find_conversation(&pinfo->src, &pinfo->dst,
1019 pinfo->ptype, pinfo->srcport,
1020 pinfo->destport, 0);
1021 if (conversation == NULL) {
1022 /* There is no conversation, thus no encryption state */
1026 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1028 if (conv_ntlmssp_info == NULL) {
1029 /* There is no NTLMSSP state tied to the conversation */
1032 if (conv_ntlmssp_info->rc4_state_initialized != 1 ) {
1033 /* The crypto sybsystem is not initialized. This means that either
1034 the conversation did not include a challenge, or we are doing
1035 something other than NTLMSSP v1 */
1039 if (conv_ntlmssp_info->peer1_dest_port == pinfo->destport) {
1040 rc4_state = get_encrypted_state(pinfo, 1);
1041 rc4_state_peer = get_encrypted_state(pinfo, 0);
1043 rc4_state = get_encrypted_state(pinfo, 0);
1044 rc4_state_peer = get_encrypted_state(pinfo, 1);
1047 if (rc4_state == NULL || rc4_state_peer == NULL) {
1048 /* There is no encryption state, so we cannot decrypt */
1052 /* Setup the buffer to decrypt to */
1053 tvb_memcpy(tvb, packet_ntlmssp_info->verifier,
1054 offset, encrypted_block_length);
1056 /* Do the actual decryption of the verifier */
1057 crypt_rc4(rc4_state, packet_ntlmssp_info->verifier,
1058 encrypted_block_length);
1060 /* We setup a temporary buffer so we can re-encrypt the payload after
1061 decryption. This is to update the opposite peer's RC4 state */
1062 peer_block = g_malloc(encrypted_block_length);
1063 memcpy(peer_block, packet_ntlmssp_info->verifier,
1064 encrypted_block_length);
1065 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
1068 /* Mark the packet as decrypted so that subsequent attempts to dissect
1069 the packet use the already decrypted payload instead of attempting
1071 packet_ntlmssp_info->verifier_decrypted = TRUE;
1074 /* Show the decrypted buffer in a new window */
1075 decr_tvb = tvb_new_real_data(packet_ntlmssp_info->verifier,
1076 encrypted_block_length,
1077 encrypted_block_length);
1078 tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
1079 add_new_data_source(pinfo, decr_tvb,
1080 "Decrypted NTLMSSP Verifier");
1082 /* Show the decrypted payload in the tree */
1083 tf = proto_tree_add_text(tree, decr_tvb, 0, -1,
1084 "Decrypted Verifier (%d byte%s)",
1085 encrypted_block_length,
1086 plurality(encrypted_block_length, "", "s"));
1087 decr_tree = proto_item_add_subtree (tf, ett_ntlmssp);
1089 /* LKCL page 45 says this is a "reserved" field. I'm not sure if it's
1090 garbage because it's some sort of nonce, or because there is a problem
1091 with the verifier decryption routine. */
1092 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_unknown1,
1093 decr_tvb, decrypted_offset, 4, TRUE);
1094 decrypted_offset += 4;
1096 /* CRC32 of the DCE fragment data */
1097 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_crc32,
1098 decr_tvb, decrypted_offset, 4, TRUE);
1099 decrypted_offset += 4;
1101 /* Incrementing sequence number of DCE conversation */
1102 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_sequence,
1103 decr_tvb, decrypted_offset, 4, TRUE);
1104 decrypted_offset += 4;
1108 dissect_ntlmssp_verf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1110 volatile int offset = 0;
1111 proto_tree *volatile ntlmssp_tree = NULL;
1112 proto_item *tf = NULL;
1113 guint32 verifier_length;
1114 guint32 encrypted_block_length;
1116 verifier_length = tvb_length_remaining (tvb, offset);
1117 encrypted_block_length = verifier_length - 4;
1119 if (encrypted_block_length < 12) {
1120 /* Don't know why this would happen, but if it does, don't even bother
1121 attempting decryption/dissection */
1122 return offset + verifier_length;
1125 /* Setup a new tree for the NTLMSSP payload */
1127 tf = proto_tree_add_item (tree,
1129 tvb, offset, -1, FALSE);
1131 ntlmssp_tree = proto_item_add_subtree (tf,
1136 * Catch the ReportedBoundsError exception; the stuff we've been
1137 * handed doesn't necessarily run to the end of the packet, it's
1138 * an item inside a packet, so if it happens to be malformed (or
1139 * we, or a dissector we call, has a bug), so that an exception
1140 * is thrown, we want to report the error, but return and let
1141 * our caller dissect the rest of the packet.
1143 * If it gets a BoundsError, we can stop, as there's nothing more
1144 * in the packet after our blob to see, so we just re-throw the
1148 /* Version number */
1149 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_vers,
1150 tvb, offset, 4, TRUE);
1153 /* Encrypted body */
1154 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_body,
1155 tvb, offset, encrypted_block_length, TRUE);
1157 /* Try to decrypt */
1158 decrypt_verifier (tvb, offset, encrypted_block_length, pinfo, ntlmssp_tree);
1160 offset += encrypted_block_length;
1161 } CATCH(BoundsError) {
1163 } CATCH(ReportedBoundsError) {
1164 show_reported_bounds_error(tvb, pinfo, tree);
1172 dissect_ntlmssp_encrypted_payload(tvbuff_t *tvb,
1173 packet_info *pinfo, proto_tree *tree)
1175 volatile int offset = 0;
1176 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
1178 conversation_t *conversation;
1179 guint32 encrypted_block_length;
1180 rc4_state_struct *rc4_state;
1181 rc4_state_struct *rc4_state_peer;
1182 ntlmssp_info *conv_ntlmssp_info = NULL;
1183 ntlmssp_packet_info *packet_ntlmssp_info = NULL;
1185 static ntlmssp_decrypted_info_t ndi;
1187 encrypted_block_length = tvb_length_remaining (tvb, offset);
1189 /* Check to see if we already have state for this packet */
1190 packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1191 if (packet_ntlmssp_info == NULL) {
1192 /* We don't have any packet state, so create one */
1193 packet_ntlmssp_info = g_mem_chunk_alloc(ntlmssp_packet_info_chunk);
1194 memset(packet_ntlmssp_info, 0, sizeof(ntlmssp_packet_info));
1195 p_add_proto_data(pinfo->fd, proto_ntlmssp, packet_ntlmssp_info);
1198 if (!packet_ntlmssp_info->payload_decrypted) {
1199 /* Pull the challenge info from the conversation */
1200 conversation = find_conversation(&pinfo->src, &pinfo->dst,
1201 pinfo->ptype, pinfo->srcport,
1202 pinfo->destport, 0);
1203 if (conversation == NULL) {
1204 /* There is no conversation, thus no encryption state */
1205 return offset + encrypted_block_length;
1208 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1210 if (conv_ntlmssp_info == NULL) {
1211 /* There is no NTLMSSP state tied to the conversation */
1212 return offset + encrypted_block_length;
1215 /* Get the pair of RC4 state structures. One is used for to decrypt the
1216 payload. The other is used to re-encrypt the payload to represent
1218 if (conv_ntlmssp_info->peer1_dest_port == pinfo->destport) {
1219 rc4_state = get_encrypted_state(pinfo, 1);
1220 rc4_state_peer = get_encrypted_state(pinfo, 0);
1222 rc4_state = get_encrypted_state(pinfo, 0);
1223 rc4_state_peer = get_encrypted_state(pinfo, 1);
1226 if (rc4_state == NULL || rc4_state_peer == NULL) {
1227 /* There is no encryption state, so we cannot decrypt */
1228 return offset + encrypted_block_length;
1231 /* Store the decrypted contents in the packet state struct
1232 (of course at this point, they aren't decrypted yet) */
1233 packet_ntlmssp_info->decrypted_payload = g_malloc (encrypted_block_length);
1234 decrypted_payloads = g_slist_prepend(decrypted_payloads,
1235 packet_ntlmssp_info->decrypted_payload);
1236 tvb_memcpy(tvb, packet_ntlmssp_info->decrypted_payload,
1237 offset, encrypted_block_length);
1239 /* Do the decryption of the payload */
1240 crypt_rc4(rc4_state, packet_ntlmssp_info->decrypted_payload,
1241 encrypted_block_length);
1243 /* We setup a temporary buffer so we can re-encrypt the payload after
1244 decryption. This is to update the opposite peer's RC4 state */
1245 peer_block = g_malloc(encrypted_block_length);
1246 memcpy(peer_block, packet_ntlmssp_info->decrypted_payload,
1247 encrypted_block_length);
1248 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
1251 packet_ntlmssp_info->payload_decrypted = TRUE;
1254 /* Show the decrypted buffer in a new window */
1255 decr_tvb = tvb_new_real_data(packet_ntlmssp_info->decrypted_payload,
1256 encrypted_block_length,
1257 encrypted_block_length);
1258 tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
1259 add_new_data_source(pinfo, decr_tvb,
1260 "Decrypted NTLMSSP block");
1262 /* Show the decrypted payload in the tree */
1263 it=proto_tree_add_text(tree, decr_tvb, 0, -1,
1264 "Decrypted stub data (%d byte%s)",
1265 encrypted_block_length,
1266 plurality(encrypted_block_length, "", "s"));
1267 ndi.decr_tree=proto_item_add_subtree(it, ett_ntlmssp_decrypted_tree);
1268 ndi.decr_tvb=decr_tvb;
1269 pinfo->decrypted_data=&ndi;
1271 offset += encrypted_block_length;
1276 free_payload(gpointer decrypted_payload, gpointer user_data _U_)
1278 g_free(decrypted_payload);
1282 ntlmssp_init_protocol(void)
1284 if (ntlmssp_info_chunk != NULL)
1285 g_mem_chunk_destroy(ntlmssp_info_chunk);
1286 if (ntlmssp_packet_info_chunk != NULL)
1287 g_mem_chunk_destroy(ntlmssp_packet_info_chunk);
1290 * Free the decrypted payloads, and then free the list of decrypted
1293 if (decrypted_payloads != NULL) {
1294 g_slist_foreach(decrypted_payloads, free_payload, NULL);
1295 g_slist_free(decrypted_payloads);
1296 decrypted_payloads = NULL;
1299 ntlmssp_info_chunk = g_mem_chunk_new("ntlmssp_info_chunk",
1300 sizeof(ntlmssp_info),
1301 ntlmssp_info_count * sizeof(ntlmssp_info),
1303 ntlmssp_packet_info_chunk = g_mem_chunk_new("ntlmssp_packet_info_chunk",
1304 sizeof(ntlmssp_packet_info),
1305 ntlmssp_packet_info_count * sizeof(ntlmssp_packet_info),
1310 proto_register_ntlmssp(void)
1313 static hf_register_info hf[] = {
1315 { "NTLMSSP", "ntlmssp", FT_NONE, BASE_NONE, NULL, 0x0, "NTLMSSP", HFILL }},
1318 { "NTLMSSP identifier", "ntlmssp.identifier", FT_STRING, BASE_NONE, NULL, 0x0, "NTLMSSP Identifier", HFILL }},
1320 { &hf_ntlmssp_message_type,
1321 { "NTLM Message Type", "ntlmssp.messagetype", FT_UINT32, BASE_HEX, VALS(ntlmssp_message_types), 0x0, "", HFILL }},
1323 { &hf_ntlmssp_negotiate_flags,
1324 { "Flags", "ntlmssp.negotiateflags", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1325 { &hf_ntlmssp_negotiate_flags_01,
1327 { "Negotiate UNICODE", "ntlmssp.negotiateunicode", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_UNICODE, "", HFILL }},
1328 { &hf_ntlmssp_negotiate_flags_02,
1329 { "Negotiate OEM", "ntlmssp.negotiateoem", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_OEM, "", HFILL }},
1330 { &hf_ntlmssp_negotiate_flags_04,
1331 { "Request Target", "ntlmssp.requesttarget", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_REQUEST_TARGET, "", HFILL }},
1332 { &hf_ntlmssp_negotiate_flags_08,
1333 { "Request 0x00000008", "ntlmssp.negotiate00000008", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000008, "", HFILL }},
1334 { &hf_ntlmssp_negotiate_flags_10,
1335 { "Negotiate Sign", "ntlmssp.negotiatesign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SIGN, "", HFILL }},
1336 { &hf_ntlmssp_negotiate_flags_20,
1337 { "Negotiate Seal", "ntlmssp.negotiateseal", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SEAL, "", HFILL }},
1338 { &hf_ntlmssp_negotiate_flags_40,
1339 { "Negotiate Datagram Style", "ntlmssp.negotiatedatagramstyle", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_DATAGRAM_STYLE, "", HFILL }},
1340 { &hf_ntlmssp_negotiate_flags_80,
1341 { "Negotiate Lan Manager Key", "ntlmssp.negotiatelmkey", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_LM_KEY, "", HFILL }},
1342 { &hf_ntlmssp_negotiate_flags_100,
1343 { "Negotiate Netware", "ntlmssp.negotiatenetware", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NETWARE, "", HFILL }},
1344 { &hf_ntlmssp_negotiate_flags_200,
1345 { "Negotiate NTLM key", "ntlmssp.negotiatentlm", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM, "", HFILL }},
1346 { &hf_ntlmssp_negotiate_flags_400,
1347 { "Negotiate 0x00000400", "ntlmssp.negotiate00000400", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000400, "", HFILL }},
1348 { &hf_ntlmssp_negotiate_flags_800,
1349 { "Negotiate 0x00000800", "ntlmssp.negotiate00000800", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000800, "", HFILL }},
1350 { &hf_ntlmssp_negotiate_flags_1000,
1351 { "Negotiate Domain Supplied", "ntlmssp.negotiatedomainsupplied", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED, "", HFILL }},
1352 { &hf_ntlmssp_negotiate_flags_2000,
1353 { "Negotiate Workstation Supplied", "ntlmssp.negotiateworkstationsupplied", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED, "", HFILL }},
1354 { &hf_ntlmssp_negotiate_flags_4000,
1355 { "Negotiate This is Local Call", "ntlmssp.negotiatethisislocalcall", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL, "", HFILL }},
1356 { &hf_ntlmssp_negotiate_flags_8000,
1357 { "Negotiate Always Sign", "ntlmssp.negotiatealwayssign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_ALWAYS_SIGN, "", HFILL }},
1358 { &hf_ntlmssp_negotiate_flags_10000,
1359 { "Negotiate Challenge Init Response", "ntlmssp.negotiatechallengeinitresponse", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_INIT_RESPONSE, "", HFILL }},
1360 { &hf_ntlmssp_negotiate_flags_20000,
1361 { "Negotiate Challenge Accept Response", "ntlmssp.negotiatechallengeacceptresponse", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_ACCEPT_RESPONSE, "", HFILL }},
1362 { &hf_ntlmssp_negotiate_flags_40000,
1363 { "Negotiate Challenge Non NT Session Key", "ntlmssp.negotiatechallengenonntsessionkey", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_NON_NT_SESSION_KEY, "", HFILL }},
1364 { &hf_ntlmssp_negotiate_flags_80000,
1365 { "Negotiate NTLM2 key", "ntlmssp.negotiatentlm2", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM2, "", HFILL }},
1366 { &hf_ntlmssp_negotiate_flags_100000,
1367 { "Negotiate 0x00100000", "ntlmssp.negotiatent00100000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00100000, "", HFILL }},
1368 { &hf_ntlmssp_negotiate_flags_200000,
1369 { "Negotiate 0x00200000", "ntlmssp.negotiatent00200000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00200000, "", HFILL }},
1370 { &hf_ntlmssp_negotiate_flags_400000,
1371 { "Negotiate 0x00400000", "ntlmssp.negotiatent00400000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00400000, "", HFILL }},
1372 { &hf_ntlmssp_negotiate_flags_800000,
1373 { "Negotiate Target Info", "ntlmssp.negotiatetargetinfo", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_TARGET_INFO, "", HFILL }},
1374 { &hf_ntlmssp_negotiate_flags_1000000,
1375 { "Negotiate 0x01000000", "ntlmssp.negotiatent01000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_01000000, "", HFILL }},
1376 { &hf_ntlmssp_negotiate_flags_2000000,
1377 { "Negotiate 0x02000000", "ntlmssp.negotiatent02000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_02000000, "", HFILL }},
1378 { &hf_ntlmssp_negotiate_flags_4000000,
1379 { "Negotiate 0x04000000", "ntlmssp.negotiatent04000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_04000000, "", HFILL }},
1380 { &hf_ntlmssp_negotiate_flags_8000000,
1381 { "Negotiate 0x08000000", "ntlmssp.negotiatent08000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_08000000, "", HFILL }},
1382 { &hf_ntlmssp_negotiate_flags_10000000,
1383 { "Negotiate 0x10000000", "ntlmssp.negotiatent10000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_10000000, "", HFILL }},
1384 { &hf_ntlmssp_negotiate_flags_20000000,
1385 { "Negotiate 128", "ntlmssp.negotiate128", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_128, "", HFILL }},
1386 { &hf_ntlmssp_negotiate_flags_40000000,
1387 { "Negotiate Key Exchange", "ntlmssp.negotiatekeyexch", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_KEY_EXCH, "", HFILL }},
1388 { &hf_ntlmssp_negotiate_flags_80000000,
1389 { "Negotiate 0x80000000", "ntlmssp.negotiatent80000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_80000000, "", HFILL }},
1390 { &hf_ntlmssp_negotiate_workstation_strlen,
1391 { "Calling workstation name length", "ntlmssp.negotiate.callingworkstation.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1392 { &hf_ntlmssp_negotiate_workstation_maxlen,
1393 { "Calling workstation name max length", "ntlmssp.negotiate.callingworkstation.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1394 { &hf_ntlmssp_negotiate_workstation_buffer,
1395 { "Calling workstation name buffer", "ntlmssp.negotiate.callingworkstation.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1396 { &hf_ntlmssp_negotiate_workstation,
1397 { "Calling workstation name", "ntlmssp.negotiate.callingworkstation", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1398 { &hf_ntlmssp_negotiate_domain_strlen,
1399 { "Calling workstation domain length", "ntlmssp.negotiate.domain.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1400 { &hf_ntlmssp_negotiate_domain_maxlen,
1401 { "Calling workstation domain max length", "ntlmssp.negotiate.domain.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1402 { &hf_ntlmssp_negotiate_domain_buffer,
1403 { "Calling workstation domain buffer", "ntlmssp.negotiate.domain.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1404 { &hf_ntlmssp_negotiate_domain,
1405 { "Calling workstation domain", "ntlmssp.negotiate.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1406 { &hf_ntlmssp_ntlm_challenge,
1407 { "NTLM Challenge", "ntlmssp.ntlmchallenge", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1408 { &hf_ntlmssp_reserved,
1409 { "Reserved", "ntlmssp.reserved", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1410 { &hf_ntlmssp_challenge_domain,
1411 { "Domain", "ntlmssp.challenge.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1412 { &hf_ntlmssp_auth_domain,
1413 { "Domain name", "ntlmssp.auth.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1414 { &hf_ntlmssp_auth_username,
1415 { "User name", "ntlmssp.auth.username", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1416 { &hf_ntlmssp_auth_hostname,
1417 { "Host name", "ntlmssp.auth.hostname", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1418 { &hf_ntlmssp_auth_lmresponse,
1419 { "Lan Manager Response", "ntlmssp.auth.lmresponse", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1420 { &hf_ntlmssp_auth_ntresponse,
1421 { "NTLM Response", "ntlmssp.auth.ntresponse", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1422 { &hf_ntlmssp_auth_sesskey,
1423 { "Session Key", "ntlmssp.auth.sesskey", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1424 { &hf_ntlmssp_string_len,
1425 { "Length", "ntlmssp.string.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1426 { &hf_ntlmssp_string_maxlen,
1427 { "Maxlen", "ntlmssp.string.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1428 { &hf_ntlmssp_string_offset,
1429 { "Offset", "ntlmssp.string.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1430 { &hf_ntlmssp_blob_len,
1431 { "Length", "ntlmssp.blob.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1432 { &hf_ntlmssp_blob_maxlen,
1433 { "Maxlen", "ntlmssp.blob.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1434 { &hf_ntlmssp_blob_offset,
1435 { "Offset", "ntlmssp.blob.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1436 { &hf_ntlmssp_address_list,
1437 { "Address List", "ntlmssp.challenge.addresslist", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL}},
1438 { &hf_ntlmssp_address_list_len,
1439 { "Length", "ntlmssp.challenge.addresslist.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1440 { &hf_ntlmssp_address_list_maxlen,
1441 { "Maxlen", "ntlmssp.challenge.addresslist.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1442 { &hf_ntlmssp_address_list_offset,
1443 { "Offset", "ntlmssp.challenge.addresslist.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1444 { &hf_ntlmssp_address_list_server_nb,
1445 { "Server NetBIOS Name", "ntlmssp.challenge.addresslist.servernb", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1446 { &hf_ntlmssp_address_list_domain_nb,
1447 { "Domain NetBIOS Name", "ntlmssp.challenge.addresslist.domainnb", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1448 { &hf_ntlmssp_address_list_server_dns,
1449 { "Server DNS Name", "ntlmssp.challenge.addresslist.serverdns", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1450 { &hf_ntlmssp_address_list_domain_dns,
1451 { "Domain DNS Name", "ntlmssp.challenge.addresslist.domaindns", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1454 { "NTLMSSP Verifier", "ntlmssp.verf", FT_NONE, BASE_NONE, NULL, 0x0, "NTLMSSP Verifier", HFILL }},
1455 { &hf_ntlmssp_verf_vers,
1456 { "Version Number", "ntlmssp.verf.vers", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
1457 { &hf_ntlmssp_verf_body,
1458 { "Verifier Body", "ntlmssp.verf.body", FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }},
1459 { &hf_ntlmssp_decrypted_payload,
1460 { "NTLM Decrypted Payload", "ntlmssp.decrypted_payload", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1461 { &hf_ntlmssp_verf_unknown1,
1462 { "Unknown 1", "ntlmssp.verf.unknown1", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1463 { &hf_ntlmssp_verf_crc32,
1464 { "Verifier CRC32", "ntlmssp.verf.crc32", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1465 { &hf_ntlmssp_verf_sequence,
1466 { "Verifier Sequence Number", "ntlmssp.verf.sequence", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }}
1471 static gint *ett[] = {
1473 &ett_ntlmssp_negotiate_flags,
1474 &ett_ntlmssp_string,
1476 &ett_ntlmssp_address_list,
1477 &ett_ntlmssp_decrypted_tree
1479 module_t *ntlmssp_module;
1481 proto_ntlmssp = proto_register_protocol (
1482 "NTLM Secure Service Provider", /* name */
1483 "NTLMSSP", /* short name */
1484 "ntlmssp" /* abbrev */
1486 proto_register_field_array (proto_ntlmssp, hf, array_length (hf));
1487 proto_register_subtree_array (ett, array_length (ett));
1488 register_init_routine(&ntlmssp_init_protocol);
1490 ntlmssp_module = prefs_register_protocol(proto_ntlmssp, NULL);
1492 prefs_register_string_preference(ntlmssp_module, "nt_password",
1494 "NT Password (used to decrypt payloads)",
1497 register_dissector("ntlmssp", dissect_ntlmssp, proto_ntlmssp);
1498 new_register_dissector("ntlmssp_verf", dissect_ntlmssp_verf, proto_ntlmssp);
1499 new_register_dissector("ntlmssp_encrypted_payload",
1500 dissect_ntlmssp_encrypted_payload, proto_ntlmssp);
1504 proto_reg_handoff_ntlmssp(void)
1506 dissector_handle_t ntlmssp_handle, ntlmssp_wrap_handle;
1508 /* Register protocol with the GSS-API module */
1510 ntlmssp_handle = find_dissector("ntlmssp");
1511 ntlmssp_wrap_handle = find_dissector("ntlmssp_verf");
1512 gssapi_init_oid("1.3.6.1.4.1.311.2.2.10", proto_ntlmssp, ett_ntlmssp,
1513 ntlmssp_handle, ntlmssp_wrap_handle,
1514 "NTLMSSP - Microsoft NTLM Security Support Provider");