2 * Routines for NTLM Secure Service Provider
3 * Devin Heitmueller <dheitmueller@netilla.com>
4 * Copyright 2003, Tim Potter <tpot@samba.org>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
35 #include <epan/packet.h>
37 #include "packet-windows-common.h"
38 #include "packet-smb-common.h"
39 #include "packet-frame.h"
40 #include <epan/prefs.h>
41 #include <epan/emem.h>
43 #include <epan/crypt/crypt-rc4.h>
44 #include <epan/crypt/crypt-md4.h>
45 #include <epan/crypt/crypt-des.h>
46 #include "packet-dcerpc.h"
47 #include "packet-gssapi.h"
49 #include "packet-ntlmssp.h"
51 static int ntlmssp_tap = -1;
55 #define NTLMSSP_NEGOTIATE 1
56 #define NTLMSSP_CHALLENGE 2
57 #define NTLMSSP_AUTH 3
58 #define NTLMSSP_UNKNOWN 4
60 static const value_string ntlmssp_message_types[] = {
61 { NTLMSSP_NEGOTIATE, "NTLMSSP_NEGOTIATE" },
62 { NTLMSSP_CHALLENGE, "NTLMSSP_CHALLENGE" },
63 { NTLMSSP_AUTH, "NTLMSSP_AUTH" },
64 { NTLMSSP_UNKNOWN, "NTLMSSP_UNKNOWN" },
69 * NTLMSSP negotiation flags
74 * http://davenport.sourceforge.net/ntlm.html
76 * although that document says that:
78 * 0x00010000 is "Target Type Domain";
79 * 0x00020000 is "Target Type Server"
80 * 0x00040000 is "Target Type Share";
82 * and that 0x00100000, 0x00200000, and 0x00400000 are
83 * "Request Init Response", "Request Accept Response", and
84 * "Request Non-NT Session Key", rather than those values shifted
85 * right one having those interpretations.
87 * UPDATE: Further information obtained from [MS-NLMP]:
88 * NT LAN Manager (NTLM) Authentication Protocol Specification
89 * http://msdn2.microsoft.com/en-us/library/cc236621.aspx
92 #define NTLMSSP_NEGOTIATE_UNICODE 0x00000001
93 #define NTLMSSP_NEGOTIATE_OEM 0x00000002
94 #define NTLMSSP_REQUEST_TARGET 0x00000004
95 #define NTLMSSP_NEGOTIATE_00000008 0x00000008
96 #define NTLMSSP_NEGOTIATE_SIGN 0x00000010
97 #define NTLMSSP_NEGOTIATE_SEAL 0x00000020
98 #define NTLMSSP_NEGOTIATE_DATAGRAM 0x00000040
99 #define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080
100 #define NTLMSSP_NEGOTIATE_00000100 0x00000100
101 #define NTLMSSP_NEGOTIATE_NTLM 0x00000200
102 #define NTLMSSP_NEGOTIATE_NT_ONLY 0x00000400
103 #define NTLMSSP_NEGOTIATE_00000800 0x00000800
104 #define NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED 0x00001000
105 #define NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED 0x00002000
106 #define NTLMSSP_NEGOTIATE_00004000 0x00004000
107 #define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000
108 #define NTLMSSP_TARGET_TYPE_DOMAIN 0x00010000
109 #define NTLMSSP_TARGET_TYPE_SERVER 0x00020000
110 #define NTLMSSP_TARGET_TYPE_SHARE 0x00040000
111 #define NTLMSSP_NEGOTIATE_NTLM2 0x00080000
112 #define NTLMSSP_NEGOTIATE_IDENTIFY 0x00100000
113 #define NTLMSSP_NEGOTIATE_00200000 0x00200000
114 #define NTLMSSP_REQUEST_NON_NT_SESSION 0x00400000
115 #define NTLMSSP_NEGOTIATE_TARGET_INFO 0x00800000
116 #define NTLMSSP_NEGOTIATE_01000000 0x01000000
117 #define NTLMSSP_NEGOTIATE_VERSION 0x02000000
118 #define NTLMSSP_NEGOTIATE_04000000 0x04000000
119 #define NTLMSSP_NEGOTIATE_08000000 0x08000000
120 #define NTLMSSP_NEGOTIATE_10000000 0x10000000
121 #define NTLMSSP_NEGOTIATE_128 0x20000000
122 #define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000
123 #define NTLMSSP_NEGOTIATE_56 0x80000000
125 static int proto_ntlmssp = -1;
126 static int hf_ntlmssp = -1;
127 static int hf_ntlmssp_auth = -1;
128 static int hf_ntlmssp_message_type = -1;
129 static int hf_ntlmssp_negotiate_flags = -1;
130 static int hf_ntlmssp_negotiate_flags_01 = -1;
131 static int hf_ntlmssp_negotiate_flags_02 = -1;
132 static int hf_ntlmssp_negotiate_flags_04 = -1;
133 static int hf_ntlmssp_negotiate_flags_08 = -1;
134 static int hf_ntlmssp_negotiate_flags_10 = -1;
135 static int hf_ntlmssp_negotiate_flags_20 = -1;
136 static int hf_ntlmssp_negotiate_flags_40 = -1;
137 static int hf_ntlmssp_negotiate_flags_80 = -1;
138 static int hf_ntlmssp_negotiate_flags_100 = -1;
139 static int hf_ntlmssp_negotiate_flags_200 = -1;
140 static int hf_ntlmssp_negotiate_flags_400 = -1;
141 static int hf_ntlmssp_negotiate_flags_800 = -1;
142 static int hf_ntlmssp_negotiate_flags_1000 = -1;
143 static int hf_ntlmssp_negotiate_flags_2000 = -1;
144 static int hf_ntlmssp_negotiate_flags_4000 = -1;
145 static int hf_ntlmssp_negotiate_flags_8000 = -1;
146 static int hf_ntlmssp_negotiate_flags_10000 = -1;
147 static int hf_ntlmssp_negotiate_flags_20000 = -1;
148 static int hf_ntlmssp_negotiate_flags_40000 = -1;
149 static int hf_ntlmssp_negotiate_flags_80000 = -1;
150 static int hf_ntlmssp_negotiate_flags_100000 = -1;
151 static int hf_ntlmssp_negotiate_flags_200000 = -1;
152 static int hf_ntlmssp_negotiate_flags_400000 = -1;
153 static int hf_ntlmssp_negotiate_flags_800000 = -1;
154 static int hf_ntlmssp_negotiate_flags_1000000 = -1;
155 static int hf_ntlmssp_negotiate_flags_2000000 = -1;
156 static int hf_ntlmssp_negotiate_flags_4000000 = -1;
157 static int hf_ntlmssp_negotiate_flags_8000000 = -1;
158 static int hf_ntlmssp_negotiate_flags_10000000 = -1;
159 static int hf_ntlmssp_negotiate_flags_20000000 = -1;
160 static int hf_ntlmssp_negotiate_flags_40000000 = -1;
161 static int hf_ntlmssp_negotiate_flags_80000000 = -1;
162 static int hf_ntlmssp_negotiate_workstation_strlen = -1;
163 static int hf_ntlmssp_negotiate_workstation_maxlen = -1;
164 static int hf_ntlmssp_negotiate_workstation_buffer = -1;
165 static int hf_ntlmssp_negotiate_workstation = -1;
166 static int hf_ntlmssp_negotiate_domain_strlen = -1;
167 static int hf_ntlmssp_negotiate_domain_maxlen = -1;
168 static int hf_ntlmssp_negotiate_domain_buffer = -1;
169 static int hf_ntlmssp_negotiate_domain = -1;
170 static int hf_ntlmssp_ntlm_challenge = -1;
171 static int hf_ntlmssp_reserved = -1;
172 static int hf_ntlmssp_challenge_domain = -1;
173 static int hf_ntlmssp_auth_username = -1;
174 static int hf_ntlmssp_auth_domain = -1;
175 static int hf_ntlmssp_auth_hostname = -1;
176 static int hf_ntlmssp_auth_lmresponse = -1;
177 static int hf_ntlmssp_auth_ntresponse = -1;
178 static int hf_ntlmssp_auth_sesskey = -1;
179 static int hf_ntlmssp_string_len = -1;
180 static int hf_ntlmssp_string_maxlen = -1;
181 static int hf_ntlmssp_string_offset = -1;
182 static int hf_ntlmssp_blob_len = -1;
183 static int hf_ntlmssp_blob_maxlen = -1;
184 static int hf_ntlmssp_blob_offset = -1;
185 static int hf_ntlmssp_address_list = -1;
186 static int hf_ntlmssp_address_list_len = -1;
187 static int hf_ntlmssp_address_list_maxlen = -1;
188 static int hf_ntlmssp_address_list_offset = -1;
189 static int hf_ntlmssp_address_list_server_nb = -1;
190 static int hf_ntlmssp_address_list_domain_nb = -1;
191 static int hf_ntlmssp_address_list_server_dns = -1;
192 static int hf_ntlmssp_address_list_domain_dns = -1;
193 static int hf_ntlmssp_address_list_terminator = -1;
194 static int hf_ntlmssp_address_list_item_type = -1;
195 static int hf_ntlmssp_address_list_item_len = -1;
196 static int hf_ntlmssp_address_list_item_content = -1;
197 static int hf_ntlmssp_verf = -1;
198 static int hf_ntlmssp_verf_vers = -1;
199 static int hf_ntlmssp_verf_body = -1;
200 static int hf_ntlmssp_verf_unknown1 = -1;
201 static int hf_ntlmssp_verf_crc32 = -1;
202 static int hf_ntlmssp_verf_sequence = -1;
203 static int hf_ntlmssp_decrypted_payload = -1;
204 static int hf_ntlmssp_ntlmv2_response = -1;
205 static int hf_ntlmssp_ntlmv2_response_hmac = -1;
206 static int hf_ntlmssp_ntlmv2_response_header = -1;
207 static int hf_ntlmssp_ntlmv2_response_reserved = -1;
208 static int hf_ntlmssp_ntlmv2_response_time = -1;
209 static int hf_ntlmssp_ntlmv2_response_chal = -1;
210 static int hf_ntlmssp_ntlmv2_response_unknown = -1;
211 static int hf_ntlmssp_ntlmv2_response_name = -1;
212 static int hf_ntlmssp_ntlmv2_response_name_type = -1;
213 static int hf_ntlmssp_ntlmv2_response_name_len = -1;
214 static int hf_ntlmssp_ntlmv2_response_client_time = -1;
216 static gint ett_ntlmssp = -1;
217 static gint ett_ntlmssp_negotiate_flags = -1;
218 static gint ett_ntlmssp_string = -1;
219 static gint ett_ntlmssp_blob = -1;
220 static gint ett_ntlmssp_address_list = -1;
221 static gint ett_ntlmssp_address_list_item = -1;
222 static gint ett_ntlmssp_ntlmv2_response = -1;
223 static gint ett_ntlmssp_ntlmv2_response_name = -1;
225 /* Configuration variables */
226 static const char *nt_password = NULL;
228 #define MAX_BLOB_SIZE 256
229 typedef struct _ntlmssp_blob {
231 guint8 contents[MAX_BLOB_SIZE];
234 /* Used in the conversation function */
235 typedef struct _ntlmssp_info {
237 rc4_state_struct rc4_state_peer1;
238 rc4_state_struct rc4_state_peer2;
239 guint32 peer1_dest_port;
240 int rc4_state_initialized;
241 ntlmssp_blob ntlm_response;
242 ntlmssp_blob lm_response;
245 /* If this struct exists in the payload_decrypt, then we have already
247 typedef struct _ntlmssp_packet_info {
249 guint8 *decrypted_payload;
251 gboolean payload_decrypted;
252 gboolean verifier_decrypted;
253 } ntlmssp_packet_info;
257 * GSlist of decrypted payloads.
259 static GSList *decrypted_payloads;
262 Generate a challenge response, given an eight byte challenge and
263 either the NT or the Lan Manager password hash (16 bytes).
264 Returns output in response, which is expected to be 24 bytes.
266 static int ntlmssp_generate_challenge_response(guint8 *response,
267 const guint8 *passhash,
268 const guint8 *challenge)
270 guint8 pw21[21]; /* Password hash padded to 21 bytes */
272 memset(pw21, 0x0, sizeof(pw21));
273 memcpy(pw21, passhash, 16);
275 memset(response, 0, 24);
277 crypt_des_ecb(response, challenge, pw21, 1);
278 crypt_des_ecb(response + 8, challenge, pw21 + 7, 1);
279 crypt_des_ecb(response + 16, challenge, pw21 + 14, 1);
284 /* Create an NTLMSSP version 1 key.
285 * password points to the ANSI password to encrypt, challenge points to
286 * the 8 octet challenge string, key128 will do a 128 bit key if set to 1,
287 * otherwise it will do a 40 bit key. The result is stored in
288 * sspkey (expected to be 16 octets)
291 create_ntlmssp_v1_key(const char *nt_password, const guint8 *challenge,
292 int use_key_128, guint8 *sspkey)
294 unsigned char lm_password_upper[16];
295 unsigned char lm_password_hash[16];
296 guint8 lm_challenge_response[24];
298 guint8 pw21[21]; /* Password hash padded to 21 bytes */
301 unsigned char lmhash_key[] =
302 {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
304 memset(lm_password_upper, 0, sizeof(lm_password_upper));
306 /* Create a Lan Manager hash of the input password */
307 if (nt_password[0] != '\0') {
308 password_len = strlen(nt_password);
309 /* Truncate password if too long */
310 if (password_len > 16)
312 for (i = 0; i < password_len; i++) {
313 lm_password_upper[i] = toupper(nt_password[i]);
317 crypt_des_ecb(lm_password_hash, lmhash_key, lm_password_upper, 1);
318 crypt_des_ecb(lm_password_hash+8, lmhash_key, lm_password_upper+7, 1);
320 /* Generate the LanMan Challenge Response */
321 ntlmssp_generate_challenge_response(lm_challenge_response,
322 lm_password_hash, challenge);
324 /* Generate the NTLMSSP-v1 RC4 Key.
325 * The RC4 key is derived from the Lan Manager Hash.
326 * See lkcl "DCE/RPC over SMB" page 254 for the algorithm.
328 memset(pw21, 0xBD, sizeof(pw21));
329 memcpy(pw21, lm_password_hash, sizeof(lm_password_hash));
331 /* Only the first eight bytes of challenge_response is used */
332 crypt_des_ecb(rc4key, lm_challenge_response, pw21, 1);
333 crypt_des_ecb(rc4key + 8, lm_challenge_response, pw21 + 7, 1);
334 crypt_des_ecb(rc4key + 16, lm_challenge_response, pw21 + 14, 1);
336 /* Create the SSP Key */
337 memset(sspkey, 0, sizeof(sspkey));
339 /* Create 128 bit key */
340 memcpy(sspkey, rc4key, 16);
343 /* Create 40 bit key */
344 memcpy(sspkey, rc4key, 5);
352 /* dissect a string - header area contains:
355 four byte offset of string in data area
356 The function returns the offset at the end of the string header,
357 but the 'end' parameter returns the offset of the end of the string itself
358 The 'start' parameter returns the offset of the beginning of the string
361 dissect_ntlmssp_string (tvbuff_t *tvb, int offset,
362 proto_tree *ntlmssp_tree,
363 gboolean unicode_strings,
364 int string_hf, int *start, int *end,
365 const char **stringp)
367 proto_tree *tree = NULL;
368 proto_item *tf = NULL;
369 gint16 string_length = tvb_get_letohs(tvb, offset);
370 gint16 string_maxlen = tvb_get_letohs(tvb, offset+2);
371 gint32 string_offset = tvb_get_letohl(tvb, offset+4);
372 const char *string_text = NULL;
376 *start = (string_offset > offset+8 ? string_offset : offset+8);
377 if (0 == string_length) {
380 proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
387 bc = result_length = string_length;
388 string_text = get_unicode_or_ascii_string(tvb, &string_offset,
389 unicode_strings, &result_length,
392 *stringp = string_text;
395 tf = proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
396 string_offset, result_length, string_text);
397 tree = proto_item_add_subtree(tf, ett_ntlmssp_string);
399 proto_tree_add_uint(tree, hf_ntlmssp_string_len,
400 tvb, offset, 2, string_length);
402 proto_tree_add_uint(tree, hf_ntlmssp_string_maxlen,
403 tvb, offset, 2, string_maxlen);
405 proto_tree_add_uint(tree, hf_ntlmssp_string_offset,
406 tvb, offset, 4, string_offset);
409 *end = string_offset + string_length;
413 /* dissect a generic blob - header area contains:
416 four byte offset of blob in data area
417 The function returns the offset at the end of the blob header,
418 but the 'end' parameter returns the offset of the end of the blob itself
421 dissect_ntlmssp_blob (tvbuff_t *tvb, int offset,
422 proto_tree *ntlmssp_tree,
423 int blob_hf, int *end, ntlmssp_blob *result)
425 proto_item *tf = NULL;
426 proto_tree *tree = NULL;
427 guint16 blob_length = tvb_get_letohs(tvb, offset);
428 guint16 blob_maxlen = tvb_get_letohs(tvb, offset+2);
429 guint32 blob_offset = tvb_get_letohl(tvb, offset+4);
431 if (0 == blob_length) {
432 *end = (blob_offset > ((guint)offset)+8 ? blob_offset : ((guint)offset)+8);
434 proto_tree_add_text(ntlmssp_tree, tvb, offset, 8, "%s: Empty",
435 proto_registrar_get_name(blob_hf));
440 tf = proto_tree_add_item (ntlmssp_tree, blob_hf, tvb,
441 blob_offset, blob_length, FALSE);
442 tree = proto_item_add_subtree(tf, ett_ntlmssp_blob);
444 proto_tree_add_uint(tree, hf_ntlmssp_blob_len,
445 tvb, offset, 2, blob_length);
447 proto_tree_add_uint(tree, hf_ntlmssp_blob_maxlen,
448 tvb, offset, 2, blob_maxlen);
450 proto_tree_add_uint(tree, hf_ntlmssp_blob_offset,
451 tvb, offset, 4, blob_offset);
454 *end = blob_offset + blob_length;
456 if (result != NULL) {
457 result->length = blob_length;
458 memset(result->contents, 0, MAX_BLOB_SIZE);
459 if (blob_length < MAX_BLOB_SIZE)
460 tvb_memcpy(tvb, result->contents, blob_offset, blob_length);
463 /* If we are dissecting the NTLM response and it is a NTLMv2
464 response call the appropriate dissector. */
466 if (blob_hf == hf_ntlmssp_auth_ntresponse && blob_length > 24)
467 dissect_ntlmv2_response(tvb, tree, blob_offset, blob_length);
473 dissect_ntlmssp_negotiate_flags (tvbuff_t *tvb, int offset,
474 proto_tree *ntlmssp_tree,
475 guint32 negotiate_flags)
477 proto_tree *negotiate_flags_tree = NULL;
478 proto_item *tf = NULL;
481 tf = proto_tree_add_uint (ntlmssp_tree,
482 hf_ntlmssp_negotiate_flags,
483 tvb, offset, 4, negotiate_flags);
484 negotiate_flags_tree = proto_item_add_subtree (tf, ett_ntlmssp_negotiate_flags);
487 proto_tree_add_boolean (negotiate_flags_tree,
488 hf_ntlmssp_negotiate_flags_80000000,
489 tvb, offset, 4, negotiate_flags);
490 proto_tree_add_boolean (negotiate_flags_tree,
491 hf_ntlmssp_negotiate_flags_40000000,
492 tvb, offset, 4, negotiate_flags);
493 proto_tree_add_boolean (negotiate_flags_tree,
494 hf_ntlmssp_negotiate_flags_20000000,
495 tvb, offset, 4, negotiate_flags);
496 proto_tree_add_boolean (negotiate_flags_tree,
497 hf_ntlmssp_negotiate_flags_10000000,
498 tvb, offset, 4, negotiate_flags);
499 proto_tree_add_boolean (negotiate_flags_tree,
500 hf_ntlmssp_negotiate_flags_8000000,
501 tvb, offset, 4, negotiate_flags);
502 proto_tree_add_boolean (negotiate_flags_tree,
503 hf_ntlmssp_negotiate_flags_4000000,
504 tvb, offset, 4, negotiate_flags);
505 proto_tree_add_boolean (negotiate_flags_tree,
506 hf_ntlmssp_negotiate_flags_2000000,
507 tvb, offset, 4, negotiate_flags);
508 proto_tree_add_boolean (negotiate_flags_tree,
509 hf_ntlmssp_negotiate_flags_1000000,
510 tvb, offset, 4, negotiate_flags);
511 proto_tree_add_boolean (negotiate_flags_tree,
512 hf_ntlmssp_negotiate_flags_800000,
513 tvb, offset, 4, negotiate_flags);
514 proto_tree_add_boolean (negotiate_flags_tree,
515 hf_ntlmssp_negotiate_flags_400000,
516 tvb, offset, 4, negotiate_flags);
517 proto_tree_add_boolean (negotiate_flags_tree,
518 hf_ntlmssp_negotiate_flags_200000,
519 tvb, offset, 4, negotiate_flags);
520 proto_tree_add_boolean (negotiate_flags_tree,
521 hf_ntlmssp_negotiate_flags_100000,
522 tvb, offset, 4, negotiate_flags);
523 proto_tree_add_boolean (negotiate_flags_tree,
524 hf_ntlmssp_negotiate_flags_80000,
525 tvb, offset, 4, negotiate_flags);
526 proto_tree_add_boolean (negotiate_flags_tree,
527 hf_ntlmssp_negotiate_flags_40000,
528 tvb, offset, 4, negotiate_flags);
529 proto_tree_add_boolean (negotiate_flags_tree,
530 hf_ntlmssp_negotiate_flags_20000,
531 tvb, offset, 4, negotiate_flags);
532 proto_tree_add_boolean (negotiate_flags_tree,
533 hf_ntlmssp_negotiate_flags_10000,
534 tvb, offset, 4, negotiate_flags);
535 proto_tree_add_boolean (negotiate_flags_tree,
536 hf_ntlmssp_negotiate_flags_8000,
537 tvb, offset, 4, negotiate_flags);
538 proto_tree_add_boolean (negotiate_flags_tree,
539 hf_ntlmssp_negotiate_flags_4000,
540 tvb, offset, 4, negotiate_flags);
541 proto_tree_add_boolean (negotiate_flags_tree,
542 hf_ntlmssp_negotiate_flags_2000,
543 tvb, offset, 4, negotiate_flags);
544 proto_tree_add_boolean (negotiate_flags_tree,
545 hf_ntlmssp_negotiate_flags_1000,
546 tvb, offset, 4, negotiate_flags);
547 proto_tree_add_boolean (negotiate_flags_tree,
548 hf_ntlmssp_negotiate_flags_800,
549 tvb, offset, 4, negotiate_flags);
550 proto_tree_add_boolean (negotiate_flags_tree,
551 hf_ntlmssp_negotiate_flags_400,
552 tvb, offset, 4, negotiate_flags);
553 proto_tree_add_boolean (negotiate_flags_tree,
554 hf_ntlmssp_negotiate_flags_200,
555 tvb, offset, 4, negotiate_flags);
556 proto_tree_add_boolean (negotiate_flags_tree,
557 hf_ntlmssp_negotiate_flags_100,
558 tvb, offset, 4, negotiate_flags);
559 proto_tree_add_boolean (negotiate_flags_tree,
560 hf_ntlmssp_negotiate_flags_80,
561 tvb, offset, 4, negotiate_flags);
562 proto_tree_add_boolean (negotiate_flags_tree,
563 hf_ntlmssp_negotiate_flags_40,
564 tvb, offset, 4, negotiate_flags);
565 proto_tree_add_boolean (negotiate_flags_tree,
566 hf_ntlmssp_negotiate_flags_20,
567 tvb, offset, 4, negotiate_flags);
568 proto_tree_add_boolean (negotiate_flags_tree,
569 hf_ntlmssp_negotiate_flags_10,
570 tvb, offset, 4, negotiate_flags);
571 proto_tree_add_boolean (negotiate_flags_tree,
572 hf_ntlmssp_negotiate_flags_08,
573 tvb, offset, 4, negotiate_flags);
574 proto_tree_add_boolean (negotiate_flags_tree,
575 hf_ntlmssp_negotiate_flags_04,
576 tvb, offset, 4, negotiate_flags);
577 proto_tree_add_boolean (negotiate_flags_tree,
578 hf_ntlmssp_negotiate_flags_02,
579 tvb, offset, 4, negotiate_flags);
580 proto_tree_add_boolean (negotiate_flags_tree,
581 hf_ntlmssp_negotiate_flags_01,
582 tvb, offset, 4, negotiate_flags);
587 /* Dissect a NTLM response. This is documented at
588 http://ubiqx.org/cifs/SMB.html#SMB.8, para 2.8.5.3 */
593 * XXX - the davenport document says that a type of 5 has been seen,
594 * "apparently containing the 'parent' DNS domain for servers in
598 #define NTLM_NAME_END 0x0000
599 #define NTLM_NAME_NB_HOST 0x0001
600 #define NTLM_NAME_NB_DOMAIN 0x0002
601 #define NTLM_NAME_DNS_HOST 0x0003
602 #define NTLM_NAME_DNS_DOMAIN 0x0004
603 #define NTLM_NAME_CLIENT_TIME 0x0007
605 static const value_string ntlm_name_types[] = {
606 { NTLM_NAME_END, "End of list" },
607 { NTLM_NAME_NB_HOST, "NetBIOS host name" },
608 { NTLM_NAME_NB_DOMAIN, "NetBIOS domain name" },
609 { NTLM_NAME_DNS_HOST, "DNS host name" },
610 { NTLM_NAME_DNS_DOMAIN, "DNS domain name" },
611 { NTLM_NAME_CLIENT_TIME, "Client Time" },
616 dissect_ntlmv2_response(tvbuff_t *tvb, proto_tree *tree, int offset, int len)
618 proto_item *ntlmv2_item = NULL;
619 proto_tree *ntlmv2_tree = NULL;
621 /* Dissect NTLMv2 bits&pieces */
624 ntlmv2_item = proto_tree_add_item(
625 tree, hf_ntlmssp_ntlmv2_response, tvb,
627 ntlmv2_tree = proto_item_add_subtree(
628 ntlmv2_item, ett_ntlmssp_ntlmv2_response);
632 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_hmac, tvb,
638 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_header, tvb,
644 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_reserved, tvb,
649 offset = dissect_nt_64bit_time(
650 tvb, ntlmv2_tree, offset, hf_ntlmssp_ntlmv2_response_time);
653 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_chal, tvb,
659 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_unknown, tvb,
664 /* Variable length list of names */
667 guint16 name_type = tvb_get_letohs(tvb, offset);
668 guint16 name_len = tvb_get_letohs(tvb, offset + 2);
669 proto_tree *name_tree = NULL;
670 proto_item *name_item = NULL;
674 name_item = proto_tree_add_item(
675 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_name,
676 tvb, offset, 0, TRUE);
677 name_tree = proto_item_add_subtree(
678 name_item, ett_ntlmssp_ntlmv2_response_name);
681 /* Dissect name header */
684 name_tree, hf_ntlmssp_ntlmv2_response_name_type, tvb,
690 name_tree, hf_ntlmssp_ntlmv2_response_name_len, tvb,
700 proto_item_append_text(
702 val_to_str(name_type, ntlm_name_types,
705 case NTLM_NAME_CLIENT_TIME:
706 dissect_nt_64bit_time(
707 tvb, name_tree, offset,
708 hf_ntlmssp_ntlmv2_response_client_time);
709 proto_item_append_text(
710 name_item, "Client Time");
712 case NTLM_NAME_NB_HOST:
713 case NTLM_NAME_NB_DOMAIN:
714 case NTLM_NAME_DNS_HOST:
715 case NTLM_NAME_DNS_DOMAIN:
717 name = tvb_get_ephemeral_faked_unicode(
718 tvb, offset, name_len / 2, TRUE);
721 name_tree, tvb, offset, name_len,
723 proto_item_append_text(
725 val_to_str(name_type, ntlm_name_types,
733 proto_item_set_len(name_item, name_len + 4);
735 if (name_type == 0) /* End of list */
740 * XXX - Windows puts 4 bytes of additional stuff here.
741 * Samba's smbclient doesn't.
742 * Both of them appear to be able to connect to W2K SMB
744 * Should we display the rest of the response as an
747 * XXX - we should also check whether we go past the length
753 /* tapping into ntlmssph not yet implemented */
755 dissect_ntlmssp_negotiate (tvbuff_t *tvb, int offset, proto_tree *ntlmssp_tree, ntlmssp_header_t *ntlmssph _U_)
757 guint32 negotiate_flags;
762 /* NTLMSSP Negotiate Flags */
763 negotiate_flags = tvb_get_letohl (tvb, offset);
764 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
768 * XXX - the davenport document says that these might not be
769 * sent at all, presumably meaning the length of the message
770 * isn't enough to contain them.
772 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
773 hf_ntlmssp_negotiate_domain,
774 &start, &workstation_end, NULL);
775 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
776 hf_ntlmssp_negotiate_workstation,
777 &start, &domain_end, NULL);
779 /* XXX - two blobs after this one, sometimes? */
781 return MAX(workstation_end, domain_end);
786 dissect_ntlmssp_address_list (tvbuff_t *tvb, int offset,
787 proto_tree *ntlmssp_tree,
790 guint16 list_length = tvb_get_letohs(tvb, offset);
791 guint16 list_maxlen = tvb_get_letohs(tvb, offset+2);
792 guint32 list_offset = tvb_get_letohl(tvb, offset+4);
793 guint16 item_type, item_length;
795 proto_item *tf = NULL;
796 proto_tree *tree = NULL;
797 proto_item *addr_tf = NULL;
798 proto_tree *addr_tree = NULL;
800 /* the address list is just a blob */
801 if (0 == list_length) {
802 *end = (list_offset > ((guint)offset)+8 ? list_offset : ((guint)offset)+8);
804 proto_tree_add_text(ntlmssp_tree, tvb, offset, 8,
805 "Address List: Empty");
810 tf = proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_address_list, tvb,
811 list_offset, list_length, FALSE);
812 tree = proto_item_add_subtree(tf, ett_ntlmssp_address_list);
814 proto_tree_add_uint(tree, hf_ntlmssp_address_list_len,
815 tvb, offset, 2, list_length);
817 proto_tree_add_uint(tree, hf_ntlmssp_address_list_maxlen,
818 tvb, offset, 2, list_maxlen);
820 proto_tree_add_uint(tree, hf_ntlmssp_address_list_offset,
821 tvb, offset, 4, list_offset);
824 /* Now enumerate through the individual items in the list */
825 item_offset = list_offset;
827 while (item_offset < (list_offset + list_length)) {
828 const char *text=NULL;
829 guint32 content_offset;
830 guint16 content_length;
835 type_offset = item_offset;
836 item_type = tvb_get_letohs(tvb, type_offset);
839 len_offset = type_offset + 2;
840 content_length = tvb_get_letohs(tvb, len_offset);
843 content_offset = len_offset + 2;
844 item_length = content_length + 4;
846 /* Strings are always in Unicode regardless of the negotiated
848 if (content_length > 0) {
853 item_offset_int = content_offset;
855 text = get_unicode_or_ascii_string(tvb, &item_offset_int,
856 TRUE, &result_length,
860 if (!text) text = ""; /* Make sure we don't blow up below */
863 case NTLM_NAME_NB_HOST:
864 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_server_nb,
865 tvb, item_offset, item_length, text);
867 case NTLM_NAME_NB_DOMAIN:
868 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_domain_nb,
869 tvb, item_offset, item_length, text);
871 case NTLM_NAME_DNS_HOST:
872 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_server_dns,
873 tvb, item_offset, item_length, text);
875 case NTLM_NAME_DNS_DOMAIN:
876 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_domain_dns,
877 tvb, item_offset, item_length, text);
880 addr_tf = proto_tree_add_item(tree, hf_ntlmssp_address_list_terminator,
881 tvb, item_offset, item_length, TRUE);
884 addr_tf = proto_tree_add_text(tree, tvb, item_offset, item_length, "Unknown type:0x%04x", item_type);
887 /* Now show the actual bytes that made up the summary line */
888 addr_tree = proto_item_add_subtree (addr_tf,
889 ett_ntlmssp_address_list_item);
890 proto_tree_add_item (addr_tree, hf_ntlmssp_address_list_item_type,
891 tvb, type_offset, 2, TRUE);
892 proto_tree_add_item (addr_tree, hf_ntlmssp_address_list_item_len,
893 tvb, len_offset, 2, TRUE);
894 if (content_length > 0) {
895 proto_tree_add_string(addr_tree, hf_ntlmssp_address_list_item_content,
896 tvb, content_offset, content_length, text);
899 item_offset += item_length;
902 *end = list_offset + list_length;
906 /* tapping into ntlmssph not yet implemented */
908 dissect_ntlmssp_challenge (tvbuff_t *tvb, packet_info *pinfo, int offset,
909 proto_tree *ntlmssp_tree, ntlmssp_header_t *ntlmssph _U_)
911 guint32 negotiate_flags;
912 int item_start, item_end;
913 int data_start, data_end;
914 ntlmssp_info *conv_ntlmssp_info;
915 conversation_t *conversation;
916 gboolean unicode_strings = FALSE;
918 guint8 sspkey[16]; /* NTLMSSP cipher key */
919 guint8 ssp_key_len; /* Either 8 or 16 (40 bit or 128) */
921 /* need to find unicode flag */
922 negotiate_flags = tvb_get_letohl (tvb, offset+8);
923 if (negotiate_flags & NTLMSSP_NEGOTIATE_UNICODE)
924 unicode_strings = TRUE;
928 * XXX - the davenport document calls this the "Target Name",
929 * presumably because non-domain targets are supported.
931 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, unicode_strings,
932 hf_ntlmssp_challenge_domain,
933 &item_start, &item_end, NULL);
934 data_start = item_start;
937 /* NTLMSSP Negotiate Flags */
938 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
941 /* NTLMSSP NT Lan Manager Challenge */
942 proto_tree_add_item (ntlmssp_tree,
943 hf_ntlmssp_ntlm_challenge,
944 tvb, offset, 8, FALSE);
947 * Store the flags and the RC4 state information with the conversation,
948 * as they're needed in order to dissect subsequent messages.
950 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
951 pinfo->ptype, pinfo->srcport,
953 if (!conversation) { /* Create one */
954 conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype,
955 pinfo->srcport, pinfo->destport, 0);
958 if (!conversation_get_proto_data(conversation, proto_ntlmssp)) {
959 conv_ntlmssp_info = se_alloc(sizeof(ntlmssp_info));
960 /* Insert the flags into the conversation */
961 conv_ntlmssp_info->flags = negotiate_flags;
962 /* Insert the RC4 state information into the conversation */
963 tvb_memcpy(tvb, challenge, offset, 8);
965 /* Between the challenge and the user provided password, we can build the
966 NTLMSSP key and initialize the cipher */
967 if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_128) {
968 create_ntlmssp_v1_key(nt_password, challenge, 1, sspkey);
972 create_ntlmssp_v1_key(nt_password, challenge, 0, sspkey);
975 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_peer1, sspkey, ssp_key_len);
976 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_peer2, sspkey, ssp_key_len);
977 conv_ntlmssp_info->peer1_dest_port = pinfo->destport;
978 conv_ntlmssp_info->rc4_state_initialized = 1;
980 conversation_add_proto_data(conversation, proto_ntlmssp, conv_ntlmssp_info);
984 /* Reserved (function not completely known) */
986 * XXX - SSP key? The davenport document says
988 * The context field is typically populated when Negotiate Local
989 * Call is set. It contains an SSPI context handle, which allows
990 * the client to "short-circuit" authentication and effectively
991 * circumvent responding to the challenge. Physically, the context
992 * is two long values. This is covered in greater detail later,
993 * in the "Local Authentication" section.
995 * It also says that that information may be omitted.
997 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_reserved,
998 tvb, offset, 8, FALSE);
1002 * The presence or absence of this field is not obviously correlated
1003 * with any flags in the previous NEGOTIATE message or in this
1004 * message (other than the "Workstation Supplied" and "Domain
1005 * Supplied" flags in the NEGOTIATE message, at least in the capture
1006 * I've seen - but those also correlate with the presence of workstation
1007 * and domain name fields, so it doesn't seem to make sense that they
1008 * actually *indicate* whether the subsequent CHALLENGE has an
1011 if (offset < data_start) {
1012 offset = dissect_ntlmssp_address_list(tvb, offset, ntlmssp_tree, &item_end);
1013 data_end = MAX(data_end, item_end);
1016 return MAX(offset, data_end);
1020 dissect_ntlmssp_auth (tvbuff_t *tvb, packet_info *pinfo, int offset,
1021 proto_tree *ntlmssp_tree, ntlmssp_header_t *ntlmssph)
1023 int item_start, item_end;
1024 int data_start, data_end = 0;
1025 guint32 negotiate_flags;
1026 gboolean unicode_strings = FALSE;
1027 ntlmssp_info *conv_ntlmssp_info;
1028 conversation_t *conversation;
1031 * Get flag info from the original negotiate message, if any.
1032 * This is because the flag information is sometimes missing from
1033 * the AUTHENTICATE message, so we can't figure out whether
1034 * strings are Unicode or not by looking at *our* flags.
1036 conv_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1037 if (conv_ntlmssp_info == NULL) {
1039 * There isn't any. Is there any from this conversation? If so,
1040 * it means this is the first time we've dissected this frame, so
1041 * we should give it flag info.
1043 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1044 pinfo->ptype, pinfo->srcport,
1045 pinfo->destport, 0);
1046 if (conversation != NULL) {
1047 conv_ntlmssp_info = conversation_get_proto_data(conversation, proto_ntlmssp);
1048 if (conv_ntlmssp_info != NULL) {
1050 * We have flag info; attach it to the frame.
1052 p_add_proto_data(pinfo->fd, proto_ntlmssp, conv_ntlmssp_info);
1056 if (conv_ntlmssp_info != NULL) {
1057 if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_UNICODE)
1058 unicode_strings = TRUE;
1062 * Sometimes the session key and flags are missing.
1063 * Sometimes the session key is present but the flags are missing.
1064 * Sometimes they're both present.
1066 * This does not correlate with any flags in the previous CHALLENGE
1067 * message, and only correlates with "Negotiate Unicode", "Workstation
1068 * Supplied", and "Domain Supplied" in the NEGOTIATE message - but
1069 * those don't make sense as flags to use to determine this.
1071 * So we check all of the descriptors to figure out where the data
1072 * area begins, and if the session key or the flags would be in the
1073 * middle of the data area, we assume the field in question is
1077 /* Lan Manager response */
1078 data_start = tvb_get_letohl(tvb, offset+4);
1079 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
1080 hf_ntlmssp_auth_lmresponse,
1082 conv_ntlmssp_info == NULL ? NULL :
1083 &conv_ntlmssp_info->lm_response);
1084 data_end = MAX(data_end, item_end);
1087 item_start = tvb_get_letohl(tvb, offset+4);
1088 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
1089 hf_ntlmssp_auth_ntresponse,
1091 conv_ntlmssp_info == NULL ? NULL :
1092 &conv_ntlmssp_info->ntlm_response);
1093 data_start = MIN(data_start, item_start);
1094 data_end = MAX(data_end, item_end);
1097 item_start = tvb_get_letohl(tvb, offset+4);
1098 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
1100 hf_ntlmssp_auth_domain,
1101 &item_start, &item_end, &(ntlmssph->domain_name));
1102 data_start = MIN(data_start, item_start);
1103 data_end = MAX(data_end, item_end);
1106 item_start = tvb_get_letohl(tvb, offset+4);
1107 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
1109 hf_ntlmssp_auth_username,
1110 &item_start, &item_end, &(ntlmssph->acct_name));
1111 data_start = MIN(data_start, item_start);
1112 data_end = MAX(data_end, item_end);
1114 if (check_col(pinfo->cinfo, COL_INFO))
1115 col_append_fstr(pinfo->cinfo, COL_INFO, ", User: %s\\%s",
1116 ntlmssph->domain_name, ntlmssph->acct_name);
1119 item_start = tvb_get_letohl(tvb, offset+4);
1120 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
1122 hf_ntlmssp_auth_hostname,
1123 &item_start, &item_end, &(ntlmssph->host_name));
1124 data_start = MIN(data_start, item_start);
1125 data_end = MAX(data_end, item_end);
1127 if (offset < data_start) {
1129 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
1130 hf_ntlmssp_auth_sesskey,
1132 data_end = MAX(data_end, item_end);
1135 if (offset < data_start) {
1136 /* NTLMSSP Negotiate Flags */
1137 negotiate_flags = tvb_get_letohl (tvb, offset);
1138 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
1142 return MAX(offset, data_end);
1146 dissect_ntlmssp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1148 volatile int offset = 0;
1149 proto_tree *volatile ntlmssp_tree = NULL;
1150 proto_item *tf = NULL;
1151 ntlmssp_header_t *ntlmssph;
1153 ntlmssph=ep_alloc(sizeof(ntlmssp_header_t));
1155 ntlmssph->domain_name=NULL;
1156 ntlmssph->acct_name=NULL;
1157 ntlmssph->host_name=NULL;
1159 /* Setup a new tree for the NTLMSSP payload */
1161 tf = proto_tree_add_item (tree,
1163 tvb, offset, -1, FALSE);
1165 ntlmssp_tree = proto_item_add_subtree (tf,
1170 * Catch the ReportedBoundsError exception; the stuff we've been
1171 * handed doesn't necessarily run to the end of the packet, it's
1172 * an item inside a packet, so if it happens to be malformed (or
1173 * we, or a dissector we call, has a bug), so that an exception
1174 * is thrown, we want to report the error, but return and let
1175 * our caller dissect the rest of the packet.
1177 * If it gets a BoundsError, we can stop, as there's nothing more
1178 * in the packet after our blob to see, so we just re-throw the
1182 /* NTLMSSP constant */
1183 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth,
1184 tvb, offset, 8, FALSE);
1187 /* NTLMSSP Message Type */
1188 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_message_type,
1189 tvb, offset, 4, TRUE);
1190 ntlmssph->type = tvb_get_letohl (tvb, offset);
1193 if (check_col(pinfo->cinfo, COL_INFO))
1194 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
1195 val_to_str(ntlmssph->type,
1196 ntlmssp_message_types,
1197 "Unknown message type"));
1199 /* Call the appropriate dissector based on the Message Type */
1200 switch (ntlmssph->type) {
1202 case NTLMSSP_NEGOTIATE:
1203 offset = dissect_ntlmssp_negotiate (tvb, offset, ntlmssp_tree, ntlmssph);
1206 case NTLMSSP_CHALLENGE:
1207 offset = dissect_ntlmssp_challenge (tvb, pinfo, offset, ntlmssp_tree, ntlmssph);
1211 offset = dissect_ntlmssp_auth (tvb, pinfo, offset, ntlmssp_tree, ntlmssph);
1215 /* Unrecognized message type */
1216 proto_tree_add_text (ntlmssp_tree, tvb, offset, -1,
1217 "Unrecognized NTLMSSP Message");
1220 } CATCH(BoundsError) {
1222 } CATCH(ReportedBoundsError) {
1223 show_reported_bounds_error(tvb, pinfo, tree);
1226 tap_queue_packet(ntlmssp_tap, pinfo, ntlmssph);
1230 * Get the encryption state tied to this conversation. cryptpeer indicates
1231 * whether to retrieve the data for peer1 or peer2.
1233 static rc4_state_struct *
1234 get_encrypted_state(packet_info *pinfo, int cryptpeer)
1236 conversation_t *conversation;
1237 ntlmssp_info *conv_ntlmssp_info;
1239 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1240 pinfo->ptype, pinfo->srcport,
1241 pinfo->destport, 0);
1242 if (conversation == NULL) {
1243 /* We don't have a conversation. In this case, stop processing
1244 because we do not have enough info to decrypt the payload */
1248 /* We have a conversation, check for encryption state */
1249 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1251 if (conv_ntlmssp_info == NULL) {
1252 /* No encryption state tied to the conversation. Therefore, we
1253 cannot decrypt the payload */
1257 /* We have the encryption state in the conversation. So return the
1258 crypt state tied to the requested peer
1260 if (cryptpeer == 1) {
1261 return &conv_ntlmssp_info->rc4_state_peer1;
1263 return &conv_ntlmssp_info->rc4_state_peer2;
1270 * See page 45 of "DCE/RPC over SMB" by Luke Kenneth Casson Leighton.
1273 decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
1274 packet_info *pinfo, proto_tree *tree)
1276 proto_tree *decr_tree = NULL;
1277 proto_item *tf = NULL;
1278 conversation_t *conversation;
1279 rc4_state_struct *rc4_state;
1280 rc4_state_struct *rc4_state_peer;
1281 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
1283 ntlmssp_info *conv_ntlmssp_info = NULL;
1284 ntlmssp_packet_info *packet_ntlmssp_info = NULL;
1285 int decrypted_offset = 0;
1287 packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1288 if (packet_ntlmssp_info == NULL) {
1289 /* We don't have data for this packet */
1292 if (!packet_ntlmssp_info->verifier_decrypted) {
1293 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1294 pinfo->ptype, pinfo->srcport,
1295 pinfo->destport, 0);
1296 if (conversation == NULL) {
1297 /* There is no conversation, thus no encryption state */
1301 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1303 if (conv_ntlmssp_info == NULL) {
1304 /* There is no NTLMSSP state tied to the conversation */
1307 if (conv_ntlmssp_info->rc4_state_initialized != 1 ) {
1308 /* The crypto sybsystem is not initialized. This means that either
1309 the conversation did not include a challenge, or we are doing
1310 something other than NTLMSSP v1 */
1314 if (conv_ntlmssp_info->peer1_dest_port == pinfo->destport) {
1315 rc4_state = get_encrypted_state(pinfo, 1);
1316 rc4_state_peer = get_encrypted_state(pinfo, 0);
1318 rc4_state = get_encrypted_state(pinfo, 0);
1319 rc4_state_peer = get_encrypted_state(pinfo, 1);
1322 if (rc4_state == NULL || rc4_state_peer == NULL) {
1323 /* There is no encryption state, so we cannot decrypt */
1327 /* Setup the buffer to decrypt to */
1328 tvb_memcpy(tvb, packet_ntlmssp_info->verifier,
1329 offset, encrypted_block_length);
1331 /* Do the actual decryption of the verifier */
1332 crypt_rc4(rc4_state, packet_ntlmssp_info->verifier,
1333 encrypted_block_length);
1335 /* We setup a temporary buffer so we can re-encrypt the payload after
1336 decryption. This is to update the opposite peer's RC4 state */
1337 peer_block = g_malloc(encrypted_block_length);
1338 memcpy(peer_block, packet_ntlmssp_info->verifier,
1339 encrypted_block_length);
1340 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
1343 /* Mark the packet as decrypted so that subsequent attempts to dissect
1344 the packet use the already decrypted payload instead of attempting
1346 packet_ntlmssp_info->verifier_decrypted = TRUE;
1349 /* Show the decrypted buffer in a new window */
1350 decr_tvb = tvb_new_real_data(packet_ntlmssp_info->verifier,
1351 encrypted_block_length,
1352 encrypted_block_length);
1353 tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
1354 add_new_data_source(pinfo, decr_tvb,
1355 "Decrypted NTLMSSP Verifier");
1357 /* Show the decrypted payload in the tree */
1358 tf = proto_tree_add_text(tree, decr_tvb, 0, -1,
1359 "Decrypted Verifier (%d byte%s)",
1360 encrypted_block_length,
1361 plurality(encrypted_block_length, "", "s"));
1362 decr_tree = proto_item_add_subtree (tf, ett_ntlmssp);
1364 /* LKCL page 45 says this is a "reserved" field. I'm not sure if it's
1365 garbage because it's some sort of nonce, or because there is a problem
1366 with the verifier decryption routine. */
1367 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_unknown1,
1368 decr_tvb, decrypted_offset, 4, TRUE);
1369 decrypted_offset += 4;
1371 /* CRC32 of the DCE fragment data */
1372 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_crc32,
1373 decr_tvb, decrypted_offset, 4, TRUE);
1374 decrypted_offset += 4;
1376 /* Incrementing sequence number of DCE conversation */
1377 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_sequence,
1378 decr_tvb, decrypted_offset, 4, TRUE);
1379 decrypted_offset += 4;
1383 dissect_ntlmssp_verf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1385 volatile int offset = 0;
1386 proto_tree *volatile ntlmssp_tree = NULL;
1387 proto_item *tf = NULL;
1388 guint32 verifier_length;
1389 guint32 encrypted_block_length;
1391 verifier_length = tvb_length (tvb);
1392 encrypted_block_length = verifier_length - 4;
1394 if (encrypted_block_length < 12) {
1395 /* Don't know why this would happen, but if it does, don't even bother
1396 attempting decryption/dissection */
1397 return offset + verifier_length;
1400 /* Setup a new tree for the NTLMSSP payload */
1402 tf = proto_tree_add_item (tree,
1404 tvb, offset, -1, FALSE);
1406 ntlmssp_tree = proto_item_add_subtree (tf,
1411 * Catch the ReportedBoundsError exception; the stuff we've been
1412 * handed doesn't necessarily run to the end of the packet, it's
1413 * an item inside a packet, so if it happens to be malformed (or
1414 * we, or a dissector we call, has a bug), so that an exception
1415 * is thrown, we want to report the error, but return and let
1416 * our caller dissect the rest of the packet.
1418 * If it gets a BoundsError, we can stop, as there's nothing more
1419 * in the packet after our blob to see, so we just re-throw the
1423 /* Version number */
1424 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_vers,
1425 tvb, offset, 4, TRUE);
1428 /* Encrypted body */
1429 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_body,
1430 tvb, offset, encrypted_block_length, TRUE);
1432 /* Try to decrypt */
1433 decrypt_verifier (tvb, offset, encrypted_block_length, pinfo, ntlmssp_tree);
1435 offset += encrypted_block_length;
1436 } CATCH(BoundsError) {
1438 } CATCH(ReportedBoundsError) {
1439 show_reported_bounds_error(tvb, pinfo, tree);
1446 dissect_ntlmssp_encrypted_payload(tvbuff_t *data_tvb,
1447 tvbuff_t *auth_tvb _U_,
1450 dcerpc_auth_info *auth_info _U_)
1452 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
1454 conversation_t *conversation;
1455 guint32 encrypted_block_length;
1456 rc4_state_struct *rc4_state;
1457 rc4_state_struct *rc4_state_peer;
1458 ntlmssp_info *conv_ntlmssp_info = NULL;
1459 ntlmssp_packet_info *packet_ntlmssp_info = NULL;
1461 encrypted_block_length = tvb_length_remaining (data_tvb, offset);
1463 /* Check to see if we already have state for this packet */
1464 packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1465 if (packet_ntlmssp_info == NULL) {
1466 /* We don't have any packet state, so create one */
1467 packet_ntlmssp_info = se_alloc(sizeof(ntlmssp_packet_info));
1468 memset(packet_ntlmssp_info, 0, sizeof(ntlmssp_packet_info));
1469 p_add_proto_data(pinfo->fd, proto_ntlmssp, packet_ntlmssp_info);
1472 if (!packet_ntlmssp_info->payload_decrypted) {
1473 /* Pull the challenge info from the conversation */
1474 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1475 pinfo->ptype, pinfo->srcport,
1476 pinfo->destport, 0);
1477 if (conversation == NULL) {
1478 /* There is no conversation, thus no encryption state */
1482 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1484 if (conv_ntlmssp_info == NULL) {
1485 /* There is no NTLMSSP state tied to the conversation */
1489 /* Get the pair of RC4 state structures. One is used for to decrypt the
1490 payload. The other is used to re-encrypt the payload to represent
1492 if (conv_ntlmssp_info->peer1_dest_port == pinfo->destport) {
1493 rc4_state = get_encrypted_state(pinfo, 1);
1494 rc4_state_peer = get_encrypted_state(pinfo, 0);
1496 rc4_state = get_encrypted_state(pinfo, 0);
1497 rc4_state_peer = get_encrypted_state(pinfo, 1);
1500 if (rc4_state == NULL || rc4_state_peer == NULL) {
1501 /* There is no encryption state, so we cannot decrypt */
1505 /* Store the decrypted contents in the packet state struct
1506 (of course at this point, they aren't decrypted yet) */
1507 packet_ntlmssp_info->decrypted_payload = tvb_memdup(data_tvb, offset,
1508 encrypted_block_length);
1509 decrypted_payloads = g_slist_prepend(decrypted_payloads,
1510 packet_ntlmssp_info->decrypted_payload);
1512 /* Do the decryption of the payload */
1513 crypt_rc4(rc4_state, packet_ntlmssp_info->decrypted_payload,
1514 encrypted_block_length);
1516 /* We setup a temporary buffer so we can re-encrypt the payload after
1517 decryption. This is to update the opposite peer's RC4 state */
1518 peer_block = g_malloc(encrypted_block_length);
1519 memcpy(peer_block, packet_ntlmssp_info->decrypted_payload,
1520 encrypted_block_length);
1521 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
1524 packet_ntlmssp_info->payload_decrypted = TRUE;
1527 /* Show the decrypted buffer in a new window */
1528 decr_tvb = tvb_new_real_data(packet_ntlmssp_info->decrypted_payload,
1529 encrypted_block_length,
1530 encrypted_block_length);
1532 tvb_set_child_real_data_tvbuff(data_tvb, decr_tvb);
1534 offset += encrypted_block_length;
1540 free_payload(gpointer decrypted_payload, gpointer user_data _U_)
1542 g_free(decrypted_payload);
1546 ntlmssp_init_protocol(void)
1549 * Free the decrypted payloads, and then free the list of decrypted
1552 if (decrypted_payloads != NULL) {
1553 g_slist_foreach(decrypted_payloads, free_payload, NULL);
1554 g_slist_free(decrypted_payloads);
1555 decrypted_payloads = NULL;
1561 proto_register_ntlmssp(void)
1564 static hf_register_info hf[] = {
1566 { "NTLMSSP", "ntlmssp", FT_NONE, BASE_NONE, NULL, 0x0, "NTLMSSP", HFILL }},
1568 { "NTLMSSP identifier", "ntlmssp.identifier", FT_STRING, BASE_NONE, NULL, 0x0, "NTLMSSP Identifier", HFILL }},
1569 { &hf_ntlmssp_message_type,
1570 { "NTLM Message Type", "ntlmssp.messagetype", FT_UINT32, BASE_HEX, VALS(ntlmssp_message_types), 0x0, "", HFILL }},
1571 { &hf_ntlmssp_negotiate_flags,
1572 { "Flags", "ntlmssp.negotiateflags", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1573 { &hf_ntlmssp_negotiate_flags_01,
1574 { "Negotiate UNICODE", "ntlmssp.negotiateunicode", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_UNICODE, "", HFILL }},
1575 { &hf_ntlmssp_negotiate_flags_02,
1576 { "Negotiate OEM", "ntlmssp.negotiateoem", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_OEM, "", HFILL }},
1577 { &hf_ntlmssp_negotiate_flags_04,
1578 { "Request Target", "ntlmssp.requesttarget", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_REQUEST_TARGET, "", HFILL }},
1579 { &hf_ntlmssp_negotiate_flags_08,
1580 { "Request 0x00000008", "ntlmssp.negotiate00000008", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000008, "", HFILL }},
1581 { &hf_ntlmssp_negotiate_flags_10,
1582 { "Negotiate Sign", "ntlmssp.negotiatesign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SIGN, "", HFILL }},
1583 { &hf_ntlmssp_negotiate_flags_20,
1584 { "Negotiate Seal", "ntlmssp.negotiateseal", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SEAL, "", HFILL }},
1585 { &hf_ntlmssp_negotiate_flags_40,
1586 { "Negotiate Datagram", "ntlmssp.negotiatedatagram", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_DATAGRAM, "", HFILL }},
1587 { &hf_ntlmssp_negotiate_flags_80,
1588 { "Negotiate Lan Manager Key", "ntlmssp.negotiatelmkey", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_LM_KEY, "", HFILL }},
1589 { &hf_ntlmssp_negotiate_flags_100,
1590 { "Negotiate 0x00000100", "ntlmssp.negotiate00000100", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000100, "", HFILL }},
1591 { &hf_ntlmssp_negotiate_flags_200,
1592 { "Negotiate NTLM key", "ntlmssp.negotiatentlm", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM, "", HFILL }},
1593 { &hf_ntlmssp_negotiate_flags_400,
1594 { "Negotiate NT Only", "ntlmssp.negotiatentonly", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NT_ONLY, "", HFILL }},
1595 { &hf_ntlmssp_negotiate_flags_800,
1596 { "Negotiate 0x00000800", "ntlmssp.negotiate00000800", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000800, "", HFILL }},
1597 { &hf_ntlmssp_negotiate_flags_1000,
1598 { "Negotiate OEM Domain Supplied", "ntlmssp.negotiateoemdomainsupplied", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED, "", HFILL }},
1599 { &hf_ntlmssp_negotiate_flags_2000,
1600 { "Negotiate OEM Workstation Supplied", "ntlmssp.negotiateoemworkstationsupplied", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED, "", HFILL }},
1601 { &hf_ntlmssp_negotiate_flags_4000,
1602 { "Negotiate 0x00004000", "ntlmssp.negotiate00004000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00004000, "", HFILL }},
1603 { &hf_ntlmssp_negotiate_flags_8000,
1604 { "Negotiate Always Sign", "ntlmssp.negotiatealwayssign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_ALWAYS_SIGN, "", HFILL }},
1605 { &hf_ntlmssp_negotiate_flags_10000,
1606 { "Target Type Domain", "ntlmssp.targettypedomain", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_TARGET_TYPE_DOMAIN, "", HFILL }},
1607 { &hf_ntlmssp_negotiate_flags_20000,
1608 { "Target Type Server", "ntlmssp.targettypeserver", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_TARGET_TYPE_SERVER, "", HFILL }},
1609 { &hf_ntlmssp_negotiate_flags_40000,
1610 { "Target Type Share", "ntlmssp.targettypeshare", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_TARGET_TYPE_SHARE, "", HFILL }},
1611 { &hf_ntlmssp_negotiate_flags_80000,
1612 { "Negotiate NTLM2 key", "ntlmssp.negotiatentlm2", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM2, "", HFILL }},
1613 { &hf_ntlmssp_negotiate_flags_100000,
1614 { "Negotiate Identify", "ntlmssp.negotiateidentify", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_IDENTIFY, "", HFILL }},
1615 { &hf_ntlmssp_negotiate_flags_200000,
1616 { "Negotiate 0x00200000", "ntlmssp.negotiatent00200000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00200000, "", HFILL }},
1617 { &hf_ntlmssp_negotiate_flags_400000,
1618 { "Request Non-NT Session", "ntlmssp.requestnonntsession", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_REQUEST_NON_NT_SESSION, "", HFILL }},
1619 { &hf_ntlmssp_negotiate_flags_800000,
1620 { "Negotiate Target Info", "ntlmssp.negotiatetargetinfo", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_TARGET_INFO, "", HFILL }},
1621 { &hf_ntlmssp_negotiate_flags_1000000,
1622 { "Negotiate 0x01000000", "ntlmssp.negotiatent01000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_01000000, "", HFILL }},
1623 { &hf_ntlmssp_negotiate_flags_2000000,
1624 { "Negotiate Version", "ntlmssp.negotiateversion", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_VERSION, "", HFILL }},
1625 { &hf_ntlmssp_negotiate_flags_4000000,
1626 { "Negotiate 0x04000000", "ntlmssp.negotiatent04000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_04000000, "", HFILL }},
1627 { &hf_ntlmssp_negotiate_flags_8000000,
1628 { "Negotiate 0x08000000", "ntlmssp.negotiatent08000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_08000000, "", HFILL }},
1629 { &hf_ntlmssp_negotiate_flags_10000000,
1630 { "Negotiate 0x10000000", "ntlmssp.negotiatent10000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_10000000, "", HFILL }},
1631 { &hf_ntlmssp_negotiate_flags_20000000,
1632 { "Negotiate 128", "ntlmssp.negotiate128", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_128, "128-bit encryption is supported", HFILL }},
1633 { &hf_ntlmssp_negotiate_flags_40000000,
1634 { "Negotiate Key Exchange", "ntlmssp.negotiatekeyexch", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_KEY_EXCH, "", HFILL }},
1635 { &hf_ntlmssp_negotiate_flags_80000000,
1636 { "Negotiate 56", "ntlmssp.negotiate56", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_56, "56-bit encryption is supported", HFILL }},
1637 { &hf_ntlmssp_negotiate_workstation_strlen,
1638 { "Calling workstation name length", "ntlmssp.negotiate.callingworkstation.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1639 { &hf_ntlmssp_negotiate_workstation_maxlen,
1640 { "Calling workstation name max length", "ntlmssp.negotiate.callingworkstation.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1641 { &hf_ntlmssp_negotiate_workstation_buffer,
1642 { "Calling workstation name buffer", "ntlmssp.negotiate.callingworkstation.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1643 { &hf_ntlmssp_negotiate_workstation,
1644 { "Calling workstation name", "ntlmssp.negotiate.callingworkstation", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1645 { &hf_ntlmssp_negotiate_domain_strlen,
1646 { "Calling workstation domain length", "ntlmssp.negotiate.domain.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1647 { &hf_ntlmssp_negotiate_domain_maxlen,
1648 { "Calling workstation domain max length", "ntlmssp.negotiate.domain.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1649 { &hf_ntlmssp_negotiate_domain_buffer,
1650 { "Calling workstation domain buffer", "ntlmssp.negotiate.domain.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1651 { &hf_ntlmssp_negotiate_domain,
1652 { "Calling workstation domain", "ntlmssp.negotiate.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1653 { &hf_ntlmssp_ntlm_challenge,
1654 { "NTLM Challenge", "ntlmssp.ntlmchallenge", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1655 { &hf_ntlmssp_reserved,
1656 { "Reserved", "ntlmssp.reserved", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1657 { &hf_ntlmssp_challenge_domain,
1658 { "Domain", "ntlmssp.challenge.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1659 { &hf_ntlmssp_auth_domain,
1660 { "Domain name", "ntlmssp.auth.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1661 { &hf_ntlmssp_auth_username,
1662 { "User name", "ntlmssp.auth.username", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1663 { &hf_ntlmssp_auth_hostname,
1664 { "Host name", "ntlmssp.auth.hostname", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1665 { &hf_ntlmssp_auth_lmresponse,
1666 { "Lan Manager Response", "ntlmssp.auth.lmresponse", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1667 { &hf_ntlmssp_auth_ntresponse,
1668 { "NTLM Response", "ntlmssp.auth.ntresponse", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1669 { &hf_ntlmssp_auth_sesskey,
1670 { "Session Key", "ntlmssp.auth.sesskey", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1671 { &hf_ntlmssp_string_len,
1672 { "Length", "ntlmssp.string.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1673 { &hf_ntlmssp_string_maxlen,
1674 { "Maxlen", "ntlmssp.string.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1675 { &hf_ntlmssp_string_offset,
1676 { "Offset", "ntlmssp.string.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1677 { &hf_ntlmssp_blob_len,
1678 { "Length", "ntlmssp.blob.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1679 { &hf_ntlmssp_blob_maxlen,
1680 { "Maxlen", "ntlmssp.blob.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1681 { &hf_ntlmssp_blob_offset,
1682 { "Offset", "ntlmssp.blob.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1683 { &hf_ntlmssp_address_list,
1684 { "Address List", "ntlmssp.challenge.addresslist", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL}},
1685 { &hf_ntlmssp_address_list_len,
1686 { "Length", "ntlmssp.challenge.addresslist.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1687 { &hf_ntlmssp_address_list_maxlen,
1688 { "Maxlen", "ntlmssp.challenge.addresslist.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1689 { &hf_ntlmssp_address_list_offset,
1690 { "Offset", "ntlmssp.challenge.addresslist.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1691 { &hf_ntlmssp_address_list_item_type,
1692 { "Target item type", "ntlmssp.targetitemtype", FT_UINT16, BASE_HEX, VALS(ntlm_name_types), 0x0, "", HFILL }},
1693 { &hf_ntlmssp_address_list_item_len,
1694 { "Target item Length", "ntlmssp.challenge.addresslist.item.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1695 { &hf_ntlmssp_address_list_item_content,
1696 { "Target item Content", "ntlmssp.challenge.addresslist.item.content", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL}},
1697 { &hf_ntlmssp_address_list_server_nb,
1698 { "Server NetBIOS Name", "ntlmssp.challenge.addresslist.servernb", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1699 { &hf_ntlmssp_address_list_domain_nb,
1700 { "Domain NetBIOS Name", "ntlmssp.challenge.addresslist.domainnb", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1701 { &hf_ntlmssp_address_list_server_dns,
1702 { "Server DNS Name", "ntlmssp.challenge.addresslist.serverdns", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1703 { &hf_ntlmssp_address_list_domain_dns,
1704 { "Domain DNS Name", "ntlmssp.challenge.addresslist.domaindns", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1705 { &hf_ntlmssp_address_list_terminator,
1706 { "List Terminator", "ntlmssp.challenge.addresslist.terminator", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
1708 { "NTLMSSP Verifier", "ntlmssp.verf", FT_NONE, BASE_NONE, NULL, 0x0, "NTLMSSP Verifier", HFILL }},
1709 { &hf_ntlmssp_verf_vers,
1710 { "Version Number", "ntlmssp.verf.vers", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
1711 { &hf_ntlmssp_verf_body,
1712 { "Verifier Body", "ntlmssp.verf.body", FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }},
1713 { &hf_ntlmssp_decrypted_payload,
1714 { "NTLM Decrypted Payload", "ntlmssp.decrypted_payload", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1715 { &hf_ntlmssp_verf_unknown1,
1716 { "Unknown 1", "ntlmssp.verf.unknown1", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1717 { &hf_ntlmssp_verf_crc32,
1718 { "Verifier CRC32", "ntlmssp.verf.crc32", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1719 { &hf_ntlmssp_verf_sequence,
1720 { "Verifier Sequence Number", "ntlmssp.verf.sequence", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
1721 { &hf_ntlmssp_ntlmv2_response,
1722 { "NTLMv2 Response", "ntlmssp.ntlmv2response", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1723 { &hf_ntlmssp_ntlmv2_response_hmac,
1724 { "HMAC", "ntlmssp.ntlmv2response.hmac", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1725 { &hf_ntlmssp_ntlmv2_response_header,
1726 { "Header", "ntlmssp.ntlmv2response.header", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1727 { &hf_ntlmssp_ntlmv2_response_reserved,
1728 { "Reserved", "ntlmssp.ntlmv2response.reserved", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1729 { &hf_ntlmssp_ntlmv2_response_time,
1730 { "Time", "ntlmssp.ntlmv2response.time", FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0, "", HFILL }},
1731 { &hf_ntlmssp_ntlmv2_response_chal,
1732 { "Client challenge", "ntlmssp.ntlmv2response.chal", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1733 { &hf_ntlmssp_ntlmv2_response_unknown,
1734 { "Unknown", "ntlmssp.ntlmv2response.unknown", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1735 { &hf_ntlmssp_ntlmv2_response_name,
1736 { "Name", "ntlmssp.ntlmv2response.name", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1737 { &hf_ntlmssp_ntlmv2_response_name_type,
1738 { "Name type", "ntlmssp.ntlmv2response.name.type", FT_UINT32, BASE_DEC, VALS(ntlm_name_types), 0x0, "", HFILL }},
1739 { &hf_ntlmssp_ntlmv2_response_name_len,
1740 { "Name len", "ntlmssp.ntlmv2response.name.len", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
1741 { &hf_ntlmssp_ntlmv2_response_client_time,
1742 { "Client Time", "ntlmssp.ntlmv2response.client_time", FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0, "", HFILL }}
1746 static gint *ett[] = {
1748 &ett_ntlmssp_negotiate_flags,
1749 &ett_ntlmssp_string,
1751 &ett_ntlmssp_address_list,
1752 &ett_ntlmssp_address_list_item,
1753 &ett_ntlmssp_ntlmv2_response,
1754 &ett_ntlmssp_ntlmv2_response_name
1756 module_t *ntlmssp_module;
1758 proto_ntlmssp = proto_register_protocol (
1759 "NTLM Secure Service Provider", /* name */
1760 "NTLMSSP", /* short name */
1761 "ntlmssp" /* abbrev */
1763 proto_register_field_array (proto_ntlmssp, hf, array_length (hf));
1764 proto_register_subtree_array (ett, array_length (ett));
1765 register_init_routine(&ntlmssp_init_protocol);
1767 ntlmssp_module = prefs_register_protocol(proto_ntlmssp, NULL);
1769 prefs_register_string_preference(ntlmssp_module, "nt_password",
1771 "NT Password (used to decrypt payloads)",
1774 register_dissector("ntlmssp", dissect_ntlmssp, proto_ntlmssp);
1775 new_register_dissector("ntlmssp_verf", dissect_ntlmssp_verf, proto_ntlmssp);
1778 static int wrap_dissect_ntlmssp(tvbuff_t *tvb, int offset, packet_info *pinfo,
1779 proto_tree *tree, guint8 *drep _U_)
1783 auth_tvb = tvb_new_subset(
1784 tvb, offset, tvb_length_remaining(tvb, offset),
1785 tvb_length_remaining(tvb, offset));
1787 dissect_ntlmssp(auth_tvb, pinfo, tree);
1789 return tvb_length_remaining(tvb, offset);
1792 static int wrap_dissect_ntlmssp_verf(tvbuff_t *tvb, int offset, packet_info *pinfo,
1793 proto_tree *tree, guint8 *drep _U_)
1797 auth_tvb = tvb_new_subset(
1798 tvb, offset, tvb_length_remaining(tvb, offset),
1799 tvb_length_remaining(tvb, offset));
1801 return dissect_ntlmssp_verf(auth_tvb, pinfo, tree);
1804 static dcerpc_auth_subdissector_fns ntlmssp_sign_fns = {
1805 wrap_dissect_ntlmssp, /* Bind */
1806 wrap_dissect_ntlmssp, /* Bind ACK */
1807 wrap_dissect_ntlmssp, /* AUTH3 */
1808 wrap_dissect_ntlmssp_verf, /* Request verifier */
1809 wrap_dissect_ntlmssp_verf, /* Response verifier */
1810 NULL, /* Request data */
1811 NULL /* Response data */
1814 static dcerpc_auth_subdissector_fns ntlmssp_seal_fns = {
1815 wrap_dissect_ntlmssp, /* Bind */
1816 wrap_dissect_ntlmssp, /* Bind ACK */
1817 wrap_dissect_ntlmssp, /* AUTH3 */
1818 wrap_dissect_ntlmssp_verf, /* Request verifier */
1819 wrap_dissect_ntlmssp_verf, /* Response verifier */
1820 dissect_ntlmssp_encrypted_payload, /* Request data */
1821 dissect_ntlmssp_encrypted_payload /* Response data */
1825 proto_reg_handoff_ntlmssp(void)
1827 dissector_handle_t ntlmssp_handle, ntlmssp_wrap_handle;
1829 /* Register protocol with the GSS-API module */
1831 ntlmssp_handle = find_dissector("ntlmssp");
1832 ntlmssp_wrap_handle = find_dissector("ntlmssp_verf");
1833 gssapi_init_oid("1.3.6.1.4.1.311.2.2.10", proto_ntlmssp, ett_ntlmssp,
1834 ntlmssp_handle, ntlmssp_wrap_handle,
1835 "NTLMSSP - Microsoft NTLM Security Support Provider");
1837 /* Register authenticated pipe dissector */
1840 * XXX - the verifiers here seem to have a version of 1 and a body of all
1843 * XXX - DCE_C_AUTHN_LEVEL_CONNECT is, according to the DCE RPC 1.1
1844 * spec, upgraded to DCE_C_AUTHN_LEVEL_PKT. Should we register
1845 * any other levels here?
1847 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_CONNECT,
1848 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
1851 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT,
1852 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
1855 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
1856 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
1859 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
1860 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
1862 ntlmssp_tap = register_tap("ntlmssp");