2 * Routines for NTLM Secure Service Provider
3 * Devin Heitmueller <dheitmueller@netilla.com>
5 * $Id: packet-ntlmssp.c,v 1.40 2003/05/09 01:41:28 tpot Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@ethereal.com>
9 * Copyright 1998 Gerald Combs
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version 2
14 * of the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #include <epan/packet.h>
33 #include "packet-smb-common.h"
34 #include "asn1.h" /* XXX - needed for subid_t */
35 #include "packet-gssapi.h"
36 #include "packet-frame.h"
38 #include "crypt-rc4.h"
39 #include "crypt-md4.h"
40 #include "crypt-des.h"
41 #include "packet-ntlmssp.h"
45 #define NTLMSSP_NEGOTIATE 1
46 #define NTLMSSP_CHALLENGE 2
47 #define NTLMSSP_AUTH 3
48 #define NTLMSSP_UNKNOWN 4
50 static const value_string ntlmssp_message_types[] = {
51 { NTLMSSP_NEGOTIATE, "NTLMSSP_NEGOTIATE" },
52 { NTLMSSP_CHALLENGE, "NTLMSSP_CHALLENGE" },
53 { NTLMSSP_AUTH, "NTLMSSP_AUTH" },
54 { NTLMSSP_UNKNOWN, "NTLMSSP_UNKNOWN" },
59 * NTLMSSP negotiation flags
62 #define NTLMSSP_NEGOTIATE_UNICODE 0x00000001
63 #define NTLMSSP_NEGOTIATE_OEM 0x00000002
64 #define NTLMSSP_REQUEST_TARGET 0x00000004
65 #define NTLMSSP_NEGOTIATE_00000008 0x00000008
66 #define NTLMSSP_NEGOTIATE_SIGN 0x00000010
67 #define NTLMSSP_NEGOTIATE_SEAL 0x00000020
68 #define NTLMSSP_NEGOTIATE_DATAGRAM_STYLE 0x00000040
69 #define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080
70 #define NTLMSSP_NEGOTIATE_NETWARE 0x00000100
71 #define NTLMSSP_NEGOTIATE_NTLM 0x00000200
72 #define NTLMSSP_NEGOTIATE_00000400 0x00000400
73 #define NTLMSSP_NEGOTIATE_00000800 0x00000800
74 #define NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED 0x00001000
75 #define NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED 0x00002000
76 #define NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL 0x00004000
77 #define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000
78 #define NTLMSSP_CHAL_INIT_RESPONSE 0x00010000
79 #define NTLMSSP_CHAL_ACCEPT_RESPONSE 0x00020000
80 #define NTLMSSP_CHAL_NON_NT_SESSION_KEY 0x00040000
81 #define NTLMSSP_NEGOTIATE_NTLM2 0x00080000
82 #define NTLMSSP_NEGOTIATE_00100000 0x00100000
83 #define NTLMSSP_NEGOTIATE_00200000 0x00200000
84 #define NTLMSSP_NEGOTIATE_00400000 0x00400000
85 #define NTLMSSP_CHAL_TARGET_INFO 0x00800000
86 #define NTLMSSP_NEGOTIATE_01000000 0x01000000
87 #define NTLMSSP_NEGOTIATE_02000000 0x02000000
88 #define NTLMSSP_NEGOTIATE_04000000 0x04000000
89 #define NTLMSSP_NEGOTIATE_08000000 0x08000000
90 #define NTLMSSP_NEGOTIATE_10000000 0x10000000
91 #define NTLMSSP_NEGOTIATE_128 0x20000000
92 #define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000
93 #define NTLMSSP_NEGOTIATE_80000000 0x80000000
95 static int proto_ntlmssp = -1;
96 static int hf_ntlmssp = -1;
97 static int hf_ntlmssp_auth = -1;
98 static int hf_ntlmssp_message_type = -1;
99 static int hf_ntlmssp_negotiate_flags = -1;
100 static int hf_ntlmssp_negotiate_flags_01 = -1;
101 static int hf_ntlmssp_negotiate_flags_02 = -1;
102 static int hf_ntlmssp_negotiate_flags_04 = -1;
103 static int hf_ntlmssp_negotiate_flags_08 = -1;
104 static int hf_ntlmssp_negotiate_flags_10 = -1;
105 static int hf_ntlmssp_negotiate_flags_20 = -1;
106 static int hf_ntlmssp_negotiate_flags_40 = -1;
107 static int hf_ntlmssp_negotiate_flags_80 = -1;
108 static int hf_ntlmssp_negotiate_flags_100 = -1;
109 static int hf_ntlmssp_negotiate_flags_200 = -1;
110 static int hf_ntlmssp_negotiate_flags_400 = -1;
111 static int hf_ntlmssp_negotiate_flags_800 = -1;
112 static int hf_ntlmssp_negotiate_flags_1000 = -1;
113 static int hf_ntlmssp_negotiate_flags_2000 = -1;
114 static int hf_ntlmssp_negotiate_flags_4000 = -1;
115 static int hf_ntlmssp_negotiate_flags_8000 = -1;
116 static int hf_ntlmssp_negotiate_flags_10000 = -1;
117 static int hf_ntlmssp_negotiate_flags_20000 = -1;
118 static int hf_ntlmssp_negotiate_flags_40000 = -1;
119 static int hf_ntlmssp_negotiate_flags_80000 = -1;
120 static int hf_ntlmssp_negotiate_flags_100000 = -1;
121 static int hf_ntlmssp_negotiate_flags_200000 = -1;
122 static int hf_ntlmssp_negotiate_flags_400000 = -1;
123 static int hf_ntlmssp_negotiate_flags_800000 = -1;
124 static int hf_ntlmssp_negotiate_flags_1000000 = -1;
125 static int hf_ntlmssp_negotiate_flags_2000000 = -1;
126 static int hf_ntlmssp_negotiate_flags_4000000 = -1;
127 static int hf_ntlmssp_negotiate_flags_8000000 = -1;
128 static int hf_ntlmssp_negotiate_flags_10000000 = -1;
129 static int hf_ntlmssp_negotiate_flags_20000000 = -1;
130 static int hf_ntlmssp_negotiate_flags_40000000 = -1;
131 static int hf_ntlmssp_negotiate_flags_80000000 = -1;
132 static int hf_ntlmssp_negotiate_workstation_strlen = -1;
133 static int hf_ntlmssp_negotiate_workstation_maxlen = -1;
134 static int hf_ntlmssp_negotiate_workstation_buffer = -1;
135 static int hf_ntlmssp_negotiate_workstation = -1;
136 static int hf_ntlmssp_negotiate_domain_strlen = -1;
137 static int hf_ntlmssp_negotiate_domain_maxlen = -1;
138 static int hf_ntlmssp_negotiate_domain_buffer = -1;
139 static int hf_ntlmssp_negotiate_domain = -1;
140 static int hf_ntlmssp_ntlm_challenge = -1;
141 static int hf_ntlmssp_reserved = -1;
142 static int hf_ntlmssp_challenge_domain = -1;
143 static int hf_ntlmssp_auth_username = -1;
144 static int hf_ntlmssp_auth_domain = -1;
145 static int hf_ntlmssp_auth_hostname = -1;
146 static int hf_ntlmssp_auth_lmresponse = -1;
147 static int hf_ntlmssp_auth_ntresponse = -1;
148 static int hf_ntlmssp_auth_sesskey = -1;
149 static int hf_ntlmssp_string_len = -1;
150 static int hf_ntlmssp_string_maxlen = -1;
151 static int hf_ntlmssp_string_offset = -1;
152 static int hf_ntlmssp_blob_len = -1;
153 static int hf_ntlmssp_blob_maxlen = -1;
154 static int hf_ntlmssp_blob_offset = -1;
155 static int hf_ntlmssp_address_list = -1;
156 static int hf_ntlmssp_address_list_len = -1;
157 static int hf_ntlmssp_address_list_maxlen = -1;
158 static int hf_ntlmssp_address_list_offset = -1;
159 static int hf_ntlmssp_address_list_server_nb = -1;
160 static int hf_ntlmssp_address_list_domain_nb = -1;
161 static int hf_ntlmssp_address_list_server_dns = -1;
162 static int hf_ntlmssp_address_list_domain_dns = -1;
163 static int hf_ntlmssp_verf = -1;
164 static int hf_ntlmssp_verf_vers = -1;
165 static int hf_ntlmssp_verf_body = -1;
166 static int hf_ntlmssp_verf_unknown1 = -1;
167 static int hf_ntlmssp_verf_crc32 = -1;
168 static int hf_ntlmssp_verf_sequence = -1;
169 static int hf_ntlmssp_decrypted_payload = -1;
171 static gint ett_ntlmssp = -1;
172 static gint ett_ntlmssp_negotiate_flags = -1;
173 static gint ett_ntlmssp_string = -1;
174 static gint ett_ntlmssp_blob = -1;
175 static gint ett_ntlmssp_address_list = -1;
176 static gint ett_ntlmssp_decrypted_tree = -1;
178 /* Configuration variables */
179 static char *nt_password = NULL;
181 #define MAX_BLOB_SIZE 256
182 typedef struct _ntlmssp_blob {
184 guint8 contents[MAX_BLOB_SIZE];
187 /* Used in the conversation function */
188 typedef struct _ntlmssp_info {
191 rc4_state_struct rc4_state_peer1;
192 rc4_state_struct rc4_state_peer2;
193 guint32 peer1_dest_port;
194 int rc4_state_initialized;
195 ntlmssp_blob ntlm_response;
196 ntlmssp_blob lm_response;
200 * GMemChunk from which ntlmssp_info structures are allocated.
202 static GMemChunk *ntlmssp_info_chunk;
203 static int ntlmssp_info_count = 10;
205 /* If this struct exists in the payload_decrypt, then we have already
207 typedef struct _ntlmssp_packet_info {
210 guint8 *decrypted_payload;
212 gboolean payload_decrypted;
213 gboolean verifier_decrypted;
214 } ntlmssp_packet_info;
217 * GMemChunk from which ntlmssp_packet_info structures are allocated.
219 static GMemChunk *ntlmssp_packet_info_chunk;
220 static int ntlmssp_packet_info_count = 10;
223 * GSlist of decrypted payloads.
225 static GSList *decrypted_payloads;
228 Generate a challenge response, given an eight byte challenge and
229 either the NT or the Lan Manager password hash (16 bytes).
230 Returns output in response, which is expected to be 24 bytes.
232 static int ntlmssp_generate_challenge_response(guint8 *response,
233 const guint8 *passhash,
234 const guint8 *challenge)
236 guint8 pw21[21]; /* Password hash padded to 21 bytes */
238 memset(pw21, 0x0, sizeof(pw21));
239 memcpy(pw21, passhash, 16);
241 memset(response, 0, 24);
243 crypt_des_ecb(response, challenge, pw21, 1);
244 crypt_des_ecb(response + 8, challenge, pw21 + 7, 1);
245 crypt_des_ecb(response + 16, challenge, pw21 + 14, 1);
250 /* Create an NTLMSSP version 1 key.
251 * password points to the ANSI password to encrypt, challenge points to
252 * the 8 octet challenge string, key128 will do a 128 bit key if set to 1,
253 * otherwise it will do a 40 bit key. The result is stored in
254 * sspkey (expected to be 16 octets)
257 create_ntlmssp_v1_key(const char *nt_password, const guint8 *challenge,
258 int use_key_128, guint8 *sspkey)
260 unsigned char lm_password_upper[16];
261 unsigned char lm_password_hash[16];
262 guint8 lm_challenge_response[24];
264 guint8 pw21[21]; /* Password hash padded to 21 bytes */
267 unsigned char lmhash_key[] =
268 {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
270 memset(lm_password_upper, 0, sizeof(lm_password_upper));
272 /* Create a Lan Manager hash of the input password */
273 if (nt_password[0] != '\0') {
274 password_len = strlen(nt_password);
275 /* Truncate password if too long */
276 if (password_len > 16)
278 for (i = 0; i < password_len; i++) {
279 lm_password_upper[i] = toupper(nt_password[i]);
283 crypt_des_ecb(lm_password_hash, lmhash_key, lm_password_upper, 1);
284 crypt_des_ecb(lm_password_hash+8, lmhash_key, lm_password_upper+7, 1);
286 /* Generate the LanMan Challenge Response */
287 ntlmssp_generate_challenge_response(lm_challenge_response,
288 lm_password_hash, challenge);
290 /* Generate the NTLMSSP-v1 RC4 Key.
291 * The RC4 key is derived from the Lan Manager Hash.
292 * See lkcl "DCE/RPC over SMB" page 254 for the algorithm.
294 memset(pw21, 0xBD, sizeof(pw21));
295 memcpy(pw21, lm_password_hash, sizeof(lm_password_hash));
297 /* Only the first eight bytes of challenge_response is used */
298 crypt_des_ecb(rc4key, lm_challenge_response, pw21, 1);
299 crypt_des_ecb(rc4key + 8, lm_challenge_response, pw21 + 7, 1);
300 crypt_des_ecb(rc4key + 16, lm_challenge_response, pw21 + 14, 1);
302 /* Create the SSP Key */
303 memset(sspkey, 0, sizeof(sspkey));
305 /* Create 128 bit key */
306 memcpy(sspkey, rc4key, 16);
309 /* Create 40 bit key */
310 memcpy(sspkey, rc4key, 5);
318 /* dissect a string - header area contains:
321 four byte offset of string in data area
322 The function returns the offset at the end of the string header,
323 but the 'end' parameter returns the offset of the end of the string itself
324 The 'start' parameter returns the offset of the beginning of the string
327 dissect_ntlmssp_string (tvbuff_t *tvb, int offset,
328 proto_tree *ntlmssp_tree,
329 gboolean unicode_strings,
330 int string_hf, int *start, int *end)
332 proto_tree *tree = NULL;
333 proto_item *tf = NULL;
334 gint16 string_length = tvb_get_letohs(tvb, offset);
335 gint16 string_maxlen = tvb_get_letohs(tvb, offset+2);
336 gint32 string_offset = tvb_get_letohl(tvb, offset+4);
337 const char *string_text = NULL;
341 *start = (string_offset > offset+8 ? string_offset : offset+8);
342 if (0 == string_length) {
345 proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
350 bc = result_length = string_length;
351 string_text = get_unicode_or_ascii_string(tvb, &string_offset,
352 unicode_strings, &result_length,
356 tf = proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
357 string_offset, result_length, string_text);
358 tree = proto_item_add_subtree(tf, ett_ntlmssp_string);
360 proto_tree_add_uint(tree, hf_ntlmssp_string_len,
361 tvb, offset, 2, string_length);
363 proto_tree_add_uint(tree, hf_ntlmssp_string_maxlen,
364 tvb, offset, 2, string_maxlen);
366 proto_tree_add_uint(tree, hf_ntlmssp_string_offset,
367 tvb, offset, 4, string_offset);
370 *end = string_offset + string_length;
374 /* dissect a generic blob - header area contains:
377 four byte offset of blob in data area
378 The function returns the offset at the end of the blob header,
379 but the 'end' parameter returns the offset of the end of the blob itself
382 dissect_ntlmssp_blob (tvbuff_t *tvb, int offset,
383 proto_tree *ntlmssp_tree,
384 int blob_hf, int *end, ntlmssp_blob *result)
386 proto_item *tf = NULL;
387 proto_tree *tree = NULL;
388 guint16 blob_length = tvb_get_letohs(tvb, offset);
389 guint16 blob_maxlen = tvb_get_letohs(tvb, offset+2);
390 guint32 blob_offset = tvb_get_letohl(tvb, offset+4);
392 if (0 == blob_length) {
393 *end = (blob_offset > ((guint)offset)+8 ? blob_offset : ((guint)offset)+8);
395 proto_tree_add_text(ntlmssp_tree, tvb, offset, 8, "%s: Empty",
396 proto_registrar_get_name(blob_hf));
401 tf = proto_tree_add_item (ntlmssp_tree, blob_hf, tvb,
402 blob_offset, blob_length, FALSE);
403 tree = proto_item_add_subtree(tf, ett_ntlmssp_blob);
405 proto_tree_add_uint(tree, hf_ntlmssp_blob_len,
406 tvb, offset, 2, blob_length);
408 proto_tree_add_uint(tree, hf_ntlmssp_blob_maxlen,
409 tvb, offset, 2, blob_maxlen);
411 proto_tree_add_uint(tree, hf_ntlmssp_blob_offset,
412 tvb, offset, 4, blob_offset);
415 *end = blob_offset + blob_length;
417 if (result != NULL) {
418 result->length = blob_length;
419 memset(result->contents, 0, MAX_BLOB_SIZE);
420 if (blob_length < MAX_BLOB_SIZE)
421 tvb_memcpy(tvb, result->contents, blob_offset, blob_length);
424 /* If we are dissecting the NTLM response and it is a NTLMv2
425 response call the appropriate dissector. */
427 if (blob_hf == hf_ntlmssp_auth_ntresponse && blob_length > 24)
428 dissect_ntlmv2_response(tvb, tree, blob_offset, blob_length);
434 dissect_ntlmssp_negotiate_flags (tvbuff_t *tvb, int offset,
435 proto_tree *ntlmssp_tree,
436 guint32 negotiate_flags)
438 proto_tree *negotiate_flags_tree = NULL;
439 proto_item *tf = NULL;
442 tf = proto_tree_add_uint (ntlmssp_tree,
443 hf_ntlmssp_negotiate_flags,
444 tvb, offset, 4, negotiate_flags);
445 negotiate_flags_tree = proto_item_add_subtree (tf, ett_ntlmssp_negotiate_flags);
448 proto_tree_add_boolean (negotiate_flags_tree,
449 hf_ntlmssp_negotiate_flags_80000000,
450 tvb, offset, 4, negotiate_flags);
451 proto_tree_add_boolean (negotiate_flags_tree,
452 hf_ntlmssp_negotiate_flags_40000000,
453 tvb, offset, 4, negotiate_flags);
454 proto_tree_add_boolean (negotiate_flags_tree,
455 hf_ntlmssp_negotiate_flags_20000000,
456 tvb, offset, 4, negotiate_flags);
457 proto_tree_add_boolean (negotiate_flags_tree,
458 hf_ntlmssp_negotiate_flags_10000000,
459 tvb, offset, 4, negotiate_flags);
460 proto_tree_add_boolean (negotiate_flags_tree,
461 hf_ntlmssp_negotiate_flags_8000000,
462 tvb, offset, 4, negotiate_flags);
463 proto_tree_add_boolean (negotiate_flags_tree,
464 hf_ntlmssp_negotiate_flags_4000000,
465 tvb, offset, 4, negotiate_flags);
466 proto_tree_add_boolean (negotiate_flags_tree,
467 hf_ntlmssp_negotiate_flags_2000000,
468 tvb, offset, 4, negotiate_flags);
469 proto_tree_add_boolean (negotiate_flags_tree,
470 hf_ntlmssp_negotiate_flags_1000000,
471 tvb, offset, 4, negotiate_flags);
472 proto_tree_add_boolean (negotiate_flags_tree,
473 hf_ntlmssp_negotiate_flags_800000,
474 tvb, offset, 4, negotiate_flags);
475 proto_tree_add_boolean (negotiate_flags_tree,
476 hf_ntlmssp_negotiate_flags_400000,
477 tvb, offset, 4, negotiate_flags);
478 proto_tree_add_boolean (negotiate_flags_tree,
479 hf_ntlmssp_negotiate_flags_200000,
480 tvb, offset, 4, negotiate_flags);
481 proto_tree_add_boolean (negotiate_flags_tree,
482 hf_ntlmssp_negotiate_flags_100000,
483 tvb, offset, 4, negotiate_flags);
484 proto_tree_add_boolean (negotiate_flags_tree,
485 hf_ntlmssp_negotiate_flags_80000,
486 tvb, offset, 4, negotiate_flags);
487 proto_tree_add_boolean (negotiate_flags_tree,
488 hf_ntlmssp_negotiate_flags_40000,
489 tvb, offset, 4, negotiate_flags);
490 proto_tree_add_boolean (negotiate_flags_tree,
491 hf_ntlmssp_negotiate_flags_20000,
492 tvb, offset, 4, negotiate_flags);
493 proto_tree_add_boolean (negotiate_flags_tree,
494 hf_ntlmssp_negotiate_flags_10000,
495 tvb, offset, 4, negotiate_flags);
496 proto_tree_add_boolean (negotiate_flags_tree,
497 hf_ntlmssp_negotiate_flags_8000,
498 tvb, offset, 4, negotiate_flags);
499 proto_tree_add_boolean (negotiate_flags_tree,
500 hf_ntlmssp_negotiate_flags_4000,
501 tvb, offset, 4, negotiate_flags);
502 proto_tree_add_boolean (negotiate_flags_tree,
503 hf_ntlmssp_negotiate_flags_2000,
504 tvb, offset, 4, negotiate_flags);
505 proto_tree_add_boolean (negotiate_flags_tree,
506 hf_ntlmssp_negotiate_flags_1000,
507 tvb, offset, 4, negotiate_flags);
508 proto_tree_add_boolean (negotiate_flags_tree,
509 hf_ntlmssp_negotiate_flags_800,
510 tvb, offset, 4, negotiate_flags);
511 proto_tree_add_boolean (negotiate_flags_tree,
512 hf_ntlmssp_negotiate_flags_400,
513 tvb, offset, 4, negotiate_flags);
514 proto_tree_add_boolean (negotiate_flags_tree,
515 hf_ntlmssp_negotiate_flags_200,
516 tvb, offset, 4, negotiate_flags);
517 proto_tree_add_boolean (negotiate_flags_tree,
518 hf_ntlmssp_negotiate_flags_100,
519 tvb, offset, 4, negotiate_flags);
520 proto_tree_add_boolean (negotiate_flags_tree,
521 hf_ntlmssp_negotiate_flags_80,
522 tvb, offset, 4, negotiate_flags);
523 proto_tree_add_boolean (negotiate_flags_tree,
524 hf_ntlmssp_negotiate_flags_40,
525 tvb, offset, 4, negotiate_flags);
526 proto_tree_add_boolean (negotiate_flags_tree,
527 hf_ntlmssp_negotiate_flags_20,
528 tvb, offset, 4, negotiate_flags);
529 proto_tree_add_boolean (negotiate_flags_tree,
530 hf_ntlmssp_negotiate_flags_10,
531 tvb, offset, 4, negotiate_flags);
532 proto_tree_add_boolean (negotiate_flags_tree,
533 hf_ntlmssp_negotiate_flags_08,
534 tvb, offset, 4, negotiate_flags);
535 proto_tree_add_boolean (negotiate_flags_tree,
536 hf_ntlmssp_negotiate_flags_04,
537 tvb, offset, 4, negotiate_flags);
538 proto_tree_add_boolean (negotiate_flags_tree,
539 hf_ntlmssp_negotiate_flags_02,
540 tvb, offset, 4, negotiate_flags);
541 proto_tree_add_boolean (negotiate_flags_tree,
542 hf_ntlmssp_negotiate_flags_01,
543 tvb, offset, 4, negotiate_flags);
550 dissect_ntlmssp_negotiate (tvbuff_t *tvb, int offset, proto_tree *ntlmssp_tree)
552 guint32 negotiate_flags;
557 /* NTLMSSP Negotiate Flags */
558 negotiate_flags = tvb_get_letohl (tvb, offset);
559 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
562 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
563 hf_ntlmssp_negotiate_domain,
564 &start, &workstation_end);
565 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
566 hf_ntlmssp_negotiate_workstation,
567 &start, &domain_end);
569 /* XXX - two blobs after this one, sometimes? */
571 return MAX(workstation_end, domain_end);
576 dissect_ntlmssp_address_list (tvbuff_t *tvb, int offset,
577 proto_tree *ntlmssp_tree,
580 guint16 list_length = tvb_get_letohs(tvb, offset);
581 guint16 list_maxlen = tvb_get_letohs(tvb, offset+2);
582 guint32 list_offset = tvb_get_letohl(tvb, offset+4);
583 guint16 item_type, item_length;
585 proto_item *tf = NULL;
586 proto_tree *tree = NULL;
588 /* the address list is just a blob */
589 if (0 == list_length) {
590 *end = (list_offset > ((guint)offset)+8 ? list_offset : ((guint)offset)+8);
592 proto_tree_add_text(ntlmssp_tree, tvb, offset, 8,
593 "Address List: Empty");
598 tf = proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_address_list, tvb,
599 list_offset, list_length, FALSE);
600 tree = proto_item_add_subtree(tf, ett_ntlmssp_address_list);
602 proto_tree_add_uint(tree, hf_ntlmssp_address_list_len,
603 tvb, offset, 2, list_length);
605 proto_tree_add_uint(tree, hf_ntlmssp_address_list_maxlen,
606 tvb, offset, 2, list_maxlen);
608 proto_tree_add_uint(tree, hf_ntlmssp_address_list_offset,
609 tvb, offset, 4, list_offset);
612 item_offset = list_offset;
613 item_type = tvb_get_letohs(tvb, item_offset);
615 item_length = tvb_get_letohs(tvb, item_offset);
623 /* Strings are always in unicode regardless of the negotiated
626 text = get_unicode_or_ascii_string(tvb, &item_offset,
627 TRUE, &result_length,
630 if (!text) text = ""; /* Make sure we don't blow up below */
633 case NTLM_NAME_NB_HOST:
634 proto_tree_add_string(tree, hf_ntlmssp_address_list_server_nb,
635 tvb, item_offset, item_length, text);
637 case NTLM_NAME_NB_DOMAIN:
638 proto_tree_add_string(tree, hf_ntlmssp_address_list_domain_nb,
639 tvb, item_offset, item_length, text);
641 case NTLM_NAME_DNS_HOST:
642 proto_tree_add_string(tree, hf_ntlmssp_address_list_server_dns,
643 tvb, item_offset, item_length, text);
645 case NTLM_NAME_DNS_DOMAIN:
646 proto_tree_add_string(tree, hf_ntlmssp_address_list_domain_dns,
647 tvb, item_offset, item_length, text);
650 item_offset += item_length;
651 item_type = tvb_get_letohs(tvb, item_offset);
653 item_length = tvb_get_letohs(tvb, item_offset);
657 *end = list_offset + list_length;
662 dissect_ntlmssp_challenge (tvbuff_t *tvb, packet_info *pinfo, int offset,
663 proto_tree *ntlmssp_tree)
665 guint32 negotiate_flags;
666 int item_start, item_end;
667 int data_start, data_end;
668 ntlmssp_info *conv_ntlmssp_info;
669 conversation_t *conversation;
670 gboolean unicode_strings = FALSE;
671 guint8 sspkey[16]; /* NTLMSSP cipher key */
672 guint8 ssp_key_len; /* Either 8 or 16 (40 bit or 128) */
674 /* need to find unicode flag */
675 negotiate_flags = tvb_get_letohl (tvb, offset+8);
676 if (negotiate_flags & NTLMSSP_NEGOTIATE_UNICODE)
677 unicode_strings = TRUE;
680 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, unicode_strings,
681 hf_ntlmssp_challenge_domain,
682 &item_start, &item_end);
683 data_start = item_start;
686 /* NTLMSSP Negotiate Flags */
687 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
690 /* NTLMSSP NT Lan Manager Challenge */
691 proto_tree_add_item (ntlmssp_tree,
692 hf_ntlmssp_ntlm_challenge,
693 tvb, offset, 8, FALSE);
696 * Store the flags and the challenge with the conversation, as they're
697 * needed in order to dissect subsequent messages.
699 conversation = find_conversation(&pinfo->src, &pinfo->dst,
700 pinfo->ptype, pinfo->srcport,
702 if (!conversation) { /* Create one */
703 conversation = conversation_new(&pinfo->src, &pinfo->dst, pinfo->ptype,
704 pinfo->srcport, pinfo->destport, 0);
707 if (!conversation_get_proto_data(conversation, proto_ntlmssp)) {
708 conv_ntlmssp_info = g_mem_chunk_alloc(ntlmssp_info_chunk);
709 /* Insert the flags into the conversation */
710 conv_ntlmssp_info->flags = negotiate_flags;
711 /* Insert the challenge into the conversation */
712 tvb_memcpy(tvb, conv_ntlmssp_info->challenge, offset, 8);
714 /* Between the challenge and the user provided password, we can build the
715 NTLMSSP key and initialize the cipher */
716 if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_128) {
717 create_ntlmssp_v1_key(nt_password, conv_ntlmssp_info->challenge,
722 create_ntlmssp_v1_key(nt_password, conv_ntlmssp_info->challenge,
726 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_peer1, sspkey, ssp_key_len);
727 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_peer2, sspkey, ssp_key_len);
728 conv_ntlmssp_info->peer1_dest_port = pinfo->destport;
729 conv_ntlmssp_info->rc4_state_initialized = 1;
731 conversation_add_proto_data(conversation, proto_ntlmssp, conv_ntlmssp_info);
735 /* Reserved (function not completely known) */
737 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_reserved,
738 tvb, offset, 8, FALSE);
742 * The presence or absence of this field is not obviously correlated
743 * with any flags in the previous NEGOTIATE message or in this
744 * message (other than the "Workstation Supplied" and "Domain
745 * Supplied" flags in the NEGOTIATE message, at least in the capture
746 * I've seen - but those also correlate with the presence of workstation
747 * and domain name fields, so it doesn't seem to make sense that they
748 * actually *indicate* whether the subsequent CHALLENGE has an
751 if (offset < data_start) {
752 offset = dissect_ntlmssp_address_list(tvb, offset, ntlmssp_tree, &item_end);
753 data_end = MAX(data_end, item_end);
756 return MAX(offset, data_end);
760 dissect_ntlmssp_auth (tvbuff_t *tvb, packet_info *pinfo, int offset,
761 proto_tree *ntlmssp_tree)
763 int item_start, item_end;
764 int data_start, data_end = 0;
765 guint32 negotiate_flags;
766 gboolean unicode_strings = FALSE;
767 ntlmssp_info *conv_ntlmssp_info;
768 conversation_t *conversation;
771 * Get flag info from the original negotiate message, if any.
772 * This is because the flag information is sometimes missing from
773 * the AUTHENTICATE message, so we can't figure out whether
774 * strings are Unicode or not by looking at *our* flags.
776 conv_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
777 if (conv_ntlmssp_info == NULL) {
779 * There isn't any. Is there any from this conversation? If so,
780 * it means this is the first time we've dissected this frame, so
781 * we should give it flag info.
783 conversation = find_conversation(&pinfo->src, &pinfo->dst,
784 pinfo->ptype, pinfo->srcport,
786 if (conversation != NULL) {
787 conv_ntlmssp_info = conversation_get_proto_data(conversation, proto_ntlmssp);
788 if (conv_ntlmssp_info != NULL) {
790 * We have flag info; attach it to the frame.
792 p_add_proto_data(pinfo->fd, proto_ntlmssp, conv_ntlmssp_info);
796 if (conv_ntlmssp_info != NULL) {
797 if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_UNICODE)
798 unicode_strings = TRUE;
802 * Sometimes the session key and flags are missing.
803 * Sometimes the session key is present but the flags are missing.
804 * Sometimes they're both present.
806 * This does not correlate with any flags in the previous CHALLENGE
807 * message, and only correlates with "Negotiate Unicode", "Workstation
808 * Supplied", and "Domain Supplied" in the NEGOTIATE message - but
809 * those don't make sense as flags to use to determine this.
811 * So we check all of the descriptors to figure out where the data
812 * area begins, and if the session key or the flags would be in the
813 * middle of the data area, we assume the field in question is
817 /* Lan Manager response */
818 data_start = tvb_get_letohl(tvb, offset+4);
819 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
820 hf_ntlmssp_auth_lmresponse,
822 conv_ntlmssp_info == NULL ? NULL :
823 &conv_ntlmssp_info->lm_response);
824 data_end = MAX(data_end, item_end);
827 item_start = tvb_get_letohl(tvb, offset+4);
828 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
829 hf_ntlmssp_auth_ntresponse,
831 conv_ntlmssp_info == NULL ? NULL :
832 &conv_ntlmssp_info->ntlm_response);
833 data_start = MIN(data_start, item_start);
834 data_end = MAX(data_end, item_end);
837 item_start = tvb_get_letohl(tvb, offset+4);
838 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
840 hf_ntlmssp_auth_domain,
841 &item_start, &item_end);
842 data_start = MIN(data_start, item_start);
843 data_end = MAX(data_end, item_end);
846 item_start = tvb_get_letohl(tvb, offset+4);
847 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
849 hf_ntlmssp_auth_username,
850 &item_start, &item_end);
851 data_start = MIN(data_start, item_start);
852 data_end = MAX(data_end, item_end);
855 item_start = tvb_get_letohl(tvb, offset+4);
856 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
858 hf_ntlmssp_auth_hostname,
859 &item_start, &item_end);
860 data_start = MIN(data_start, item_start);
861 data_end = MAX(data_end, item_end);
863 if (offset < data_start) {
865 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
866 hf_ntlmssp_auth_sesskey,
868 data_end = MAX(data_end, item_end);
871 if (offset < data_start) {
872 /* NTLMSSP Negotiate Flags */
873 negotiate_flags = tvb_get_letohl (tvb, offset);
874 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
878 return MAX(offset, data_end);
882 dissect_ntlmssp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
884 guint32 ntlmssp_message_type;
885 volatile int offset = 0;
886 proto_tree *volatile ntlmssp_tree = NULL;
887 proto_item *tf = NULL;
889 /* Setup a new tree for the NTLMSSP payload */
891 tf = proto_tree_add_item (tree,
893 tvb, offset, -1, FALSE);
895 ntlmssp_tree = proto_item_add_subtree (tf,
900 * Catch the ReportedBoundsError exception; the stuff we've been
901 * handed doesn't necessarily run to the end of the packet, it's
902 * an item inside a packet, so if it happens to be malformed (or
903 * we, or a dissector we call, has a bug), so that an exception
904 * is thrown, we want to report the error, but return and let
905 * our caller dissect the rest of the packet.
907 * If it gets a BoundsError, we can stop, as there's nothing more
908 * in the packet after our blob to see, so we just re-throw the
912 /* NTLMSSP constant */
913 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth,
914 tvb, offset, 8, FALSE);
917 /* NTLMSSP Message Type */
918 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_message_type,
919 tvb, offset, 4, TRUE);
920 ntlmssp_message_type = tvb_get_letohl (tvb, offset);
923 if (check_col(pinfo->cinfo, COL_INFO))
924 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
925 val_to_str(ntlmssp_message_type,
926 ntlmssp_message_types,
927 "Unknown message type"));
929 /* Call the appropriate dissector based on the Message Type */
930 switch (ntlmssp_message_type) {
932 case NTLMSSP_NEGOTIATE:
933 offset = dissect_ntlmssp_negotiate (tvb, offset, ntlmssp_tree);
936 case NTLMSSP_CHALLENGE:
937 offset = dissect_ntlmssp_challenge (tvb, pinfo, offset, ntlmssp_tree);
941 offset = dissect_ntlmssp_auth (tvb, pinfo, offset, ntlmssp_tree);
945 /* Unrecognized message type */
946 proto_tree_add_text (ntlmssp_tree, tvb, offset, -1,
947 "Unrecognized NTLMSSP Message");
950 } CATCH(BoundsError) {
952 } CATCH(ReportedBoundsError) {
953 show_reported_bounds_error(tvb, pinfo, tree);
958 * Get the encryption state tied to this conversation. cryptpeer indicates
959 * whether to retrieve the data for peer1 or peer2.
961 static rc4_state_struct *
962 get_encrypted_state(packet_info *pinfo, int cryptpeer)
964 conversation_t *conversation;
965 ntlmssp_info *conv_ntlmssp_info;
967 conversation = find_conversation(&pinfo->src, &pinfo->dst,
968 pinfo->ptype, pinfo->srcport,
970 if (conversation == NULL) {
971 /* We don't have a conversation. In this case, stop processing
972 because we do not have enough info to decrypt the payload */
976 /* We have a conversation, check for encryption state */
977 conv_ntlmssp_info = conversation_get_proto_data(conversation,
979 if (conv_ntlmssp_info == NULL) {
980 /* No encryption state tied to the conversation. Therefore, we
981 cannot decrypt the payload */
985 /* We have the encryption state in the conversation. So return the
986 crypt state tied to the requested peer
988 if (cryptpeer == 1) {
989 return &conv_ntlmssp_info->rc4_state_peer1;
991 return &conv_ntlmssp_info->rc4_state_peer2;
999 * See page 45 of "DCE/RPC over SMB" by Luke Kenneth Casson Leighton.
1002 decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
1003 packet_info *pinfo, proto_tree *tree)
1005 proto_tree *decr_tree = NULL;
1006 proto_item *tf = NULL;
1007 conversation_t *conversation;
1008 rc4_state_struct *rc4_state;
1009 rc4_state_struct *rc4_state_peer;
1010 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
1012 ntlmssp_info *conv_ntlmssp_info = NULL;
1013 ntlmssp_packet_info *packet_ntlmssp_info = NULL;
1014 int decrypted_offset = 0;
1016 packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1017 if (packet_ntlmssp_info == NULL) {
1018 /* We don't have data for this packet */
1021 if (!packet_ntlmssp_info->verifier_decrypted) {
1022 conversation = find_conversation(&pinfo->src, &pinfo->dst,
1023 pinfo->ptype, pinfo->srcport,
1024 pinfo->destport, 0);
1025 if (conversation == NULL) {
1026 /* There is no conversation, thus no encryption state */
1030 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1032 if (conv_ntlmssp_info == NULL) {
1033 /* There is no NTLMSSP state tied to the conversation */
1036 if (conv_ntlmssp_info->rc4_state_initialized != 1 ) {
1037 /* The crypto sybsystem is not initialized. This means that either
1038 the conversation did not include a challenge, or we are doing
1039 something other than NTLMSSP v1 */
1043 if (conv_ntlmssp_info->peer1_dest_port == pinfo->destport) {
1044 rc4_state = get_encrypted_state(pinfo, 1);
1045 rc4_state_peer = get_encrypted_state(pinfo, 0);
1047 rc4_state = get_encrypted_state(pinfo, 0);
1048 rc4_state_peer = get_encrypted_state(pinfo, 1);
1051 if (rc4_state == NULL || rc4_state_peer == NULL) {
1052 /* There is no encryption state, so we cannot decrypt */
1056 /* Setup the buffer to decrypt to */
1057 tvb_memcpy(tvb, packet_ntlmssp_info->verifier,
1058 offset, encrypted_block_length);
1060 /* Do the actual decryption of the verifier */
1061 crypt_rc4(rc4_state, packet_ntlmssp_info->verifier,
1062 encrypted_block_length);
1064 /* We setup a temporary buffer so we can re-encrypt the payload after
1065 decryption. This is to update the opposite peer's RC4 state */
1066 peer_block = g_malloc(encrypted_block_length);
1067 memcpy(peer_block, packet_ntlmssp_info->verifier,
1068 encrypted_block_length);
1069 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
1072 /* Mark the packet as decrypted so that subsequent attempts to dissect
1073 the packet use the already decrypted payload instead of attempting
1075 packet_ntlmssp_info->verifier_decrypted = TRUE;
1078 /* Show the decrypted buffer in a new window */
1079 decr_tvb = tvb_new_real_data(packet_ntlmssp_info->verifier,
1080 encrypted_block_length,
1081 encrypted_block_length);
1082 tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
1083 add_new_data_source(pinfo, decr_tvb,
1084 "Decrypted NTLMSSP Verifier");
1086 /* Show the decrypted payload in the tree */
1087 tf = proto_tree_add_text(tree, decr_tvb, 0, -1,
1088 "Decrypted Verifier (%d byte%s)",
1089 encrypted_block_length,
1090 plurality(encrypted_block_length, "", "s"));
1091 decr_tree = proto_item_add_subtree (tf, ett_ntlmssp);
1093 /* LKCL page 45 says this is a "reserved" field. I'm not sure if it's
1094 garbage because it's some sort of nonce, or because there is a problem
1095 with the verifier decryption routine. */
1096 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_unknown1,
1097 decr_tvb, decrypted_offset, 4, TRUE);
1098 decrypted_offset += 4;
1100 /* CRC32 of the DCE fragment data */
1101 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_crc32,
1102 decr_tvb, decrypted_offset, 4, TRUE);
1103 decrypted_offset += 4;
1105 /* Incrementing sequence number of DCE conversation */
1106 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_sequence,
1107 decr_tvb, decrypted_offset, 4, TRUE);
1108 decrypted_offset += 4;
1112 dissect_ntlmssp_verf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1114 volatile int offset = 0;
1115 proto_tree *volatile ntlmssp_tree = NULL;
1116 proto_item *tf = NULL;
1117 guint32 verifier_length;
1118 guint32 encrypted_block_length;
1120 verifier_length = tvb_length_remaining (tvb, offset);
1121 encrypted_block_length = verifier_length - 4;
1123 if (encrypted_block_length < 12) {
1124 /* Don't know why this would happen, but if it does, don't even bother
1125 attempting decryption/dissection */
1126 return offset + verifier_length;
1129 /* Setup a new tree for the NTLMSSP payload */
1131 tf = proto_tree_add_item (tree,
1133 tvb, offset, -1, FALSE);
1135 ntlmssp_tree = proto_item_add_subtree (tf,
1140 * Catch the ReportedBoundsError exception; the stuff we've been
1141 * handed doesn't necessarily run to the end of the packet, it's
1142 * an item inside a packet, so if it happens to be malformed (or
1143 * we, or a dissector we call, has a bug), so that an exception
1144 * is thrown, we want to report the error, but return and let
1145 * our caller dissect the rest of the packet.
1147 * If it gets a BoundsError, we can stop, as there's nothing more
1148 * in the packet after our blob to see, so we just re-throw the
1152 /* Version number */
1153 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_vers,
1154 tvb, offset, 4, TRUE);
1157 /* Encrypted body */
1158 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_body,
1159 tvb, offset, encrypted_block_length, TRUE);
1161 /* Try to decrypt */
1162 decrypt_verifier (tvb, offset, encrypted_block_length, pinfo, ntlmssp_tree);
1164 offset += encrypted_block_length;
1165 } CATCH(BoundsError) {
1167 } CATCH(ReportedBoundsError) {
1168 show_reported_bounds_error(tvb, pinfo, tree);
1176 dissect_ntlmssp_encrypted_payload(tvbuff_t *tvb,
1177 packet_info *pinfo, proto_tree *tree)
1179 volatile int offset = 0;
1180 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
1182 conversation_t *conversation;
1183 guint32 encrypted_block_length;
1184 rc4_state_struct *rc4_state;
1185 rc4_state_struct *rc4_state_peer;
1186 ntlmssp_info *conv_ntlmssp_info = NULL;
1187 ntlmssp_packet_info *packet_ntlmssp_info = NULL;
1189 static ntlmssp_decrypted_info_t ndi;
1191 encrypted_block_length = tvb_length_remaining (tvb, offset);
1193 /* Check to see if we already have state for this packet */
1194 packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1195 if (packet_ntlmssp_info == NULL) {
1196 /* We don't have any packet state, so create one */
1197 packet_ntlmssp_info = g_mem_chunk_alloc(ntlmssp_packet_info_chunk);
1198 memset(packet_ntlmssp_info, 0, sizeof(ntlmssp_packet_info));
1199 p_add_proto_data(pinfo->fd, proto_ntlmssp, packet_ntlmssp_info);
1202 if (!packet_ntlmssp_info->payload_decrypted) {
1203 /* Pull the challenge info from the conversation */
1204 conversation = find_conversation(&pinfo->src, &pinfo->dst,
1205 pinfo->ptype, pinfo->srcport,
1206 pinfo->destport, 0);
1207 if (conversation == NULL) {
1208 /* There is no conversation, thus no encryption state */
1209 return offset + encrypted_block_length;
1212 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1214 if (conv_ntlmssp_info == NULL) {
1215 /* There is no NTLMSSP state tied to the conversation */
1216 return offset + encrypted_block_length;
1219 /* Get the pair of RC4 state structures. One is used for to decrypt the
1220 payload. The other is used to re-encrypt the payload to represent
1222 if (conv_ntlmssp_info->peer1_dest_port == pinfo->destport) {
1223 rc4_state = get_encrypted_state(pinfo, 1);
1224 rc4_state_peer = get_encrypted_state(pinfo, 0);
1226 rc4_state = get_encrypted_state(pinfo, 0);
1227 rc4_state_peer = get_encrypted_state(pinfo, 1);
1230 if (rc4_state == NULL || rc4_state_peer == NULL) {
1231 /* There is no encryption state, so we cannot decrypt */
1232 return offset + encrypted_block_length;
1235 /* Store the decrypted contents in the packet state struct
1236 (of course at this point, they aren't decrypted yet) */
1237 packet_ntlmssp_info->decrypted_payload = g_malloc (encrypted_block_length);
1238 decrypted_payloads = g_slist_prepend(decrypted_payloads,
1239 packet_ntlmssp_info->decrypted_payload);
1240 tvb_memcpy(tvb, packet_ntlmssp_info->decrypted_payload,
1241 offset, encrypted_block_length);
1243 /* Do the decryption of the payload */
1244 crypt_rc4(rc4_state, packet_ntlmssp_info->decrypted_payload,
1245 encrypted_block_length);
1247 /* We setup a temporary buffer so we can re-encrypt the payload after
1248 decryption. This is to update the opposite peer's RC4 state */
1249 peer_block = g_malloc(encrypted_block_length);
1250 memcpy(peer_block, packet_ntlmssp_info->decrypted_payload,
1251 encrypted_block_length);
1252 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
1255 packet_ntlmssp_info->payload_decrypted = TRUE;
1258 /* Show the decrypted buffer in a new window */
1259 decr_tvb = tvb_new_real_data(packet_ntlmssp_info->decrypted_payload,
1260 encrypted_block_length,
1261 encrypted_block_length);
1262 tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
1263 add_new_data_source(pinfo, decr_tvb,
1264 "Decrypted NTLMSSP block");
1266 /* Show the decrypted payload in the tree */
1267 it=proto_tree_add_text(tree, decr_tvb, 0, -1,
1268 "Decrypted stub data (%d byte%s)",
1269 encrypted_block_length,
1270 plurality(encrypted_block_length, "", "s"));
1271 ndi.decr_tree=proto_item_add_subtree(it, ett_ntlmssp_decrypted_tree);
1272 ndi.decr_tvb=decr_tvb;
1273 pinfo->decrypted_data=&ndi;
1275 offset += encrypted_block_length;
1280 free_payload(gpointer decrypted_payload, gpointer user_data _U_)
1282 g_free(decrypted_payload);
1286 ntlmssp_init_protocol(void)
1288 if (ntlmssp_info_chunk != NULL)
1289 g_mem_chunk_destroy(ntlmssp_info_chunk);
1290 if (ntlmssp_packet_info_chunk != NULL)
1291 g_mem_chunk_destroy(ntlmssp_packet_info_chunk);
1294 * Free the decrypted payloads, and then free the list of decrypted
1297 if (decrypted_payloads != NULL) {
1298 g_slist_foreach(decrypted_payloads, free_payload, NULL);
1299 g_slist_free(decrypted_payloads);
1300 decrypted_payloads = NULL;
1303 ntlmssp_info_chunk = g_mem_chunk_new("ntlmssp_info_chunk",
1304 sizeof(ntlmssp_info),
1305 ntlmssp_info_count * sizeof(ntlmssp_info),
1307 ntlmssp_packet_info_chunk = g_mem_chunk_new("ntlmssp_packet_info_chunk",
1308 sizeof(ntlmssp_packet_info),
1309 ntlmssp_packet_info_count * sizeof(ntlmssp_packet_info),
1314 proto_register_ntlmssp(void)
1317 static hf_register_info hf[] = {
1319 { "NTLMSSP", "ntlmssp", FT_NONE, BASE_NONE, NULL, 0x0, "NTLMSSP", HFILL }},
1322 { "NTLMSSP identifier", "ntlmssp.identifier", FT_STRING, BASE_NONE, NULL, 0x0, "NTLMSSP Identifier", HFILL }},
1324 { &hf_ntlmssp_message_type,
1325 { "NTLM Message Type", "ntlmssp.messagetype", FT_UINT32, BASE_HEX, VALS(ntlmssp_message_types), 0x0, "", HFILL }},
1327 { &hf_ntlmssp_negotiate_flags,
1328 { "Flags", "ntlmssp.negotiateflags", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1329 { &hf_ntlmssp_negotiate_flags_01,
1331 { "Negotiate UNICODE", "ntlmssp.negotiateunicode", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_UNICODE, "", HFILL }},
1332 { &hf_ntlmssp_negotiate_flags_02,
1333 { "Negotiate OEM", "ntlmssp.negotiateoem", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_OEM, "", HFILL }},
1334 { &hf_ntlmssp_negotiate_flags_04,
1335 { "Request Target", "ntlmssp.requesttarget", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_REQUEST_TARGET, "", HFILL }},
1336 { &hf_ntlmssp_negotiate_flags_08,
1337 { "Request 0x00000008", "ntlmssp.negotiate00000008", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000008, "", HFILL }},
1338 { &hf_ntlmssp_negotiate_flags_10,
1339 { "Negotiate Sign", "ntlmssp.negotiatesign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SIGN, "", HFILL }},
1340 { &hf_ntlmssp_negotiate_flags_20,
1341 { "Negotiate Seal", "ntlmssp.negotiateseal", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_SEAL, "", HFILL }},
1342 { &hf_ntlmssp_negotiate_flags_40,
1343 { "Negotiate Datagram Style", "ntlmssp.negotiatedatagramstyle", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_DATAGRAM_STYLE, "", HFILL }},
1344 { &hf_ntlmssp_negotiate_flags_80,
1345 { "Negotiate Lan Manager Key", "ntlmssp.negotiatelmkey", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_LM_KEY, "", HFILL }},
1346 { &hf_ntlmssp_negotiate_flags_100,
1347 { "Negotiate Netware", "ntlmssp.negotiatenetware", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NETWARE, "", HFILL }},
1348 { &hf_ntlmssp_negotiate_flags_200,
1349 { "Negotiate NTLM key", "ntlmssp.negotiatentlm", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM, "", HFILL }},
1350 { &hf_ntlmssp_negotiate_flags_400,
1351 { "Negotiate 0x00000400", "ntlmssp.negotiate00000400", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000400, "", HFILL }},
1352 { &hf_ntlmssp_negotiate_flags_800,
1353 { "Negotiate 0x00000800", "ntlmssp.negotiate00000800", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00000800, "", HFILL }},
1354 { &hf_ntlmssp_negotiate_flags_1000,
1355 { "Negotiate Domain Supplied", "ntlmssp.negotiatedomainsupplied", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED, "", HFILL }},
1356 { &hf_ntlmssp_negotiate_flags_2000,
1357 { "Negotiate Workstation Supplied", "ntlmssp.negotiateworkstationsupplied", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED, "", HFILL }},
1358 { &hf_ntlmssp_negotiate_flags_4000,
1359 { "Negotiate This is Local Call", "ntlmssp.negotiatethisislocalcall", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL, "", HFILL }},
1360 { &hf_ntlmssp_negotiate_flags_8000,
1361 { "Negotiate Always Sign", "ntlmssp.negotiatealwayssign", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_ALWAYS_SIGN, "", HFILL }},
1362 { &hf_ntlmssp_negotiate_flags_10000,
1363 { "Negotiate Challenge Init Response", "ntlmssp.negotiatechallengeinitresponse", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_INIT_RESPONSE, "", HFILL }},
1364 { &hf_ntlmssp_negotiate_flags_20000,
1365 { "Negotiate Challenge Accept Response", "ntlmssp.negotiatechallengeacceptresponse", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_ACCEPT_RESPONSE, "", HFILL }},
1366 { &hf_ntlmssp_negotiate_flags_40000,
1367 { "Negotiate Challenge Non NT Session Key", "ntlmssp.negotiatechallengenonntsessionkey", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_NON_NT_SESSION_KEY, "", HFILL }},
1368 { &hf_ntlmssp_negotiate_flags_80000,
1369 { "Negotiate NTLM2 key", "ntlmssp.negotiatentlm2", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_NTLM2, "", HFILL }},
1370 { &hf_ntlmssp_negotiate_flags_100000,
1371 { "Negotiate 0x00100000", "ntlmssp.negotiatent00100000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00100000, "", HFILL }},
1372 { &hf_ntlmssp_negotiate_flags_200000,
1373 { "Negotiate 0x00200000", "ntlmssp.negotiatent00200000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00200000, "", HFILL }},
1374 { &hf_ntlmssp_negotiate_flags_400000,
1375 { "Negotiate 0x00400000", "ntlmssp.negotiatent00400000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_00400000, "", HFILL }},
1376 { &hf_ntlmssp_negotiate_flags_800000,
1377 { "Negotiate Target Info", "ntlmssp.negotiatetargetinfo", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_CHAL_TARGET_INFO, "", HFILL }},
1378 { &hf_ntlmssp_negotiate_flags_1000000,
1379 { "Negotiate 0x01000000", "ntlmssp.negotiatent01000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_01000000, "", HFILL }},
1380 { &hf_ntlmssp_negotiate_flags_2000000,
1381 { "Negotiate 0x02000000", "ntlmssp.negotiatent02000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_02000000, "", HFILL }},
1382 { &hf_ntlmssp_negotiate_flags_4000000,
1383 { "Negotiate 0x04000000", "ntlmssp.negotiatent04000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_04000000, "", HFILL }},
1384 { &hf_ntlmssp_negotiate_flags_8000000,
1385 { "Negotiate 0x08000000", "ntlmssp.negotiatent08000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_08000000, "", HFILL }},
1386 { &hf_ntlmssp_negotiate_flags_10000000,
1387 { "Negotiate 0x10000000", "ntlmssp.negotiatent10000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_10000000, "", HFILL }},
1388 { &hf_ntlmssp_negotiate_flags_20000000,
1389 { "Negotiate 128", "ntlmssp.negotiate128", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_128, "", HFILL }},
1390 { &hf_ntlmssp_negotiate_flags_40000000,
1391 { "Negotiate Key Exchange", "ntlmssp.negotiatekeyexch", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_KEY_EXCH, "", HFILL }},
1392 { &hf_ntlmssp_negotiate_flags_80000000,
1393 { "Negotiate 0x80000000", "ntlmssp.negotiatent80000000", FT_BOOLEAN, 32, TFS (&flags_set_truth), NTLMSSP_NEGOTIATE_80000000, "", HFILL }},
1394 { &hf_ntlmssp_negotiate_workstation_strlen,
1395 { "Calling workstation name length", "ntlmssp.negotiate.callingworkstation.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1396 { &hf_ntlmssp_negotiate_workstation_maxlen,
1397 { "Calling workstation name max length", "ntlmssp.negotiate.callingworkstation.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1398 { &hf_ntlmssp_negotiate_workstation_buffer,
1399 { "Calling workstation name buffer", "ntlmssp.negotiate.callingworkstation.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1400 { &hf_ntlmssp_negotiate_workstation,
1401 { "Calling workstation name", "ntlmssp.negotiate.callingworkstation", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1402 { &hf_ntlmssp_negotiate_domain_strlen,
1403 { "Calling workstation domain length", "ntlmssp.negotiate.domain.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1404 { &hf_ntlmssp_negotiate_domain_maxlen,
1405 { "Calling workstation domain max length", "ntlmssp.negotiate.domain.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }},
1406 { &hf_ntlmssp_negotiate_domain_buffer,
1407 { "Calling workstation domain buffer", "ntlmssp.negotiate.domain.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1408 { &hf_ntlmssp_negotiate_domain,
1409 { "Calling workstation domain", "ntlmssp.negotiate.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1410 { &hf_ntlmssp_ntlm_challenge,
1411 { "NTLM Challenge", "ntlmssp.ntlmchallenge", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1412 { &hf_ntlmssp_reserved,
1413 { "Reserved", "ntlmssp.reserved", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1414 { &hf_ntlmssp_challenge_domain,
1415 { "Domain", "ntlmssp.challenge.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1416 { &hf_ntlmssp_auth_domain,
1417 { "Domain name", "ntlmssp.auth.domain", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1418 { &hf_ntlmssp_auth_username,
1419 { "User name", "ntlmssp.auth.username", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1420 { &hf_ntlmssp_auth_hostname,
1421 { "Host name", "ntlmssp.auth.hostname", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1422 { &hf_ntlmssp_auth_lmresponse,
1423 { "Lan Manager Response", "ntlmssp.auth.lmresponse", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1424 { &hf_ntlmssp_auth_ntresponse,
1425 { "NTLM Response", "ntlmssp.auth.ntresponse", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1426 { &hf_ntlmssp_auth_sesskey,
1427 { "Session Key", "ntlmssp.auth.sesskey", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1428 { &hf_ntlmssp_string_len,
1429 { "Length", "ntlmssp.string.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1430 { &hf_ntlmssp_string_maxlen,
1431 { "Maxlen", "ntlmssp.string.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1432 { &hf_ntlmssp_string_offset,
1433 { "Offset", "ntlmssp.string.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1434 { &hf_ntlmssp_blob_len,
1435 { "Length", "ntlmssp.blob.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1436 { &hf_ntlmssp_blob_maxlen,
1437 { "Maxlen", "ntlmssp.blob.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1438 { &hf_ntlmssp_blob_offset,
1439 { "Offset", "ntlmssp.blob.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1440 { &hf_ntlmssp_address_list,
1441 { "Address List", "ntlmssp.challenge.addresslist", FT_NONE, BASE_NONE, NULL, 0x0, "", HFILL}},
1442 { &hf_ntlmssp_address_list_len,
1443 { "Length", "ntlmssp.challenge.addresslist.length", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1444 { &hf_ntlmssp_address_list_maxlen,
1445 { "Maxlen", "ntlmssp.challenge.addresslist.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL}},
1446 { &hf_ntlmssp_address_list_offset,
1447 { "Offset", "ntlmssp.challenge.addresslist.offset", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL}},
1448 { &hf_ntlmssp_address_list_server_nb,
1449 { "Server NetBIOS Name", "ntlmssp.challenge.addresslist.servernb", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1450 { &hf_ntlmssp_address_list_domain_nb,
1451 { "Domain NetBIOS Name", "ntlmssp.challenge.addresslist.domainnb", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1452 { &hf_ntlmssp_address_list_server_dns,
1453 { "Server DNS Name", "ntlmssp.challenge.addresslist.serverdns", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1454 { &hf_ntlmssp_address_list_domain_dns,
1455 { "Domain DNS Name", "ntlmssp.challenge.addresslist.domaindns", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
1458 { "NTLMSSP Verifier", "ntlmssp.verf", FT_NONE, BASE_NONE, NULL, 0x0, "NTLMSSP Verifier", HFILL }},
1459 { &hf_ntlmssp_verf_vers,
1460 { "Version Number", "ntlmssp.verf.vers", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
1461 { &hf_ntlmssp_verf_body,
1462 { "Verifier Body", "ntlmssp.verf.body", FT_BYTES, BASE_NONE, NULL, 0x0, "", HFILL }},
1463 { &hf_ntlmssp_decrypted_payload,
1464 { "NTLM Decrypted Payload", "ntlmssp.decrypted_payload", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
1465 { &hf_ntlmssp_verf_unknown1,
1466 { "Unknown 1", "ntlmssp.verf.unknown1", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1467 { &hf_ntlmssp_verf_crc32,
1468 { "Verifier CRC32", "ntlmssp.verf.crc32", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
1469 { &hf_ntlmssp_verf_sequence,
1470 { "Verifier Sequence Number", "ntlmssp.verf.sequence", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }}
1474 static gint *ett[] = {
1476 &ett_ntlmssp_negotiate_flags,
1477 &ett_ntlmssp_string,
1479 &ett_ntlmssp_address_list,
1480 &ett_ntlmssp_decrypted_tree
1482 module_t *ntlmssp_module;
1484 proto_ntlmssp = proto_register_protocol (
1485 "NTLM Secure Service Provider", /* name */
1486 "NTLMSSP", /* short name */
1487 "ntlmssp" /* abbrev */
1489 proto_register_field_array (proto_ntlmssp, hf, array_length (hf));
1490 proto_register_subtree_array (ett, array_length (ett));
1491 register_init_routine(&ntlmssp_init_protocol);
1493 ntlmssp_module = prefs_register_protocol(proto_ntlmssp, NULL);
1495 prefs_register_string_preference(ntlmssp_module, "nt_password",
1497 "NT Password (used to decrypt payloads)",
1500 register_dissector("ntlmssp", dissect_ntlmssp, proto_ntlmssp);
1501 new_register_dissector("ntlmssp_verf", dissect_ntlmssp_verf, proto_ntlmssp);
1502 new_register_dissector("ntlmssp_encrypted_payload",
1503 dissect_ntlmssp_encrypted_payload, proto_ntlmssp);
1507 proto_reg_handoff_ntlmssp(void)
1509 dissector_handle_t ntlmssp_handle, ntlmssp_wrap_handle;
1511 /* Register protocol with the GSS-API module */
1513 ntlmssp_handle = find_dissector("ntlmssp");
1514 ntlmssp_wrap_handle = find_dissector("ntlmssp_verf");
1515 gssapi_init_oid("1.3.6.1.4.1.311.2.2.10", proto_ntlmssp, ett_ntlmssp,
1516 ntlmssp_handle, ntlmssp_wrap_handle,
1517 "NTLMSSP - Microsoft NTLM Security Support Provider");