2 * Routines for NTLM Secure Service Provider
3 * Devin Heitmueller <dheitmueller@netilla.com>
5 * $Id: packet-ntlmssp.c,v 1.34 2003/01/06 11:27:00 sahlberg 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;
200 /* If this struct exists in the payload_decrypt, then we have already
202 typedef struct _ntlmssp_packet_info {
205 guint8 decrypted_payload[1500]; /* 1500 is an arbitrary size */
207 gboolean payload_decrypted;
208 gboolean verifier_decrypted;
209 } ntlmssp_packet_info;
212 Generate a challenge response, given an eight byte challenge and
213 either the NT or the Lan Manager password hash (16 bytes).
214 Returns output in response, which is expected to be 24 bytes.
216 static int ntlmssp_generate_challenge_response(guint8 *response,
217 const guint8 *passhash,
218 const guint8 *challenge)
220 guint8 pw21[21]; /* Password hash padded to 21 bytes */
222 memset(pw21, 0x0, sizeof(pw21));
223 memcpy(pw21, passhash, 16);
225 memset(response, 0, 24);
227 crypt_des_ecb(response, challenge, pw21, 1);
228 crypt_des_ecb(response + 8, challenge, pw21 + 7, 1);
229 crypt_des_ecb(response + 16, challenge, pw21 + 14, 1);
234 /* Create an NTLMSSP version 1 key.
235 * password points to the ANSI password to encrypt, challenge points to
236 * the 8 octet challenge string, key128 will do a 128 bit key if set to 1,
237 * otherwise it will do a 40 bit key. The result is stored in
238 * sspkey (expected to be 16 octets)
241 create_ntlmssp_v1_key(const char *nt_password, const guint8 *challenge,
242 int use_key_128, guint8 *sspkey)
244 unsigned char lm_password_upper[16];
245 unsigned char lm_password_hash[16];
246 guint8 lm_challenge_response[24];
248 guint8 pw21[21]; /* Password hash padded to 21 bytes */
251 unsigned char lmhash_key[] =
252 {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
254 memset(lm_password_upper, 0, sizeof(lm_password_upper));
256 /* Create a Lan Manager hash of the input password */
258 password_len = strlen(nt_password);
259 /* Truncate password if too long */
260 if (password_len > 16)
262 for (i = 0; i < password_len; i++) {
263 lm_password_upper[i] = toupper(nt_password[i]);
267 crypt_des_ecb(lm_password_hash, lmhash_key, lm_password_upper, 1);
268 crypt_des_ecb(lm_password_hash+8, lmhash_key, lm_password_upper+7, 1);
270 /* Generate the LanMan Challenge Response */
271 ntlmssp_generate_challenge_response(lm_challenge_response,
272 lm_password_hash, challenge);
274 /* Generate the NTLMSSP-v1 RC4 Key.
275 * The RC4 key is derived from the Lan Manager Hash.
276 * See lkcl "DCE/RPC over SMB" page 254 for the algorithm.
278 memset(pw21, 0xBD, sizeof(pw21));
279 memcpy(pw21, lm_password_hash, sizeof(lm_password_hash));
281 /* Only the first eight bytes of challenge_reponse is used */
282 crypt_des_ecb(rc4key, lm_challenge_response, pw21, 1);
283 crypt_des_ecb(rc4key + 8, lm_challenge_response, pw21 + 7, 1);
284 crypt_des_ecb(rc4key + 16, lm_challenge_response, pw21 + 14, 1);
286 /* Create the SSP Key */
287 memset(sspkey, 0, sizeof(sspkey));
289 /* Create 128 bit key */
290 memcpy(sspkey, rc4key, 16);
293 /* Create 40 bit key */
294 memcpy(sspkey, rc4key, 5);
302 /* dissect a string - header area contains:
305 four byte offset of string in data area
306 The function returns the offset at the end of the string header,
307 but the 'end' parameter returns the offset of the end of the string itself
308 The 'start' parameter returns the offset of the beginning of the string
311 dissect_ntlmssp_string (tvbuff_t *tvb, int offset,
312 proto_tree *ntlmssp_tree,
313 gboolean unicode_strings,
314 int string_hf, int *start, int *end)
316 proto_tree *tree = NULL;
317 proto_item *tf = NULL;
318 gint16 string_length = tvb_get_letohs(tvb, offset);
319 gint16 string_maxlen = tvb_get_letohs(tvb, offset+2);
320 gint32 string_offset = tvb_get_letohl(tvb, offset+4);
321 const char *string_text = NULL;
325 *start = (string_offset > offset+8 ? string_offset : offset+8);
326 if (0 == string_length) {
329 proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
334 bc = result_length = string_length;
335 string_text = get_unicode_or_ascii_string(tvb, &string_offset,
336 unicode_strings, &result_length,
340 tf = proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
341 string_offset, result_length, string_text);
342 tree = proto_item_add_subtree(tf, ett_ntlmssp_string);
344 proto_tree_add_uint(tree, hf_ntlmssp_string_len,
345 tvb, offset, 2, string_length);
347 proto_tree_add_uint(tree, hf_ntlmssp_string_maxlen,
348 tvb, offset, 2, string_maxlen);
350 proto_tree_add_uint(tree, hf_ntlmssp_string_offset,
351 tvb, offset, 4, string_offset);
354 *end = string_offset + string_length;
358 /* dissect a generic blob - header area contains:
361 four byte offset of blob in data area
362 The function returns the offset at the end of the blob header,
363 but the 'end' parameter returns the offset of the end of the blob itself
366 dissect_ntlmssp_blob (tvbuff_t *tvb, int offset,
367 proto_tree *ntlmssp_tree,
368 int blob_hf, int *end, ntlmssp_blob *result)
370 proto_item *tf = NULL;
371 proto_tree *tree = NULL;
372 guint16 blob_length = tvb_get_letohs(tvb, offset);
373 guint16 blob_maxlen = tvb_get_letohs(tvb, offset+2);
374 guint32 blob_offset = tvb_get_letohl(tvb, offset+4);
376 if (0 == blob_length) {
377 *end = (blob_offset > ((guint)offset)+8 ? blob_offset : ((guint)offset)+8);
379 proto_tree_add_text(ntlmssp_tree, tvb, offset, 8, "%s: Empty",
380 proto_registrar_get_name(blob_hf));
385 tf = proto_tree_add_item (ntlmssp_tree, blob_hf, tvb,
386 blob_offset, blob_length, FALSE);
387 tree = proto_item_add_subtree(tf, ett_ntlmssp_blob);
389 proto_tree_add_uint(tree, hf_ntlmssp_blob_len,
390 tvb, offset, 2, blob_length);
392 proto_tree_add_uint(tree, hf_ntlmssp_blob_maxlen,
393 tvb, offset, 2, blob_maxlen);
395 proto_tree_add_uint(tree, hf_ntlmssp_blob_offset,
396 tvb, offset, 4, blob_offset);
399 *end = blob_offset + blob_length;
401 if (result != NULL) {
402 result->length = blob_length;
403 memset(result->contents, 0, MAX_BLOB_SIZE);
404 if (blob_length < MAX_BLOB_SIZE)
405 tvb_memcpy(tvb, result->contents, blob_offset, blob_length);
413 dissect_ntlmssp_negotiate_flags (tvbuff_t *tvb, int offset,
414 proto_tree *ntlmssp_tree,
415 guint32 negotiate_flags)
417 proto_tree *negotiate_flags_tree = NULL;
418 proto_item *tf = NULL;
421 tf = proto_tree_add_uint (ntlmssp_tree,
422 hf_ntlmssp_negotiate_flags,
423 tvb, offset, 4, negotiate_flags);
424 negotiate_flags_tree = proto_item_add_subtree (tf, ett_ntlmssp_negotiate_flags);
427 proto_tree_add_boolean (negotiate_flags_tree,
428 hf_ntlmssp_negotiate_flags_80000000,
429 tvb, offset, 4, negotiate_flags);
430 proto_tree_add_boolean (negotiate_flags_tree,
431 hf_ntlmssp_negotiate_flags_40000000,
432 tvb, offset, 4, negotiate_flags);
433 proto_tree_add_boolean (negotiate_flags_tree,
434 hf_ntlmssp_negotiate_flags_20000000,
435 tvb, offset, 4, negotiate_flags);
436 proto_tree_add_boolean (negotiate_flags_tree,
437 hf_ntlmssp_negotiate_flags_10000000,
438 tvb, offset, 4, negotiate_flags);
439 proto_tree_add_boolean (negotiate_flags_tree,
440 hf_ntlmssp_negotiate_flags_8000000,
441 tvb, offset, 4, negotiate_flags);
442 proto_tree_add_boolean (negotiate_flags_tree,
443 hf_ntlmssp_negotiate_flags_4000000,
444 tvb, offset, 4, negotiate_flags);
445 proto_tree_add_boolean (negotiate_flags_tree,
446 hf_ntlmssp_negotiate_flags_2000000,
447 tvb, offset, 4, negotiate_flags);
448 proto_tree_add_boolean (negotiate_flags_tree,
449 hf_ntlmssp_negotiate_flags_1000000,
450 tvb, offset, 4, negotiate_flags);
451 proto_tree_add_boolean (negotiate_flags_tree,
452 hf_ntlmssp_negotiate_flags_800000,
453 tvb, offset, 4, negotiate_flags);
454 proto_tree_add_boolean (negotiate_flags_tree,
455 hf_ntlmssp_negotiate_flags_400000,
456 tvb, offset, 4, negotiate_flags);
457 proto_tree_add_boolean (negotiate_flags_tree,
458 hf_ntlmssp_negotiate_flags_200000,
459 tvb, offset, 4, negotiate_flags);
460 proto_tree_add_boolean (negotiate_flags_tree,
461 hf_ntlmssp_negotiate_flags_100000,
462 tvb, offset, 4, negotiate_flags);
463 proto_tree_add_boolean (negotiate_flags_tree,
464 hf_ntlmssp_negotiate_flags_80000,
465 tvb, offset, 4, negotiate_flags);
466 proto_tree_add_boolean (negotiate_flags_tree,
467 hf_ntlmssp_negotiate_flags_40000,
468 tvb, offset, 4, negotiate_flags);
469 proto_tree_add_boolean (negotiate_flags_tree,
470 hf_ntlmssp_negotiate_flags_20000,
471 tvb, offset, 4, negotiate_flags);
472 proto_tree_add_boolean (negotiate_flags_tree,
473 hf_ntlmssp_negotiate_flags_10000,
474 tvb, offset, 4, negotiate_flags);
475 proto_tree_add_boolean (negotiate_flags_tree,
476 hf_ntlmssp_negotiate_flags_8000,
477 tvb, offset, 4, negotiate_flags);
478 proto_tree_add_boolean (negotiate_flags_tree,
479 hf_ntlmssp_negotiate_flags_4000,
480 tvb, offset, 4, negotiate_flags);
481 proto_tree_add_boolean (negotiate_flags_tree,
482 hf_ntlmssp_negotiate_flags_2000,
483 tvb, offset, 4, negotiate_flags);
484 proto_tree_add_boolean (negotiate_flags_tree,
485 hf_ntlmssp_negotiate_flags_1000,
486 tvb, offset, 4, negotiate_flags);
487 proto_tree_add_boolean (negotiate_flags_tree,
488 hf_ntlmssp_negotiate_flags_800,
489 tvb, offset, 4, negotiate_flags);
490 proto_tree_add_boolean (negotiate_flags_tree,
491 hf_ntlmssp_negotiate_flags_400,
492 tvb, offset, 4, negotiate_flags);
493 proto_tree_add_boolean (negotiate_flags_tree,
494 hf_ntlmssp_negotiate_flags_200,
495 tvb, offset, 4, negotiate_flags);
496 proto_tree_add_boolean (negotiate_flags_tree,
497 hf_ntlmssp_negotiate_flags_100,
498 tvb, offset, 4, negotiate_flags);
499 proto_tree_add_boolean (negotiate_flags_tree,
500 hf_ntlmssp_negotiate_flags_80,
501 tvb, offset, 4, negotiate_flags);
502 proto_tree_add_boolean (negotiate_flags_tree,
503 hf_ntlmssp_negotiate_flags_40,
504 tvb, offset, 4, negotiate_flags);
505 proto_tree_add_boolean (negotiate_flags_tree,
506 hf_ntlmssp_negotiate_flags_20,
507 tvb, offset, 4, negotiate_flags);
508 proto_tree_add_boolean (negotiate_flags_tree,
509 hf_ntlmssp_negotiate_flags_10,
510 tvb, offset, 4, negotiate_flags);
511 proto_tree_add_boolean (negotiate_flags_tree,
512 hf_ntlmssp_negotiate_flags_08,
513 tvb, offset, 4, negotiate_flags);
514 proto_tree_add_boolean (negotiate_flags_tree,
515 hf_ntlmssp_negotiate_flags_04,
516 tvb, offset, 4, negotiate_flags);
517 proto_tree_add_boolean (negotiate_flags_tree,
518 hf_ntlmssp_negotiate_flags_02,
519 tvb, offset, 4, negotiate_flags);
520 proto_tree_add_boolean (negotiate_flags_tree,
521 hf_ntlmssp_negotiate_flags_01,
522 tvb, offset, 4, negotiate_flags);
529 dissect_ntlmssp_negotiate (tvbuff_t *tvb, int offset, proto_tree *ntlmssp_tree)
531 guint32 negotiate_flags;
536 /* NTLMSSP Negotiate Flags */
537 negotiate_flags = tvb_get_letohl (tvb, offset);
538 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
541 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
542 hf_ntlmssp_negotiate_domain,
543 &start, &workstation_end);
544 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
545 hf_ntlmssp_negotiate_workstation,
546 &start, &domain_end);
548 /* XXX - two blobs after this one, sometimes? */
550 return MAX(workstation_end, domain_end);
555 dissect_ntlmssp_address_list (tvbuff_t *tvb, int offset,
556 proto_tree *ntlmssp_tree,
559 guint16 list_length = tvb_get_letohs(tvb, offset);
560 guint16 list_maxlen = tvb_get_letohs(tvb, offset+2);
561 guint32 list_offset = tvb_get_letohl(tvb, offset+4);
562 guint16 item_type, item_length;
564 proto_item *tf = NULL;
565 proto_tree *tree = NULL;
567 /* the address list is just a blob */
568 if (0 == list_length) {
569 *end = (list_offset > ((guint)offset)+8 ? list_offset : ((guint)offset)+8);
571 proto_tree_add_text(ntlmssp_tree, tvb, offset, 8,
572 "Address List: Empty");
577 tf = proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_address_list, tvb,
578 list_offset, list_length, FALSE);
579 tree = proto_item_add_subtree(tf, ett_ntlmssp_address_list);
581 proto_tree_add_uint(tree, hf_ntlmssp_address_list_len,
582 tvb, offset, 2, list_length);
584 proto_tree_add_uint(tree, hf_ntlmssp_address_list_maxlen,
585 tvb, offset, 2, list_maxlen);
587 proto_tree_add_uint(tree, hf_ntlmssp_address_list_offset,
588 tvb, offset, 4, list_offset);
591 item_offset = list_offset;
592 item_type = tvb_get_letohs(tvb, item_offset);
594 item_length = tvb_get_letohs(tvb, item_offset);
602 /* Strings are always in unicode regardless of the negotiated
605 text = get_unicode_or_ascii_string(tvb, &item_offset,
606 TRUE, &result_length,
609 if (!text) text = ""; /* Make sure we don't blow up below */
613 proto_tree_add_string(tree, hf_ntlmssp_address_list_server_nb,
614 tvb, item_offset, item_length, text);
617 proto_tree_add_string(tree, hf_ntlmssp_address_list_domain_nb,
618 tvb, item_offset, item_length, text);
621 proto_tree_add_string(tree, hf_ntlmssp_address_list_server_dns,
622 tvb, item_offset, item_length, text);
625 proto_tree_add_string(tree, hf_ntlmssp_address_list_domain_dns,
626 tvb, item_offset, item_length, text);
629 item_offset += item_length;
630 item_type = tvb_get_letohs(tvb, item_offset);
632 item_length = tvb_get_letohs(tvb, item_offset);
636 *end = list_offset + list_length;
641 dissect_ntlmssp_challenge (tvbuff_t *tvb, packet_info *pinfo, int offset,
642 proto_tree *ntlmssp_tree)
644 guint32 negotiate_flags;
645 int item_start, item_end;
646 int data_start, data_end;
647 ntlmssp_info *conv_ntlmssp_info;
648 conversation_t *conversation;
649 gboolean unicode_strings = FALSE;
650 guint8 sspkey[16]; /* NTLMSSP cipher key */
651 guint8 ssp_key_len; /* Either 8 or 16 (40 bit or 128) */
653 /* need to find unicode flag */
654 negotiate_flags = tvb_get_letohl (tvb, offset+8);
655 if (negotiate_flags & NTLMSSP_NEGOTIATE_UNICODE)
656 unicode_strings = TRUE;
659 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, unicode_strings,
660 hf_ntlmssp_challenge_domain,
661 &item_start, &item_end);
662 data_start = item_start;
665 /* NTLMSSP Negotiate Flags */
666 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
669 /* NTLMSSP NT Lan Manager Challenge */
670 proto_tree_add_item (ntlmssp_tree,
671 hf_ntlmssp_ntlm_challenge,
672 tvb, offset, 8, FALSE);
675 * Store the flags and the challenge with the conversation, as they're
676 * needed in order to dissect subsequent messages.
678 conversation = find_conversation(&pinfo->src, &pinfo->dst,
679 pinfo->ptype, pinfo->srcport,
681 if (!conversation) { /* Create one */
682 conversation = conversation_new(&pinfo->src, &pinfo->dst, pinfo->ptype,
683 pinfo->srcport, pinfo->destport, 0);
686 if (!conversation_get_proto_data(conversation, proto_ntlmssp)) {
687 conv_ntlmssp_info = g_malloc(sizeof(ntlmssp_info));
688 /* Insert the flags into the conversation */
689 conv_ntlmssp_info->flags = negotiate_flags;
690 /* Insert the challenge into the conversation */
691 tvb_memcpy(tvb, conv_ntlmssp_info->challenge, offset, 8);
693 /* Between the challenge and the user provided password, we can build the
694 NTLMSSP key and initialize the cipher */
695 if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_128) {
696 create_ntlmssp_v1_key(nt_password, conv_ntlmssp_info->challenge,
701 create_ntlmssp_v1_key(nt_password, conv_ntlmssp_info->challenge,
705 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_peer1, sspkey, ssp_key_len);
706 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_peer2, sspkey, ssp_key_len);
707 conv_ntlmssp_info->peer1_dest_port = pinfo->destport;
708 conv_ntlmssp_info->rc4_state_initialized = 1;
710 conversation_add_proto_data(conversation, proto_ntlmssp, conv_ntlmssp_info);
714 /* Reserved (function not completely known) */
716 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_reserved,
717 tvb, offset, 8, FALSE);
721 * The presence or absence of this field is not obviously correlated
722 * with any flags in the previous NEGOTIATE message or in this
723 * message (other than the "Workstation Supplied" and "Domain
724 * Supplied" flags in the NEGOTIATE message, at least in the capture
725 * I've seen - but those also correlate with the presence of workstation
726 * and domain name fields, so it doesn't seem to make sense that they
727 * actually *indicate* whether the subsequent CHALLENGE has an
730 if (offset < data_start) {
731 offset = dissect_ntlmssp_address_list(tvb, offset, ntlmssp_tree, &item_end);
732 data_end = MAX(data_end, item_end);
735 return MAX(offset, data_end);
739 dissect_ntlmssp_auth (tvbuff_t *tvb, packet_info *pinfo, int offset,
740 proto_tree *ntlmssp_tree)
742 int item_start, item_end;
743 int data_start, data_end = 0;
744 guint32 negotiate_flags;
745 gboolean unicode_strings = FALSE;
746 ntlmssp_info *conv_ntlmssp_info;
747 conversation_t *conversation;
750 * Get flag info from the original negotiate message, if any.
751 * This is because the flag information is sometimes missing from
752 * the AUTHENTICATE message, so we can't figure out whether
753 * strings are Unicode or not by looking at *our* flags.
755 conv_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
756 if (conv_ntlmssp_info == NULL) {
758 * There isn't any. Is there any from this conversation? If so,
759 * it means this is the first time we've dissected this frame, so
760 * we should give it flag info.
762 conversation = find_conversation(&pinfo->src, &pinfo->dst,
763 pinfo->ptype, pinfo->srcport,
765 if (conversation != NULL) {
766 conv_ntlmssp_info = conversation_get_proto_data(conversation, proto_ntlmssp);
767 if (conv_ntlmssp_info != NULL) {
769 * We have flag info; attach it to the frame.
771 p_add_proto_data(pinfo->fd, proto_ntlmssp, conv_ntlmssp_info);
775 if (conv_ntlmssp_info != NULL) {
776 if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_UNICODE)
777 unicode_strings = TRUE;
781 * Sometimes the session key and flags are missing.
782 * Sometimes the session key is present but the flags are missing.
783 * Sometimes they're both present.
785 * This does not correlate with any flags in the previous CHALLENGE
786 * message, and only correlates with "Negotiate Unicode", "Workstation
787 * Supplied", and "Domain Supplied" in the NEGOTIATE message - but
788 * those don't make sense as flags to use to determine this.
790 * So we check all of the descriptors to figure out where the data
791 * area begins, and if the session key or the flags would be in the
792 * middle of the data area, we assume the field in question is
796 /* Lan Manager response */
797 data_start = tvb_get_letohl(tvb, offset+4);
798 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
799 hf_ntlmssp_auth_lmresponse,
801 conv_ntlmssp_info == NULL ? NULL :
802 &conv_ntlmssp_info->lm_response);
803 data_end = MAX(data_end, item_end);
806 item_start = tvb_get_letohl(tvb, offset+4);
807 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
808 hf_ntlmssp_auth_ntresponse,
810 conv_ntlmssp_info == NULL ? NULL :
811 &conv_ntlmssp_info->ntlm_response);
812 data_start = MIN(data_start, item_start);
813 data_end = MAX(data_end, item_end);
816 item_start = tvb_get_letohl(tvb, offset+4);
817 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
819 hf_ntlmssp_auth_domain,
820 &item_start, &item_end);
821 data_start = MIN(data_start, item_start);
822 data_end = MAX(data_end, item_end);
825 item_start = tvb_get_letohl(tvb, offset+4);
826 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
828 hf_ntlmssp_auth_username,
829 &item_start, &item_end);
830 data_start = MIN(data_start, item_start);
831 data_end = MAX(data_end, item_end);
834 item_start = tvb_get_letohl(tvb, offset+4);
835 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
837 hf_ntlmssp_auth_hostname,
838 &item_start, &item_end);
839 data_start = MIN(data_start, item_start);
840 data_end = MAX(data_end, item_end);
842 if (offset < data_start) {
844 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
845 hf_ntlmssp_auth_sesskey,
847 data_end = MAX(data_end, item_end);
850 if (offset < data_start) {
851 /* NTLMSSP Negotiate Flags */
852 negotiate_flags = tvb_get_letohl (tvb, offset);
853 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
857 return MAX(offset, data_end);
861 dissect_ntlmssp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
863 guint32 ntlmssp_message_type;
864 volatile int offset = 0;
865 proto_tree *volatile ntlmssp_tree = NULL;
866 proto_item *tf = NULL;
868 /* Setup a new tree for the NTLMSSP payload */
870 tf = proto_tree_add_item (tree,
872 tvb, offset, -1, FALSE);
874 ntlmssp_tree = proto_item_add_subtree (tf,
879 * Catch the ReportedBoundsError exception; the stuff we've been
880 * handed doesn't necessarily run to the end of the packet, it's
881 * an item inside a packet, so if it happens to be malformed (or
882 * we, or a dissector we call, has a bug), so that an exception
883 * is thrown, we want to report the error, but return and let
884 * our caller dissect the rest of the packet.
886 * If it gets a BoundsError, we can stop, as there's nothing more
887 * in the packet after our blob to see, so we just re-throw the
891 /* NTLMSSP constant */
892 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth,
893 tvb, offset, 8, FALSE);
896 /* NTLMSSP Message Type */
897 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_message_type,
898 tvb, offset, 4, TRUE);
899 ntlmssp_message_type = tvb_get_letohl (tvb, offset);
902 if (check_col(pinfo->cinfo, COL_INFO))
903 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
904 val_to_str(ntlmssp_message_type,
905 ntlmssp_message_types,
906 "Unknown message type"));
908 /* Call the appropriate dissector based on the Message Type */
909 switch (ntlmssp_message_type) {
911 case NTLMSSP_NEGOTIATE:
912 offset = dissect_ntlmssp_negotiate (tvb, offset, ntlmssp_tree);
915 case NTLMSSP_CHALLENGE:
916 offset = dissect_ntlmssp_challenge (tvb, pinfo, offset, ntlmssp_tree);
920 offset = dissect_ntlmssp_auth (tvb, pinfo, offset, ntlmssp_tree);
924 /* Unrecognized message type */
925 proto_tree_add_text (ntlmssp_tree, tvb, offset, -1,
926 "Unrecognized NTLMSSP Message");
929 } CATCH(BoundsError) {
931 } CATCH(ReportedBoundsError) {
932 show_reported_bounds_error(tvb, pinfo, tree);
937 * Get the encryption state tied to this conversation. cryptpeer indicates
938 * whether to retrieve the data for peer1 or peer2.
940 static rc4_state_struct *
941 get_encrypted_state(packet_info *pinfo, int cryptpeer)
943 conversation_t *conversation;
944 ntlmssp_info *conv_ntlmssp_info;
946 conversation = find_conversation(&pinfo->src, &pinfo->dst,
947 pinfo->ptype, pinfo->srcport,
949 if (conversation == NULL) {
950 /* We don't have a conversation. In this case, stop processing
951 because we do not have enough info to decrypt the payload */
955 /* We have a conversation, check for encryption state */
956 conv_ntlmssp_info = conversation_get_proto_data(conversation,
958 if (conv_ntlmssp_info == NULL) {
959 /* No encryption state tied to the conversation. Therefore, we
960 cannot decrypt the payload */
964 /* We have the encryption state in the conversation. So return the
965 crypt state tied to the requested peer
967 if (cryptpeer == 1) {
968 return &conv_ntlmssp_info->rc4_state_peer1;
970 return &conv_ntlmssp_info->rc4_state_peer2;
978 * See page 45 of "DCE/RPC over SMB" by Luke Kenneth Casson Leighton.
981 decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
982 packet_info *pinfo, proto_tree *tree)
984 proto_tree *decr_tree = NULL;
985 proto_item *tf = NULL;
986 conversation_t *conversation;
987 rc4_state_struct *rc4_state;
988 rc4_state_struct *rc4_state_peer;
989 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
991 ntlmssp_info *conv_ntlmssp_info = NULL;
992 ntlmssp_packet_info *packet_ntlmssp_info = NULL;
993 int decrypted_offset = 0;
995 packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
996 if (packet_ntlmssp_info == NULL) {
997 /* We don't have data for this packet */
1000 if (!packet_ntlmssp_info->verifier_decrypted) {
1001 conversation = find_conversation(&pinfo->src, &pinfo->dst,
1002 pinfo->ptype, pinfo->srcport,
1003 pinfo->destport, 0);
1004 if (conversation == NULL) {
1005 /* There is no conversation, thus no encryption state */
1009 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1011 if (conv_ntlmssp_info == NULL) {
1012 /* There is no NTLMSSP state tied to the conversation */
1015 if (conv_ntlmssp_info->rc4_state_initialized != 1 ) {
1016 /* The crypto sybsystem is not initialized. This means that either
1017 the conversation did not include a challenge, or we are doing
1018 something other than NTLMSSP v1 */
1022 if (conv_ntlmssp_info->peer1_dest_port == pinfo->destport) {
1023 rc4_state = get_encrypted_state(pinfo, 1);
1024 rc4_state_peer = get_encrypted_state(pinfo, 0);
1026 rc4_state = get_encrypted_state(pinfo, 0);
1027 rc4_state_peer = get_encrypted_state(pinfo, 1);
1030 if (rc4_state == NULL || rc4_state_peer == NULL) {
1031 /* There is no encryption state, so we cannot decrypt */
1035 /* Setup the buffer to decrypt to */
1036 tvb_memcpy(tvb, packet_ntlmssp_info->verifier,
1037 offset, encrypted_block_length);
1039 /* Do the actual decryption of the verifier */
1040 crypt_rc4(rc4_state, packet_ntlmssp_info->verifier,
1041 encrypted_block_length);
1043 /* We setup a temporary buffer so we can re-encrypt the payload after
1044 decryption. This is to update the opposite peer's RC4 state */
1045 peer_block = g_malloc(encrypted_block_length);
1046 memcpy(peer_block, packet_ntlmssp_info->verifier,
1047 encrypted_block_length);
1048 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
1051 /* Mark the packet as decrypted so that subsequent attempts to dissect
1052 the packet use the already decrypted payload instead of attempting
1054 packet_ntlmssp_info->verifier_decrypted = TRUE;
1057 /* Show the decrypted buffer in a new window */
1058 decr_tvb = tvb_new_real_data(packet_ntlmssp_info->verifier,
1059 encrypted_block_length,
1060 encrypted_block_length);
1061 tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
1062 add_new_data_source(pinfo, decr_tvb,
1063 "Decrypted NTLMSSP Verifier");
1065 /* Show the decrypted payload in the tree */
1066 tf = proto_tree_add_text(tree, decr_tvb, 0, -1,
1067 "Decrypted Verifier (%d byte%s)",
1068 encrypted_block_length,
1069 plurality(encrypted_block_length, "", "s"));
1070 decr_tree = proto_item_add_subtree (tf, ett_ntlmssp);
1072 /* LKCL page 45 says this is a "reserved" field. I'm not sure if it's
1073 garbage because it's some sort of nonce, or because there is a problem
1074 with the verifier decryption routine. */
1075 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_unknown1,
1076 decr_tvb, decrypted_offset, 4, TRUE);
1077 decrypted_offset += 4;
1079 /* CRC32 of the DCE fragment data */
1080 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_crc32,
1081 decr_tvb, decrypted_offset, 4, TRUE);
1082 decrypted_offset += 4;
1084 /* Incrementing sequence number of DCE conversation */
1085 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_sequence,
1086 decr_tvb, decrypted_offset, 4, TRUE);
1087 decrypted_offset += 4;
1091 dissect_ntlmssp_verf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1093 volatile int offset = 0;
1094 proto_tree *volatile ntlmssp_tree = NULL;
1095 proto_item *tf = NULL;
1096 guint32 verifier_length;
1097 guint32 encrypted_block_length;
1099 verifier_length = tvb_length_remaining (tvb, offset);
1100 encrypted_block_length = verifier_length - 4;
1102 if (encrypted_block_length < 12) {
1103 /* Don't know why this would happen, but if it does, don't even bother
1104 attempting decryption/dissection */
1105 return offset + verifier_length;
1108 /* Setup a new tree for the NTLMSSP payload */
1110 tf = proto_tree_add_item (tree,
1112 tvb, offset, -1, FALSE);
1114 ntlmssp_tree = proto_item_add_subtree (tf,
1119 * Catch the ReportedBoundsError exception; the stuff we've been
1120 * handed doesn't necessarily run to the end of the packet, it's
1121 * an item inside a packet, so if it happens to be malformed (or
1122 * we, or a dissector we call, has a bug), so that an exception
1123 * is thrown, we want to report the error, but return and let
1124 * our caller dissect the rest of the packet.
1126 * If it gets a BoundsError, we can stop, as there's nothing more
1127 * in the packet after our blob to see, so we just re-throw the
1131 /* Version number */
1132 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_vers,
1133 tvb, offset, 4, TRUE);
1136 /* Encrypted body */
1137 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_body,
1138 tvb, offset, encrypted_block_length, TRUE);
1140 /* Try to decrypt */
1141 decrypt_verifier (tvb, offset, encrypted_block_length, pinfo, ntlmssp_tree);
1143 offset += encrypted_block_length;
1144 } CATCH(BoundsError) {
1146 } CATCH(ReportedBoundsError) {
1147 show_reported_bounds_error(tvb, pinfo, tree);
1155 dissect_ntlmssp_encrypted_payload(tvbuff_t *tvb,
1156 packet_info *pinfo, proto_tree *tree)
1158 volatile int offset = 0;
1159 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
1161 conversation_t *conversation;
1162 guint32 encrypted_block_length;
1163 rc4_state_struct *rc4_state;
1164 rc4_state_struct *rc4_state_peer;
1165 ntlmssp_info *conv_ntlmssp_info = NULL;
1166 ntlmssp_packet_info *packet_ntlmssp_info = NULL;
1168 static ntlmssp_decrypted_info_t ndi;
1170 encrypted_block_length = tvb_length_remaining (tvb, offset);
1172 /* Check to see if we already have state for this packet */
1173 packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1174 if (packet_ntlmssp_info == NULL) {
1175 /* We don't have any packet state, so create one */
1176 packet_ntlmssp_info = g_malloc(sizeof(ntlmssp_packet_info));
1177 memset(packet_ntlmssp_info, 0, sizeof(ntlmssp_packet_info));
1178 p_add_proto_data(pinfo->fd, proto_ntlmssp, packet_ntlmssp_info);
1181 if (!packet_ntlmssp_info->payload_decrypted) {
1182 /* Pull the challenge info from the conversation */
1183 conversation = find_conversation(&pinfo->src, &pinfo->dst,
1184 pinfo->ptype, pinfo->srcport,
1185 pinfo->destport, 0);
1186 if (conversation == NULL) {
1187 /* There is no conversation, thus no encryption state */
1188 return offset + encrypted_block_length;
1191 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1193 if (conv_ntlmssp_info == NULL) {
1194 /* There is no NTLMSSP state tied to the conversation */
1195 return offset + encrypted_block_length;
1198 /* Get the pair of RC4 state structures. One is used for to decrypt the
1199 payload. The other is used to re-encrypt the payload to represent
1201 if (conv_ntlmssp_info->peer1_dest_port == pinfo->destport) {
1202 rc4_state = get_encrypted_state(pinfo, 1);
1203 rc4_state_peer = get_encrypted_state(pinfo, 0);
1205 rc4_state = get_encrypted_state(pinfo, 0);
1206 rc4_state_peer = get_encrypted_state(pinfo, 1);
1209 if (rc4_state == NULL || rc4_state_peer == NULL) {
1210 /* There is no encryption state, so we cannot decrypt */
1211 return offset + encrypted_block_length;
1214 /* Store the decrypted contents in the packet state struct
1215 (of course at this point, they aren't decrypted yet) */
1216 tvb_memcpy(tvb, packet_ntlmssp_info->decrypted_payload,
1217 offset, encrypted_block_length);
1219 /* Do the decryption of the payload */
1220 crypt_rc4(rc4_state, packet_ntlmssp_info->decrypted_payload,
1221 encrypted_block_length);
1223 /* We setup a temporary buffer so we can re-encrypt the payload after
1224 decryption. This is to update the opposite peer's RC4 state */
1225 peer_block = g_malloc(encrypted_block_length);
1226 memcpy(peer_block, packet_ntlmssp_info->decrypted_payload,
1227 encrypted_block_length);
1228 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
1231 packet_ntlmssp_info->payload_decrypted = TRUE;
1234 /* Show the decrypted buffer in a new window */
1235 decr_tvb = tvb_new_real_data(packet_ntlmssp_info->decrypted_payload,
1236 encrypted_block_length,
1237 encrypted_block_length);
1238 tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
1239 add_new_data_source(pinfo, decr_tvb,
1240 "Decrypted NTLMSSP block");
1242 /* Show the decrypted payload in the tree */
1243 it=proto_tree_add_text(tree, decr_tvb, 0, -1,
1244 "Decrypted stub data (%d byte%s)",
1245 encrypted_block_length,
1246 plurality(encrypted_block_length, "", "s"));
1247 ndi.decr_tree=proto_item_add_subtree(it, ett_ntlmssp_decrypted_tree);
1248 ndi.decr_tvb=decr_tvb;
1249 pinfo->decrypted_data=&ndi;
1251 offset += encrypted_block_length;
1256 ntlmssp_init_protocol(void)
1262 proto_register_ntlmssp(void)
1265 static hf_register_info hf[] = {
1267 { "NTLMSSP", "ntlmssp", FT_NONE, BASE_NONE, NULL, 0x0, "NTLMSSP", HFILL }},
1270 { "NTLMSSP identifier", "ntlmssp.identifier", FT_STRING, BASE_NONE, NULL, 0x0, "NTLMSSP Identifier", HFILL }},
1272 { &hf_ntlmssp_message_type,
1273 { "NTLM Message Type", "ntlmssp.messagetype", FT_UINT32, BASE_HEX, VALS(ntlmssp_message_types), 0x0, "", HFILL }},
1275 { &hf_ntlmssp_negotiate_flags,
1276 { "Flags", "ntlmssp.negotiateflags", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1277 { &hf_ntlmssp_negotiate_flags_01,
1279 { "Negotiate UNICODE", "ntlmssp.negotiateunicode", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_UNICODE, "", HFILL }},
1280 { &hf_ntlmssp_negotiate_flags_02,
1281 { "Negotiate OEM", "ntlmssp.negotiateoem", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_OEM, "", HFILL }},
1282 { &hf_ntlmssp_negotiate_flags_04,
1283 { "Request Target", "ntlmssp.requesttarget", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_REQUEST_TARGET, "", HFILL }},
1284 { &hf_ntlmssp_negotiate_flags_08,
1285 { "Request 0x00000008", "ntlmssp.negotiate00000008", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000008, "", HFILL }},
1286 { &hf_ntlmssp_negotiate_flags_10,
1287 { "Negotiate Sign", "ntlmssp.negotiatesign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SIGN, "", HFILL }},
1288 { &hf_ntlmssp_negotiate_flags_20,
1289 { "Negotiate Seal", "ntlmssp.negotiateseal", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SEAL, "", HFILL }},
1290 { &hf_ntlmssp_negotiate_flags_40,
1291 { "Negotiate Datagram Style", "ntlmssp.negotiatedatagramstyle", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_DATAGRAM_STYLE, "", HFILL }},
1292 { &hf_ntlmssp_negotiate_flags_80,
1293 { "Negotiate Lan Manager Key", "ntlmssp.negotiatelmkey", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_LM_KEY, "", HFILL }},
1294 { &hf_ntlmssp_negotiate_flags_100,
1295 { "Negotiate Netware", "ntlmssp.negotiatenetware", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NETWARE, "", HFILL }},
1296 { &hf_ntlmssp_negotiate_flags_200,
1297 { "Negotiate NTLM key", "ntlmssp.negotiatentlm", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM, "", HFILL }},
1298 { &hf_ntlmssp_negotiate_flags_400,
1299 { "Negotiate 0x00000400", "ntlmssp.negotiate00000400", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000400, "", HFILL }},
1300 { &hf_ntlmssp_negotiate_flags_800,
1301 { "Negotiate 0x00000800", "ntlmssp.negotiate00000800", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000800, "", HFILL }},
1302 { &hf_ntlmssp_negotiate_flags_1000,
1303 { "Negotiate Domain Supplied", "ntlmssp.negotiatedomainsupplied", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED, "", HFILL }},
1304 { &hf_ntlmssp_negotiate_flags_2000,
1305 { "Negotiate Workstation Supplied", "ntlmssp.negotiateworkstationsupplied", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED, "", HFILL }},
1306 { &hf_ntlmssp_negotiate_flags_4000,
1307 { "Negotiate This is Local Call", "ntlmssp.negotiatethisislocalcall", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL, "", HFILL }},
1308 { &hf_ntlmssp_negotiate_flags_8000,
1309 { "Negotiate Always Sign", "ntlmssp.negotiatealwayssign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_ALWAYS_SIGN, "", HFILL }},
1310 { &hf_ntlmssp_negotiate_flags_10000,
1311 { "Negotiate Challenge Init Response", "ntlmssp.negotiatechallengeinitresponse", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_INIT_RESPONSE, "", HFILL }},
1312 { &hf_ntlmssp_negotiate_flags_20000,
1313 { "Negotiate Challenge Accept Response", "ntlmssp.negotiatechallengeacceptresponse", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_ACCEPT_RESPONSE, "", HFILL }},
1314 { &hf_ntlmssp_negotiate_flags_40000,
1315 { "Negotiate Challenge Non NT Session Key", "ntlmssp.negotiatechallengenonntsessionkey", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_NON_NT_SESSION_KEY, "", HFILL }},
1316 { &hf_ntlmssp_negotiate_flags_80000,
1317 { "Negotiate NTLM2 key", "ntlmssp.negotiatentlm2", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM2, "", HFILL }},
1318 { &hf_ntlmssp_negotiate_flags_100000,
1319 { "Negotiate 0x00100000", "ntlmssp.negotiatent00100000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00100000, "", HFILL }},
1320 { &hf_ntlmssp_negotiate_flags_200000,
1321 { "Negotiate 0x00200000", "ntlmssp.negotiatent00200000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00200000, "", HFILL }},
1322 { &hf_ntlmssp_negotiate_flags_400000,
1323 { "Negotiate 0x00400000", "ntlmssp.negotiatent00400000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00400000, "", HFILL }},
1324 { &hf_ntlmssp_negotiate_flags_800000,
1325 { "Negotiate Target Info", "ntlmssp.negotiatetargetinfo", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_TARGET_INFO, "", HFILL }},
1326 { &hf_ntlmssp_negotiate_flags_1000000,
1327 { "Negotiate 0x01000000", "ntlmssp.negotiatent01000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_01000000, "", HFILL }},
1328 { &hf_ntlmssp_negotiate_flags_2000000,
1329 { "Negotiate 0x02000000", "ntlmssp.negotiatent02000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_02000000, "", HFILL }},
1330 { &hf_ntlmssp_negotiate_flags_4000000,
1331 { "Negotiate 0x04000000", "ntlmssp.negotiatent04000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_04000000, "", HFILL }},
1332 { &hf_ntlmssp_negotiate_flags_8000000,
1333 { "Negotiate 0x08000000", "ntlmssp.negotiatent08000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_08000000, "", HFILL }},
1334 { &hf_ntlmssp_negotiate_flags_10000000,
1335 { "Negotiate 0x10000000", "ntlmssp.negotiatent10000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_10000000, "", HFILL }},
1336 { &hf_ntlmssp_negotiate_flags_20000000,
1337 { "Negotiate 128", "ntlmssp.negotiate128", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_128, "", HFILL }},
1338 { &hf_ntlmssp_negotiate_flags_40000000,
1339 { "Negotiate Key Exchange", "ntlmssp.negotiatekeyexch", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_KEY_EXCH, "", HFILL }},
1340 { &hf_ntlmssp_negotiate_flags_80000000,
1341 { "Negotiate 0x80000000", "ntlmssp.negotiatent80000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_80000000, "", HFILL }},
1342 { &hf_ntlmssp_negotiate_workstation_strlen,
1343 { "Calling workstation name length", "ntlmssp.negotiate.callingworkstation.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1344 { &hf_ntlmssp_negotiate_workstation_maxlen,
1345 { "Calling workstation name max length", "ntlmssp.negotiate.callingworkstation.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1346 { &hf_ntlmssp_negotiate_workstation_buffer,
1347 { "Calling workstation name buffer", "ntlmssp.negotiate.callingworkstation.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1348 { &hf_ntlmssp_negotiate_workstation,
1349 { "Calling workstation name", "ntlmssp.negotiate.callingworkstation", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1350 { &hf_ntlmssp_negotiate_domain_strlen,
1351 { "Calling workstation domain length", "ntlmssp.negotiate.domain.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1352 { &hf_ntlmssp_negotiate_domain_maxlen,
1353 { "Calling workstation domain max length", "ntlmssp.negotiate.domain.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1354 { &hf_ntlmssp_negotiate_domain_buffer,
1355 { "Calling workstation domain buffer", "ntlmssp.negotiate.domain.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1356 { &hf_ntlmssp_negotiate_domain,
1357 { "Calling workstation domain", "ntlmssp.negotiate.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1358 { &hf_ntlmssp_ntlm_challenge,
1359 { "NTLM Challenge", "ntlmssp.ntlmchallenge", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1360 { &hf_ntlmssp_reserved,
1361 { "Reserved", "ntlmssp.reserved", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1362 { &hf_ntlmssp_challenge_domain,
1363 { "Domain", "ntlmssp.challenge.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1364 { &hf_ntlmssp_auth_domain,
1365 { "Domain name", "ntlmssp.auth.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1366 { &hf_ntlmssp_auth_username,
1367 { "User name", "ntlmssp.auth.username", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1368 { &hf_ntlmssp_auth_hostname,
1369 { "Host name", "ntlmssp.auth.hostname", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1370 { &hf_ntlmssp_auth_lmresponse,
1371 { "Lan Manager Response", "ntlmssp.auth.lmresponse", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1372 { &hf_ntlmssp_auth_ntresponse,
1373 { "NTLM Response", "ntlmssp.auth.ntresponse", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1374 { &hf_ntlmssp_auth_sesskey,
1375 { "Session Key", "ntlmssp.auth.sesskey", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1376 { &hf_ntlmssp_string_len,
1377 { "Length", "ntlmssp.string.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1378 { &hf_ntlmssp_string_maxlen,
1379 { "Maxlen", "ntlmssp.string.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1380 { &hf_ntlmssp_string_offset,
1381 { "Offset", "ntlmssp.string.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1382 { &hf_ntlmssp_blob_len,
1383 { "Length", "ntlmssp.blob.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1384 { &hf_ntlmssp_blob_maxlen,
1385 { "Maxlen", "ntlmssp.blob.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1386 { &hf_ntlmssp_blob_offset,
1387 { "Offset", "ntlmssp.blob.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1388 { &hf_ntlmssp_address_list,
1389 { "Address List", "ntlmssp.challenge.addresslist", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL}},
1390 { &hf_ntlmssp_address_list_len,
1391 { "Length", "ntlmssp.challenge.addresslist.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1392 { &hf_ntlmssp_address_list_maxlen,
1393 { "Maxlen", "ntlmssp.challenge.addresslist.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1394 { &hf_ntlmssp_address_list_offset,
1395 { "Offset", "ntlmssp.challenge.addresslist.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1396 { &hf_ntlmssp_address_list_server_nb,
1397 { "Server NetBIOS Name", "ntlmssp.challenge.addresslist.servernb", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1398 { &hf_ntlmssp_address_list_domain_nb,
1399 { "Domain NetBIOS Name", "ntlmssp.challenge.addresslist.domainnb", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1400 { &hf_ntlmssp_address_list_server_dns,
1401 { "Server DNS Name", "ntlmssp.challenge.addresslist.serverdns", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1402 { &hf_ntlmssp_address_list_domain_dns,
1403 { "Domain DNS Name", "ntlmssp.challenge.addresslist.domaindns", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1406 { "NTLMSSP Verifier", "ntlmssp.verf", FT_NONE, BASE_NONE, NULL, 0x0, "NTLMSSP Verifier", HFILL }},
1407 { &hf_ntlmssp_verf_vers,
1408 { "Version Number", "ntlmssp.verf.vers", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
1409 { &hf_ntlmssp_verf_body,
1410 { "Verifier Body", "ntlmssp.verf.body", FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }},
1411 { &hf_ntlmssp_decrypted_payload,
1412 { "NTLM Decrypted Payload", "ntlmssp.decrypted_payload", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1413 { &hf_ntlmssp_verf_unknown1,
1414 { "Unknown 1", "ntlmssp.verf.unknown1", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1415 { &hf_ntlmssp_verf_crc32,
1416 { "Verifier CRC32", "ntlmssp.verf.crc32", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1417 { &hf_ntlmssp_verf_sequence,
1418 { "Verifier Sequence Number", "ntlmssp.verf.sequence", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }}
1423 static gint *ett[] = {
1425 &ett_ntlmssp_negotiate_flags,
1426 &ett_ntlmssp_string,
1428 &ett_ntlmssp_address_list,
1429 &ett_ntlmssp_decrypted_tree
1431 module_t *ntlmssp_module;
1433 proto_ntlmssp = proto_register_protocol (
1434 "NTLM Secure Service Provider", /* name */
1435 "NTLMSSP", /* short name */
1436 "ntlmssp" /* abbrev */
1438 proto_register_field_array (proto_ntlmssp, hf, array_length (hf));
1439 proto_register_subtree_array (ett, array_length (ett));
1440 register_init_routine(&ntlmssp_init_protocol);
1442 ntlmssp_module = prefs_register_protocol(proto_ntlmssp, NULL);
1444 prefs_register_string_preference(ntlmssp_module, "nt_password",
1446 "NT Password (used to decrypt payloads)",
1449 register_dissector("ntlmssp", dissect_ntlmssp, proto_ntlmssp);
1450 new_register_dissector("ntlmssp_verf", dissect_ntlmssp_verf, proto_ntlmssp);
1451 new_register_dissector("ntlmssp_encrypted_payload",
1452 dissect_ntlmssp_encrypted_payload, proto_ntlmssp);
1456 proto_reg_handoff_ntlmssp(void)
1458 dissector_handle_t ntlmssp_handle, ntlmssp_wrap_handle;
1460 /* Register protocol with the GSS-API module */
1462 ntlmssp_handle = find_dissector("ntlmssp");
1463 ntlmssp_wrap_handle = find_dissector("ntlmssp_verf");
1464 gssapi_init_oid("1.3.6.1.4.1.311.2.2.10", proto_ntlmssp, ett_ntlmssp,
1465 ntlmssp_handle, ntlmssp_wrap_handle,
1466 "NTLMSSP - Microsoft NTLM Security Support Provider");