2 * Routines for NTLM Secure Service Provider
3 * Devin Heitmueller <dheitmueller@netilla.com>
4 * Copyright 2003, Tim Potter <tpot@samba.org>
8 * Ethereal - Network traffic analyzer
9 * By Gerald Combs <gerald@ethereal.com>
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 "asn1.h" /* XXX - needed for subid_t */
40 #include "packet-gssapi.h"
41 #include "packet-frame.h"
43 #include "crypt-rc4.h"
44 #include "crypt-md4.h"
45 #include "crypt-des.h"
46 #include "packet-dcerpc.h"
48 #include "packet-ntlmssp.h"
52 #define NTLMSSP_NEGOTIATE 1
53 #define NTLMSSP_CHALLENGE 2
54 #define NTLMSSP_AUTH 3
55 #define NTLMSSP_UNKNOWN 4
57 static const value_string ntlmssp_message_types[] = {
58 { NTLMSSP_NEGOTIATE, "NTLMSSP_NEGOTIATE" },
59 { NTLMSSP_CHALLENGE, "NTLMSSP_CHALLENGE" },
60 { NTLMSSP_AUTH, "NTLMSSP_AUTH" },
61 { NTLMSSP_UNKNOWN, "NTLMSSP_UNKNOWN" },
66 * NTLMSSP negotiation flags
71 * http://davenport.sourceforge.net/ntlm.html
73 * although that document says that:
75 * 0x00010000 is "Target Type Domain";
76 * 0x00020000 is "Target Type Server"
77 * 0x00040000 is "Target Type Share";
79 * and that 0x00100000, 0x00200000, and 0x00400000 are
80 * "Request Init Response", "Request Accept Response", and
81 * "Request Non-NT Session Key", rather than those values shifted
82 * right one having those interpretations.
84 #define NTLMSSP_NEGOTIATE_UNICODE 0x00000001
85 #define NTLMSSP_NEGOTIATE_OEM 0x00000002
86 #define NTLMSSP_REQUEST_TARGET 0x00000004
87 #define NTLMSSP_NEGOTIATE_00000008 0x00000008
88 #define NTLMSSP_NEGOTIATE_SIGN 0x00000010
89 #define NTLMSSP_NEGOTIATE_SEAL 0x00000020
90 #define NTLMSSP_NEGOTIATE_DATAGRAM_STYLE 0x00000040
91 #define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080
92 #define NTLMSSP_NEGOTIATE_NETWARE 0x00000100
93 #define NTLMSSP_NEGOTIATE_NTLM 0x00000200
94 #define NTLMSSP_NEGOTIATE_00000400 0x00000400
95 #define NTLMSSP_NEGOTIATE_00000800 0x00000800
96 #define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED 0x00001000
97 #define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED 0x00002000
98 #define NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL 0x00004000
99 #define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000
100 #define NTLMSSP_CHAL_INIT_RESPONSE 0x00010000
101 #define NTLMSSP_CHAL_ACCEPT_RESPONSE 0x00020000
102 #define NTLMSSP_CHAL_NON_NT_SESSION_KEY 0x00040000
103 #define NTLMSSP_NEGOTIATE_NTLM2 0x00080000
104 #define NTLMSSP_NEGOTIATE_00100000 0x00100000
105 #define NTLMSSP_NEGOTIATE_00200000 0x00200000
106 #define NTLMSSP_NEGOTIATE_00400000 0x00400000
107 #define NTLMSSP_CHAL_TARGET_INFO 0x00800000
108 #define NTLMSSP_NEGOTIATE_01000000 0x01000000
109 #define NTLMSSP_NEGOTIATE_02000000 0x02000000
110 #define NTLMSSP_NEGOTIATE_04000000 0x04000000
111 #define NTLMSSP_NEGOTIATE_08000000 0x08000000
112 #define NTLMSSP_NEGOTIATE_10000000 0x10000000
113 #define NTLMSSP_NEGOTIATE_128 0x20000000
114 #define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000
115 #define NTLMSSP_NEGOTIATE_56 0x80000000
117 static int proto_ntlmssp = -1;
118 static int hf_ntlmssp = -1;
119 static int hf_ntlmssp_auth = -1;
120 static int hf_ntlmssp_message_type = -1;
121 static int hf_ntlmssp_negotiate_flags = -1;
122 static int hf_ntlmssp_negotiate_flags_01 = -1;
123 static int hf_ntlmssp_negotiate_flags_02 = -1;
124 static int hf_ntlmssp_negotiate_flags_04 = -1;
125 static int hf_ntlmssp_negotiate_flags_08 = -1;
126 static int hf_ntlmssp_negotiate_flags_10 = -1;
127 static int hf_ntlmssp_negotiate_flags_20 = -1;
128 static int hf_ntlmssp_negotiate_flags_40 = -1;
129 static int hf_ntlmssp_negotiate_flags_80 = -1;
130 static int hf_ntlmssp_negotiate_flags_100 = -1;
131 static int hf_ntlmssp_negotiate_flags_200 = -1;
132 static int hf_ntlmssp_negotiate_flags_400 = -1;
133 static int hf_ntlmssp_negotiate_flags_800 = -1;
134 static int hf_ntlmssp_negotiate_flags_1000 = -1;
135 static int hf_ntlmssp_negotiate_flags_2000 = -1;
136 static int hf_ntlmssp_negotiate_flags_4000 = -1;
137 static int hf_ntlmssp_negotiate_flags_8000 = -1;
138 static int hf_ntlmssp_negotiate_flags_10000 = -1;
139 static int hf_ntlmssp_negotiate_flags_20000 = -1;
140 static int hf_ntlmssp_negotiate_flags_40000 = -1;
141 static int hf_ntlmssp_negotiate_flags_80000 = -1;
142 static int hf_ntlmssp_negotiate_flags_100000 = -1;
143 static int hf_ntlmssp_negotiate_flags_200000 = -1;
144 static int hf_ntlmssp_negotiate_flags_400000 = -1;
145 static int hf_ntlmssp_negotiate_flags_800000 = -1;
146 static int hf_ntlmssp_negotiate_flags_1000000 = -1;
147 static int hf_ntlmssp_negotiate_flags_2000000 = -1;
148 static int hf_ntlmssp_negotiate_flags_4000000 = -1;
149 static int hf_ntlmssp_negotiate_flags_8000000 = -1;
150 static int hf_ntlmssp_negotiate_flags_10000000 = -1;
151 static int hf_ntlmssp_negotiate_flags_20000000 = -1;
152 static int hf_ntlmssp_negotiate_flags_40000000 = -1;
153 static int hf_ntlmssp_negotiate_flags_80000000 = -1;
154 static int hf_ntlmssp_negotiate_workstation_strlen = -1;
155 static int hf_ntlmssp_negotiate_workstation_maxlen = -1;
156 static int hf_ntlmssp_negotiate_workstation_buffer = -1;
157 static int hf_ntlmssp_negotiate_workstation = -1;
158 static int hf_ntlmssp_negotiate_domain_strlen = -1;
159 static int hf_ntlmssp_negotiate_domain_maxlen = -1;
160 static int hf_ntlmssp_negotiate_domain_buffer = -1;
161 static int hf_ntlmssp_negotiate_domain = -1;
162 static int hf_ntlmssp_ntlm_challenge = -1;
163 static int hf_ntlmssp_reserved = -1;
164 static int hf_ntlmssp_challenge_domain = -1;
165 static int hf_ntlmssp_auth_username = -1;
166 static int hf_ntlmssp_auth_domain = -1;
167 static int hf_ntlmssp_auth_hostname = -1;
168 static int hf_ntlmssp_auth_lmresponse = -1;
169 static int hf_ntlmssp_auth_ntresponse = -1;
170 static int hf_ntlmssp_auth_sesskey = -1;
171 static int hf_ntlmssp_string_len = -1;
172 static int hf_ntlmssp_string_maxlen = -1;
173 static int hf_ntlmssp_string_offset = -1;
174 static int hf_ntlmssp_blob_len = -1;
175 static int hf_ntlmssp_blob_maxlen = -1;
176 static int hf_ntlmssp_blob_offset = -1;
177 static int hf_ntlmssp_address_list = -1;
178 static int hf_ntlmssp_address_list_len = -1;
179 static int hf_ntlmssp_address_list_maxlen = -1;
180 static int hf_ntlmssp_address_list_offset = -1;
181 static int hf_ntlmssp_address_list_server_nb = -1;
182 static int hf_ntlmssp_address_list_domain_nb = -1;
183 static int hf_ntlmssp_address_list_server_dns = -1;
184 static int hf_ntlmssp_address_list_domain_dns = -1;
185 static int hf_ntlmssp_address_list_terminator = -1;
186 static int hf_ntlmssp_address_list_item_type = -1;
187 static int hf_ntlmssp_address_list_item_len = -1;
188 static int hf_ntlmssp_address_list_item_content = -1;
189 static int hf_ntlmssp_verf = -1;
190 static int hf_ntlmssp_verf_vers = -1;
191 static int hf_ntlmssp_verf_body = -1;
192 static int hf_ntlmssp_verf_unknown1 = -1;
193 static int hf_ntlmssp_verf_crc32 = -1;
194 static int hf_ntlmssp_verf_sequence = -1;
195 static int hf_ntlmssp_decrypted_payload = -1;
196 static int hf_ntlmssp_ntlmv2_response = -1;
197 static int hf_ntlmssp_ntlmv2_response_hmac = -1;
198 static int hf_ntlmssp_ntlmv2_response_header = -1;
199 static int hf_ntlmssp_ntlmv2_response_reserved = -1;
200 static int hf_ntlmssp_ntlmv2_response_time = -1;
201 static int hf_ntlmssp_ntlmv2_response_chal = -1;
202 static int hf_ntlmssp_ntlmv2_response_unknown = -1;
203 static int hf_ntlmssp_ntlmv2_response_name = -1;
204 static int hf_ntlmssp_ntlmv2_response_name_type = -1;
205 static int hf_ntlmssp_ntlmv2_response_name_len = -1;
207 static gint ett_ntlmssp = -1;
208 static gint ett_ntlmssp_negotiate_flags = -1;
209 static gint ett_ntlmssp_string = -1;
210 static gint ett_ntlmssp_blob = -1;
211 static gint ett_ntlmssp_address_list = -1;
212 static gint ett_ntlmssp_address_list_item = -1;
213 static gint ett_ntlmssp_ntlmv2_response = -1;
214 static gint ett_ntlmssp_ntlmv2_response_name = -1;
216 /* Configuration variables */
217 static char *nt_password = NULL;
219 #define MAX_BLOB_SIZE 256
220 typedef struct _ntlmssp_blob {
222 guint8 contents[MAX_BLOB_SIZE];
225 /* Used in the conversation function */
226 typedef struct _ntlmssp_info {
228 rc4_state_struct rc4_state_peer1;
229 rc4_state_struct rc4_state_peer2;
230 guint32 peer1_dest_port;
231 int rc4_state_initialized;
232 ntlmssp_blob ntlm_response;
233 ntlmssp_blob lm_response;
237 * GMemChunk from which ntlmssp_info structures are allocated.
239 static GMemChunk *ntlmssp_info_chunk;
240 static int ntlmssp_info_count = 10;
242 /* If this struct exists in the payload_decrypt, then we have already
244 typedef struct _ntlmssp_packet_info {
246 guint8 *decrypted_payload;
248 gboolean payload_decrypted;
249 gboolean verifier_decrypted;
250 } ntlmssp_packet_info;
253 * GMemChunk from which ntlmssp_packet_info structures are allocated.
255 static GMemChunk *ntlmssp_packet_info_chunk;
256 static int ntlmssp_packet_info_count = 10;
259 * GSlist of decrypted payloads.
261 static GSList *decrypted_payloads;
264 Generate a challenge response, given an eight byte challenge and
265 either the NT or the Lan Manager password hash (16 bytes).
266 Returns output in response, which is expected to be 24 bytes.
268 static int ntlmssp_generate_challenge_response(guint8 *response,
269 const guint8 *passhash,
270 const guint8 *challenge)
272 guint8 pw21[21]; /* Password hash padded to 21 bytes */
274 memset(pw21, 0x0, sizeof(pw21));
275 memcpy(pw21, passhash, 16);
277 memset(response, 0, 24);
279 crypt_des_ecb(response, challenge, pw21, 1);
280 crypt_des_ecb(response + 8, challenge, pw21 + 7, 1);
281 crypt_des_ecb(response + 16, challenge, pw21 + 14, 1);
286 /* Create an NTLMSSP version 1 key.
287 * password points to the ANSI password to encrypt, challenge points to
288 * the 8 octet challenge string, key128 will do a 128 bit key if set to 1,
289 * otherwise it will do a 40 bit key. The result is stored in
290 * sspkey (expected to be 16 octets)
293 create_ntlmssp_v1_key(const char *nt_password, const guint8 *challenge,
294 int use_key_128, guint8 *sspkey)
296 unsigned char lm_password_upper[16];
297 unsigned char lm_password_hash[16];
298 guint8 lm_challenge_response[24];
300 guint8 pw21[21]; /* Password hash padded to 21 bytes */
303 unsigned char lmhash_key[] =
304 {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
306 memset(lm_password_upper, 0, sizeof(lm_password_upper));
308 /* Create a Lan Manager hash of the input password */
309 if (nt_password[0] != '\0') {
310 password_len = strlen(nt_password);
311 /* Truncate password if too long */
312 if (password_len > 16)
314 for (i = 0; i < password_len; i++) {
315 lm_password_upper[i] = toupper(nt_password[i]);
319 crypt_des_ecb(lm_password_hash, lmhash_key, lm_password_upper, 1);
320 crypt_des_ecb(lm_password_hash+8, lmhash_key, lm_password_upper+7, 1);
322 /* Generate the LanMan Challenge Response */
323 ntlmssp_generate_challenge_response(lm_challenge_response,
324 lm_password_hash, challenge);
326 /* Generate the NTLMSSP-v1 RC4 Key.
327 * The RC4 key is derived from the Lan Manager Hash.
328 * See lkcl "DCE/RPC over SMB" page 254 for the algorithm.
330 memset(pw21, 0xBD, sizeof(pw21));
331 memcpy(pw21, lm_password_hash, sizeof(lm_password_hash));
333 /* Only the first eight bytes of challenge_response is used */
334 crypt_des_ecb(rc4key, lm_challenge_response, pw21, 1);
335 crypt_des_ecb(rc4key + 8, lm_challenge_response, pw21 + 7, 1);
336 crypt_des_ecb(rc4key + 16, lm_challenge_response, pw21 + 14, 1);
338 /* Create the SSP Key */
339 memset(sspkey, 0, sizeof(sspkey));
341 /* Create 128 bit key */
342 memcpy(sspkey, rc4key, 16);
345 /* Create 40 bit key */
346 memcpy(sspkey, rc4key, 5);
354 /* dissect a string - header area contains:
357 four byte offset of string in data area
358 The function returns the offset at the end of the string header,
359 but the 'end' parameter returns the offset of the end of the string itself
360 The 'start' parameter returns the offset of the beginning of the string
363 dissect_ntlmssp_string (tvbuff_t *tvb, int offset,
364 proto_tree *ntlmssp_tree,
365 gboolean unicode_strings,
366 int string_hf, int *start, int *end)
368 proto_tree *tree = NULL;
369 proto_item *tf = NULL;
370 gint16 string_length = tvb_get_letohs(tvb, offset);
371 gint16 string_maxlen = tvb_get_letohs(tvb, offset+2);
372 gint32 string_offset = tvb_get_letohl(tvb, offset+4);
373 const char *string_text = NULL;
377 *start = (string_offset > offset+8 ? string_offset : offset+8);
378 if (0 == string_length) {
381 proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
386 bc = result_length = string_length;
387 string_text = get_unicode_or_ascii_string(tvb, &string_offset,
388 unicode_strings, &result_length,
392 tf = proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
393 string_offset, result_length, string_text);
394 tree = proto_item_add_subtree(tf, ett_ntlmssp_string);
396 proto_tree_add_uint(tree, hf_ntlmssp_string_len,
397 tvb, offset, 2, string_length);
399 proto_tree_add_uint(tree, hf_ntlmssp_string_maxlen,
400 tvb, offset, 2, string_maxlen);
402 proto_tree_add_uint(tree, hf_ntlmssp_string_offset,
403 tvb, offset, 4, string_offset);
406 *end = string_offset + string_length;
410 /* dissect a generic blob - header area contains:
413 four byte offset of blob in data area
414 The function returns the offset at the end of the blob header,
415 but the 'end' parameter returns the offset of the end of the blob itself
418 dissect_ntlmssp_blob (tvbuff_t *tvb, int offset,
419 proto_tree *ntlmssp_tree,
420 int blob_hf, int *end, ntlmssp_blob *result)
422 proto_item *tf = NULL;
423 proto_tree *tree = NULL;
424 guint16 blob_length = tvb_get_letohs(tvb, offset);
425 guint16 blob_maxlen = tvb_get_letohs(tvb, offset+2);
426 guint32 blob_offset = tvb_get_letohl(tvb, offset+4);
428 if (0 == blob_length) {
429 *end = (blob_offset > ((guint)offset)+8 ? blob_offset : ((guint)offset)+8);
431 proto_tree_add_text(ntlmssp_tree, tvb, offset, 8, "%s: Empty",
432 proto_registrar_get_name(blob_hf));
437 tf = proto_tree_add_item (ntlmssp_tree, blob_hf, tvb,
438 blob_offset, blob_length, FALSE);
439 tree = proto_item_add_subtree(tf, ett_ntlmssp_blob);
441 proto_tree_add_uint(tree, hf_ntlmssp_blob_len,
442 tvb, offset, 2, blob_length);
444 proto_tree_add_uint(tree, hf_ntlmssp_blob_maxlen,
445 tvb, offset, 2, blob_maxlen);
447 proto_tree_add_uint(tree, hf_ntlmssp_blob_offset,
448 tvb, offset, 4, blob_offset);
451 *end = blob_offset + blob_length;
453 if (result != NULL) {
454 result->length = blob_length;
455 memset(result->contents, 0, MAX_BLOB_SIZE);
456 if (blob_length < MAX_BLOB_SIZE)
457 tvb_memcpy(tvb, result->contents, blob_offset, blob_length);
460 /* If we are dissecting the NTLM response and it is a NTLMv2
461 response call the appropriate dissector. */
463 if (blob_hf == hf_ntlmssp_auth_ntresponse && blob_length > 24)
464 dissect_ntlmv2_response(tvb, tree, blob_offset, blob_length);
470 dissect_ntlmssp_negotiate_flags (tvbuff_t *tvb, int offset,
471 proto_tree *ntlmssp_tree,
472 guint32 negotiate_flags)
474 proto_tree *negotiate_flags_tree = NULL;
475 proto_item *tf = NULL;
478 tf = proto_tree_add_uint (ntlmssp_tree,
479 hf_ntlmssp_negotiate_flags,
480 tvb, offset, 4, negotiate_flags);
481 negotiate_flags_tree = proto_item_add_subtree (tf, ett_ntlmssp_negotiate_flags);
484 proto_tree_add_boolean (negotiate_flags_tree,
485 hf_ntlmssp_negotiate_flags_80000000,
486 tvb, offset, 4, negotiate_flags);
487 proto_tree_add_boolean (negotiate_flags_tree,
488 hf_ntlmssp_negotiate_flags_40000000,
489 tvb, offset, 4, negotiate_flags);
490 proto_tree_add_boolean (negotiate_flags_tree,
491 hf_ntlmssp_negotiate_flags_20000000,
492 tvb, offset, 4, negotiate_flags);
493 proto_tree_add_boolean (negotiate_flags_tree,
494 hf_ntlmssp_negotiate_flags_10000000,
495 tvb, offset, 4, negotiate_flags);
496 proto_tree_add_boolean (negotiate_flags_tree,
497 hf_ntlmssp_negotiate_flags_8000000,
498 tvb, offset, 4, negotiate_flags);
499 proto_tree_add_boolean (negotiate_flags_tree,
500 hf_ntlmssp_negotiate_flags_4000000,
501 tvb, offset, 4, negotiate_flags);
502 proto_tree_add_boolean (negotiate_flags_tree,
503 hf_ntlmssp_negotiate_flags_2000000,
504 tvb, offset, 4, negotiate_flags);
505 proto_tree_add_boolean (negotiate_flags_tree,
506 hf_ntlmssp_negotiate_flags_1000000,
507 tvb, offset, 4, negotiate_flags);
508 proto_tree_add_boolean (negotiate_flags_tree,
509 hf_ntlmssp_negotiate_flags_800000,
510 tvb, offset, 4, negotiate_flags);
511 proto_tree_add_boolean (negotiate_flags_tree,
512 hf_ntlmssp_negotiate_flags_400000,
513 tvb, offset, 4, negotiate_flags);
514 proto_tree_add_boolean (negotiate_flags_tree,
515 hf_ntlmssp_negotiate_flags_200000,
516 tvb, offset, 4, negotiate_flags);
517 proto_tree_add_boolean (negotiate_flags_tree,
518 hf_ntlmssp_negotiate_flags_100000,
519 tvb, offset, 4, negotiate_flags);
520 proto_tree_add_boolean (negotiate_flags_tree,
521 hf_ntlmssp_negotiate_flags_80000,
522 tvb, offset, 4, negotiate_flags);
523 proto_tree_add_boolean (negotiate_flags_tree,
524 hf_ntlmssp_negotiate_flags_40000,
525 tvb, offset, 4, negotiate_flags);
526 proto_tree_add_boolean (negotiate_flags_tree,
527 hf_ntlmssp_negotiate_flags_20000,
528 tvb, offset, 4, negotiate_flags);
529 proto_tree_add_boolean (negotiate_flags_tree,
530 hf_ntlmssp_negotiate_flags_10000,
531 tvb, offset, 4, negotiate_flags);
532 proto_tree_add_boolean (negotiate_flags_tree,
533 hf_ntlmssp_negotiate_flags_8000,
534 tvb, offset, 4, negotiate_flags);
535 proto_tree_add_boolean (negotiate_flags_tree,
536 hf_ntlmssp_negotiate_flags_4000,
537 tvb, offset, 4, negotiate_flags);
538 proto_tree_add_boolean (negotiate_flags_tree,
539 hf_ntlmssp_negotiate_flags_2000,
540 tvb, offset, 4, negotiate_flags);
541 proto_tree_add_boolean (negotiate_flags_tree,
542 hf_ntlmssp_negotiate_flags_1000,
543 tvb, offset, 4, negotiate_flags);
544 proto_tree_add_boolean (negotiate_flags_tree,
545 hf_ntlmssp_negotiate_flags_800,
546 tvb, offset, 4, negotiate_flags);
547 proto_tree_add_boolean (negotiate_flags_tree,
548 hf_ntlmssp_negotiate_flags_400,
549 tvb, offset, 4, negotiate_flags);
550 proto_tree_add_boolean (negotiate_flags_tree,
551 hf_ntlmssp_negotiate_flags_200,
552 tvb, offset, 4, negotiate_flags);
553 proto_tree_add_boolean (negotiate_flags_tree,
554 hf_ntlmssp_negotiate_flags_100,
555 tvb, offset, 4, negotiate_flags);
556 proto_tree_add_boolean (negotiate_flags_tree,
557 hf_ntlmssp_negotiate_flags_80,
558 tvb, offset, 4, negotiate_flags);
559 proto_tree_add_boolean (negotiate_flags_tree,
560 hf_ntlmssp_negotiate_flags_40,
561 tvb, offset, 4, negotiate_flags);
562 proto_tree_add_boolean (negotiate_flags_tree,
563 hf_ntlmssp_negotiate_flags_20,
564 tvb, offset, 4, negotiate_flags);
565 proto_tree_add_boolean (negotiate_flags_tree,
566 hf_ntlmssp_negotiate_flags_10,
567 tvb, offset, 4, negotiate_flags);
568 proto_tree_add_boolean (negotiate_flags_tree,
569 hf_ntlmssp_negotiate_flags_08,
570 tvb, offset, 4, negotiate_flags);
571 proto_tree_add_boolean (negotiate_flags_tree,
572 hf_ntlmssp_negotiate_flags_04,
573 tvb, offset, 4, negotiate_flags);
574 proto_tree_add_boolean (negotiate_flags_tree,
575 hf_ntlmssp_negotiate_flags_02,
576 tvb, offset, 4, negotiate_flags);
577 proto_tree_add_boolean (negotiate_flags_tree,
578 hf_ntlmssp_negotiate_flags_01,
579 tvb, offset, 4, negotiate_flags);
584 /* Dissect a NTLM response. This is documented at
585 http://ubiqx.org/cifs/SMB.html#SMB.8, para 2.8.5.3 */
590 * XXX - the davenport document says that a type of 5 has been seen,
591 * "apparently containing the 'parent' DNS domain for servers in
595 #define NTLM_NAME_END 0x0000
596 #define NTLM_NAME_NB_HOST 0x0001
597 #define NTLM_NAME_NB_DOMAIN 0x0002
598 #define NTLM_NAME_DNS_HOST 0x0003
599 #define NTLM_NAME_DNS_DOMAIN 0x0004
601 static const value_string ntlm_name_types[] = {
602 { NTLM_NAME_END, "End of list" },
603 { NTLM_NAME_NB_HOST, "NetBIOS host name" },
604 { NTLM_NAME_NB_DOMAIN, "NetBIOS domain name" },
605 { NTLM_NAME_DNS_HOST, "DNS host name" },
606 { NTLM_NAME_DNS_DOMAIN, "DNS domain name" },
611 dissect_ntlmv2_response(tvbuff_t *tvb, proto_tree *tree, int offset, int len)
613 proto_item *ntlmv2_item = NULL;
614 proto_tree *ntlmv2_tree = NULL;
616 /* Dissect NTLMv2 bits&pieces */
619 ntlmv2_item = proto_tree_add_item(
620 tree, hf_ntlmssp_ntlmv2_response, tvb,
622 ntlmv2_tree = proto_item_add_subtree(
623 ntlmv2_item, ett_ntlmssp_ntlmv2_response);
627 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_hmac, tvb,
633 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_header, tvb,
639 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_reserved, tvb,
644 offset = dissect_nt_64bit_time(
645 tvb, ntlmv2_tree, offset, hf_ntlmssp_ntlmv2_response_time);
648 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_chal, tvb,
654 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_unknown, tvb,
659 /* Variable length list of names */
662 guint16 name_type = tvb_get_letohs(tvb, offset);
663 guint16 name_len = tvb_get_letohs(tvb, offset + 2);
664 proto_tree *name_tree = NULL;
665 proto_item *name_item = NULL;
669 name_item = proto_tree_add_item(
670 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_name,
671 tvb, offset, 0, TRUE);
672 name_tree = proto_item_add_subtree(
673 name_item, ett_ntlmssp_ntlmv2_response_name);
676 /* Dissect name header */
679 name_tree, hf_ntlmssp_ntlmv2_response_name_type, tvb,
685 name_tree, hf_ntlmssp_ntlmv2_response_name_len, tvb,
693 name = tvb_fake_unicode(
694 tvb, offset, name_len / 2, TRUE);
697 name_tree, tvb, offset, name_len,
700 name = g_strdup("NULL");
703 proto_item_append_text(
705 val_to_str(name_type, ntlm_name_types,
708 proto_item_append_text(
710 val_to_str(name_type, ntlm_name_types,
717 proto_item_set_len(name_item, name_len + 4);
719 if (name_type == 0) /* End of list */
727 dissect_ntlmssp_negotiate (tvbuff_t *tvb, int offset, proto_tree *ntlmssp_tree)
729 guint32 negotiate_flags;
734 /* NTLMSSP Negotiate Flags */
735 negotiate_flags = tvb_get_letohl (tvb, offset);
736 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
740 * XXX - the davenport document says that these might not be
741 * sent at all, presumably meaning the length of the message
742 * isn't enough to contain them.
744 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
745 hf_ntlmssp_negotiate_domain,
746 &start, &workstation_end);
747 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
748 hf_ntlmssp_negotiate_workstation,
749 &start, &domain_end);
751 /* XXX - two blobs after this one, sometimes? */
753 return MAX(workstation_end, domain_end);
758 dissect_ntlmssp_address_list (tvbuff_t *tvb, int offset,
759 proto_tree *ntlmssp_tree,
762 guint16 list_length = tvb_get_letohs(tvb, offset);
763 guint16 list_maxlen = tvb_get_letohs(tvb, offset+2);
764 guint32 list_offset = tvb_get_letohl(tvb, offset+4);
765 guint16 item_type, item_length;
767 proto_item *tf = NULL;
768 proto_tree *tree = NULL;
769 proto_item *addr_tf = NULL;
770 proto_tree *addr_tree = NULL;
772 /* the address list is just a blob */
773 if (0 == list_length) {
774 *end = (list_offset > ((guint)offset)+8 ? list_offset : ((guint)offset)+8);
776 proto_tree_add_text(ntlmssp_tree, tvb, offset, 8,
777 "Address List: Empty");
782 tf = proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_address_list, tvb,
783 list_offset, list_length, FALSE);
784 tree = proto_item_add_subtree(tf, ett_ntlmssp_address_list);
786 proto_tree_add_uint(tree, hf_ntlmssp_address_list_len,
787 tvb, offset, 2, list_length);
789 proto_tree_add_uint(tree, hf_ntlmssp_address_list_maxlen,
790 tvb, offset, 2, list_maxlen);
792 proto_tree_add_uint(tree, hf_ntlmssp_address_list_offset,
793 tvb, offset, 4, list_offset);
796 /* Now enumerate through the individual items in the list */
797 item_offset = list_offset;
799 while (item_offset < (list_offset + list_length)) {
800 const char *text=NULL;
801 guint32 content_offset;
802 guint16 content_length;
807 type_offset = item_offset;
808 item_type = tvb_get_letohs(tvb, type_offset);
811 len_offset = type_offset + 2;
812 content_length = tvb_get_letohs(tvb, len_offset);
815 content_offset = len_offset + 2;
816 item_length = content_length + 4;
818 /* Strings are always in Unicode regardless of the negotiated
820 if (content_length > 0) {
825 item_offset_int = content_offset;
827 text = get_unicode_or_ascii_string(tvb, &item_offset_int,
828 TRUE, &result_length,
832 if (!text) text = ""; /* Make sure we don't blow up below */
835 case NTLM_NAME_NB_HOST:
836 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_server_nb,
837 tvb, item_offset, item_length, text);
839 case NTLM_NAME_NB_DOMAIN:
840 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_domain_nb,
841 tvb, item_offset, item_length, text);
843 case NTLM_NAME_DNS_HOST:
844 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_server_dns,
845 tvb, item_offset, item_length, text);
847 case NTLM_NAME_DNS_DOMAIN:
848 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_domain_dns,
849 tvb, item_offset, item_length, text);
852 addr_tf = proto_tree_add_item(tree, hf_ntlmssp_address_list_terminator,
853 tvb, item_offset, item_length, TRUE);
856 /* Now show the actual bytes that made up the summary line */
857 addr_tree = proto_item_add_subtree (addr_tf,
858 ett_ntlmssp_address_list_item);
859 proto_tree_add_item (addr_tree, hf_ntlmssp_address_list_item_type,
860 tvb, type_offset, 2, TRUE);
861 proto_tree_add_item (addr_tree, hf_ntlmssp_address_list_item_len,
862 tvb, len_offset, 2, TRUE);
863 if (content_length > 0) {
864 proto_tree_add_string(addr_tree, hf_ntlmssp_address_list_item_content,
865 tvb, content_offset, content_length, text);
868 item_offset += item_length;
871 *end = list_offset + list_length;
876 dissect_ntlmssp_challenge (tvbuff_t *tvb, packet_info *pinfo, int offset,
877 proto_tree *ntlmssp_tree)
879 guint32 negotiate_flags;
880 int item_start, item_end;
881 int data_start, data_end;
882 ntlmssp_info *conv_ntlmssp_info;
883 conversation_t *conversation;
884 gboolean unicode_strings = FALSE;
886 guint8 sspkey[16]; /* NTLMSSP cipher key */
887 guint8 ssp_key_len; /* Either 8 or 16 (40 bit or 128) */
889 /* need to find unicode flag */
890 negotiate_flags = tvb_get_letohl (tvb, offset+8);
891 if (negotiate_flags & NTLMSSP_NEGOTIATE_UNICODE)
892 unicode_strings = TRUE;
896 * XXX - the davenport document calls this the "Target Name",
897 * presumably because non-domain targets are supported.
899 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, unicode_strings,
900 hf_ntlmssp_challenge_domain,
901 &item_start, &item_end);
902 data_start = item_start;
905 /* NTLMSSP Negotiate Flags */
906 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
909 /* NTLMSSP NT Lan Manager Challenge */
910 proto_tree_add_item (ntlmssp_tree,
911 hf_ntlmssp_ntlm_challenge,
912 tvb, offset, 8, FALSE);
915 * Store the flags and the RC4 state information with the conversation,
916 * as they're needed in order to dissect subsequent messages.
918 conversation = find_conversation(&pinfo->src, &pinfo->dst,
919 pinfo->ptype, pinfo->srcport,
921 if (!conversation) { /* Create one */
922 conversation = conversation_new(&pinfo->src, &pinfo->dst, pinfo->ptype,
923 pinfo->srcport, pinfo->destport, 0);
926 if (!conversation_get_proto_data(conversation, proto_ntlmssp)) {
927 conv_ntlmssp_info = g_mem_chunk_alloc(ntlmssp_info_chunk);
928 /* Insert the flags into the conversation */
929 conv_ntlmssp_info->flags = negotiate_flags;
930 /* Insert the RC4 state information into the conversation */
931 tvb_memcpy(tvb, challenge, offset, 8);
933 /* Between the challenge and the user provided password, we can build the
934 NTLMSSP key and initialize the cipher */
935 if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_128) {
936 create_ntlmssp_v1_key(nt_password, challenge, 1, sspkey);
940 create_ntlmssp_v1_key(nt_password, challenge, 0, sspkey);
943 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_peer1, sspkey, ssp_key_len);
944 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_peer2, sspkey, ssp_key_len);
945 conv_ntlmssp_info->peer1_dest_port = pinfo->destport;
946 conv_ntlmssp_info->rc4_state_initialized = 1;
948 conversation_add_proto_data(conversation, proto_ntlmssp, conv_ntlmssp_info);
952 /* Reserved (function not completely known) */
954 * XXX - SSP key? The davenport document says
956 * The context field is typically populated when Negotiate Local
957 * Call is set. It contains an SSPI context handle, which allows
958 * the client to "short-circuit" authentication and effectively
959 * circumvent responding to the challenge. Physically, the context
960 * is two long values. This is covered in greater detail later,
961 * in the "Local Authentication" section.
963 * It also says that that information may be omitted.
965 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_reserved,
966 tvb, offset, 8, FALSE);
970 * The presence or absence of this field is not obviously correlated
971 * with any flags in the previous NEGOTIATE message or in this
972 * message (other than the "Workstation Supplied" and "Domain
973 * Supplied" flags in the NEGOTIATE message, at least in the capture
974 * I've seen - but those also correlate with the presence of workstation
975 * and domain name fields, so it doesn't seem to make sense that they
976 * actually *indicate* whether the subsequent CHALLENGE has an
979 if (offset < data_start) {
980 offset = dissect_ntlmssp_address_list(tvb, offset, ntlmssp_tree, &item_end);
981 data_end = MAX(data_end, item_end);
984 return MAX(offset, data_end);
988 dissect_ntlmssp_auth (tvbuff_t *tvb, packet_info *pinfo, int offset,
989 proto_tree *ntlmssp_tree)
991 int item_start, item_end;
992 int data_start, data_end = 0;
993 guint32 negotiate_flags;
994 gboolean unicode_strings = FALSE;
995 ntlmssp_info *conv_ntlmssp_info;
996 conversation_t *conversation;
999 * Get flag info from the original negotiate message, if any.
1000 * This is because the flag information is sometimes missing from
1001 * the AUTHENTICATE message, so we can't figure out whether
1002 * strings are Unicode or not by looking at *our* flags.
1004 conv_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1005 if (conv_ntlmssp_info == NULL) {
1007 * There isn't any. Is there any from this conversation? If so,
1008 * it means this is the first time we've dissected this frame, so
1009 * we should give it flag info.
1011 conversation = find_conversation(&pinfo->src, &pinfo->dst,
1012 pinfo->ptype, pinfo->srcport,
1013 pinfo->destport, 0);
1014 if (conversation != NULL) {
1015 conv_ntlmssp_info = conversation_get_proto_data(conversation, proto_ntlmssp);
1016 if (conv_ntlmssp_info != NULL) {
1018 * We have flag info; attach it to the frame.
1020 p_add_proto_data(pinfo->fd, proto_ntlmssp, conv_ntlmssp_info);
1024 if (conv_ntlmssp_info != NULL) {
1025 if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_UNICODE)
1026 unicode_strings = TRUE;
1030 * Sometimes the session key and flags are missing.
1031 * Sometimes the session key is present but the flags are missing.
1032 * Sometimes they're both present.
1034 * This does not correlate with any flags in the previous CHALLENGE
1035 * message, and only correlates with "Negotiate Unicode", "Workstation
1036 * Supplied", and "Domain Supplied" in the NEGOTIATE message - but
1037 * those don't make sense as flags to use to determine this.
1039 * So we check all of the descriptors to figure out where the data
1040 * area begins, and if the session key or the flags would be in the
1041 * middle of the data area, we assume the field in question is
1045 /* Lan Manager response */
1046 data_start = tvb_get_letohl(tvb, offset+4);
1047 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
1048 hf_ntlmssp_auth_lmresponse,
1050 conv_ntlmssp_info == NULL ? NULL :
1051 &conv_ntlmssp_info->lm_response);
1052 data_end = MAX(data_end, item_end);
1055 item_start = tvb_get_letohl(tvb, offset+4);
1056 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
1057 hf_ntlmssp_auth_ntresponse,
1059 conv_ntlmssp_info == NULL ? NULL :
1060 &conv_ntlmssp_info->ntlm_response);
1061 data_start = MIN(data_start, item_start);
1062 data_end = MAX(data_end, item_end);
1065 item_start = tvb_get_letohl(tvb, offset+4);
1066 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
1068 hf_ntlmssp_auth_domain,
1069 &item_start, &item_end);
1070 data_start = MIN(data_start, item_start);
1071 data_end = MAX(data_end, item_end);
1074 item_start = tvb_get_letohl(tvb, offset+4);
1075 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
1077 hf_ntlmssp_auth_username,
1078 &item_start, &item_end);
1079 data_start = MIN(data_start, item_start);
1080 data_end = MAX(data_end, item_end);
1083 item_start = tvb_get_letohl(tvb, offset+4);
1084 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
1086 hf_ntlmssp_auth_hostname,
1087 &item_start, &item_end);
1088 data_start = MIN(data_start, item_start);
1089 data_end = MAX(data_end, item_end);
1091 if (offset < data_start) {
1093 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
1094 hf_ntlmssp_auth_sesskey,
1096 data_end = MAX(data_end, item_end);
1099 if (offset < data_start) {
1100 /* NTLMSSP Negotiate Flags */
1101 negotiate_flags = tvb_get_letohl (tvb, offset);
1102 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
1106 return MAX(offset, data_end);
1110 dissect_ntlmssp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1112 guint32 ntlmssp_message_type;
1113 volatile int offset = 0;
1114 proto_tree *volatile ntlmssp_tree = NULL;
1115 proto_item *tf = NULL;
1117 /* Setup a new tree for the NTLMSSP payload */
1119 tf = proto_tree_add_item (tree,
1121 tvb, offset, -1, FALSE);
1123 ntlmssp_tree = proto_item_add_subtree (tf,
1128 * Catch the ReportedBoundsError exception; the stuff we've been
1129 * handed doesn't necessarily run to the end of the packet, it's
1130 * an item inside a packet, so if it happens to be malformed (or
1131 * we, or a dissector we call, has a bug), so that an exception
1132 * is thrown, we want to report the error, but return and let
1133 * our caller dissect the rest of the packet.
1135 * If it gets a BoundsError, we can stop, as there's nothing more
1136 * in the packet after our blob to see, so we just re-throw the
1140 /* NTLMSSP constant */
1141 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth,
1142 tvb, offset, 8, FALSE);
1145 /* NTLMSSP Message Type */
1146 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_message_type,
1147 tvb, offset, 4, TRUE);
1148 ntlmssp_message_type = tvb_get_letohl (tvb, offset);
1151 if (check_col(pinfo->cinfo, COL_INFO))
1152 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
1153 val_to_str(ntlmssp_message_type,
1154 ntlmssp_message_types,
1155 "Unknown message type"));
1157 /* Call the appropriate dissector based on the Message Type */
1158 switch (ntlmssp_message_type) {
1160 case NTLMSSP_NEGOTIATE:
1161 offset = dissect_ntlmssp_negotiate (tvb, offset, ntlmssp_tree);
1164 case NTLMSSP_CHALLENGE:
1165 offset = dissect_ntlmssp_challenge (tvb, pinfo, offset, ntlmssp_tree);
1169 offset = dissect_ntlmssp_auth (tvb, pinfo, offset, ntlmssp_tree);
1173 /* Unrecognized message type */
1174 proto_tree_add_text (ntlmssp_tree, tvb, offset, -1,
1175 "Unrecognized NTLMSSP Message");
1178 } CATCH(BoundsError) {
1180 } CATCH(ReportedBoundsError) {
1181 show_reported_bounds_error(tvb, pinfo, tree);
1186 * Get the encryption state tied to this conversation. cryptpeer indicates
1187 * whether to retrieve the data for peer1 or peer2.
1189 static rc4_state_struct *
1190 get_encrypted_state(packet_info *pinfo, int cryptpeer)
1192 conversation_t *conversation;
1193 ntlmssp_info *conv_ntlmssp_info;
1195 conversation = find_conversation(&pinfo->src, &pinfo->dst,
1196 pinfo->ptype, pinfo->srcport,
1197 pinfo->destport, 0);
1198 if (conversation == NULL) {
1199 /* We don't have a conversation. In this case, stop processing
1200 because we do not have enough info to decrypt the payload */
1204 /* We have a conversation, check for encryption state */
1205 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1207 if (conv_ntlmssp_info == NULL) {
1208 /* No encryption state tied to the conversation. Therefore, we
1209 cannot decrypt the payload */
1213 /* We have the encryption state in the conversation. So return the
1214 crypt state tied to the requested peer
1216 if (cryptpeer == 1) {
1217 return &conv_ntlmssp_info->rc4_state_peer1;
1219 return &conv_ntlmssp_info->rc4_state_peer2;
1227 * See page 45 of "DCE/RPC over SMB" by Luke Kenneth Casson Leighton.
1230 decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
1231 packet_info *pinfo, proto_tree *tree)
1233 proto_tree *decr_tree = NULL;
1234 proto_item *tf = NULL;
1235 conversation_t *conversation;
1236 rc4_state_struct *rc4_state;
1237 rc4_state_struct *rc4_state_peer;
1238 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
1240 ntlmssp_info *conv_ntlmssp_info = NULL;
1241 ntlmssp_packet_info *packet_ntlmssp_info = NULL;
1242 int decrypted_offset = 0;
1244 packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1245 if (packet_ntlmssp_info == NULL) {
1246 /* We don't have data for this packet */
1249 if (!packet_ntlmssp_info->verifier_decrypted) {
1250 conversation = find_conversation(&pinfo->src, &pinfo->dst,
1251 pinfo->ptype, pinfo->srcport,
1252 pinfo->destport, 0);
1253 if (conversation == NULL) {
1254 /* There is no conversation, thus no encryption state */
1258 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1260 if (conv_ntlmssp_info == NULL) {
1261 /* There is no NTLMSSP state tied to the conversation */
1264 if (conv_ntlmssp_info->rc4_state_initialized != 1 ) {
1265 /* The crypto sybsystem is not initialized. This means that either
1266 the conversation did not include a challenge, or we are doing
1267 something other than NTLMSSP v1 */
1271 if (conv_ntlmssp_info->peer1_dest_port == pinfo->destport) {
1272 rc4_state = get_encrypted_state(pinfo, 1);
1273 rc4_state_peer = get_encrypted_state(pinfo, 0);
1275 rc4_state = get_encrypted_state(pinfo, 0);
1276 rc4_state_peer = get_encrypted_state(pinfo, 1);
1279 if (rc4_state == NULL || rc4_state_peer == NULL) {
1280 /* There is no encryption state, so we cannot decrypt */
1284 /* Setup the buffer to decrypt to */
1285 tvb_memcpy(tvb, packet_ntlmssp_info->verifier,
1286 offset, encrypted_block_length);
1288 /* Do the actual decryption of the verifier */
1289 crypt_rc4(rc4_state, packet_ntlmssp_info->verifier,
1290 encrypted_block_length);
1292 /* We setup a temporary buffer so we can re-encrypt the payload after
1293 decryption. This is to update the opposite peer's RC4 state */
1294 peer_block = g_malloc(encrypted_block_length);
1295 memcpy(peer_block, packet_ntlmssp_info->verifier,
1296 encrypted_block_length);
1297 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
1300 /* Mark the packet as decrypted so that subsequent attempts to dissect
1301 the packet use the already decrypted payload instead of attempting
1303 packet_ntlmssp_info->verifier_decrypted = TRUE;
1306 /* Show the decrypted buffer in a new window */
1307 decr_tvb = tvb_new_real_data(packet_ntlmssp_info->verifier,
1308 encrypted_block_length,
1309 encrypted_block_length);
1310 tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
1311 add_new_data_source(pinfo, decr_tvb,
1312 "Decrypted NTLMSSP Verifier");
1314 /* Show the decrypted payload in the tree */
1315 tf = proto_tree_add_text(tree, decr_tvb, 0, -1,
1316 "Decrypted Verifier (%d byte%s)",
1317 encrypted_block_length,
1318 plurality(encrypted_block_length, "", "s"));
1319 decr_tree = proto_item_add_subtree (tf, ett_ntlmssp);
1321 /* LKCL page 45 says this is a "reserved" field. I'm not sure if it's
1322 garbage because it's some sort of nonce, or because there is a problem
1323 with the verifier decryption routine. */
1324 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_unknown1,
1325 decr_tvb, decrypted_offset, 4, TRUE);
1326 decrypted_offset += 4;
1328 /* CRC32 of the DCE fragment data */
1329 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_crc32,
1330 decr_tvb, decrypted_offset, 4, TRUE);
1331 decrypted_offset += 4;
1333 /* Incrementing sequence number of DCE conversation */
1334 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_sequence,
1335 decr_tvb, decrypted_offset, 4, TRUE);
1336 decrypted_offset += 4;
1340 dissect_ntlmssp_verf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1342 volatile int offset = 0;
1343 proto_tree *volatile ntlmssp_tree = NULL;
1344 proto_item *tf = NULL;
1345 guint32 verifier_length;
1346 guint32 encrypted_block_length;
1348 verifier_length = tvb_length_remaining (tvb, offset);
1349 encrypted_block_length = verifier_length - 4;
1351 if (encrypted_block_length < 12) {
1352 /* Don't know why this would happen, but if it does, don't even bother
1353 attempting decryption/dissection */
1354 return offset + verifier_length;
1357 /* Setup a new tree for the NTLMSSP payload */
1359 tf = proto_tree_add_item (tree,
1361 tvb, offset, -1, FALSE);
1363 ntlmssp_tree = proto_item_add_subtree (tf,
1368 * Catch the ReportedBoundsError exception; the stuff we've been
1369 * handed doesn't necessarily run to the end of the packet, it's
1370 * an item inside a packet, so if it happens to be malformed (or
1371 * we, or a dissector we call, has a bug), so that an exception
1372 * is thrown, we want to report the error, but return and let
1373 * our caller dissect the rest of the packet.
1375 * If it gets a BoundsError, we can stop, as there's nothing more
1376 * in the packet after our blob to see, so we just re-throw the
1380 /* Version number */
1381 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_vers,
1382 tvb, offset, 4, TRUE);
1385 /* Encrypted body */
1386 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_body,
1387 tvb, offset, encrypted_block_length, TRUE);
1389 /* Try to decrypt */
1390 decrypt_verifier (tvb, offset, encrypted_block_length, pinfo, ntlmssp_tree);
1392 offset += encrypted_block_length;
1393 } CATCH(BoundsError) {
1395 } CATCH(ReportedBoundsError) {
1396 show_reported_bounds_error(tvb, pinfo, tree);
1403 dissect_ntlmssp_encrypted_payload(tvbuff_t *tvb, int offset,
1405 dcerpc_auth_info *auth_info _U_)
1407 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
1409 conversation_t *conversation;
1410 guint32 encrypted_block_length;
1411 rc4_state_struct *rc4_state;
1412 rc4_state_struct *rc4_state_peer;
1413 ntlmssp_info *conv_ntlmssp_info = NULL;
1414 ntlmssp_packet_info *packet_ntlmssp_info = NULL;
1416 encrypted_block_length = tvb_length_remaining (tvb, offset);
1418 /* Check to see if we already have state for this packet */
1419 packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1420 if (packet_ntlmssp_info == NULL) {
1421 /* We don't have any packet state, so create one */
1422 packet_ntlmssp_info = g_mem_chunk_alloc(ntlmssp_packet_info_chunk);
1423 memset(packet_ntlmssp_info, 0, sizeof(ntlmssp_packet_info));
1424 p_add_proto_data(pinfo->fd, proto_ntlmssp, packet_ntlmssp_info);
1427 if (!packet_ntlmssp_info->payload_decrypted) {
1428 /* Pull the challenge info from the conversation */
1429 conversation = find_conversation(&pinfo->src, &pinfo->dst,
1430 pinfo->ptype, pinfo->srcport,
1431 pinfo->destport, 0);
1432 if (conversation == NULL) {
1433 /* There is no conversation, thus no encryption state */
1437 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1439 if (conv_ntlmssp_info == NULL) {
1440 /* There is no NTLMSSP state tied to the conversation */
1444 /* Get the pair of RC4 state structures. One is used for to decrypt the
1445 payload. The other is used to re-encrypt the payload to represent
1447 if (conv_ntlmssp_info->peer1_dest_port == pinfo->destport) {
1448 rc4_state = get_encrypted_state(pinfo, 1);
1449 rc4_state_peer = get_encrypted_state(pinfo, 0);
1451 rc4_state = get_encrypted_state(pinfo, 0);
1452 rc4_state_peer = get_encrypted_state(pinfo, 1);
1455 if (rc4_state == NULL || rc4_state_peer == NULL) {
1456 /* There is no encryption state, so we cannot decrypt */
1460 /* Store the decrypted contents in the packet state struct
1461 (of course at this point, they aren't decrypted yet) */
1462 packet_ntlmssp_info->decrypted_payload = tvb_memdup(tvb, offset,
1463 encrypted_block_length);
1464 decrypted_payloads = g_slist_prepend(decrypted_payloads,
1465 packet_ntlmssp_info->decrypted_payload);
1467 /* Do the decryption of the payload */
1468 crypt_rc4(rc4_state, packet_ntlmssp_info->decrypted_payload,
1469 encrypted_block_length);
1471 /* We setup a temporary buffer so we can re-encrypt the payload after
1472 decryption. This is to update the opposite peer's RC4 state */
1473 peer_block = g_malloc(encrypted_block_length);
1474 memcpy(peer_block, packet_ntlmssp_info->decrypted_payload,
1475 encrypted_block_length);
1476 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
1479 packet_ntlmssp_info->payload_decrypted = TRUE;
1482 /* Show the decrypted buffer in a new window */
1483 decr_tvb = tvb_new_real_data(packet_ntlmssp_info->decrypted_payload,
1484 encrypted_block_length,
1485 encrypted_block_length);
1487 tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
1489 offset += encrypted_block_length;
1495 free_payload(gpointer decrypted_payload, gpointer user_data _U_)
1497 g_free(decrypted_payload);
1501 ntlmssp_init_protocol(void)
1503 if (ntlmssp_info_chunk != NULL)
1504 g_mem_chunk_destroy(ntlmssp_info_chunk);
1505 if (ntlmssp_packet_info_chunk != NULL)
1506 g_mem_chunk_destroy(ntlmssp_packet_info_chunk);
1509 * Free the decrypted payloads, and then free the list of decrypted
1512 if (decrypted_payloads != NULL) {
1513 g_slist_foreach(decrypted_payloads, free_payload, NULL);
1514 g_slist_free(decrypted_payloads);
1515 decrypted_payloads = NULL;
1518 ntlmssp_info_chunk = g_mem_chunk_new("ntlmssp_info_chunk",
1519 sizeof(ntlmssp_info),
1520 ntlmssp_info_count * sizeof(ntlmssp_info),
1522 ntlmssp_packet_info_chunk = g_mem_chunk_new("ntlmssp_packet_info_chunk",
1523 sizeof(ntlmssp_packet_info),
1524 ntlmssp_packet_info_count * sizeof(ntlmssp_packet_info),
1529 proto_register_ntlmssp(void)
1532 static hf_register_info hf[] = {
1534 { "NTLMSSP", "ntlmssp", FT_NONE, BASE_NONE, NULL, 0x0, "NTLMSSP", HFILL }},
1536 { "NTLMSSP identifier", "ntlmssp.identifier", FT_STRING, BASE_NONE, NULL, 0x0, "NTLMSSP Identifier", HFILL }},
1537 { &hf_ntlmssp_message_type,
1538 { "NTLM Message Type", "ntlmssp.messagetype", FT_UINT32, BASE_HEX, VALS(ntlmssp_message_types), 0x0, "", HFILL }},
1539 { &hf_ntlmssp_negotiate_flags,
1540 { "Flags", "ntlmssp.negotiateflags", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1541 { &hf_ntlmssp_negotiate_flags_01,
1542 { "Negotiate UNICODE", "ntlmssp.negotiateunicode", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_UNICODE, "", HFILL }},
1543 { &hf_ntlmssp_negotiate_flags_02,
1544 { "Negotiate OEM", "ntlmssp.negotiateoem", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_OEM, "", HFILL }},
1545 { &hf_ntlmssp_negotiate_flags_04,
1546 { "Request Target", "ntlmssp.requesttarget", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_REQUEST_TARGET, "", HFILL }},
1547 { &hf_ntlmssp_negotiate_flags_08,
1548 { "Request 0x00000008", "ntlmssp.negotiate00000008", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000008, "", HFILL }},
1549 { &hf_ntlmssp_negotiate_flags_10,
1550 { "Negotiate Sign", "ntlmssp.negotiatesign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SIGN, "", HFILL }},
1551 { &hf_ntlmssp_negotiate_flags_20,
1552 { "Negotiate Seal", "ntlmssp.negotiateseal", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SEAL, "", HFILL }},
1553 { &hf_ntlmssp_negotiate_flags_40,
1554 { "Negotiate Datagram Style", "ntlmssp.negotiatedatagramstyle", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_DATAGRAM_STYLE, "", HFILL }},
1555 { &hf_ntlmssp_negotiate_flags_80,
1556 { "Negotiate Lan Manager Key", "ntlmssp.negotiatelmkey", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_LM_KEY, "", HFILL }},
1557 { &hf_ntlmssp_negotiate_flags_100,
1558 { "Negotiate Netware", "ntlmssp.negotiatenetware", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NETWARE, "", HFILL }},
1559 { &hf_ntlmssp_negotiate_flags_200,
1560 { "Negotiate NTLM key", "ntlmssp.negotiatentlm", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM, "", HFILL }},
1561 { &hf_ntlmssp_negotiate_flags_400,
1562 { "Negotiate 0x00000400", "ntlmssp.negotiate00000400", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000400, "", HFILL }},
1563 { &hf_ntlmssp_negotiate_flags_800,
1564 { "Negotiate 0x00000800", "ntlmssp.negotiate00000800", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000800, "", HFILL }},
1565 { &hf_ntlmssp_negotiate_flags_1000,
1566 { "Negotiate Domain Supplied", "ntlmssp.negotiatedomainsupplied", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED, "", HFILL }},
1567 { &hf_ntlmssp_negotiate_flags_2000,
1568 { "Negotiate Workstation Supplied", "ntlmssp.negotiateworkstationsupplied", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED, "", HFILL }},
1569 { &hf_ntlmssp_negotiate_flags_4000,
1570 { "Negotiate This is Local Call", "ntlmssp.negotiatethisislocalcall", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL, "", HFILL }},
1571 { &hf_ntlmssp_negotiate_flags_8000,
1572 { "Negotiate Always Sign", "ntlmssp.negotiatealwayssign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_ALWAYS_SIGN, "", HFILL }},
1573 { &hf_ntlmssp_negotiate_flags_10000,
1574 { "Negotiate Challenge Init Response", "ntlmssp.negotiatechallengeinitresponse", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_INIT_RESPONSE, "", HFILL }},
1575 { &hf_ntlmssp_negotiate_flags_20000,
1576 { "Negotiate Challenge Accept Response", "ntlmssp.negotiatechallengeacceptresponse", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_ACCEPT_RESPONSE, "", HFILL }},
1577 { &hf_ntlmssp_negotiate_flags_40000,
1578 { "Negotiate Challenge Non NT Session Key", "ntlmssp.negotiatechallengenonntsessionkey", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_NON_NT_SESSION_KEY, "", HFILL }},
1579 { &hf_ntlmssp_negotiate_flags_80000,
1580 { "Negotiate NTLM2 key", "ntlmssp.negotiatentlm2", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM2, "", HFILL }},
1581 { &hf_ntlmssp_negotiate_flags_100000,
1582 { "Negotiate 0x00100000", "ntlmssp.negotiatent00100000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00100000, "", HFILL }},
1583 { &hf_ntlmssp_negotiate_flags_200000,
1584 { "Negotiate 0x00200000", "ntlmssp.negotiatent00200000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00200000, "", HFILL }},
1585 { &hf_ntlmssp_negotiate_flags_400000,
1586 { "Negotiate 0x00400000", "ntlmssp.negotiatent00400000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00400000, "", HFILL }},
1587 { &hf_ntlmssp_negotiate_flags_800000,
1588 { "Negotiate Target Info", "ntlmssp.negotiatetargetinfo", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_TARGET_INFO, "", HFILL }},
1589 { &hf_ntlmssp_negotiate_flags_1000000,
1590 { "Negotiate 0x01000000", "ntlmssp.negotiatent01000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_01000000, "", HFILL }},
1591 { &hf_ntlmssp_negotiate_flags_2000000,
1592 { "Negotiate 0x02000000", "ntlmssp.negotiatent02000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_02000000, "", HFILL }},
1593 { &hf_ntlmssp_negotiate_flags_4000000,
1594 { "Negotiate 0x04000000", "ntlmssp.negotiatent04000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_04000000, "", HFILL }},
1595 { &hf_ntlmssp_negotiate_flags_8000000,
1596 { "Negotiate 0x08000000", "ntlmssp.negotiatent08000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_08000000, "", HFILL }},
1597 { &hf_ntlmssp_negotiate_flags_10000000,
1598 { "Negotiate 0x10000000", "ntlmssp.negotiatent10000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_10000000, "", HFILL }},
1599 { &hf_ntlmssp_negotiate_flags_20000000,
1600 { "Negotiate 128", "ntlmssp.negotiate128", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_128, "128-bit encryption is supported", HFILL }},
1601 { &hf_ntlmssp_negotiate_flags_40000000,
1602 { "Negotiate Key Exchange", "ntlmssp.negotiatekeyexch", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_KEY_EXCH, "", HFILL }},
1603 { &hf_ntlmssp_negotiate_flags_80000000,
1604 { "Negotiate 56", "ntlmssp.negotiate56", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_56, "56-bit encryption is supported", HFILL }},
1605 { &hf_ntlmssp_negotiate_workstation_strlen,
1606 { "Calling workstation name length", "ntlmssp.negotiate.callingworkstation.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1607 { &hf_ntlmssp_negotiate_workstation_maxlen,
1608 { "Calling workstation name max length", "ntlmssp.negotiate.callingworkstation.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1609 { &hf_ntlmssp_negotiate_workstation_buffer,
1610 { "Calling workstation name buffer", "ntlmssp.negotiate.callingworkstation.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1611 { &hf_ntlmssp_negotiate_workstation,
1612 { "Calling workstation name", "ntlmssp.negotiate.callingworkstation", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1613 { &hf_ntlmssp_negotiate_domain_strlen,
1614 { "Calling workstation domain length", "ntlmssp.negotiate.domain.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1615 { &hf_ntlmssp_negotiate_domain_maxlen,
1616 { "Calling workstation domain max length", "ntlmssp.negotiate.domain.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1617 { &hf_ntlmssp_negotiate_domain_buffer,
1618 { "Calling workstation domain buffer", "ntlmssp.negotiate.domain.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1619 { &hf_ntlmssp_negotiate_domain,
1620 { "Calling workstation domain", "ntlmssp.negotiate.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1621 { &hf_ntlmssp_ntlm_challenge,
1622 { "NTLM Challenge", "ntlmssp.ntlmchallenge", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1623 { &hf_ntlmssp_reserved,
1624 { "Reserved", "ntlmssp.reserved", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1625 { &hf_ntlmssp_challenge_domain,
1626 { "Domain", "ntlmssp.challenge.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1627 { &hf_ntlmssp_auth_domain,
1628 { "Domain name", "ntlmssp.auth.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1629 { &hf_ntlmssp_auth_username,
1630 { "User name", "ntlmssp.auth.username", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1631 { &hf_ntlmssp_auth_hostname,
1632 { "Host name", "ntlmssp.auth.hostname", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1633 { &hf_ntlmssp_auth_lmresponse,
1634 { "Lan Manager Response", "ntlmssp.auth.lmresponse", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1635 { &hf_ntlmssp_auth_ntresponse,
1636 { "NTLM Response", "ntlmssp.auth.ntresponse", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1637 { &hf_ntlmssp_auth_sesskey,
1638 { "Session Key", "ntlmssp.auth.sesskey", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1639 { &hf_ntlmssp_string_len,
1640 { "Length", "ntlmssp.string.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1641 { &hf_ntlmssp_string_maxlen,
1642 { "Maxlen", "ntlmssp.string.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1643 { &hf_ntlmssp_string_offset,
1644 { "Offset", "ntlmssp.string.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1645 { &hf_ntlmssp_blob_len,
1646 { "Length", "ntlmssp.blob.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1647 { &hf_ntlmssp_blob_maxlen,
1648 { "Maxlen", "ntlmssp.blob.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1649 { &hf_ntlmssp_blob_offset,
1650 { "Offset", "ntlmssp.blob.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1651 { &hf_ntlmssp_address_list,
1652 { "Address List", "ntlmssp.challenge.addresslist", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL}},
1653 { &hf_ntlmssp_address_list_len,
1654 { "Length", "ntlmssp.challenge.addresslist.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1655 { &hf_ntlmssp_address_list_maxlen,
1656 { "Maxlen", "ntlmssp.challenge.addresslist.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1657 { &hf_ntlmssp_address_list_offset,
1658 { "Offset", "ntlmssp.challenge.addresslist.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1659 { &hf_ntlmssp_address_list_item_type,
1660 { "Target item type", "ntlmssp.targetitemtype", FT_UINT16, BASE_HEX, VALS(ntlm_name_types), 0x0, "", HFILL }},
1661 { &hf_ntlmssp_address_list_item_len,
1662 { "Target item Length", "ntlmssp.challenge.addresslist.item.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1663 { &hf_ntlmssp_address_list_item_content,
1664 { "Target item Content", "ntlmssp.challenge.addresslist.item.content", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL}},
1665 { &hf_ntlmssp_address_list_server_nb,
1666 { "Server NetBIOS Name", "ntlmssp.challenge.addresslist.servernb", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1667 { &hf_ntlmssp_address_list_domain_nb,
1668 { "Domain NetBIOS Name", "ntlmssp.challenge.addresslist.domainnb", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1669 { &hf_ntlmssp_address_list_server_dns,
1670 { "Server DNS Name", "ntlmssp.challenge.addresslist.serverdns", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1671 { &hf_ntlmssp_address_list_domain_dns,
1672 { "Domain DNS Name", "ntlmssp.challenge.addresslist.domaindns", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1673 { &hf_ntlmssp_address_list_terminator,
1674 { "List Terminator", "ntlmssp.challenge.addresslist.terminator", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
1676 { "NTLMSSP Verifier", "ntlmssp.verf", FT_NONE, BASE_NONE, NULL, 0x0, "NTLMSSP Verifier", HFILL }},
1677 { &hf_ntlmssp_verf_vers,
1678 { "Version Number", "ntlmssp.verf.vers", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
1679 { &hf_ntlmssp_verf_body,
1680 { "Verifier Body", "ntlmssp.verf.body", FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }},
1681 { &hf_ntlmssp_decrypted_payload,
1682 { "NTLM Decrypted Payload", "ntlmssp.decrypted_payload", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1683 { &hf_ntlmssp_verf_unknown1,
1684 { "Unknown 1", "ntlmssp.verf.unknown1", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1685 { &hf_ntlmssp_verf_crc32,
1686 { "Verifier CRC32", "ntlmssp.verf.crc32", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1687 { &hf_ntlmssp_verf_sequence,
1688 { "Verifier Sequence Number", "ntlmssp.verf.sequence", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
1689 { &hf_ntlmssp_ntlmv2_response,
1690 { "NTLMv2 Response", "ntlmssp.ntlmv2response", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1691 { &hf_ntlmssp_ntlmv2_response_hmac,
1692 { "HMAC", "ntlmssp.ntlmv2response.hmac", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1693 { &hf_ntlmssp_ntlmv2_response_header,
1694 { "Header", "ntlmssp.ntlmv2response.header", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1695 { &hf_ntlmssp_ntlmv2_response_reserved,
1696 { "Reserved", "ntlmssp.ntlmv2response.reserved", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1697 { &hf_ntlmssp_ntlmv2_response_time,
1698 { "Time", "ntlmssp.ntlmv2response.time", FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0, "", HFILL }},
1699 { &hf_ntlmssp_ntlmv2_response_chal,
1700 { "Client challenge", "ntlmssp.ntlmv2response.chal", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1701 { &hf_ntlmssp_ntlmv2_response_unknown,
1702 { "Unknown", "ntlmssp.ntlmv2response.unknown", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1703 { &hf_ntlmssp_ntlmv2_response_name,
1704 { "Name", "ntlmssp.ntlmv2response.name", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1705 { &hf_ntlmssp_ntlmv2_response_name_type,
1706 { "Name type", "ntlmssp.ntlmv2response.name.type", FT_UINT32, BASE_DEC, VALS(ntlm_name_types), 0x0, "", HFILL }},
1707 { &hf_ntlmssp_ntlmv2_response_name_len,
1708 { "Name len", "ntlmssp.ntlmv2response.name.len", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }}
1712 static gint *ett[] = {
1714 &ett_ntlmssp_negotiate_flags,
1715 &ett_ntlmssp_string,
1717 &ett_ntlmssp_address_list,
1718 &ett_ntlmssp_address_list_item,
1719 &ett_ntlmssp_ntlmv2_response,
1720 &ett_ntlmssp_ntlmv2_response_name
1722 module_t *ntlmssp_module;
1724 proto_ntlmssp = proto_register_protocol (
1725 "NTLM Secure Service Provider", /* name */
1726 "NTLMSSP", /* short name */
1727 "ntlmssp" /* abbrev */
1729 proto_register_field_array (proto_ntlmssp, hf, array_length (hf));
1730 proto_register_subtree_array (ett, array_length (ett));
1731 register_init_routine(&ntlmssp_init_protocol);
1733 ntlmssp_module = prefs_register_protocol(proto_ntlmssp, NULL);
1735 prefs_register_string_preference(ntlmssp_module, "nt_password",
1737 "NT Password (used to decrypt payloads)",
1740 register_dissector("ntlmssp", dissect_ntlmssp, proto_ntlmssp);
1741 new_register_dissector("ntlmssp_verf", dissect_ntlmssp_verf, proto_ntlmssp);
1744 static int wrap_dissect_ntlmssp(tvbuff_t *tvb, int offset, packet_info *pinfo,
1745 proto_tree *tree, guint8 *drep _U_)
1749 auth_tvb = tvb_new_subset(
1750 tvb, offset, tvb_length_remaining(tvb, offset),
1751 tvb_length_remaining(tvb, offset));
1753 dissect_ntlmssp(auth_tvb, pinfo, tree);
1755 return tvb_length_remaining(tvb, offset);
1758 static int wrap_dissect_ntlmssp_verf(tvbuff_t *tvb, int offset, packet_info *pinfo,
1759 proto_tree *tree, guint8 *drep _U_)
1763 auth_tvb = tvb_new_subset(
1764 tvb, offset, tvb_length_remaining(tvb, offset),
1765 tvb_length_remaining(tvb, offset));
1767 return dissect_ntlmssp_verf(auth_tvb, pinfo, tree);
1770 static dcerpc_auth_subdissector_fns ntlmssp_sign_fns = {
1771 wrap_dissect_ntlmssp, /* Bind */
1772 wrap_dissect_ntlmssp, /* Bind ACK */
1773 wrap_dissect_ntlmssp, /* AUTH3 */
1774 wrap_dissect_ntlmssp_verf, /* Request verifier */
1775 wrap_dissect_ntlmssp_verf, /* Response verifier */
1776 NULL, /* Request data */
1777 NULL /* Response data */
1780 static dcerpc_auth_subdissector_fns ntlmssp_seal_fns = {
1781 wrap_dissect_ntlmssp, /* Bind */
1782 wrap_dissect_ntlmssp, /* Bind ACK */
1783 wrap_dissect_ntlmssp, /* AUTH3 */
1784 wrap_dissect_ntlmssp_verf, /* Request verifier */
1785 wrap_dissect_ntlmssp_verf, /* Response verifier */
1786 dissect_ntlmssp_encrypted_payload, /* Request data */
1787 dissect_ntlmssp_encrypted_payload /* Response data */
1791 proto_reg_handoff_ntlmssp(void)
1793 dissector_handle_t ntlmssp_handle, ntlmssp_wrap_handle;
1795 /* Register protocol with the GSS-API module */
1797 ntlmssp_handle = find_dissector("ntlmssp");
1798 ntlmssp_wrap_handle = find_dissector("ntlmssp_verf");
1799 gssapi_init_oid("1.3.6.1.4.1.311.2.2.10", proto_ntlmssp, ett_ntlmssp,
1800 ntlmssp_handle, ntlmssp_wrap_handle,
1801 "NTLMSSP - Microsoft NTLM Security Support Provider");
1803 /* Register authenticated pipe dissector */
1806 * XXX - the verifiers here seem to have a version of 1 and a body of all
1809 * XXX - DCE_C_AUTHN_LEVEL_CONNECT is, according to the DCE RPC 1.1
1810 * spec, upgraded to DCE_C_AUTHN_LEVEL_PKT. Should we register
1811 * any other levels here?
1813 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_CONNECT,
1814 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
1817 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
1818 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
1821 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
1822 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,