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 <epan/asn1.h> /* XXX - needed for subid_t */
40 #include "packet-frame.h"
41 #include <epan/prefs.h>
42 #include <epan/crypt-rc4.h>
43 #include <epan/crypt-md4.h>
44 #include <epan/crypt-des.h>
45 #include "packet-dcerpc.h"
46 #include "packet-gssapi.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 */
724 * XXX - Windows puts 4 bytes of additional stuff here.
725 * Samba's smbclient doesn't.
726 * Both of them appear to be able to connect to W2K SMB
728 * Should we display the rest of the response as an
731 * XXX - we should also check whether we go past the length
738 dissect_ntlmssp_negotiate (tvbuff_t *tvb, int offset, proto_tree *ntlmssp_tree)
740 guint32 negotiate_flags;
745 /* NTLMSSP Negotiate Flags */
746 negotiate_flags = tvb_get_letohl (tvb, offset);
747 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
751 * XXX - the davenport document says that these might not be
752 * sent at all, presumably meaning the length of the message
753 * isn't enough to contain them.
755 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
756 hf_ntlmssp_negotiate_domain,
757 &start, &workstation_end);
758 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
759 hf_ntlmssp_negotiate_workstation,
760 &start, &domain_end);
762 /* XXX - two blobs after this one, sometimes? */
764 return MAX(workstation_end, domain_end);
769 dissect_ntlmssp_address_list (tvbuff_t *tvb, int offset,
770 proto_tree *ntlmssp_tree,
773 guint16 list_length = tvb_get_letohs(tvb, offset);
774 guint16 list_maxlen = tvb_get_letohs(tvb, offset+2);
775 guint32 list_offset = tvb_get_letohl(tvb, offset+4);
776 guint16 item_type, item_length;
778 proto_item *tf = NULL;
779 proto_tree *tree = NULL;
780 proto_item *addr_tf = NULL;
781 proto_tree *addr_tree = NULL;
783 /* the address list is just a blob */
784 if (0 == list_length) {
785 *end = (list_offset > ((guint)offset)+8 ? list_offset : ((guint)offset)+8);
787 proto_tree_add_text(ntlmssp_tree, tvb, offset, 8,
788 "Address List: Empty");
793 tf = proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_address_list, tvb,
794 list_offset, list_length, FALSE);
795 tree = proto_item_add_subtree(tf, ett_ntlmssp_address_list);
797 proto_tree_add_uint(tree, hf_ntlmssp_address_list_len,
798 tvb, offset, 2, list_length);
800 proto_tree_add_uint(tree, hf_ntlmssp_address_list_maxlen,
801 tvb, offset, 2, list_maxlen);
803 proto_tree_add_uint(tree, hf_ntlmssp_address_list_offset,
804 tvb, offset, 4, list_offset);
807 /* Now enumerate through the individual items in the list */
808 item_offset = list_offset;
810 while (item_offset < (list_offset + list_length)) {
811 const char *text=NULL;
812 guint32 content_offset;
813 guint16 content_length;
818 type_offset = item_offset;
819 item_type = tvb_get_letohs(tvb, type_offset);
822 len_offset = type_offset + 2;
823 content_length = tvb_get_letohs(tvb, len_offset);
826 content_offset = len_offset + 2;
827 item_length = content_length + 4;
829 /* Strings are always in Unicode regardless of the negotiated
831 if (content_length > 0) {
836 item_offset_int = content_offset;
838 text = get_unicode_or_ascii_string(tvb, &item_offset_int,
839 TRUE, &result_length,
843 if (!text) text = ""; /* Make sure we don't blow up below */
846 case NTLM_NAME_NB_HOST:
847 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_server_nb,
848 tvb, item_offset, item_length, text);
850 case NTLM_NAME_NB_DOMAIN:
851 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_domain_nb,
852 tvb, item_offset, item_length, text);
854 case NTLM_NAME_DNS_HOST:
855 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_server_dns,
856 tvb, item_offset, item_length, text);
858 case NTLM_NAME_DNS_DOMAIN:
859 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_domain_dns,
860 tvb, item_offset, item_length, text);
863 addr_tf = proto_tree_add_item(tree, hf_ntlmssp_address_list_terminator,
864 tvb, item_offset, item_length, TRUE);
867 /* Now show the actual bytes that made up the summary line */
868 addr_tree = proto_item_add_subtree (addr_tf,
869 ett_ntlmssp_address_list_item);
870 proto_tree_add_item (addr_tree, hf_ntlmssp_address_list_item_type,
871 tvb, type_offset, 2, TRUE);
872 proto_tree_add_item (addr_tree, hf_ntlmssp_address_list_item_len,
873 tvb, len_offset, 2, TRUE);
874 if (content_length > 0) {
875 proto_tree_add_string(addr_tree, hf_ntlmssp_address_list_item_content,
876 tvb, content_offset, content_length, text);
879 item_offset += item_length;
882 *end = list_offset + list_length;
887 dissect_ntlmssp_challenge (tvbuff_t *tvb, packet_info *pinfo, int offset,
888 proto_tree *ntlmssp_tree)
890 guint32 negotiate_flags;
891 int item_start, item_end;
892 int data_start, data_end;
893 ntlmssp_info *conv_ntlmssp_info;
894 conversation_t *conversation;
895 gboolean unicode_strings = FALSE;
897 guint8 sspkey[16]; /* NTLMSSP cipher key */
898 guint8 ssp_key_len; /* Either 8 or 16 (40 bit or 128) */
900 /* need to find unicode flag */
901 negotiate_flags = tvb_get_letohl (tvb, offset+8);
902 if (negotiate_flags & NTLMSSP_NEGOTIATE_UNICODE)
903 unicode_strings = TRUE;
907 * XXX - the davenport document calls this the "Target Name",
908 * presumably because non-domain targets are supported.
910 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, unicode_strings,
911 hf_ntlmssp_challenge_domain,
912 &item_start, &item_end);
913 data_start = item_start;
916 /* NTLMSSP Negotiate Flags */
917 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
920 /* NTLMSSP NT Lan Manager Challenge */
921 proto_tree_add_item (ntlmssp_tree,
922 hf_ntlmssp_ntlm_challenge,
923 tvb, offset, 8, FALSE);
926 * Store the flags and the RC4 state information with the conversation,
927 * as they're needed in order to dissect subsequent messages.
929 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
930 pinfo->ptype, pinfo->srcport,
932 if (!conversation) { /* Create one */
933 conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype,
934 pinfo->srcport, pinfo->destport, 0);
937 if (!conversation_get_proto_data(conversation, proto_ntlmssp)) {
938 conv_ntlmssp_info = g_mem_chunk_alloc(ntlmssp_info_chunk);
939 /* Insert the flags into the conversation */
940 conv_ntlmssp_info->flags = negotiate_flags;
941 /* Insert the RC4 state information into the conversation */
942 tvb_memcpy(tvb, challenge, offset, 8);
944 /* Between the challenge and the user provided password, we can build the
945 NTLMSSP key and initialize the cipher */
946 if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_128) {
947 create_ntlmssp_v1_key(nt_password, challenge, 1, sspkey);
951 create_ntlmssp_v1_key(nt_password, challenge, 0, sspkey);
954 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_peer1, sspkey, ssp_key_len);
955 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_peer2, sspkey, ssp_key_len);
956 conv_ntlmssp_info->peer1_dest_port = pinfo->destport;
957 conv_ntlmssp_info->rc4_state_initialized = 1;
959 conversation_add_proto_data(conversation, proto_ntlmssp, conv_ntlmssp_info);
963 /* Reserved (function not completely known) */
965 * XXX - SSP key? The davenport document says
967 * The context field is typically populated when Negotiate Local
968 * Call is set. It contains an SSPI context handle, which allows
969 * the client to "short-circuit" authentication and effectively
970 * circumvent responding to the challenge. Physically, the context
971 * is two long values. This is covered in greater detail later,
972 * in the "Local Authentication" section.
974 * It also says that that information may be omitted.
976 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_reserved,
977 tvb, offset, 8, FALSE);
981 * The presence or absence of this field is not obviously correlated
982 * with any flags in the previous NEGOTIATE message or in this
983 * message (other than the "Workstation Supplied" and "Domain
984 * Supplied" flags in the NEGOTIATE message, at least in the capture
985 * I've seen - but those also correlate with the presence of workstation
986 * and domain name fields, so it doesn't seem to make sense that they
987 * actually *indicate* whether the subsequent CHALLENGE has an
990 if (offset < data_start) {
991 offset = dissect_ntlmssp_address_list(tvb, offset, ntlmssp_tree, &item_end);
992 data_end = MAX(data_end, item_end);
995 return MAX(offset, data_end);
999 dissect_ntlmssp_auth (tvbuff_t *tvb, packet_info *pinfo, int offset,
1000 proto_tree *ntlmssp_tree)
1002 int item_start, item_end;
1003 int data_start, data_end = 0;
1004 guint32 negotiate_flags;
1005 gboolean unicode_strings = FALSE;
1006 ntlmssp_info *conv_ntlmssp_info;
1007 conversation_t *conversation;
1010 * Get flag info from the original negotiate message, if any.
1011 * This is because the flag information is sometimes missing from
1012 * the AUTHENTICATE message, so we can't figure out whether
1013 * strings are Unicode or not by looking at *our* flags.
1015 conv_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1016 if (conv_ntlmssp_info == NULL) {
1018 * There isn't any. Is there any from this conversation? If so,
1019 * it means this is the first time we've dissected this frame, so
1020 * we should give it flag info.
1022 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1023 pinfo->ptype, pinfo->srcport,
1024 pinfo->destport, 0);
1025 if (conversation != NULL) {
1026 conv_ntlmssp_info = conversation_get_proto_data(conversation, proto_ntlmssp);
1027 if (conv_ntlmssp_info != NULL) {
1029 * We have flag info; attach it to the frame.
1031 p_add_proto_data(pinfo->fd, proto_ntlmssp, conv_ntlmssp_info);
1035 if (conv_ntlmssp_info != NULL) {
1036 if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_UNICODE)
1037 unicode_strings = TRUE;
1041 * Sometimes the session key and flags are missing.
1042 * Sometimes the session key is present but the flags are missing.
1043 * Sometimes they're both present.
1045 * This does not correlate with any flags in the previous CHALLENGE
1046 * message, and only correlates with "Negotiate Unicode", "Workstation
1047 * Supplied", and "Domain Supplied" in the NEGOTIATE message - but
1048 * those don't make sense as flags to use to determine this.
1050 * So we check all of the descriptors to figure out where the data
1051 * area begins, and if the session key or the flags would be in the
1052 * middle of the data area, we assume the field in question is
1056 /* Lan Manager response */
1057 data_start = tvb_get_letohl(tvb, offset+4);
1058 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
1059 hf_ntlmssp_auth_lmresponse,
1061 conv_ntlmssp_info == NULL ? NULL :
1062 &conv_ntlmssp_info->lm_response);
1063 data_end = MAX(data_end, item_end);
1066 item_start = tvb_get_letohl(tvb, offset+4);
1067 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
1068 hf_ntlmssp_auth_ntresponse,
1070 conv_ntlmssp_info == NULL ? NULL :
1071 &conv_ntlmssp_info->ntlm_response);
1072 data_start = MIN(data_start, item_start);
1073 data_end = MAX(data_end, item_end);
1076 item_start = tvb_get_letohl(tvb, offset+4);
1077 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
1079 hf_ntlmssp_auth_domain,
1080 &item_start, &item_end);
1081 data_start = MIN(data_start, item_start);
1082 data_end = MAX(data_end, item_end);
1085 item_start = tvb_get_letohl(tvb, offset+4);
1086 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
1088 hf_ntlmssp_auth_username,
1089 &item_start, &item_end);
1090 data_start = MIN(data_start, item_start);
1091 data_end = MAX(data_end, item_end);
1094 item_start = tvb_get_letohl(tvb, offset+4);
1095 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
1097 hf_ntlmssp_auth_hostname,
1098 &item_start, &item_end);
1099 data_start = MIN(data_start, item_start);
1100 data_end = MAX(data_end, item_end);
1102 if (offset < data_start) {
1104 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
1105 hf_ntlmssp_auth_sesskey,
1107 data_end = MAX(data_end, item_end);
1110 if (offset < data_start) {
1111 /* NTLMSSP Negotiate Flags */
1112 negotiate_flags = tvb_get_letohl (tvb, offset);
1113 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
1117 return MAX(offset, data_end);
1121 dissect_ntlmssp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1123 guint32 ntlmssp_message_type;
1124 volatile int offset = 0;
1125 proto_tree *volatile ntlmssp_tree = NULL;
1126 proto_item *tf = NULL;
1128 /* Setup a new tree for the NTLMSSP payload */
1130 tf = proto_tree_add_item (tree,
1132 tvb, offset, -1, FALSE);
1134 ntlmssp_tree = proto_item_add_subtree (tf,
1139 * Catch the ReportedBoundsError exception; the stuff we've been
1140 * handed doesn't necessarily run to the end of the packet, it's
1141 * an item inside a packet, so if it happens to be malformed (or
1142 * we, or a dissector we call, has a bug), so that an exception
1143 * is thrown, we want to report the error, but return and let
1144 * our caller dissect the rest of the packet.
1146 * If it gets a BoundsError, we can stop, as there's nothing more
1147 * in the packet after our blob to see, so we just re-throw the
1151 /* NTLMSSP constant */
1152 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth,
1153 tvb, offset, 8, FALSE);
1156 /* NTLMSSP Message Type */
1157 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_message_type,
1158 tvb, offset, 4, TRUE);
1159 ntlmssp_message_type = tvb_get_letohl (tvb, offset);
1162 if (check_col(pinfo->cinfo, COL_INFO))
1163 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
1164 val_to_str(ntlmssp_message_type,
1165 ntlmssp_message_types,
1166 "Unknown message type"));
1168 /* Call the appropriate dissector based on the Message Type */
1169 switch (ntlmssp_message_type) {
1171 case NTLMSSP_NEGOTIATE:
1172 offset = dissect_ntlmssp_negotiate (tvb, offset, ntlmssp_tree);
1175 case NTLMSSP_CHALLENGE:
1176 offset = dissect_ntlmssp_challenge (tvb, pinfo, offset, ntlmssp_tree);
1180 offset = dissect_ntlmssp_auth (tvb, pinfo, offset, ntlmssp_tree);
1184 /* Unrecognized message type */
1185 proto_tree_add_text (ntlmssp_tree, tvb, offset, -1,
1186 "Unrecognized NTLMSSP Message");
1189 } CATCH(BoundsError) {
1191 } CATCH(ReportedBoundsError) {
1192 show_reported_bounds_error(tvb, pinfo, tree);
1197 * Get the encryption state tied to this conversation. cryptpeer indicates
1198 * whether to retrieve the data for peer1 or peer2.
1200 static rc4_state_struct *
1201 get_encrypted_state(packet_info *pinfo, int cryptpeer)
1203 conversation_t *conversation;
1204 ntlmssp_info *conv_ntlmssp_info;
1206 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1207 pinfo->ptype, pinfo->srcport,
1208 pinfo->destport, 0);
1209 if (conversation == NULL) {
1210 /* We don't have a conversation. In this case, stop processing
1211 because we do not have enough info to decrypt the payload */
1215 /* We have a conversation, check for encryption state */
1216 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1218 if (conv_ntlmssp_info == NULL) {
1219 /* No encryption state tied to the conversation. Therefore, we
1220 cannot decrypt the payload */
1224 /* We have the encryption state in the conversation. So return the
1225 crypt state tied to the requested peer
1227 if (cryptpeer == 1) {
1228 return &conv_ntlmssp_info->rc4_state_peer1;
1230 return &conv_ntlmssp_info->rc4_state_peer2;
1238 * See page 45 of "DCE/RPC over SMB" by Luke Kenneth Casson Leighton.
1241 decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
1242 packet_info *pinfo, proto_tree *tree)
1244 proto_tree *decr_tree = NULL;
1245 proto_item *tf = NULL;
1246 conversation_t *conversation;
1247 rc4_state_struct *rc4_state;
1248 rc4_state_struct *rc4_state_peer;
1249 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
1251 ntlmssp_info *conv_ntlmssp_info = NULL;
1252 ntlmssp_packet_info *packet_ntlmssp_info = NULL;
1253 int decrypted_offset = 0;
1255 packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1256 if (packet_ntlmssp_info == NULL) {
1257 /* We don't have data for this packet */
1260 if (!packet_ntlmssp_info->verifier_decrypted) {
1261 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1262 pinfo->ptype, pinfo->srcport,
1263 pinfo->destport, 0);
1264 if (conversation == NULL) {
1265 /* There is no conversation, thus no encryption state */
1269 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1271 if (conv_ntlmssp_info == NULL) {
1272 /* There is no NTLMSSP state tied to the conversation */
1275 if (conv_ntlmssp_info->rc4_state_initialized != 1 ) {
1276 /* The crypto sybsystem is not initialized. This means that either
1277 the conversation did not include a challenge, or we are doing
1278 something other than NTLMSSP v1 */
1282 if (conv_ntlmssp_info->peer1_dest_port == pinfo->destport) {
1283 rc4_state = get_encrypted_state(pinfo, 1);
1284 rc4_state_peer = get_encrypted_state(pinfo, 0);
1286 rc4_state = get_encrypted_state(pinfo, 0);
1287 rc4_state_peer = get_encrypted_state(pinfo, 1);
1290 if (rc4_state == NULL || rc4_state_peer == NULL) {
1291 /* There is no encryption state, so we cannot decrypt */
1295 /* Setup the buffer to decrypt to */
1296 tvb_memcpy(tvb, packet_ntlmssp_info->verifier,
1297 offset, encrypted_block_length);
1299 /* Do the actual decryption of the verifier */
1300 crypt_rc4(rc4_state, packet_ntlmssp_info->verifier,
1301 encrypted_block_length);
1303 /* We setup a temporary buffer so we can re-encrypt the payload after
1304 decryption. This is to update the opposite peer's RC4 state */
1305 peer_block = g_malloc(encrypted_block_length);
1306 memcpy(peer_block, packet_ntlmssp_info->verifier,
1307 encrypted_block_length);
1308 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
1311 /* Mark the packet as decrypted so that subsequent attempts to dissect
1312 the packet use the already decrypted payload instead of attempting
1314 packet_ntlmssp_info->verifier_decrypted = TRUE;
1317 /* Show the decrypted buffer in a new window */
1318 decr_tvb = tvb_new_real_data(packet_ntlmssp_info->verifier,
1319 encrypted_block_length,
1320 encrypted_block_length);
1321 tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
1322 add_new_data_source(pinfo, decr_tvb,
1323 "Decrypted NTLMSSP Verifier");
1325 /* Show the decrypted payload in the tree */
1326 tf = proto_tree_add_text(tree, decr_tvb, 0, -1,
1327 "Decrypted Verifier (%d byte%s)",
1328 encrypted_block_length,
1329 plurality(encrypted_block_length, "", "s"));
1330 decr_tree = proto_item_add_subtree (tf, ett_ntlmssp);
1332 /* LKCL page 45 says this is a "reserved" field. I'm not sure if it's
1333 garbage because it's some sort of nonce, or because there is a problem
1334 with the verifier decryption routine. */
1335 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_unknown1,
1336 decr_tvb, decrypted_offset, 4, TRUE);
1337 decrypted_offset += 4;
1339 /* CRC32 of the DCE fragment data */
1340 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_crc32,
1341 decr_tvb, decrypted_offset, 4, TRUE);
1342 decrypted_offset += 4;
1344 /* Incrementing sequence number of DCE conversation */
1345 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_sequence,
1346 decr_tvb, decrypted_offset, 4, TRUE);
1347 decrypted_offset += 4;
1351 dissect_ntlmssp_verf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1353 volatile int offset = 0;
1354 proto_tree *volatile ntlmssp_tree = NULL;
1355 proto_item *tf = NULL;
1356 guint32 verifier_length;
1357 guint32 encrypted_block_length;
1359 verifier_length = tvb_length_remaining (tvb, offset);
1360 encrypted_block_length = verifier_length - 4;
1362 if (encrypted_block_length < 12) {
1363 /* Don't know why this would happen, but if it does, don't even bother
1364 attempting decryption/dissection */
1365 return offset + verifier_length;
1368 /* Setup a new tree for the NTLMSSP payload */
1370 tf = proto_tree_add_item (tree,
1372 tvb, offset, -1, FALSE);
1374 ntlmssp_tree = proto_item_add_subtree (tf,
1379 * Catch the ReportedBoundsError exception; the stuff we've been
1380 * handed doesn't necessarily run to the end of the packet, it's
1381 * an item inside a packet, so if it happens to be malformed (or
1382 * we, or a dissector we call, has a bug), so that an exception
1383 * is thrown, we want to report the error, but return and let
1384 * our caller dissect the rest of the packet.
1386 * If it gets a BoundsError, we can stop, as there's nothing more
1387 * in the packet after our blob to see, so we just re-throw the
1391 /* Version number */
1392 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_vers,
1393 tvb, offset, 4, TRUE);
1396 /* Encrypted body */
1397 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_body,
1398 tvb, offset, encrypted_block_length, TRUE);
1400 /* Try to decrypt */
1401 decrypt_verifier (tvb, offset, encrypted_block_length, pinfo, ntlmssp_tree);
1403 offset += encrypted_block_length;
1404 } CATCH(BoundsError) {
1406 } CATCH(ReportedBoundsError) {
1407 show_reported_bounds_error(tvb, pinfo, tree);
1414 dissect_ntlmssp_encrypted_payload(tvbuff_t *data_tvb,
1415 tvbuff_t *auth_tvb _U_,
1418 dcerpc_auth_info *auth_info _U_)
1420 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
1422 conversation_t *conversation;
1423 guint32 encrypted_block_length;
1424 rc4_state_struct *rc4_state;
1425 rc4_state_struct *rc4_state_peer;
1426 ntlmssp_info *conv_ntlmssp_info = NULL;
1427 ntlmssp_packet_info *packet_ntlmssp_info = NULL;
1429 encrypted_block_length = tvb_length_remaining (data_tvb, offset);
1431 /* Check to see if we already have state for this packet */
1432 packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1433 if (packet_ntlmssp_info == NULL) {
1434 /* We don't have any packet state, so create one */
1435 packet_ntlmssp_info = g_mem_chunk_alloc(ntlmssp_packet_info_chunk);
1436 memset(packet_ntlmssp_info, 0, sizeof(ntlmssp_packet_info));
1437 p_add_proto_data(pinfo->fd, proto_ntlmssp, packet_ntlmssp_info);
1440 if (!packet_ntlmssp_info->payload_decrypted) {
1441 /* Pull the challenge info from the conversation */
1442 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1443 pinfo->ptype, pinfo->srcport,
1444 pinfo->destport, 0);
1445 if (conversation == NULL) {
1446 /* There is no conversation, thus no encryption state */
1450 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1452 if (conv_ntlmssp_info == NULL) {
1453 /* There is no NTLMSSP state tied to the conversation */
1457 /* Get the pair of RC4 state structures. One is used for to decrypt the
1458 payload. The other is used to re-encrypt the payload to represent
1460 if (conv_ntlmssp_info->peer1_dest_port == pinfo->destport) {
1461 rc4_state = get_encrypted_state(pinfo, 1);
1462 rc4_state_peer = get_encrypted_state(pinfo, 0);
1464 rc4_state = get_encrypted_state(pinfo, 0);
1465 rc4_state_peer = get_encrypted_state(pinfo, 1);
1468 if (rc4_state == NULL || rc4_state_peer == NULL) {
1469 /* There is no encryption state, so we cannot decrypt */
1473 /* Store the decrypted contents in the packet state struct
1474 (of course at this point, they aren't decrypted yet) */
1475 packet_ntlmssp_info->decrypted_payload = tvb_memdup(data_tvb, offset,
1476 encrypted_block_length);
1477 decrypted_payloads = g_slist_prepend(decrypted_payloads,
1478 packet_ntlmssp_info->decrypted_payload);
1480 /* Do the decryption of the payload */
1481 crypt_rc4(rc4_state, packet_ntlmssp_info->decrypted_payload,
1482 encrypted_block_length);
1484 /* We setup a temporary buffer so we can re-encrypt the payload after
1485 decryption. This is to update the opposite peer's RC4 state */
1486 peer_block = g_malloc(encrypted_block_length);
1487 memcpy(peer_block, packet_ntlmssp_info->decrypted_payload,
1488 encrypted_block_length);
1489 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
1492 packet_ntlmssp_info->payload_decrypted = TRUE;
1495 /* Show the decrypted buffer in a new window */
1496 decr_tvb = tvb_new_real_data(packet_ntlmssp_info->decrypted_payload,
1497 encrypted_block_length,
1498 encrypted_block_length);
1500 tvb_set_child_real_data_tvbuff(data_tvb, decr_tvb);
1502 offset += encrypted_block_length;
1508 free_payload(gpointer decrypted_payload, gpointer user_data _U_)
1510 g_free(decrypted_payload);
1514 ntlmssp_init_protocol(void)
1516 if (ntlmssp_info_chunk != NULL)
1517 g_mem_chunk_destroy(ntlmssp_info_chunk);
1518 if (ntlmssp_packet_info_chunk != NULL)
1519 g_mem_chunk_destroy(ntlmssp_packet_info_chunk);
1522 * Free the decrypted payloads, and then free the list of decrypted
1525 if (decrypted_payloads != NULL) {
1526 g_slist_foreach(decrypted_payloads, free_payload, NULL);
1527 g_slist_free(decrypted_payloads);
1528 decrypted_payloads = NULL;
1531 ntlmssp_info_chunk = g_mem_chunk_new("ntlmssp_info_chunk",
1532 sizeof(ntlmssp_info),
1533 ntlmssp_info_count * sizeof(ntlmssp_info),
1535 ntlmssp_packet_info_chunk = g_mem_chunk_new("ntlmssp_packet_info_chunk",
1536 sizeof(ntlmssp_packet_info),
1537 ntlmssp_packet_info_count * sizeof(ntlmssp_packet_info),
1542 proto_register_ntlmssp(void)
1545 static hf_register_info hf[] = {
1547 { "NTLMSSP", "ntlmssp", FT_NONE, BASE_NONE, NULL, 0x0, "NTLMSSP", HFILL }},
1549 { "NTLMSSP identifier", "ntlmssp.identifier", FT_STRING, BASE_NONE, NULL, 0x0, "NTLMSSP Identifier", HFILL }},
1550 { &hf_ntlmssp_message_type,
1551 { "NTLM Message Type", "ntlmssp.messagetype", FT_UINT32, BASE_HEX, VALS(ntlmssp_message_types), 0x0, "", HFILL }},
1552 { &hf_ntlmssp_negotiate_flags,
1553 { "Flags", "ntlmssp.negotiateflags", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1554 { &hf_ntlmssp_negotiate_flags_01,
1555 { "Negotiate UNICODE", "ntlmssp.negotiateunicode", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_UNICODE, "", HFILL }},
1556 { &hf_ntlmssp_negotiate_flags_02,
1557 { "Negotiate OEM", "ntlmssp.negotiateoem", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_OEM, "", HFILL }},
1558 { &hf_ntlmssp_negotiate_flags_04,
1559 { "Request Target", "ntlmssp.requesttarget", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_REQUEST_TARGET, "", HFILL }},
1560 { &hf_ntlmssp_negotiate_flags_08,
1561 { "Request 0x00000008", "ntlmssp.negotiate00000008", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000008, "", HFILL }},
1562 { &hf_ntlmssp_negotiate_flags_10,
1563 { "Negotiate Sign", "ntlmssp.negotiatesign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SIGN, "", HFILL }},
1564 { &hf_ntlmssp_negotiate_flags_20,
1565 { "Negotiate Seal", "ntlmssp.negotiateseal", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SEAL, "", HFILL }},
1566 { &hf_ntlmssp_negotiate_flags_40,
1567 { "Negotiate Datagram Style", "ntlmssp.negotiatedatagramstyle", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_DATAGRAM_STYLE, "", HFILL }},
1568 { &hf_ntlmssp_negotiate_flags_80,
1569 { "Negotiate Lan Manager Key", "ntlmssp.negotiatelmkey", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_LM_KEY, "", HFILL }},
1570 { &hf_ntlmssp_negotiate_flags_100,
1571 { "Negotiate Netware", "ntlmssp.negotiatenetware", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NETWARE, "", HFILL }},
1572 { &hf_ntlmssp_negotiate_flags_200,
1573 { "Negotiate NTLM key", "ntlmssp.negotiatentlm", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM, "", HFILL }},
1574 { &hf_ntlmssp_negotiate_flags_400,
1575 { "Negotiate 0x00000400", "ntlmssp.negotiate00000400", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000400, "", HFILL }},
1576 { &hf_ntlmssp_negotiate_flags_800,
1577 { "Negotiate 0x00000800", "ntlmssp.negotiate00000800", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000800, "", HFILL }},
1578 { &hf_ntlmssp_negotiate_flags_1000,
1579 { "Negotiate Domain Supplied", "ntlmssp.negotiatedomainsupplied", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED, "", HFILL }},
1580 { &hf_ntlmssp_negotiate_flags_2000,
1581 { "Negotiate Workstation Supplied", "ntlmssp.negotiateworkstationsupplied", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED, "", HFILL }},
1582 { &hf_ntlmssp_negotiate_flags_4000,
1583 { "Negotiate This is Local Call", "ntlmssp.negotiatethisislocalcall", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL, "", HFILL }},
1584 { &hf_ntlmssp_negotiate_flags_8000,
1585 { "Negotiate Always Sign", "ntlmssp.negotiatealwayssign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_ALWAYS_SIGN, "", HFILL }},
1586 { &hf_ntlmssp_negotiate_flags_10000,
1587 { "Negotiate Challenge Init Response", "ntlmssp.negotiatechallengeinitresponse", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_INIT_RESPONSE, "", HFILL }},
1588 { &hf_ntlmssp_negotiate_flags_20000,
1589 { "Negotiate Challenge Accept Response", "ntlmssp.negotiatechallengeacceptresponse", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_ACCEPT_RESPONSE, "", HFILL }},
1590 { &hf_ntlmssp_negotiate_flags_40000,
1591 { "Negotiate Challenge Non NT Session Key", "ntlmssp.negotiatechallengenonntsessionkey", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_NON_NT_SESSION_KEY, "", HFILL }},
1592 { &hf_ntlmssp_negotiate_flags_80000,
1593 { "Negotiate NTLM2 key", "ntlmssp.negotiatentlm2", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM2, "", HFILL }},
1594 { &hf_ntlmssp_negotiate_flags_100000,
1595 { "Negotiate 0x00100000", "ntlmssp.negotiatent00100000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00100000, "", HFILL }},
1596 { &hf_ntlmssp_negotiate_flags_200000,
1597 { "Negotiate 0x00200000", "ntlmssp.negotiatent00200000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00200000, "", HFILL }},
1598 { &hf_ntlmssp_negotiate_flags_400000,
1599 { "Negotiate 0x00400000", "ntlmssp.negotiatent00400000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00400000, "", HFILL }},
1600 { &hf_ntlmssp_negotiate_flags_800000,
1601 { "Negotiate Target Info", "ntlmssp.negotiatetargetinfo", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_TARGET_INFO, "", HFILL }},
1602 { &hf_ntlmssp_negotiate_flags_1000000,
1603 { "Negotiate 0x01000000", "ntlmssp.negotiatent01000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_01000000, "", HFILL }},
1604 { &hf_ntlmssp_negotiate_flags_2000000,
1605 { "Negotiate 0x02000000", "ntlmssp.negotiatent02000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_02000000, "", HFILL }},
1606 { &hf_ntlmssp_negotiate_flags_4000000,
1607 { "Negotiate 0x04000000", "ntlmssp.negotiatent04000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_04000000, "", HFILL }},
1608 { &hf_ntlmssp_negotiate_flags_8000000,
1609 { "Negotiate 0x08000000", "ntlmssp.negotiatent08000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_08000000, "", HFILL }},
1610 { &hf_ntlmssp_negotiate_flags_10000000,
1611 { "Negotiate 0x10000000", "ntlmssp.negotiatent10000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_10000000, "", HFILL }},
1612 { &hf_ntlmssp_negotiate_flags_20000000,
1613 { "Negotiate 128", "ntlmssp.negotiate128", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_128, "128-bit encryption is supported", HFILL }},
1614 { &hf_ntlmssp_negotiate_flags_40000000,
1615 { "Negotiate Key Exchange", "ntlmssp.negotiatekeyexch", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_KEY_EXCH, "", HFILL }},
1616 { &hf_ntlmssp_negotiate_flags_80000000,
1617 { "Negotiate 56", "ntlmssp.negotiate56", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_56, "56-bit encryption is supported", HFILL }},
1618 { &hf_ntlmssp_negotiate_workstation_strlen,
1619 { "Calling workstation name length", "ntlmssp.negotiate.callingworkstation.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1620 { &hf_ntlmssp_negotiate_workstation_maxlen,
1621 { "Calling workstation name max length", "ntlmssp.negotiate.callingworkstation.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1622 { &hf_ntlmssp_negotiate_workstation_buffer,
1623 { "Calling workstation name buffer", "ntlmssp.negotiate.callingworkstation.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1624 { &hf_ntlmssp_negotiate_workstation,
1625 { "Calling workstation name", "ntlmssp.negotiate.callingworkstation", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1626 { &hf_ntlmssp_negotiate_domain_strlen,
1627 { "Calling workstation domain length", "ntlmssp.negotiate.domain.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1628 { &hf_ntlmssp_negotiate_domain_maxlen,
1629 { "Calling workstation domain max length", "ntlmssp.negotiate.domain.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1630 { &hf_ntlmssp_negotiate_domain_buffer,
1631 { "Calling workstation domain buffer", "ntlmssp.negotiate.domain.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1632 { &hf_ntlmssp_negotiate_domain,
1633 { "Calling workstation domain", "ntlmssp.negotiate.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1634 { &hf_ntlmssp_ntlm_challenge,
1635 { "NTLM Challenge", "ntlmssp.ntlmchallenge", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1636 { &hf_ntlmssp_reserved,
1637 { "Reserved", "ntlmssp.reserved", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1638 { &hf_ntlmssp_challenge_domain,
1639 { "Domain", "ntlmssp.challenge.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1640 { &hf_ntlmssp_auth_domain,
1641 { "Domain name", "ntlmssp.auth.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1642 { &hf_ntlmssp_auth_username,
1643 { "User name", "ntlmssp.auth.username", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1644 { &hf_ntlmssp_auth_hostname,
1645 { "Host name", "ntlmssp.auth.hostname", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1646 { &hf_ntlmssp_auth_lmresponse,
1647 { "Lan Manager Response", "ntlmssp.auth.lmresponse", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1648 { &hf_ntlmssp_auth_ntresponse,
1649 { "NTLM Response", "ntlmssp.auth.ntresponse", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1650 { &hf_ntlmssp_auth_sesskey,
1651 { "Session Key", "ntlmssp.auth.sesskey", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1652 { &hf_ntlmssp_string_len,
1653 { "Length", "ntlmssp.string.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1654 { &hf_ntlmssp_string_maxlen,
1655 { "Maxlen", "ntlmssp.string.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1656 { &hf_ntlmssp_string_offset,
1657 { "Offset", "ntlmssp.string.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1658 { &hf_ntlmssp_blob_len,
1659 { "Length", "ntlmssp.blob.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1660 { &hf_ntlmssp_blob_maxlen,
1661 { "Maxlen", "ntlmssp.blob.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1662 { &hf_ntlmssp_blob_offset,
1663 { "Offset", "ntlmssp.blob.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1664 { &hf_ntlmssp_address_list,
1665 { "Address List", "ntlmssp.challenge.addresslist", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL}},
1666 { &hf_ntlmssp_address_list_len,
1667 { "Length", "ntlmssp.challenge.addresslist.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1668 { &hf_ntlmssp_address_list_maxlen,
1669 { "Maxlen", "ntlmssp.challenge.addresslist.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1670 { &hf_ntlmssp_address_list_offset,
1671 { "Offset", "ntlmssp.challenge.addresslist.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1672 { &hf_ntlmssp_address_list_item_type,
1673 { "Target item type", "ntlmssp.targetitemtype", FT_UINT16, BASE_HEX, VALS(ntlm_name_types), 0x0, "", HFILL }},
1674 { &hf_ntlmssp_address_list_item_len,
1675 { "Target item Length", "ntlmssp.challenge.addresslist.item.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1676 { &hf_ntlmssp_address_list_item_content,
1677 { "Target item Content", "ntlmssp.challenge.addresslist.item.content", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL}},
1678 { &hf_ntlmssp_address_list_server_nb,
1679 { "Server NetBIOS Name", "ntlmssp.challenge.addresslist.servernb", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1680 { &hf_ntlmssp_address_list_domain_nb,
1681 { "Domain NetBIOS Name", "ntlmssp.challenge.addresslist.domainnb", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1682 { &hf_ntlmssp_address_list_server_dns,
1683 { "Server DNS Name", "ntlmssp.challenge.addresslist.serverdns", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1684 { &hf_ntlmssp_address_list_domain_dns,
1685 { "Domain DNS Name", "ntlmssp.challenge.addresslist.domaindns", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1686 { &hf_ntlmssp_address_list_terminator,
1687 { "List Terminator", "ntlmssp.challenge.addresslist.terminator", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL }},
1689 { "NTLMSSP Verifier", "ntlmssp.verf", FT_NONE, BASE_NONE, NULL, 0x0, "NTLMSSP Verifier", HFILL }},
1690 { &hf_ntlmssp_verf_vers,
1691 { "Version Number", "ntlmssp.verf.vers", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
1692 { &hf_ntlmssp_verf_body,
1693 { "Verifier Body", "ntlmssp.verf.body", FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }},
1694 { &hf_ntlmssp_decrypted_payload,
1695 { "NTLM Decrypted Payload", "ntlmssp.decrypted_payload", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1696 { &hf_ntlmssp_verf_unknown1,
1697 { "Unknown 1", "ntlmssp.verf.unknown1", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1698 { &hf_ntlmssp_verf_crc32,
1699 { "Verifier CRC32", "ntlmssp.verf.crc32", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1700 { &hf_ntlmssp_verf_sequence,
1701 { "Verifier Sequence Number", "ntlmssp.verf.sequence", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
1702 { &hf_ntlmssp_ntlmv2_response,
1703 { "NTLMv2 Response", "ntlmssp.ntlmv2response", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1704 { &hf_ntlmssp_ntlmv2_response_hmac,
1705 { "HMAC", "ntlmssp.ntlmv2response.hmac", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1706 { &hf_ntlmssp_ntlmv2_response_header,
1707 { "Header", "ntlmssp.ntlmv2response.header", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1708 { &hf_ntlmssp_ntlmv2_response_reserved,
1709 { "Reserved", "ntlmssp.ntlmv2response.reserved", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1710 { &hf_ntlmssp_ntlmv2_response_time,
1711 { "Time", "ntlmssp.ntlmv2response.time", FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0, "", HFILL }},
1712 { &hf_ntlmssp_ntlmv2_response_chal,
1713 { "Client challenge", "ntlmssp.ntlmv2response.chal", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1714 { &hf_ntlmssp_ntlmv2_response_unknown,
1715 { "Unknown", "ntlmssp.ntlmv2response.unknown", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1716 { &hf_ntlmssp_ntlmv2_response_name,
1717 { "Name", "ntlmssp.ntlmv2response.name", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1718 { &hf_ntlmssp_ntlmv2_response_name_type,
1719 { "Name type", "ntlmssp.ntlmv2response.name.type", FT_UINT32, BASE_DEC, VALS(ntlm_name_types), 0x0, "", HFILL }},
1720 { &hf_ntlmssp_ntlmv2_response_name_len,
1721 { "Name len", "ntlmssp.ntlmv2response.name.len", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }}
1725 static gint *ett[] = {
1727 &ett_ntlmssp_negotiate_flags,
1728 &ett_ntlmssp_string,
1730 &ett_ntlmssp_address_list,
1731 &ett_ntlmssp_address_list_item,
1732 &ett_ntlmssp_ntlmv2_response,
1733 &ett_ntlmssp_ntlmv2_response_name
1735 module_t *ntlmssp_module;
1737 proto_ntlmssp = proto_register_protocol (
1738 "NTLM Secure Service Provider", /* name */
1739 "NTLMSSP", /* short name */
1740 "ntlmssp" /* abbrev */
1742 proto_register_field_array (proto_ntlmssp, hf, array_length (hf));
1743 proto_register_subtree_array (ett, array_length (ett));
1744 register_init_routine(&ntlmssp_init_protocol);
1746 ntlmssp_module = prefs_register_protocol(proto_ntlmssp, NULL);
1748 prefs_register_string_preference(ntlmssp_module, "nt_password",
1750 "NT Password (used to decrypt payloads)",
1753 register_dissector("ntlmssp", dissect_ntlmssp, proto_ntlmssp);
1754 new_register_dissector("ntlmssp_verf", dissect_ntlmssp_verf, proto_ntlmssp);
1757 static int wrap_dissect_ntlmssp(tvbuff_t *tvb, int offset, packet_info *pinfo,
1758 proto_tree *tree, guint8 *drep _U_)
1762 auth_tvb = tvb_new_subset(
1763 tvb, offset, tvb_length_remaining(tvb, offset),
1764 tvb_length_remaining(tvb, offset));
1766 dissect_ntlmssp(auth_tvb, pinfo, tree);
1768 return tvb_length_remaining(tvb, offset);
1771 static int wrap_dissect_ntlmssp_verf(tvbuff_t *tvb, int offset, packet_info *pinfo,
1772 proto_tree *tree, guint8 *drep _U_)
1776 auth_tvb = tvb_new_subset(
1777 tvb, offset, tvb_length_remaining(tvb, offset),
1778 tvb_length_remaining(tvb, offset));
1780 return dissect_ntlmssp_verf(auth_tvb, pinfo, tree);
1783 static dcerpc_auth_subdissector_fns ntlmssp_sign_fns = {
1784 wrap_dissect_ntlmssp, /* Bind */
1785 wrap_dissect_ntlmssp, /* Bind ACK */
1786 wrap_dissect_ntlmssp, /* AUTH3 */
1787 wrap_dissect_ntlmssp_verf, /* Request verifier */
1788 wrap_dissect_ntlmssp_verf, /* Response verifier */
1789 NULL, /* Request data */
1790 NULL /* Response data */
1793 static dcerpc_auth_subdissector_fns ntlmssp_seal_fns = {
1794 wrap_dissect_ntlmssp, /* Bind */
1795 wrap_dissect_ntlmssp, /* Bind ACK */
1796 wrap_dissect_ntlmssp, /* AUTH3 */
1797 wrap_dissect_ntlmssp_verf, /* Request verifier */
1798 wrap_dissect_ntlmssp_verf, /* Response verifier */
1799 dissect_ntlmssp_encrypted_payload, /* Request data */
1800 dissect_ntlmssp_encrypted_payload /* Response data */
1804 proto_reg_handoff_ntlmssp(void)
1806 dissector_handle_t ntlmssp_handle, ntlmssp_wrap_handle;
1808 /* Register protocol with the GSS-API module */
1810 ntlmssp_handle = find_dissector("ntlmssp");
1811 ntlmssp_wrap_handle = find_dissector("ntlmssp_verf");
1812 gssapi_init_oid("1.3.6.1.4.1.311.2.2.10", proto_ntlmssp, ett_ntlmssp,
1813 ntlmssp_handle, ntlmssp_wrap_handle,
1814 "NTLMSSP - Microsoft NTLM Security Support Provider");
1816 /* Register authenticated pipe dissector */
1819 * XXX - the verifiers here seem to have a version of 1 and a body of all
1822 * XXX - DCE_C_AUTHN_LEVEL_CONNECT is, according to the DCE RPC 1.1
1823 * spec, upgraded to DCE_C_AUTHN_LEVEL_PKT. Should we register
1824 * any other levels here?
1826 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_CONNECT,
1827 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
1830 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
1831 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
1834 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
1835 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,