2 * Add-on for better NTLM v1/v2 handling
3 * Copyright 2009, 2012 Matthieu Patou <mat@matws.net>
4 * Routines for NTLM Secure Service Provider
5 * Devin Heitmueller <dheitmueller@netilla.com>
6 * Copyright 2003, Tim Potter <tpot@samba.org>
8 * Wireshark - Network traffic analyzer
9 * By Gerald Combs <gerald@wireshark.org>
10 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
26 /* Just set me to activate debug #define DEBUG_NTLMSSP */
36 #include <wsutil/rc4.h>
37 #include <wsutil/md4.h>
38 #include <wsutil/md5.h>
39 #include <wsutil/des.h>
40 #include <wsutil/crc32.h>
42 #include <epan/packet.h>
43 #include <epan/exceptions.h>
44 #include <epan/asn1.h>
45 #include <epan/prefs.h>
46 #include <epan/wmem/wmem.h>
48 #include <epan/expert.h>
49 #include <epan/show_exception.h>
51 #include "packet-windows-common.h"
52 #include "packet-smb-common.h"
53 #include "packet-kerberos.h"
54 #include "packet-dcerpc.h"
55 #include "packet-gssapi.h"
57 #include "packet-ntlmssp.h"
59 void proto_register_ntlmssp(void);
60 void proto_reg_handoff_ntlmssp(void);
62 static int ntlmssp_tap = -1;
64 #define CLIENT_SIGN_TEXT "session key to client-to-server signing key magic constant"
65 #define CLIENT_SEAL_TEXT "session key to client-to-server sealing key magic constant"
66 #define SERVER_SIGN_TEXT "session key to server-to-client signing key magic constant"
67 #define SERVER_SEAL_TEXT "session key to server-to-client sealing key magic constant"
69 static const value_string ntlmssp_message_types[] = {
70 { NTLMSSP_NEGOTIATE, "NTLMSSP_NEGOTIATE" },
71 { NTLMSSP_CHALLENGE, "NTLMSSP_CHALLENGE" },
72 { NTLMSSP_AUTH, "NTLMSSP_AUTH" },
73 { NTLMSSP_UNKNOWN, "NTLMSSP_UNKNOWN" },
77 typedef struct _md4_pass {
78 guint8 md4[NTLMSSP_KEY_LEN];
81 static const unsigned char gbl_zeros[24] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
82 static GHashTable* hash_packet = NULL;
85 * NTLMSSP negotiation flags
90 * http://davenport.sourceforge.net/ntlm.html
92 * although that document says that:
94 * 0x00010000 is "Target Type Domain";
95 * 0x00020000 is "Target Type Server"
96 * 0x00040000 is "Target Type Share";
98 * and that 0x00100000, 0x00200000, and 0x00400000 are
99 * "Request Init Response", "Request Accept Response", and
100 * "Request Non-NT Session Key", rather than those values shifted
101 * right one having those interpretations.
103 * UPDATE: Further information obtained from [MS-NLMP] 2.2.2.5:
104 * NT LAN Manager (NTLM) Authentication Protocol Specification
105 * http://msdn2.microsoft.com/en-us/library/cc236621.aspx
108 #define NTLMSSP_NEGOTIATE_UNICODE 0x00000001
109 #define NTLMSSP_NEGOTIATE_OEM 0x00000002
110 #define NTLMSSP_REQUEST_TARGET 0x00000004
111 #define NTLMSSP_NEGOTIATE_00000008 0x00000008
112 #define NTLMSSP_NEGOTIATE_SIGN 0x00000010
113 #define NTLMSSP_NEGOTIATE_SEAL 0x00000020
114 #define NTLMSSP_NEGOTIATE_DATAGRAM 0x00000040
115 #define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080
116 #define NTLMSSP_NEGOTIATE_00000100 0x00000100
117 #define NTLMSSP_NEGOTIATE_NTLM 0x00000200
118 #define NTLMSSP_NEGOTIATE_NT_ONLY 0x00000400
119 #define NTLMSSP_NEGOTIATE_ANONYMOUS 0x00000800
120 #define NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED 0x00001000
121 #define NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED 0x00002000
122 #define NTLMSSP_NEGOTIATE_00004000 0x00004000
123 #define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000
124 #define NTLMSSP_TARGET_TYPE_DOMAIN 0x00010000
125 #define NTLMSSP_TARGET_TYPE_SERVER 0x00020000
126 #define NTLMSSP_TARGET_TYPE_SHARE 0x00040000
127 #define NTLMSSP_NEGOTIATE_EXTENDED_SECURITY 0x00080000
128 #define NTLMSSP_NEGOTIATE_IDENTIFY 0x00100000
129 #define NTLMSSP_NEGOTIATE_00200000 0x00200000
130 #define NTLMSSP_REQUEST_NON_NT_SESSION 0x00400000
131 #define NTLMSSP_NEGOTIATE_TARGET_INFO 0x00800000
132 #define NTLMSSP_NEGOTIATE_01000000 0x01000000
133 #define NTLMSSP_NEGOTIATE_VERSION 0x02000000
134 #define NTLMSSP_NEGOTIATE_04000000 0x04000000
135 #define NTLMSSP_NEGOTIATE_08000000 0x08000000
136 #define NTLMSSP_NEGOTIATE_10000000 0x10000000
137 #define NTLMSSP_NEGOTIATE_128 0x20000000
138 #define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000
139 #define NTLMSSP_NEGOTIATE_56 0x80000000
141 static int proto_ntlmssp = -1;
142 static int hf_ntlmssp_auth = -1;
143 static int hf_ntlmssp_message_type = -1;
144 static int hf_ntlmssp_negotiate_flags = -1;
145 static int hf_ntlmssp_negotiate_flags_01 = -1;
146 static int hf_ntlmssp_negotiate_flags_02 = -1;
147 static int hf_ntlmssp_negotiate_flags_04 = -1;
148 static int hf_ntlmssp_negotiate_flags_08 = -1;
149 static int hf_ntlmssp_negotiate_flags_10 = -1;
150 static int hf_ntlmssp_negotiate_flags_20 = -1;
151 static int hf_ntlmssp_negotiate_flags_40 = -1;
152 static int hf_ntlmssp_negotiate_flags_80 = -1;
153 static int hf_ntlmssp_negotiate_flags_100 = -1;
154 static int hf_ntlmssp_negotiate_flags_200 = -1;
155 static int hf_ntlmssp_negotiate_flags_400 = -1;
156 static int hf_ntlmssp_negotiate_flags_800 = -1;
157 static int hf_ntlmssp_negotiate_flags_1000 = -1;
158 static int hf_ntlmssp_negotiate_flags_2000 = -1;
159 static int hf_ntlmssp_negotiate_flags_4000 = -1;
160 static int hf_ntlmssp_negotiate_flags_8000 = -1;
161 static int hf_ntlmssp_negotiate_flags_10000 = -1;
162 static int hf_ntlmssp_negotiate_flags_20000 = -1;
163 static int hf_ntlmssp_negotiate_flags_40000 = -1;
164 static int hf_ntlmssp_negotiate_flags_80000 = -1;
165 static int hf_ntlmssp_negotiate_flags_100000 = -1;
166 static int hf_ntlmssp_negotiate_flags_200000 = -1;
167 static int hf_ntlmssp_negotiate_flags_400000 = -1;
168 static int hf_ntlmssp_negotiate_flags_800000 = -1;
169 static int hf_ntlmssp_negotiate_flags_1000000 = -1;
170 static int hf_ntlmssp_negotiate_flags_2000000 = -1;
171 static int hf_ntlmssp_negotiate_flags_4000000 = -1;
172 static int hf_ntlmssp_negotiate_flags_8000000 = -1;
173 static int hf_ntlmssp_negotiate_flags_10000000 = -1;
174 static int hf_ntlmssp_negotiate_flags_20000000 = -1;
175 static int hf_ntlmssp_negotiate_flags_40000000 = -1;
176 static int hf_ntlmssp_negotiate_flags_80000000 = -1;
177 /* static int hf_ntlmssp_negotiate_workstation_strlen = -1; */
178 /* static int hf_ntlmssp_negotiate_workstation_maxlen = -1; */
179 /* static int hf_ntlmssp_negotiate_workstation_buffer = -1; */
180 static int hf_ntlmssp_negotiate_workstation = -1;
181 /* static int hf_ntlmssp_negotiate_domain_strlen = -1; */
182 /* static int hf_ntlmssp_negotiate_domain_maxlen = -1; */
183 /* static int hf_ntlmssp_negotiate_domain_buffer = -1; */
184 static int hf_ntlmssp_negotiate_domain = -1;
185 static int hf_ntlmssp_ntlm_server_challenge = -1;
186 static int hf_ntlmssp_ntlm_client_challenge = -1;
187 static int hf_ntlmssp_reserved = -1;
188 static int hf_ntlmssp_challenge_target_name = -1;
189 static int hf_ntlmssp_auth_username = -1;
190 static int hf_ntlmssp_auth_domain = -1;
191 static int hf_ntlmssp_auth_hostname = -1;
192 static int hf_ntlmssp_auth_lmresponse = -1;
193 static int hf_ntlmssp_auth_ntresponse = -1;
194 static int hf_ntlmssp_auth_sesskey = -1;
195 static int hf_ntlmssp_string_len = -1;
196 static int hf_ntlmssp_string_maxlen = -1;
197 static int hf_ntlmssp_string_offset = -1;
198 static int hf_ntlmssp_blob_len = -1;
199 static int hf_ntlmssp_blob_maxlen = -1;
200 static int hf_ntlmssp_blob_offset = -1;
201 static int hf_ntlmssp_version = -1;
202 static int hf_ntlmssp_version_major = -1;
203 static int hf_ntlmssp_version_minor = -1;
204 static int hf_ntlmssp_version_build_number = -1;
205 static int hf_ntlmssp_version_ntlm_current_revision = -1;
207 static int hf_ntlmssp_challenge_target_info = -1;
208 static int hf_ntlmssp_challenge_target_info_len = -1;
209 static int hf_ntlmssp_challenge_target_info_maxlen = -1;
210 static int hf_ntlmssp_challenge_target_info_offset = -1;
212 static int hf_ntlmssp_challenge_target_info_item_type = -1;
213 static int hf_ntlmssp_challenge_target_info_item_len = -1;
215 static int hf_ntlmssp_challenge_target_info_end = -1;
216 static int hf_ntlmssp_challenge_target_info_nb_computer_name = -1;
217 static int hf_ntlmssp_challenge_target_info_nb_domain_name = -1;
218 static int hf_ntlmssp_challenge_target_info_dns_computer_name = -1;
219 static int hf_ntlmssp_challenge_target_info_dns_domain_name = -1;
220 static int hf_ntlmssp_challenge_target_info_dns_tree_name = -1;
221 static int hf_ntlmssp_challenge_target_info_flags = -1;
222 static int hf_ntlmssp_challenge_target_info_timestamp = -1;
223 static int hf_ntlmssp_challenge_target_info_restrictions = -1;
224 static int hf_ntlmssp_challenge_target_info_target_name =-1;
225 static int hf_ntlmssp_challenge_target_info_channel_bindings =-1;
227 static int hf_ntlmssp_ntlmv2_response_item_type = -1;
228 static int hf_ntlmssp_ntlmv2_response_item_len = -1;
230 static int hf_ntlmssp_ntlmv2_response_end = -1;
231 static int hf_ntlmssp_ntlmv2_response_nb_computer_name = -1;
232 static int hf_ntlmssp_ntlmv2_response_nb_domain_name = -1;
233 static int hf_ntlmssp_ntlmv2_response_dns_computer_name = -1;
234 static int hf_ntlmssp_ntlmv2_response_dns_domain_name = -1;
235 static int hf_ntlmssp_ntlmv2_response_dns_tree_name = -1;
236 static int hf_ntlmssp_ntlmv2_response_flags = -1;
237 static int hf_ntlmssp_ntlmv2_response_timestamp = -1;
238 static int hf_ntlmssp_ntlmv2_response_restrictions = -1;
239 static int hf_ntlmssp_ntlmv2_response_target_name =-1;
240 static int hf_ntlmssp_ntlmv2_response_channel_bindings =-1;
242 static int hf_ntlmssp_message_integrity_code = -1;
243 static int hf_ntlmssp_verf = -1;
244 static int hf_ntlmssp_verf_vers = -1;
245 static int hf_ntlmssp_verf_body = -1;
246 static int hf_ntlmssp_verf_randompad = -1;
247 static int hf_ntlmssp_verf_hmacmd5 = -1;
248 static int hf_ntlmssp_verf_crc32 = -1;
249 static int hf_ntlmssp_verf_sequence = -1;
250 /* static int hf_ntlmssp_decrypted_payload = -1; */
252 static int hf_ntlmssp_ntlmv2_response = -1;
253 static int hf_ntlmssp_ntlmv2_response_ntproofstr = -1;
254 static int hf_ntlmssp_ntlmv2_response_rversion = -1;
255 static int hf_ntlmssp_ntlmv2_response_hirversion = -1;
256 static int hf_ntlmssp_ntlmv2_response_z = -1;
257 static int hf_ntlmssp_ntlmv2_response_pad = -1;
258 static int hf_ntlmssp_ntlmv2_response_time = -1;
259 static int hf_ntlmssp_ntlmv2_response_chal = -1;
261 static gint ett_ntlmssp = -1;
262 static gint ett_ntlmssp_negotiate_flags = -1;
263 static gint ett_ntlmssp_string = -1;
264 static gint ett_ntlmssp_blob = -1;
265 static gint ett_ntlmssp_version = -1;
266 static gint ett_ntlmssp_challenge_target_info = -1;
267 static gint ett_ntlmssp_challenge_target_info_item = -1;
268 static gint ett_ntlmssp_ntlmv2_response = -1;
269 static gint ett_ntlmssp_ntlmv2_response_item = -1;
271 static expert_field ei_ntlmssp_v2_key_too_long = EI_INIT;
272 static expert_field ei_ntlmssp_blob_len_too_long = EI_INIT;
273 static expert_field ei_ntlmssp_target_info_attr = EI_INIT;
275 /* Configuration variables */
276 const char *gbl_nt_password = NULL;
278 #define MAX_BLOB_SIZE 10240
279 typedef struct _ntlmssp_blob {
284 #define NTLMSSP_CONV_INFO_KEY 0
285 /* Used in the conversation function */
286 typedef struct _ntlmssp_info {
289 rc4_state_struct rc4_state_client;
290 rc4_state_struct rc4_state_server;
291 guint8 sign_key_client[NTLMSSP_KEY_LEN];
292 guint8 sign_key_server[NTLMSSP_KEY_LEN];
293 guint32 server_dest_port;
294 unsigned char server_challenge[8];
295 unsigned char client_challenge[8];
296 int rc4_state_initialized;
297 ntlmssp_blob ntlm_response;
298 ntlmssp_blob lm_response;
301 #define NTLMSSP_PACKET_INFO_KEY 1
302 /* If this struct exists in the payload_decrypt, then we have already
304 typedef struct _ntlmssp_packet_info {
305 guint8 *decrypted_payload;
307 guint8 verifier[NTLMSSP_KEY_LEN];
308 gboolean payload_decrypted;
309 gboolean verifier_decrypted;
310 } ntlmssp_packet_info;
313 static void printnbyte(const guint8* tab, int nb, const char* txt, const char* txt2)
316 fprintf(stderr, "%s ", txt);
319 fprintf(stderr, "%02X ", *(tab+i));
321 fprintf(stderr, "%s", txt2);
324 static void printnchar(const guint8* tab, int nb, char* txt, char* txt2)
327 fprintf(stderr, "%s ", txt);
330 fprintf(stderr, "%c", *(tab+i));
332 fprintf(stderr, "%s", txt2);
336 static void printnbyte(const guint8* tab _U_, int nb _U_, const char* txt _U_, const char* txt2 _U_)
342 * GSlist of decrypted payloads.
344 static GSList *decrypted_payloads;
348 LEBE_Convert(int value)
352 a = value&0x000000FF;
353 b = (value&0x0000FF00) >> 8;
354 c = (value&0x00FF0000) >> 16;
355 d = (value&0xFF000000) >> 24;
356 return (a << 24) | (b << 16) | (c << 8) | d;
361 Perform a DES encryption with a 16 bit key and 8bit data item.
362 It's in fact 3 susbsequent call to crypt_des_ecb with a 7 bit key.
363 Missing bits for the key are replaced by 0;
364 Returns output in response, which is expected to be 24 bytes.
367 crypt_des_ecb_long(guint8 *response,
371 guint8 pw21[21]; /* 21 bytes place for the needed key */
373 memset(pw21, 0, sizeof(pw21));
374 memcpy(pw21, key, 16);
376 memset(response, 0, 24);
377 /* crypt_des_ecb(data, key)*/
378 crypt_des_ecb(response, data, pw21, 1);
379 crypt_des_ecb(response + 8, data, pw21 + 7, 1);
380 crypt_des_ecb(response + 16, data, pw21 + 14, 1);
386 Generate a challenge response, given an eight byte challenge and
387 either the NT or the Lan Manager password hash (16 bytes).
388 Returns output in response, which is expected to be 24 bytes.
391 ntlmssp_generate_challenge_response(guint8 *response,
392 const guint8 *passhash,
393 const guint8 *challenge)
395 guint8 pw21[21]; /* Password hash padded to 21 bytes */
397 memset(pw21, 0x0, sizeof(pw21));
398 memcpy(pw21, passhash, 16);
400 memset(response, 0, 24);
402 crypt_des_ecb(response, challenge, pw21, 1);
403 crypt_des_ecb(response + 8, challenge, pw21 + 7, 1);
404 crypt_des_ecb(response + 16, challenge, pw21 + 14, 1);
410 /* Ultra simple ainsi to unicode converter, will only work for ascii password ...*/
412 str_to_unicode(const char *nt_password, char *nt_password_unicode)
417 password_len = strlen(nt_password);
418 if (nt_password_unicode != NULL) {
419 for (i=0; i<(password_len); i++) {
420 nt_password_unicode[i*2]=nt_password[i];
421 nt_password_unicode[i*2+1]=0;
423 nt_password_unicode[2*password_len]='\0';
427 /* This function generate the Key Exchange Key
428 * Depending on the flags this key will either be used to crypt the exported session key
429 * or will be used directly as exported session key.
430 * Exported session key is the key that will be used for sealing and signing communication*/
433 get_keyexchange_key(unsigned char keyexchangekey[NTLMSSP_KEY_LEN], const unsigned char sessionbasekey[NTLMSSP_KEY_LEN], const unsigned char lm_challenge_response[24], int flags)
435 guint8 basekey[NTLMSSP_KEY_LEN];
438 memset(keyexchangekey, 0, NTLMSSP_KEY_LEN);
439 memset(basekey, 0, NTLMSSP_KEY_LEN);
440 /* sessionbasekey is either derived from lm_password_hash or from nt_password_hash depending on the key type negotiated */
441 memcpy(basekey, sessionbasekey, 8);
442 memset(basekey, 0xBD, 8);
443 if (flags&NTLMSSP_NEGOTIATE_LM_KEY) {
445 crypt_des_ecb(keyexchangekey, lm_challenge_response, basekey, 1);
446 crypt_des_ecb(keyexchangekey+8, lm_challenge_response, basekey+7, 1);
449 if (flags&NTLMSSP_REQUEST_NON_NT_SESSION) {
450 /*People from samba tends to use the same function in this case than in the previous one but with 0 data
451 * it's not clear that it produce the good result
452 * memcpy(keyexchangekey, lm_hash, 8);
453 * Let's trust samba implementation it mights seem weird but they are more often rights than the spec !
455 memset(zeros, 0, 24);
456 crypt_des_ecb(keyexchangekey, zeros, basekey, 3);
457 crypt_des_ecb(keyexchangekey+8, zeros, basekey+7, 1);
460 /* it is stated page 65 of NTLM SSP spec that sessionbasekey should be encrypted with hmac_md5 using the concact of both challenge
461 * when it's NTLM v1 + extended security but it turns out to be wrong !
463 memcpy(keyexchangekey, sessionbasekey, NTLMSSP_KEY_LEN);
468 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
470 get_md4pass_list(md4_pass** p_pass_list, const char* nt_password)
475 unsigned char nt_password_hash[NTLMSSP_KEY_LEN];
476 char nt_password_unicode[256];
484 read_keytab_file_from_preferences();
486 for (ek=enc_key_list; ek; ek=ek->next) {
487 if (ek->keylength == NTLMSSP_KEY_LEN) {
491 memset(nt_password_unicode, 0, sizeof(nt_password_unicode));
492 memset(nt_password_hash, 0, NTLMSSP_KEY_LEN);
493 if ((nt_password[0] != '\0') && (strlen(nt_password) < 129)) {
496 password_len = (int)strlen(nt_password);
497 str_to_unicode(nt_password, nt_password_unicode);
498 crypt_md4(nt_password_hash, nt_password_unicode, password_len*2);
501 /* Unable to calculate the session key without a password or if password is more than 128 char ......*/
505 *p_pass_list = (md4_pass *)wmem_alloc(wmem_packet_scope(), nb_pass*sizeof(md4_pass));
506 pass_list = *p_pass_list;
508 if (memcmp(nt_password_hash, gbl_zeros, NTLMSSP_KEY_LEN) != 0) {
509 memcpy(pass_list[i].md4, nt_password_hash, NTLMSSP_KEY_LEN);
512 for (ek=enc_key_list; ek; ek=ek->next) {
513 if (ek->keylength == NTLMSSP_KEY_LEN) {
514 memcpy(pass_list[i].md4, ek->keyvalue, NTLMSSP_KEY_LEN);
522 /* Create an NTLMSSP version 2 key
525 create_ntlmssp_v2_key(const char *nt_password _U_, const guint8 *serverchallenge , const guint8 *clientchallenge ,
526 guint8 *sessionkey , const guint8 *encryptedsessionkey , int flags ,
527 const ntlmssp_blob *ntlm_response, const ntlmssp_blob *lm_response _U_, ntlmssp_header_t *ntlmssph)
529 /* static const would be nicer, but -Werror=vla does not like it */
530 #define DOMAIN_NAME_BUF_SIZE 512
531 #define USER_BUF_SIZE 256
532 #define BUF_SIZE (DOMAIN_NAME_BUF_SIZE + USER_BUF_SIZE)
533 char domain_name_unicode[DOMAIN_NAME_BUF_SIZE];
534 char user_uppercase[USER_BUF_SIZE];
536 /*guint8 md4[NTLMSSP_KEY_LEN];*/
537 unsigned char nt_password_hash[NTLMSSP_KEY_LEN];
538 unsigned char nt_proof[NTLMSSP_KEY_LEN];
539 unsigned char ntowf[NTLMSSP_KEY_LEN];
540 guint8 sessionbasekey[NTLMSSP_KEY_LEN];
541 guint8 keyexchangekey[NTLMSSP_KEY_LEN];
542 guint8 lm_challenge_response[24];
545 rc4_state_struct rc4state;
548 md4_pass *pass_list = NULL;
550 gboolean found = FALSE;
552 /* We are going to try password encrypted in keytab as well, it's an idean of Stefan Metzmacher <metze@samba.org>
553 * The idea is to be able to test all the key of domain in once and to be able to decode the NTLM dialogs */
555 memset(sessionkey, 0, NTLMSSP_KEY_LEN);
556 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
557 nb_pass = get_md4pass_list(&pass_list, nt_password);
560 memset(user_uppercase, 0, USER_BUF_SIZE);
561 user_len = strlen(ntlmssph->acct_name);
562 if (user_len < USER_BUF_SIZE / 2) {
563 memset(buf, 0, BUF_SIZE);
564 str_to_unicode(ntlmssph->acct_name, buf);
565 for (j = 0; j < (2*user_len); j++) {
566 if (buf[j] != '\0') {
567 user_uppercase[j] = toupper(buf[j]);
572 /* Unable to calculate the session not enought space in buffer, note this is unlikely to happen but ......*/
575 domain_len = strlen(ntlmssph->domain_name);
576 if (domain_len < DOMAIN_NAME_BUF_SIZE / 2) {
577 str_to_unicode(ntlmssph->domain_name, domain_name_unicode);
580 /* Unable to calculate the session not enought space in buffer, note this is unlikely to happen but ......*/
583 while (i < nb_pass) {
585 fprintf(stderr, "Turn %d, ", i);
587 memcpy(nt_password_hash, pass_list[i].md4, NTLMSSP_KEY_LEN);
588 printnbyte(nt_password_hash, NTLMSSP_KEY_LEN, "Current NT password hash: ", "\n");
590 /* ntowf computation */
591 memset(buf, 0, BUF_SIZE);
592 memcpy(buf, user_uppercase, user_len*2);
593 memcpy(buf+user_len*2, domain_name_unicode, domain_len*2);
594 md5_hmac(buf, domain_len*2+user_len*2, nt_password_hash, NTLMSSP_KEY_LEN, ntowf);
595 printnbyte(ntowf, NTLMSSP_KEY_LEN, "NTOWF: ", "\n");
598 memset(buf, 0, BUF_SIZE);
599 memcpy(buf, serverchallenge, 8);
600 memcpy(buf+8, clientchallenge, 8);
601 md5_hmac(buf, NTLMSSP_KEY_LEN, ntowf, NTLMSSP_KEY_LEN, lm_challenge_response);
602 memcpy(lm_challenge_response+NTLMSSP_KEY_LEN, clientchallenge, 8);
603 printnbyte(lm_challenge_response, 24, "LM Response: ", "\n");
605 /* NT proof = First NTLMSSP_KEY_LEN bytes of NT response */
606 memset(buf, 0, BUF_SIZE);
607 memcpy(buf, serverchallenge, 8);
608 memcpy(buf+8, ntlm_response->contents+NTLMSSP_KEY_LEN, MIN(BUF_SIZE - 8, ntlm_response->length-NTLMSSP_KEY_LEN));
609 md5_hmac(buf, ntlm_response->length-8, ntowf, NTLMSSP_KEY_LEN, nt_proof);
610 printnbyte(nt_proof, NTLMSSP_KEY_LEN, "NT proof: ", "\n");
611 if (!memcmp(nt_proof, ntlm_response->contents, NTLMSSP_KEY_LEN)) {
620 md5_hmac(nt_proof, NTLMSSP_KEY_LEN, ntowf, NTLMSSP_KEY_LEN, sessionbasekey);
621 get_keyexchange_key(keyexchangekey, sessionbasekey, lm_challenge_response, flags);
622 /* now decrypt session key if needed and setup sessionkey for decrypting further communications */
623 if (flags & NTLMSSP_NEGOTIATE_KEY_EXCH)
625 memcpy(sessionkey, encryptedsessionkey, NTLMSSP_KEY_LEN);
626 crypt_rc4_init(&rc4state, keyexchangekey, NTLMSSP_KEY_LEN);
627 crypt_rc4(&rc4state, sessionkey, NTLMSSP_KEY_LEN);
631 memcpy(sessionkey, keyexchangekey, NTLMSSP_KEY_LEN);
634 memcpy(ntlmssph->session_key, sessionkey, NTLMSSP_KEY_LEN);
637 /* Create an NTLMSSP version 1 key
638 * That is more complicated logic and methods and user challenge as well.
639 * password points to the ANSI password to encrypt, challenge points to
640 * the 8 octet challenge string
643 create_ntlmssp_v1_key(const char *nt_password, const guint8 *serverchallenge, const guint8 *clientchallenge,
644 guint8 *sessionkey, const guint8 *encryptedsessionkey, int flags,
645 const guint8 *ref_nt_challenge_response, const guint8 *ref_lm_challenge_response,
646 ntlmssp_header_t *ntlmssph)
648 unsigned char lm_password_upper[NTLMSSP_KEY_LEN];
649 unsigned char lm_password_hash[NTLMSSP_KEY_LEN];
650 unsigned char nt_password_hash[NTLMSSP_KEY_LEN];
651 unsigned char challenges_hash[NTLMSSP_KEY_LEN];
652 unsigned char challenges_hash_first8[8];
653 unsigned char challenges[NTLMSSP_KEY_LEN];
654 guint8 md4[NTLMSSP_KEY_LEN];
656 guint8 sessionbasekey[NTLMSSP_KEY_LEN];
657 guint8 keyexchangekey[NTLMSSP_KEY_LEN];
658 guint8 lm_challenge_response[24];
659 guint8 nt_challenge_response[24];
660 rc4_state_struct rc4state;
661 md5_state_t md5state;
662 char nt_password_unicode[256];
665 gboolean found = FALSE;
666 md4_pass *pass_list = NULL;
668 static const unsigned char lmhash_key[] =
669 {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
671 memset(sessionkey, 0, NTLMSSP_KEY_LEN);
672 memset(lm_password_upper, 0, sizeof(lm_password_upper));
673 /* lm auth/lm session == (!NTLM_NEGOTIATE_NT_ONLY && NTLMSSP_NEGOTIATE_LM_KEY) || ! (EXTENDED_SECURITY) || ! NTLMSSP_NEGOTIATE_NTLM*/
674 /* Create a Lan Manager hash of the input password */
675 if (nt_password[0] != '\0') {
676 password_len = strlen(nt_password);
677 /*Do not forget to free nt_password_nt*/
678 str_to_unicode(nt_password, nt_password_unicode);
679 crypt_md4(nt_password_hash, nt_password_unicode, password_len*2);
680 /* Truncate password if too long */
681 if (password_len > NTLMSSP_KEY_LEN)
682 password_len = NTLMSSP_KEY_LEN;
683 for (i = 0; i < password_len; i++) {
684 lm_password_upper[i] = toupper(nt_password[i]);
689 /* Unable to calculate the session key without a password ... and we will not use one for a keytab*/
690 if (!(flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY)) {
694 if ((flags & NTLMSSP_NEGOTIATE_LM_KEY && !(flags & NTLMSSP_NEGOTIATE_NT_ONLY)) || !(flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY) || !(flags & NTLMSSP_NEGOTIATE_NTLM)) {
695 crypt_des_ecb(lm_password_hash, lmhash_key, lm_password_upper, 1);
696 crypt_des_ecb(lm_password_hash+8, lmhash_key, lm_password_upper+7, 1);
697 ntlmssp_generate_challenge_response(lm_challenge_response,
698 lm_password_hash, serverchallenge);
699 memcpy(sessionbasekey, lm_password_hash, NTLMSSP_KEY_LEN);
703 memset(lm_challenge_response, 0, 24);
704 if (flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY) {
705 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
706 nb_pass = get_md4pass_list(&pass_list, nt_password);
709 while (i < nb_pass) {
710 /*fprintf(stderr, "Turn %d, ", i);*/
711 memcpy(nt_password_hash, pass_list[i].md4, NTLMSSP_KEY_LEN);
712 /*printnbyte(nt_password_hash, NTLMSSP_KEY_LEN, "Current NT password hash: ", "\n");*/
715 memcpy(lm_challenge_response, clientchallenge, 8);
718 md5_append(&md5state, serverchallenge, 8);
719 md5_append(&md5state, clientchallenge, 8);
720 md5_finish(&md5state, challenges_hash);
721 memcpy(challenges_hash_first8, challenges_hash, 8);
722 crypt_des_ecb_long(nt_challenge_response, nt_password_hash, challenges_hash_first8);
723 if (ref_nt_challenge_response && !memcmp(ref_nt_challenge_response, nt_challenge_response, 24)) {
730 crypt_des_ecb_long(nt_challenge_response, nt_password_hash, serverchallenge);
731 if (flags & NTLMSSP_NEGOTIATE_NT_ONLY) {
732 memcpy(lm_challenge_response, nt_challenge_response, 24);
735 crypt_des_ecb_long(lm_challenge_response, lm_password_hash, serverchallenge);
737 if (ref_nt_challenge_response &&
738 !memcmp(ref_nt_challenge_response, nt_challenge_response, 24) &&
739 ref_lm_challenge_response &&
740 !memcmp(ref_lm_challenge_response, lm_challenge_response, 24))
745 /* So it's clearly not like this that's put into NTLMSSP doc but after some digging into samba code I'm quite confident
746 * that sessionbasekey should be based md4(nt_password_hash) only in the case of some NT auth
747 * Otherwise it should be lm_password_hash ...*/
748 crypt_md4(md4, nt_password_hash, NTLMSSP_KEY_LEN);
749 if (flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY) {
750 memcpy(challenges, serverchallenge, 8);
752 memcpy(challenges+8, clientchallenge, 8);
754 /*md5_hmac(text, text_len, key, key_len, digest);*/
755 md5_hmac(challenges, NTLMSSP_KEY_LEN, md4, NTLMSSP_KEY_LEN, sessionbasekey);
758 memcpy(sessionbasekey, md4, NTLMSSP_KEY_LEN);
766 get_keyexchange_key(keyexchangekey, sessionbasekey, lm_challenge_response, flags);
767 memset(sessionkey, 0, NTLMSSP_KEY_LEN);
768 /*printnbyte(nt_challenge_response, 24, "NT challenge response", "\n");
769 printnbyte(lm_challenge_response, 24, "LM challenge response", "\n");*/
770 /* now decrypt session key if needed and setup sessionkey for decrypting further communications */
771 if (flags & NTLMSSP_NEGOTIATE_KEY_EXCH)
773 memcpy(sessionkey, encryptedsessionkey, NTLMSSP_KEY_LEN);
774 crypt_rc4_init(&rc4state, keyexchangekey, NTLMSSP_KEY_LEN);
775 crypt_rc4(&rc4state, sessionkey, NTLMSSP_KEY_LEN);
779 memcpy(sessionkey, keyexchangekey, NTLMSSP_KEY_LEN);
781 memcpy(ntlmssph->session_key, sessionkey, NTLMSSP_KEY_LEN);
785 get_siging_key(guint8 *sign_key_server, guint8* sign_key_client, const guint8 key[NTLMSSP_KEY_LEN], int keylen)
787 md5_state_t md5state;
788 md5_state_t md5state2;
790 memset(sign_key_client, 0, NTLMSSP_KEY_LEN);
791 memset(sign_key_server, 0, NTLMSSP_KEY_LEN);
793 md5_append(&md5state, key, keylen);
794 md5_append(&md5state, CLIENT_SIGN_TEXT, strlen(CLIENT_SIGN_TEXT)+1);
795 md5_finish(&md5state, sign_key_client);
796 md5_init(&md5state2);
797 md5_append(&md5state2, key, keylen);
798 md5_append(&md5state2, SERVER_SIGN_TEXT, strlen(SERVER_SIGN_TEXT)+1);
799 md5_finish(&md5state2, sign_key_server);
803 /* We return either a 128 or 64 bit key
806 get_sealing_rc4key(const guint8 exportedsessionkey[NTLMSSP_KEY_LEN] , const int flags , int *keylen ,
807 guint8 *clientsealkey , guint8 *serversealkey)
809 md5_state_t md5state;
810 md5_state_t md5state2;
812 memset(clientsealkey, 0, NTLMSSP_KEY_LEN);
813 memset(serversealkey, 0, NTLMSSP_KEY_LEN);
814 memcpy(clientsealkey, exportedsessionkey, NTLMSSP_KEY_LEN);
815 if (flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY)
817 if (flags & NTLMSSP_NEGOTIATE_128)
819 /* The exportedsessionkey has already the good length just update the length*/
824 if (flags & NTLMSSP_NEGOTIATE_56)
826 memset(clientsealkey+7, 0, 9);
831 memset(clientsealkey+5, 0, 11);
835 memcpy(serversealkey, clientsealkey, NTLMSSP_KEY_LEN);
837 md5_append(&md5state, clientsealkey,*keylen);
838 md5_append(&md5state, CLIENT_SEAL_TEXT, strlen(CLIENT_SEAL_TEXT)+1);
839 md5_finish(&md5state, clientsealkey);
840 md5_init(&md5state2);
841 md5_append(&md5state2, serversealkey,*keylen);
842 md5_append(&md5state2, SERVER_SEAL_TEXT, strlen(SERVER_SEAL_TEXT)+1);
843 md5_finish(&md5state2, serversealkey);
847 if (flags & NTLMSSP_NEGOTIATE_128)
849 /* The exportedsessionkey has already the good length just update the length*/
855 if (flags & NTLMSSP_NEGOTIATE_56)
857 memset(clientsealkey+7, 0, 9);
861 memset(clientsealkey+5, 0, 11);
862 clientsealkey[5]=0xe5;
863 clientsealkey[6]=0x38;
864 clientsealkey[7]=0xb0;
867 memcpy(serversealkey, clientsealkey,*keylen);
870 /* Create an NTLMSSP version 1 key.
871 * password points to the ANSI password to encrypt, challenge points to
872 * the 8 octet challenge string, key128 will do a 128 bit key if set to 1,
873 * otherwise it will do a 40 bit key. The result is stored in
874 * sspkey (expected to be NTLMSSP_KEY_LEN octets)
876 /* dissect a string - header area contains:
879 four byte offset of string in data area
880 The function returns the offset at the end of the string header,
881 but the 'end' parameter returns the offset of the end of the string itself
882 The 'start' parameter returns the offset of the beginning of the string
883 If there's no string, just use the offset of the end of the tvb as start/end.
886 dissect_ntlmssp_string (tvbuff_t *tvb, int offset,
887 proto_tree *ntlmssp_tree,
888 gboolean unicode_strings,
889 int string_hf, int *start, int *end,
890 const char **stringp)
892 proto_tree *tree = NULL;
893 proto_item *tf = NULL;
894 gint16 string_length = tvb_get_letohs(tvb, offset);
895 gint16 string_maxlen = tvb_get_letohs(tvb, offset+2);
896 gint32 string_offset = tvb_get_letohl(tvb, offset+4);
897 const char *string_text = NULL;
901 *start = (string_offset > offset+8 ? string_offset : (signed)tvb_reported_length(tvb));
902 if (0 == string_length) {
905 proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
912 bc = result_length = string_length;
913 string_text = get_unicode_or_ascii_string(tvb, &string_offset,
914 unicode_strings, &result_length,
917 if (stringp != NULL) {
918 if (!string_text) string_text = ""; /* Make sure we don't blow up later */
920 *stringp = string_text;
924 tf = proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
925 string_offset, result_length, string_text);
926 tree = proto_item_add_subtree(tf, ett_ntlmssp_string);
928 proto_tree_add_uint(tree, hf_ntlmssp_string_len,
929 tvb, offset, 2, string_length);
931 proto_tree_add_uint(tree, hf_ntlmssp_string_maxlen,
932 tvb, offset, 2, string_maxlen);
934 proto_tree_add_uint(tree, hf_ntlmssp_string_offset,
935 tvb, offset, 4, string_offset);
938 *end = string_offset + string_length;
942 /* dissect a generic blob - header area contains:
945 four byte offset of blob in data area
946 The function returns the offset at the end of the blob header,
947 but the 'end' parameter returns the offset of the end of the blob itself
950 dissect_ntlmssp_blob (tvbuff_t *tvb, packet_info *pinfo,
951 proto_tree *ntlmssp_tree, int offset,
952 int blob_hf, int *end, ntlmssp_blob *result)
954 proto_item *tf = NULL;
955 proto_tree *tree = NULL;
956 guint16 blob_length = tvb_get_letohs(tvb, offset);
957 guint16 blob_maxlen = tvb_get_letohs(tvb, offset+2);
958 guint32 blob_offset = tvb_get_letohl(tvb, offset+4);
960 if (0 == blob_length) {
961 *end = (blob_offset > ((guint)offset)+8 ? blob_offset : ((guint)offset)+8);
963 proto_tree_add_text(ntlmssp_tree, tvb, offset, 8, "%s: Empty",
964 proto_registrar_get_name(blob_hf));
966 result->contents = NULL;
971 tf = proto_tree_add_item (ntlmssp_tree, blob_hf, tvb,
972 blob_offset, blob_length, ENC_NA);
973 tree = proto_item_add_subtree(tf, ett_ntlmssp_blob);
975 proto_tree_add_uint(tree, hf_ntlmssp_blob_len,
976 tvb, offset, 2, blob_length);
978 proto_tree_add_uint(tree, hf_ntlmssp_blob_maxlen,
979 tvb, offset, 2, blob_maxlen);
981 proto_tree_add_uint(tree, hf_ntlmssp_blob_offset,
982 tvb, offset, 4, blob_offset);
985 *end = blob_offset + blob_length;
987 if (result != NULL) {
988 result->length = blob_length;
989 if (blob_length < MAX_BLOB_SIZE)
991 result->contents = (guint8 *)wmem_alloc(wmem_file_scope(), blob_length);
992 tvb_memcpy(tvb, result->contents, blob_offset, blob_length);
993 if (blob_hf == hf_ntlmssp_auth_lmresponse &&
994 !(tvb_memeql(tvb, blob_offset+8, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", NTLMSSP_KEY_LEN)))
996 proto_tree_add_item (ntlmssp_tree,
997 hf_ntlmssp_ntlm_client_challenge,
998 tvb, blob_offset, 8, ENC_NA);
1002 result->contents = NULL;
1003 expert_add_info_format(pinfo, tf, &ei_ntlmssp_v2_key_too_long,
1004 "NTLM v2 key is %d bytes long, too big for our %d buffer", blob_length, MAX_BLOB_SIZE);
1008 /* If we are dissecting the NTLM response and it is a NTLMv2
1009 response call the appropriate dissector. */
1011 if (blob_hf == hf_ntlmssp_auth_ntresponse && blob_length > 24)
1013 proto_tree_add_item (ntlmssp_tree,
1014 hf_ntlmssp_ntlm_client_challenge,
1015 tvb, blob_offset+32, 8, ENC_NA);
1016 dissect_ntlmv2_response(tvb, pinfo, tree, blob_offset, blob_length);
1023 dissect_ntlmssp_negotiate_flags (tvbuff_t *tvb, int offset,
1024 proto_tree *ntlmssp_tree,
1025 guint32 negotiate_flags)
1027 proto_tree *negotiate_flags_tree = NULL;
1028 proto_item *tf = NULL;
1031 tf = proto_tree_add_uint (ntlmssp_tree,
1032 hf_ntlmssp_negotiate_flags,
1033 tvb, offset, 4, negotiate_flags);
1034 negotiate_flags_tree = proto_item_add_subtree (tf, ett_ntlmssp_negotiate_flags);
1037 proto_tree_add_boolean (negotiate_flags_tree,
1038 hf_ntlmssp_negotiate_flags_80000000,
1039 tvb, offset, 4, negotiate_flags);
1040 proto_tree_add_boolean (negotiate_flags_tree,
1041 hf_ntlmssp_negotiate_flags_40000000,
1042 tvb, offset, 4, negotiate_flags);
1043 proto_tree_add_boolean (negotiate_flags_tree,
1044 hf_ntlmssp_negotiate_flags_20000000,
1045 tvb, offset, 4, negotiate_flags);
1046 proto_tree_add_boolean (negotiate_flags_tree,
1047 hf_ntlmssp_negotiate_flags_10000000,
1048 tvb, offset, 4, negotiate_flags);
1049 proto_tree_add_boolean (negotiate_flags_tree,
1050 hf_ntlmssp_negotiate_flags_8000000,
1051 tvb, offset, 4, negotiate_flags);
1052 proto_tree_add_boolean (negotiate_flags_tree,
1053 hf_ntlmssp_negotiate_flags_4000000,
1054 tvb, offset, 4, negotiate_flags);
1055 proto_tree_add_boolean (negotiate_flags_tree,
1056 hf_ntlmssp_negotiate_flags_2000000,
1057 tvb, offset, 4, negotiate_flags);
1058 proto_tree_add_boolean (negotiate_flags_tree,
1059 hf_ntlmssp_negotiate_flags_1000000,
1060 tvb, offset, 4, negotiate_flags);
1061 proto_tree_add_boolean (negotiate_flags_tree,
1062 hf_ntlmssp_negotiate_flags_800000,
1063 tvb, offset, 4, negotiate_flags);
1064 proto_tree_add_boolean (negotiate_flags_tree,
1065 hf_ntlmssp_negotiate_flags_400000,
1066 tvb, offset, 4, negotiate_flags);
1067 proto_tree_add_boolean (negotiate_flags_tree,
1068 hf_ntlmssp_negotiate_flags_200000,
1069 tvb, offset, 4, negotiate_flags);
1070 proto_tree_add_boolean (negotiate_flags_tree,
1071 hf_ntlmssp_negotiate_flags_100000,
1072 tvb, offset, 4, negotiate_flags);
1073 proto_tree_add_boolean (negotiate_flags_tree,
1074 hf_ntlmssp_negotiate_flags_80000,
1075 tvb, offset, 4, negotiate_flags);
1076 proto_tree_add_boolean (negotiate_flags_tree,
1077 hf_ntlmssp_negotiate_flags_40000,
1078 tvb, offset, 4, negotiate_flags);
1079 proto_tree_add_boolean (negotiate_flags_tree,
1080 hf_ntlmssp_negotiate_flags_20000,
1081 tvb, offset, 4, negotiate_flags);
1082 proto_tree_add_boolean (negotiate_flags_tree,
1083 hf_ntlmssp_negotiate_flags_10000,
1084 tvb, offset, 4, negotiate_flags);
1085 proto_tree_add_boolean (negotiate_flags_tree,
1086 hf_ntlmssp_negotiate_flags_8000,
1087 tvb, offset, 4, negotiate_flags);
1088 proto_tree_add_boolean (negotiate_flags_tree,
1089 hf_ntlmssp_negotiate_flags_4000,
1090 tvb, offset, 4, negotiate_flags);
1091 proto_tree_add_boolean (negotiate_flags_tree,
1092 hf_ntlmssp_negotiate_flags_2000,
1093 tvb, offset, 4, negotiate_flags);
1094 proto_tree_add_boolean (negotiate_flags_tree,
1095 hf_ntlmssp_negotiate_flags_1000,
1096 tvb, offset, 4, negotiate_flags);
1097 proto_tree_add_boolean (negotiate_flags_tree,
1098 hf_ntlmssp_negotiate_flags_800,
1099 tvb, offset, 4, negotiate_flags);
1100 proto_tree_add_boolean (negotiate_flags_tree,
1101 hf_ntlmssp_negotiate_flags_400,
1102 tvb, offset, 4, negotiate_flags);
1103 proto_tree_add_boolean (negotiate_flags_tree,
1104 hf_ntlmssp_negotiate_flags_200,
1105 tvb, offset, 4, negotiate_flags);
1106 proto_tree_add_boolean (negotiate_flags_tree,
1107 hf_ntlmssp_negotiate_flags_100,
1108 tvb, offset, 4, negotiate_flags);
1109 proto_tree_add_boolean (negotiate_flags_tree,
1110 hf_ntlmssp_negotiate_flags_80,
1111 tvb, offset, 4, negotiate_flags);
1112 proto_tree_add_boolean (negotiate_flags_tree,
1113 hf_ntlmssp_negotiate_flags_40,
1114 tvb, offset, 4, negotiate_flags);
1115 proto_tree_add_boolean (negotiate_flags_tree,
1116 hf_ntlmssp_negotiate_flags_20,
1117 tvb, offset, 4, negotiate_flags);
1118 proto_tree_add_boolean (negotiate_flags_tree,
1119 hf_ntlmssp_negotiate_flags_10,
1120 tvb, offset, 4, negotiate_flags);
1121 proto_tree_add_boolean (negotiate_flags_tree,
1122 hf_ntlmssp_negotiate_flags_08,
1123 tvb, offset, 4, negotiate_flags);
1124 proto_tree_add_boolean (negotiate_flags_tree,
1125 hf_ntlmssp_negotiate_flags_04,
1126 tvb, offset, 4, negotiate_flags);
1127 proto_tree_add_boolean (negotiate_flags_tree,
1128 hf_ntlmssp_negotiate_flags_02,
1129 tvb, offset, 4, negotiate_flags);
1130 proto_tree_add_boolean (negotiate_flags_tree,
1131 hf_ntlmssp_negotiate_flags_01,
1132 tvb, offset, 4, negotiate_flags);
1134 return (offset + 4);
1137 /* Dissect "version" */
1140 0 Major Version Number 1 byte
1141 1 Minor Version Number 1 byte
1142 2 Build Number short(LE)
1143 3 (Reserved) 3 bytes
1144 4 NTLM Current Revision 1 byte
1148 dissect_ntlmssp_version(tvbuff_t *tvb, int offset,
1149 proto_tree *ntlmssp_tree)
1153 proto_tree *version_tree;
1154 tf = proto_tree_add_none_format(ntlmssp_tree, hf_ntlmssp_version, tvb, offset, 8,
1155 "Version %u.%u (Build %u); NTLM Current Revision %u",
1156 tvb_get_guint8(tvb, offset),
1157 tvb_get_guint8(tvb, offset+1),
1158 tvb_get_letohs(tvb, offset+2),
1159 tvb_get_guint8(tvb, offset+7));
1160 version_tree = proto_item_add_subtree (tf, ett_ntlmssp_version);
1161 proto_tree_add_item(version_tree, hf_ntlmssp_version_major , tvb, offset , 1, ENC_NA);
1162 proto_tree_add_item(version_tree, hf_ntlmssp_version_minor , tvb, offset+1, 1, ENC_NA);
1163 proto_tree_add_item(version_tree, hf_ntlmssp_version_build_number , tvb, offset+2, 2, ENC_LITTLE_ENDIAN);
1164 proto_tree_add_item(version_tree, hf_ntlmssp_version_ntlm_current_revision, tvb, offset+7, 1, ENC_NA);
1169 /* Dissect a NTLM response. This is documented at
1170 http://ubiqx.org/cifs/SMB.html#SMB.8, para 2.8.5.3 */
1172 /* Attribute types */
1174 * XXX - the davenport document says that a type of 5 has been seen,
1175 * "apparently containing the 'parent' DNS domain for servers in
1177 * XXX: MS-NLMP info is newer than Davenport info;
1178 * The attribute type list and the attribute names below are
1179 * based upon MS-NLMP.
1182 #define NTLM_TARGET_INFO_END 0x0000
1183 #define NTLM_TARGET_INFO_NB_COMPUTER_NAME 0x0001
1184 #define NTLM_TARGET_INFO_NB_DOMAIN_NAME 0x0002
1185 #define NTLM_TARGET_INFO_DNS_COMPUTER_NAME 0x0003
1186 #define NTLM_TARGET_INFO_DNS_DOMAIN_NAME 0x0004
1187 #define NTLM_TARGET_INFO_DNS_TREE_NAME 0x0005
1188 #define NTLM_TARGET_INFO_FLAGS 0x0006
1189 #define NTLM_TARGET_INFO_TIMESTAMP 0x0007
1190 #define NTLM_TARGET_INFO_RESTRICTIONS 0x0008
1191 #define NTLM_TARGET_INFO_TARGET_NAME 0x0009
1192 #define NTLM_TARGET_INFO_CHANNEL_BINDINGS 0x000A
1194 static const value_string ntlm_name_types[] = {
1195 { NTLM_TARGET_INFO_END, "End of list" },
1196 { NTLM_TARGET_INFO_NB_COMPUTER_NAME, "NetBIOS computer name" },
1197 { NTLM_TARGET_INFO_NB_DOMAIN_NAME, "NetBIOS domain name" },
1198 { NTLM_TARGET_INFO_DNS_COMPUTER_NAME, "DNS computer name" },
1199 { NTLM_TARGET_INFO_DNS_DOMAIN_NAME, "DNS domain name" },
1200 { NTLM_TARGET_INFO_DNS_TREE_NAME, "DNS tree name" },
1201 { NTLM_TARGET_INFO_FLAGS, "Flags" },
1202 { NTLM_TARGET_INFO_TIMESTAMP, "Timestamp" },
1203 { NTLM_TARGET_INFO_RESTRICTIONS, "Restrictions" },
1204 { NTLM_TARGET_INFO_TARGET_NAME, "Target Name"},
1205 { NTLM_TARGET_INFO_CHANNEL_BINDINGS, "Channel Bindings"},
1208 static value_string_ext ntlm_name_types_ext = VALUE_STRING_EXT_INIT(ntlm_name_types);
1210 /* The following *must* match the order of the list of attribute types */
1211 /* Assumption: values in the list are a sequence starting with 0 and */
1212 /* with no gaps allowing a direct access of the array by attribute type */
1213 static int *ntlmssp_hf_challenge_target_info_hf_ptr_array[] = {
1214 &hf_ntlmssp_challenge_target_info_end,
1215 &hf_ntlmssp_challenge_target_info_nb_computer_name,
1216 &hf_ntlmssp_challenge_target_info_nb_domain_name,
1217 &hf_ntlmssp_challenge_target_info_dns_computer_name,
1218 &hf_ntlmssp_challenge_target_info_dns_domain_name,
1219 &hf_ntlmssp_challenge_target_info_dns_tree_name,
1220 &hf_ntlmssp_challenge_target_info_flags,
1221 &hf_ntlmssp_challenge_target_info_timestamp,
1222 &hf_ntlmssp_challenge_target_info_restrictions,
1223 &hf_ntlmssp_challenge_target_info_target_name,
1224 &hf_ntlmssp_challenge_target_info_channel_bindings
1227 static int *ntlmssp_hf_ntlmv2_response_hf_ptr_array[] = {
1228 &hf_ntlmssp_ntlmv2_response_end,
1229 &hf_ntlmssp_ntlmv2_response_nb_computer_name,
1230 &hf_ntlmssp_ntlmv2_response_nb_domain_name,
1231 &hf_ntlmssp_ntlmv2_response_dns_computer_name,
1232 &hf_ntlmssp_ntlmv2_response_dns_domain_name,
1233 &hf_ntlmssp_ntlmv2_response_dns_tree_name,
1234 &hf_ntlmssp_ntlmv2_response_flags,
1235 &hf_ntlmssp_ntlmv2_response_timestamp,
1236 &hf_ntlmssp_ntlmv2_response_restrictions,
1237 &hf_ntlmssp_ntlmv2_response_target_name,
1238 &hf_ntlmssp_ntlmv2_response_channel_bindings
1241 typedef struct _tif {
1244 int *hf_item_length;
1245 int **hf_attr_array_p;
1248 static tif_t ntlmssp_challenge_target_info_tif = {
1249 &ett_ntlmssp_challenge_target_info_item,
1250 &hf_ntlmssp_challenge_target_info_item_type,
1251 &hf_ntlmssp_challenge_target_info_item_len,
1252 ntlmssp_hf_challenge_target_info_hf_ptr_array
1255 static tif_t ntlmssp_ntlmv2_response_tif = {
1256 &ett_ntlmssp_ntlmv2_response_item,
1257 &hf_ntlmssp_ntlmv2_response_item_type,
1258 &hf_ntlmssp_ntlmv2_response_item_len,
1259 ntlmssp_hf_ntlmv2_response_hf_ptr_array
1262 /** See [MS-NLMP] 2.2.2.1 */
1264 dissect_ntlmssp_target_info_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1265 guint32 target_info_offset, guint16 target_info_length,
1268 guint32 item_offset;
1269 guint16 item_type = ~0;
1270 guint16 item_length;
1272 /* Now enumerate through the individual items in the list */
1273 item_offset = target_info_offset;
1275 while (item_offset < (target_info_offset + target_info_length) && (item_type != NTLM_TARGET_INFO_END)) {
1276 proto_item *target_info_tf;
1277 proto_tree *target_info_tree;
1278 guint32 content_offset;
1279 guint16 content_length;
1280 guint32 type_offset;
1282 const gchar *text = NULL;
1284 int **hf_array_p = tif_p->hf_attr_array_p;
1287 type_offset = item_offset;
1288 item_type = tvb_get_letohs(tvb, type_offset);
1290 /* Content length */
1291 len_offset = type_offset + 2;
1292 content_length = tvb_get_letohs(tvb, len_offset);
1295 content_offset = len_offset + 2;
1296 item_length = content_length + 4;
1298 target_info_tf = proto_tree_add_text(tree, tvb, item_offset, item_length, "Attribute: %s",
1299 val_to_str_ext(item_type, &ntlm_name_types_ext, "Unknown (%d)"));
1301 target_info_tree = proto_item_add_subtree (target_info_tf, *tif_p->ett);
1302 proto_tree_add_item (target_info_tree, *tif_p->hf_item_type, tvb, type_offset, 2, ENC_LITTLE_ENDIAN);
1303 proto_tree_add_item (target_info_tree, *tif_p->hf_item_length, tvb, len_offset, 2, ENC_LITTLE_ENDIAN);
1305 if (content_length > 0) {
1306 switch (item_type) {
1307 case NTLM_TARGET_INFO_NB_COMPUTER_NAME:
1308 case NTLM_TARGET_INFO_NB_DOMAIN_NAME:
1309 case NTLM_TARGET_INFO_DNS_COMPUTER_NAME:
1310 case NTLM_TARGET_INFO_DNS_DOMAIN_NAME:
1311 case NTLM_TARGET_INFO_DNS_TREE_NAME:
1312 case NTLM_TARGET_INFO_TARGET_NAME:
1313 text = tvb_get_string_enc(wmem_packet_scope(), tvb, content_offset, content_length, ENC_UTF_16|ENC_LITTLE_ENDIAN);
1314 proto_tree_add_string(target_info_tree, *hf_array_p[item_type], tvb, content_offset, content_length, text);
1315 proto_item_append_text(target_info_tf, ": %s", text);
1318 case NTLM_TARGET_INFO_FLAGS:
1319 proto_tree_add_item(target_info_tree, *hf_array_p[item_type], tvb, content_offset, content_length, ENC_LITTLE_ENDIAN);
1322 case NTLM_TARGET_INFO_TIMESTAMP:
1323 dissect_nt_64bit_time(tvb, target_info_tree, content_offset, *hf_array_p[item_type]);
1326 case NTLM_TARGET_INFO_RESTRICTIONS:
1327 case NTLM_TARGET_INFO_CHANNEL_BINDINGS:
1328 proto_tree_add_item(target_info_tree, *hf_array_p[item_type], tvb, content_offset, content_length, ENC_NA);
1332 proto_tree_add_expert(target_info_tree, pinfo, &ei_ntlmssp_target_info_attr,
1333 tvb, content_offset, content_length);
1338 item_offset += item_length;
1344 /** See [MS-NLMP] 3.3.2 */
1346 dissect_ntlmv2_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int len)
1348 proto_item *ntlmv2_item = NULL;
1349 proto_tree *ntlmv2_tree = NULL;
1350 const int orig_offset = offset;
1353 ntlmv2_item = proto_tree_add_item(
1354 tree, hf_ntlmssp_ntlmv2_response, tvb,
1355 offset, len, ENC_NA);
1356 ntlmv2_tree = proto_item_add_subtree(
1357 ntlmv2_item, ett_ntlmssp_ntlmv2_response);
1360 proto_tree_add_item(
1361 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_ntproofstr, tvb,
1362 offset, 16, ENC_NA);
1365 proto_tree_add_item(ntlmv2_tree, hf_ntlmssp_ntlmv2_response_rversion, tvb, offset, 1, ENC_NA);
1368 proto_tree_add_item(ntlmv2_tree, hf_ntlmssp_ntlmv2_response_hirversion, tvb, offset, 1, ENC_NA);
1371 proto_tree_add_item(ntlmv2_tree, hf_ntlmssp_ntlmv2_response_z, tvb, offset, 6, ENC_NA);
1374 offset = dissect_nt_64bit_time(
1375 tvb, ntlmv2_tree, offset, hf_ntlmssp_ntlmv2_response_time);
1376 proto_tree_add_item(
1377 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_chal, tvb,
1381 proto_tree_add_item(ntlmv2_tree, hf_ntlmssp_ntlmv2_response_z, tvb, offset, 4, ENC_NA);
1384 offset = dissect_ntlmssp_target_info_list(tvb, pinfo, ntlmv2_tree, offset, len - (offset - orig_offset), &ntlmssp_ntlmv2_response_tif);
1386 if ((offset - orig_offset) < len) {
1387 proto_tree_add_item(ntlmv2_tree, hf_ntlmssp_ntlmv2_response_z, tvb, offset, 4, ENC_NA);
1391 if ((offset - orig_offset) < len) {
1392 proto_tree_add_item(ntlmv2_tree, hf_ntlmssp_ntlmv2_response_pad, tvb, offset, len - (offset - orig_offset), ENC_NA);
1398 /* tapping into ntlmssph not yet implemented */
1400 dissect_ntlmssp_negotiate (tvbuff_t *tvb, int offset, proto_tree *ntlmssp_tree, ntlmssp_header_t *ntlmssph _U_)
1402 guint32 negotiate_flags;
1408 /* NTLMSSP Negotiate Flags */
1409 negotiate_flags = tvb_get_letohl (tvb, offset);
1410 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
1414 * XXX - the davenport document says that these might not be
1415 * sent at all, presumably meaning the length of the message
1416 * isn't enough to contain them.
1418 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
1419 hf_ntlmssp_negotiate_domain,
1420 &data_start, &data_end, NULL);
1422 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
1423 hf_ntlmssp_negotiate_workstation,
1424 &item_start, &item_end, NULL);
1425 data_start = MIN(data_start, item_start);
1426 data_end = MAX(data_end, item_end);
1428 /* If there are more bytes before the data block dissect a version field
1429 if NTLMSSP_NEGOTIATE_VERSION is set in the flags (see MS-NLMP) */
1430 if (offset < data_start) {
1431 if (negotiate_flags & NTLMSSP_NEGOTIATE_VERSION)
1432 dissect_ntlmssp_version(tvb, offset, ntlmssp_tree);
1439 dissect_ntlmssp_challenge_target_info_blob (packet_info *pinfo, tvbuff_t *tvb, int offset,
1440 proto_tree *ntlmssp_tree,
1443 guint16 challenge_target_info_length = tvb_get_letohs(tvb, offset);
1444 guint16 challenge_target_info_maxlen = tvb_get_letohs(tvb, offset+2);
1445 guint32 challenge_target_info_offset = tvb_get_letohl(tvb, offset+4);
1446 proto_item *tf = NULL;
1447 proto_tree *challenge_target_info_tree = NULL;
1449 /* the target info list is just a blob */
1450 if (0 == challenge_target_info_length) {
1451 *end = (challenge_target_info_offset > ((guint)offset)+8 ? challenge_target_info_offset : ((guint)offset)+8);
1453 proto_tree_add_text(ntlmssp_tree, tvb, offset, 8,
1454 "Target Info List: Empty");
1459 tf = proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_challenge_target_info, tvb,
1460 challenge_target_info_offset, challenge_target_info_length, ENC_NA);
1461 challenge_target_info_tree = proto_item_add_subtree(tf, ett_ntlmssp_challenge_target_info);
1463 proto_tree_add_uint(challenge_target_info_tree, hf_ntlmssp_challenge_target_info_len,
1464 tvb, offset, 2, challenge_target_info_length);
1466 proto_tree_add_uint(challenge_target_info_tree, hf_ntlmssp_challenge_target_info_maxlen,
1467 tvb, offset, 2, challenge_target_info_maxlen);
1469 proto_tree_add_uint(challenge_target_info_tree, hf_ntlmssp_challenge_target_info_offset,
1470 tvb, offset, 4, challenge_target_info_offset);
1473 dissect_ntlmssp_target_info_list(tvb, pinfo, challenge_target_info_tree,
1474 challenge_target_info_offset, challenge_target_info_length,
1475 &ntlmssp_challenge_target_info_tif);
1477 *end = challenge_target_info_offset + challenge_target_info_length;
1481 /* tapping into ntlmssph not yet implemented */
1483 dissect_ntlmssp_challenge (tvbuff_t *tvb, packet_info *pinfo, int offset,
1484 proto_tree *ntlmssp_tree, ntlmssp_header_t *ntlmssph _U_)
1486 guint32 negotiate_flags;
1487 int item_start, item_end;
1488 int data_start, data_end; /* MIN and MAX seen */
1489 guint8 clientkey[NTLMSSP_KEY_LEN]; /* NTLMSSP cipher key for client */
1490 guint8 serverkey[NTLMSSP_KEY_LEN]; /* NTLMSSP cipher key for server*/
1491 ntlmssp_info *conv_ntlmssp_info = NULL;
1492 conversation_t *conversation;
1493 gboolean unicode_strings = FALSE;
1495 guint8 sspkey[NTLMSSP_KEY_LEN]; /* NTLMSSP cipher key */
1496 int ssp_key_len; /* Either 8 or 16 (40 bit or 128) */
1498 /* need to find unicode flag */
1499 negotiate_flags = tvb_get_letohl (tvb, offset+8);
1500 if (negotiate_flags & NTLMSSP_NEGOTIATE_UNICODE)
1501 unicode_strings = TRUE;
1505 * XXX - the davenport document (and MS-NLMP) calls this "Target Name",
1506 * presumably because non-domain targets are supported.
1507 * XXX - Original name "domain" changed to "target_name" to match MS-NLMP
1509 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, unicode_strings,
1510 hf_ntlmssp_challenge_target_name,
1511 &item_start, &item_end, NULL);
1512 data_start = item_start;
1513 data_end = item_end;
1515 /* NTLMSSP Negotiate Flags */
1516 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
1519 /* NTLMSSP NT Lan Manager Challenge */
1520 proto_tree_add_item (ntlmssp_tree,
1521 hf_ntlmssp_ntlm_server_challenge,
1522 tvb, offset, 8, ENC_NA);
1525 * Store the flags and the RC4 state information with the conversation,
1526 * as they're needed in order to dissect subsequent messages.
1528 conversation = find_or_create_conversation(pinfo);
1530 tvb_memcpy(tvb, tmp, offset, 8); /* challenge */
1531 /* We can face more than one NTLM exchange over the same couple of IP and ports ...*/
1532 conv_ntlmssp_info = (ntlmssp_info *)conversation_get_proto_data(conversation, proto_ntlmssp);
1533 /* XXX: The following code is (re)executed every time a particular frame is dissected
1534 * (in whatever order). Thus it seems to me that "multiple exchanges" might not be
1535 * handled well depending on the order that frames are visited after the initial dissection.
1537 if (!conv_ntlmssp_info || memcmp(tmp, conv_ntlmssp_info->server_challenge, 8) != 0) {
1538 conv_ntlmssp_info = wmem_new0(wmem_file_scope(), ntlmssp_info);
1539 /* Insert the flags into the conversation */
1540 conv_ntlmssp_info->flags = negotiate_flags;
1541 /* Insert the RC4 state information into the conversation */
1542 tvb_memcpy(tvb, conv_ntlmssp_info->server_challenge, offset, 8);
1543 conv_ntlmssp_info->is_auth_ntlm_v2 = 0;
1544 /* Between the challenge and the user provided password, we can build the
1545 NTLMSSP key and initialize the cipher if we are not in EXTENDED SECURITY
1546 in this case we need the client challenge as well*/
1547 /* BTW this is true just if we are in LM Authentification if not the logic is a bit different.
1548 * Right now it's not very clear what is LM Authentification it __seems__ to be when
1549 * NEGOTIATE NT ONLY is not set and NEGOSIATE EXTENDED SECURITY is not set as well*/
1550 if (!(conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY))
1552 conv_ntlmssp_info->rc4_state_initialized = 0;
1553 /* XXX - Make sure there is 24 bytes for the key */
1554 conv_ntlmssp_info->ntlm_response.contents = (guint8 *)wmem_alloc0(wmem_file_scope(), 24);
1555 conv_ntlmssp_info->lm_response.contents = (guint8 *)wmem_alloc0(wmem_file_scope(), 24);
1557 create_ntlmssp_v1_key(gbl_nt_password, conv_ntlmssp_info->server_challenge, NULL, sspkey, NULL, conv_ntlmssp_info->flags, conv_ntlmssp_info->ntlm_response.contents, conv_ntlmssp_info->lm_response.contents, ntlmssph);
1558 if (memcmp(sspkey, gbl_zeros, NTLMSSP_KEY_LEN) != 0) {
1559 get_sealing_rc4key(sspkey, conv_ntlmssp_info->flags, &ssp_key_len, clientkey, serverkey);
1560 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_client, sspkey, ssp_key_len);
1561 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_server, sspkey, ssp_key_len);
1562 conv_ntlmssp_info->server_dest_port = pinfo->destport;
1563 conv_ntlmssp_info->rc4_state_initialized = 1;
1567 conversation_add_proto_data(conversation, proto_ntlmssp, conv_ntlmssp_info);
1571 /* If no more bytes (ie: no "reserved", ...) before start of data block, then return */
1572 /* XXX: According to Davenport "This form is seen in older Win9x-based systems" */
1573 /* Also: I've seen a capture with an HTTP CONNECT proxy-authentication */
1574 /* message wherein the challenge from the proxy has this form. */
1575 if (offset >= data_start) {
1579 /* Reserved (function not completely known) */
1581 * XXX - SSP key? The davenport document says
1583 * The context field is typically populated when Negotiate Local
1584 * Call is set. It contains an SSPI context handle, which allows
1585 * the client to "short-circuit" authentication and effectively
1586 * circumvent responding to the challenge. Physically, the context
1587 * is two long values. This is covered in greater detail later,
1588 * in the "Local Authentication" section.
1590 * It also says that that information may be omitted.
1592 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_reserved,
1593 tvb, offset, 8, ENC_NA);
1597 * The presence or absence of this field is not obviously correlated
1598 * with any flags in the previous NEGOTIATE message or in this
1599 * message (other than the "Workstation Supplied" and "Domain
1600 * Supplied" flags in the NEGOTIATE message, at least in the capture
1601 * I've seen - but those also correlate with the presence of workstation
1602 * and domain name fields, so it doesn't seem to make sense that they
1603 * actually *indicate* whether the subsequent CHALLENGE has an
1606 if (offset < data_start) {
1607 offset = dissect_ntlmssp_challenge_target_info_blob(pinfo, tvb, offset, ntlmssp_tree, &item_end);
1608 /* XXX: This code assumes that the address list in the data block */
1609 /* is always after the target name. Is this OK ? */
1610 data_end = MAX(data_end, item_end);
1613 /* If there are more bytes before the data block dissect a version field
1614 if NTLMSSP_NEGOTIATE_VERSION is set in the flags (see MS-NLMP) */
1615 if (offset < data_start) {
1616 if (negotiate_flags & NTLMSSP_NEGOTIATE_VERSION)
1617 offset = dissect_ntlmssp_version(tvb, offset, ntlmssp_tree);
1620 return MAX(offset, data_end);
1624 dissect_ntlmssp_auth (tvbuff_t *tvb, packet_info *pinfo, int offset,
1625 proto_tree *ntlmssp_tree, ntlmssp_header_t *ntlmssph)
1627 int item_start, item_end;
1628 int data_start, data_end = 0;
1629 guint32 negotiate_flags;
1630 guint8 sspkey[NTLMSSP_KEY_LEN]; /* exported session key */
1631 guint8 clientkey[NTLMSSP_KEY_LEN]; /* NTLMSSP cipher key for client */
1632 guint8 serverkey[NTLMSSP_KEY_LEN]; /* NTLMSSP cipher key for server*/
1633 guint8 encryptedsessionkey[NTLMSSP_KEY_LEN];
1634 ntlmssp_blob sessionblob;
1635 gboolean unicode_strings = FALSE;
1636 ntlmssp_info *conv_ntlmssp_info;
1637 conversation_t *conversation;
1641 * Get flag info from the original negotiate message, if any.
1642 * This is because the flag information is sometimes missing from
1643 * the AUTHENTICATE message, so we can't figure out whether
1644 * strings are Unicode or not by looking at *our* flags.
1645 * XXX it seems it's more from the CHALLENGE message, which is more clever in fact
1646 * because the server can change some flags.
1647 * But according to MS NTLMSSP doc it's not that simple.
1648 * In case of Conection less mode AUTHENTICATE flags should be used because they
1649 * reprensent the choice of the client after having been informed of options of the
1650 * server in the CHALLENGE message.
1651 * In Connection mode then the CHALLENGE flags should (must ?) be used
1652 * XXX: MS-NLMP says the flag field in the AUTHENTICATE message "contains the set of bit
1653 * flags (section 2.2.2.5) negotiated in the previous messages."
1654 * I read that to mean that the flags for in connection-mode AUTHENTICATE also represent
1655 * the choice of the client (for the flags which are negotiated).
1656 * XXX: In the absence of CHALLENGE flags, as a last resort we'll use the flags
1657 * (if available) from this AUTHENTICATE message.
1658 * I've seen a capture which does an HTTP CONNECT which:
1659 * - has the NEGOTIATE & CHALLENGE messages in one TCP connection;
1660 * - has the AUTHENTICATE message in a second TCP connection;
1661 * (The authentication aparently succeeded).
1663 conv_ntlmssp_info = (ntlmssp_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_ntlmssp, NTLMSSP_CONV_INFO_KEY);
1664 if (conv_ntlmssp_info == NULL) {
1666 * There isn't any. Is there any from this conversation? If so,
1667 * it means this is the first time we've dissected this frame, so
1668 * we should give it flag info.
1670 /* XXX: Create conv_ntlmssp_info & etc if no previous CHALLENGE seen */
1671 /* so we'll have a place to store flags. */
1672 /* This is a bit brute-force but looks like it will be OK. */
1673 conversation = find_or_create_conversation(pinfo);
1674 conv_ntlmssp_info = (ntlmssp_info *)conversation_get_proto_data(conversation, proto_ntlmssp);
1675 if (conv_ntlmssp_info == NULL) {
1676 conv_ntlmssp_info = wmem_new0(wmem_file_scope(), ntlmssp_info);
1677 conversation_add_proto_data(conversation, proto_ntlmssp, conv_ntlmssp_info);
1679 /* XXX: The *conv_ntlmssp_info struct attached to the frame is the
1680 same as the one attached to the conversation. That is: *both* point to
1681 the exact same struct in memory. Is this what is indended ? */
1682 p_add_proto_data(wmem_file_scope(), pinfo, proto_ntlmssp, NTLMSSP_CONV_INFO_KEY, conv_ntlmssp_info);
1685 if (conv_ntlmssp_info != NULL) {
1686 if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_UNICODE)
1687 unicode_strings = TRUE;
1691 * Sometimes the session key and flags are missing.
1692 * Sometimes the session key is present but the flags are missing.
1693 * XXX Who stay so ? Reading spec I would rather say the opposite: flags are
1694 * always present, session information are always there as well but sometime
1695 * session information could be null (in case of no session)
1696 * Sometimes they're both present.
1698 * This does not correlate with any flags in the previous CHALLENGE
1699 * message, and only correlates with "Negotiate Unicode", "Workstation
1700 * Supplied", and "Domain Supplied" in the NEGOTIATE message - but
1701 * those don't make sense as flags to use to determine this.
1703 * So we check all of the descriptors to figure out where the data
1704 * area begins, and if the session key or the flags would be in the
1705 * middle of the data area, we assume the field in question is
1708 * XXX - Reading Davenport and MS-NLMP: as I see it the possibilities are:
1709 * a. No session-key; no flags; no version ("Win9x")
1710 * b. Session-key & flags.
1711 * c. Session-key, flags & version.
1712 * In cases b and c the session key may be "null".
1716 /* Lan Manager response */
1717 data_start = tvb_get_letohl(tvb, offset+4);
1718 offset = dissect_ntlmssp_blob(tvb, pinfo, ntlmssp_tree, offset,
1719 hf_ntlmssp_auth_lmresponse,
1721 conv_ntlmssp_info == NULL ? NULL :
1722 &conv_ntlmssp_info->lm_response);
1723 data_end = MAX(data_end, item_end);
1726 item_start = tvb_get_letohl(tvb, offset+4);
1727 offset = dissect_ntlmssp_blob(tvb, pinfo, ntlmssp_tree, offset,
1728 hf_ntlmssp_auth_ntresponse,
1730 conv_ntlmssp_info == NULL ? NULL :
1731 &conv_ntlmssp_info->ntlm_response);
1732 if (conv_ntlmssp_info != NULL && conv_ntlmssp_info->ntlm_response.length > 24) {
1733 memcpy(conv_ntlmssp_info->client_challenge, conv_ntlmssp_info->ntlm_response.contents+32, 8);
1735 data_start = MIN(data_start, item_start);
1736 data_end = MAX(data_end, item_end);
1737 if (conv_ntlmssp_info != NULL)
1739 if (conv_ntlmssp_info->ntlm_response.length > 24)
1741 conv_ntlmssp_info->is_auth_ntlm_v2 = 1;
1745 conv_ntlmssp_info->is_auth_ntlm_v2 = 0;
1750 item_start = tvb_get_letohl(tvb, offset+4);
1751 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
1753 hf_ntlmssp_auth_domain,
1754 &item_start, &item_end, &(ntlmssph->domain_name));
1755 /*ntlmssph->domain_name_len = item_end-item_start;*/
1756 data_start = MIN(data_start, item_start);
1757 data_end = MAX(data_end, item_end);
1760 item_start = tvb_get_letohl(tvb, offset+4);
1761 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
1763 hf_ntlmssp_auth_username,
1764 &item_start, &item_end, &(ntlmssph->acct_name));
1765 /*ntlmssph->acct_name_len = item_end-item_start;*/
1766 data_start = MIN(data_start, item_start);
1767 data_end = MAX(data_end, item_end);
1769 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ", ", "User: %s\\%s",
1770 ntlmssph->domain_name, ntlmssph->acct_name);
1773 item_start = tvb_get_letohl(tvb, offset+4);
1774 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
1776 hf_ntlmssp_auth_hostname,
1777 &item_start, &item_end, &(ntlmssph->host_name));
1778 data_start = MIN(data_start, item_start);
1779 data_end = MAX(data_end, item_end);
1781 sessionblob.length = 0;
1782 if (offset < data_start) {
1784 offset = dissect_ntlmssp_blob(tvb, pinfo, ntlmssp_tree, offset,
1785 hf_ntlmssp_auth_sesskey,
1786 &item_end, &sessionblob);
1787 data_end = MAX(data_end, item_end);
1790 if (offset < data_start) {
1791 /* NTLMSSP Negotiate Flags */
1792 negotiate_flags = tvb_get_letohl (tvb, offset);
1793 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
1795 /* If no previous flags seen (ie: no previous CHALLENGE) use flags
1796 from the AUTHENTICATE message).
1797 Assumption: (flags == 0) means flags not previously seen */
1798 if ((conv_ntlmssp_info != NULL) && (conv_ntlmssp_info->flags == 0)) {
1799 conv_ntlmssp_info->flags = negotiate_flags;
1802 negotiate_flags = 0;
1804 /* If there are more bytes before the data block dissect a version field
1805 if NTLMSSP_NEGOTIATE_VERSION is set in the flags (see MS-NLMP) */
1806 if (offset < data_start) {
1807 if (negotiate_flags & NTLMSSP_NEGOTIATE_VERSION)
1808 offset = dissect_ntlmssp_version(tvb, offset, ntlmssp_tree);
1811 /* If there are still more bytes before the data block dissect an MIC (message integrity_code) field */
1813 if (offset < data_start) {
1814 proto_tree_add_item(ntlmssp_tree, hf_ntlmssp_message_integrity_code, tvb, offset, 16, ENC_NA);
1818 if (sessionblob.length > NTLMSSP_KEY_LEN) {
1819 expert_add_info_format(pinfo, NULL, &ei_ntlmssp_blob_len_too_long, "Session blob length too long: %u", sessionblob.length);
1820 } else if (sessionblob.length != 0) {
1821 memcpy(encryptedsessionkey, sessionblob.contents, sessionblob.length);
1822 /* Try to attach to an existing conversation if not then it's useless to try to do so
1823 * because we are missing important information (ie. server challenge)
1825 if (conv_ntlmssp_info) {
1826 /* If we are in EXTENDED SECURITY then we can now initialize cipher */
1827 if ((conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY))
1829 conv_ntlmssp_info->rc4_state_initialized = 0;
1830 if (conv_ntlmssp_info->is_auth_ntlm_v2) {
1831 create_ntlmssp_v2_key(gbl_nt_password, conv_ntlmssp_info->server_challenge, conv_ntlmssp_info->client_challenge, sspkey, encryptedsessionkey, conv_ntlmssp_info->flags, &conv_ntlmssp_info->ntlm_response, &conv_ntlmssp_info->lm_response, ntlmssph);
1835 if (conv_ntlmssp_info->lm_response.contents == NULL || conv_ntlmssp_info->lm_response.length < 8) {
1836 memset(conv_ntlmssp_info->client_challenge, 0, 8);
1838 memcpy(conv_ntlmssp_info->client_challenge, conv_ntlmssp_info->lm_response.contents, 8);
1840 create_ntlmssp_v1_key(gbl_nt_password, conv_ntlmssp_info->server_challenge, conv_ntlmssp_info->client_challenge, sspkey, encryptedsessionkey, conv_ntlmssp_info->flags, conv_ntlmssp_info->ntlm_response.contents, conv_ntlmssp_info->lm_response.contents, ntlmssph);
1842 /* ssp is the exported session key */
1843 if (memcmp(sspkey, gbl_zeros, NTLMSSP_KEY_LEN) != 0) {
1844 get_sealing_rc4key(sspkey, conv_ntlmssp_info->flags, &ssp_key_len, clientkey, serverkey);
1845 get_siging_key((guint8*)&conv_ntlmssp_info->sign_key_server, (guint8*)&conv_ntlmssp_info->sign_key_client, sspkey, ssp_key_len);
1846 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_server, serverkey, ssp_key_len);
1847 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_client, clientkey, ssp_key_len);
1848 conv_ntlmssp_info->server_dest_port = pinfo->destport;
1849 conv_ntlmssp_info->rc4_state_initialized = 1;
1854 return MAX(offset, data_end);
1858 get_sign_key(packet_info *pinfo, int cryptpeer)
1860 conversation_t *conversation;
1861 ntlmssp_info *conv_ntlmssp_info;
1863 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1864 pinfo->ptype, pinfo->srcport,
1865 pinfo->destport, 0);
1866 if (conversation == NULL) {
1867 /* We don't have a conversation. In this case, stop processing
1868 because we do not have enough info to decrypt the payload */
1872 /* We have a conversation, check for encryption state */
1873 conv_ntlmssp_info = (ntlmssp_info *)conversation_get_proto_data(conversation,
1875 if (conv_ntlmssp_info == NULL) {
1876 /* No encryption state tied to the conversation. Therefore, we
1877 cannot decrypt the payload */
1881 /* We have the encryption state in the conversation. So return the
1882 crypt state tied to the requested peer
1884 if (cryptpeer == 1) {
1885 return (guint8*)&conv_ntlmssp_info->sign_key_client;
1887 return (guint8*)&conv_ntlmssp_info->sign_key_server;
1894 * Get the encryption state tied to this conversation. cryptpeer indicates
1895 * whether to retrieve the client key (1) or the server key (0)
1897 static rc4_state_struct *
1898 get_encrypted_state(packet_info *pinfo, int cryptpeer)
1900 conversation_t *conversation;
1901 ntlmssp_info *conv_ntlmssp_info;
1903 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1904 pinfo->ptype, pinfo->srcport,
1905 pinfo->destport, 0);
1906 if (conversation == NULL) {
1907 /* We don't have a conversation. In this case, stop processing
1908 because we do not have enough info to decrypt the payload */
1912 /* We have a conversation, check for encryption state */
1913 conv_ntlmssp_info = (ntlmssp_info *)conversation_get_proto_data(conversation,
1915 if (conv_ntlmssp_info == NULL) {
1916 /* No encryption state tied to the conversation. Therefore, we
1917 cannot decrypt the payload */
1921 /* We have the encryption state in the conversation. So return the
1922 crypt state tied to the requested peer
1924 if (cryptpeer == 1) {
1925 return &conv_ntlmssp_info->rc4_state_client;
1927 return &conv_ntlmssp_info->rc4_state_server;
1934 decrypt_data_payload(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
1935 packet_info *pinfo, proto_tree *tree _U_, gpointer key);
1937 decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
1938 packet_info *pinfo, proto_tree *tree, gpointer key);
1942 dissect_ntlmssp_encrypted_payload(tvbuff_t *data_tvb,
1943 tvbuff_t *auth_tvb _U_,
1946 dcerpc_auth_info *auth_info _U_)
1950 dissect_ntlmssp_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1952 volatile int offset = 0;
1953 proto_tree *volatile ntlmssp_tree = NULL;
1954 proto_item *tf = NULL;
1956 guint32 encrypted_block_length;
1957 guint8 key[NTLMSSP_KEY_LEN];
1958 /* the magic ntlm is the identifier of a NTLMSSP packet that's 00 00 00 01 */
1959 guint32 ntlm_magic_size = 4;
1960 guint32 ntlm_signature_size = 8;
1961 guint32 ntlm_seq_size = 4;
1964 length = tvb_length (tvb);
1965 /* signature + seq + real payload */
1966 encrypted_block_length = length - ntlm_magic_size;
1968 if (encrypted_block_length < (ntlm_signature_size + ntlm_seq_size)) {
1969 /* Don't know why this would happen, but if it does, don't even bother
1970 attempting decryption/dissection */
1971 return offset + length;
1974 /* Setup a new tree for the NTLMSSP payload */
1976 tf = proto_tree_add_item (tree,
1978 tvb, offset, -1, ENC_NA);
1980 ntlmssp_tree = proto_item_add_subtree (tf,
1985 * Catch the ReportedBoundsError exception; the stuff we've been
1986 * handed doesn't necessarily run to the end of the packet, it's
1987 * an item inside a packet, so if it happens to be malformed (or
1988 * we, or a dissector we call, has a bug), so that an exception
1989 * is thrown, we want to report the error, but return and let
1990 * our caller dissect the rest of the packet.
1992 * If it gets a BoundsError, we can stop, as there's nothing more
1993 * in the packet after our blob to see, so we just re-throw the
1996 pd_save = pinfo->private_data;
1998 /* Version number */
1999 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_vers,
2000 tvb, offset, 4, ENC_LITTLE_ENDIAN);
2003 /* Encrypted body */
2004 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_body,
2005 tvb, offset, ntlm_signature_size + ntlm_seq_size, ENC_NA);
2006 memset(key, 0, sizeof(key));
2007 tvb_memcpy(tvb, key, offset, ntlm_signature_size + ntlm_seq_size);
2008 /* Try to decrypt */
2009 decrypt_data_payload (tvb, offset+(ntlm_signature_size + ntlm_seq_size), encrypted_block_length-(ntlm_signature_size + ntlm_seq_size), pinfo, ntlmssp_tree, key);
2010 decrypt_verifier (tvb, offset, ntlm_signature_size + ntlm_seq_size, pinfo, ntlmssp_tree, key);
2011 /* let's try to hook ourselves here */
2014 } CATCH_NONFATAL_ERRORS {
2015 /* Restore the private_data structure in case one of the
2016 * called dissectors modified it (and, due to the exception,
2017 * was unable to restore it).
2019 pinfo->private_data = pd_save;
2020 show_exception(tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
2027 decrypt_data_payload(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
2028 packet_info *pinfo, proto_tree *tree _U_, gpointer key)
2030 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
2031 ntlmssp_packet_info *packet_ntlmssp_info;
2032 ntlmssp_packet_info *stored_packet_ntlmssp_info = NULL;
2034 /* Check to see if we already have state for this packet */
2035 packet_ntlmssp_info = (ntlmssp_packet_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_ntlmssp, NTLMSSP_PACKET_INFO_KEY);
2036 if (packet_ntlmssp_info == NULL) {
2037 /* We don't have any packet state, so create one */
2038 packet_ntlmssp_info = wmem_new0(wmem_file_scope(), ntlmssp_packet_info);
2039 p_add_proto_data(wmem_file_scope(), pinfo, proto_ntlmssp, NTLMSSP_PACKET_INFO_KEY, packet_ntlmssp_info);
2041 if (!packet_ntlmssp_info->payload_decrypted) {
2042 conversation_t *conversation;
2043 ntlmssp_info *conv_ntlmssp_info;
2045 /* Pull the challenge info from the conversation */
2046 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
2047 pinfo->ptype, pinfo->srcport,
2048 pinfo->destport, 0);
2049 if (conversation == NULL) {
2050 /* There is no conversation, thus no encryption state */
2054 conv_ntlmssp_info = (ntlmssp_info *)conversation_get_proto_data(conversation,
2056 if (conv_ntlmssp_info == NULL) {
2057 /* There is no NTLMSSP state tied to the conversation */
2060 if (conv_ntlmssp_info->rc4_state_initialized != 1) {
2061 /* The crypto sybsystem is not initialized. This means that either
2062 the conversation did not include a challenge, or that we do not have the right password */
2066 stored_packet_ntlmssp_info = (ntlmssp_packet_info *)g_hash_table_lookup(hash_packet, key);
2068 if (stored_packet_ntlmssp_info != NULL && stored_packet_ntlmssp_info->payload_decrypted == TRUE) {
2069 /* Mat TBD (stderr, "Found a already decrypted packet\n");*/
2070 memcpy(packet_ntlmssp_info, stored_packet_ntlmssp_info, sizeof(ntlmssp_packet_info));
2071 /* Mat TBD printnbyte(packet_ntlmssp_info->decrypted_payload, encrypted_block_length, "Data: ", "\n");*/
2074 rc4_state_struct *rc4_state;
2075 rc4_state_struct *rc4_state_peer;
2077 /* Get the pair of RC4 state structures. One is used for to decrypt the
2078 payload. The other is used to re-encrypt the payload to represent
2080 if (conv_ntlmssp_info->server_dest_port == pinfo->destport) {
2082 rc4_state = get_encrypted_state(pinfo, 1);
2083 rc4_state_peer = get_encrypted_state(pinfo, 0);
2086 rc4_state = get_encrypted_state(pinfo, 0);
2087 rc4_state_peer = get_encrypted_state(pinfo, 1);
2090 if (rc4_state == NULL) {
2091 /* There is no encryption state, so we cannot decrypt */
2095 /* Store the decrypted contents in the packet state struct
2096 (of course at this point, they aren't decrypted yet) */
2097 packet_ntlmssp_info->decrypted_payload = (guint8 *)tvb_memdup(NULL, tvb, offset,
2098 encrypted_block_length);
2099 packet_ntlmssp_info->payload_len = encrypted_block_length;
2100 decrypted_payloads = g_slist_prepend(decrypted_payloads,
2101 packet_ntlmssp_info->decrypted_payload);
2103 g_hash_table_insert(hash_packet, key, packet_ntlmssp_info);
2106 /* Do the decryption of the payload */
2107 crypt_rc4(rc4_state, packet_ntlmssp_info->decrypted_payload,
2108 encrypted_block_length);
2109 /* decrypt the verifier */
2110 /*printnchar(packet_ntlmssp_info->decrypted_payload, encrypted_block_length, "data: ", "\n");*/
2111 /* We setup a temporary buffer so we can re-encrypt the payload after
2112 decryption. This is to update the opposite peer's RC4 state
2113 it's useful when we have only one key for both conversation
2114 in case of KEY_EXCH we have independent key so this is not needed*/
2115 if (!(NTLMSSP_NEGOTIATE_KEY_EXCH & conv_ntlmssp_info->flags)) {
2117 peer_block = (guint8 *)wmem_memdup(wmem_packet_scope(), packet_ntlmssp_info->decrypted_payload, encrypted_block_length);
2118 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
2121 packet_ntlmssp_info->payload_decrypted = TRUE;
2125 /* Show the decrypted buffer in a new window */
2126 decr_tvb = tvb_new_child_real_data(tvb, packet_ntlmssp_info->decrypted_payload,
2127 encrypted_block_length,
2128 encrypted_block_length);
2130 add_new_data_source(pinfo, decr_tvb,
2132 pinfo->gssapi_decrypted_tvb = decr_tvb;
2136 dissect_ntlmssp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2138 volatile int offset = 0;
2139 proto_tree *volatile ntlmssp_tree = NULL;
2140 proto_item *tf = NULL;
2141 ntlmssp_header_t *ntlmssph;
2144 ntlmssph = wmem_new(wmem_packet_scope(), ntlmssp_header_t);
2146 ntlmssph->domain_name = NULL;
2147 ntlmssph->acct_name = NULL;
2148 ntlmssph->host_name = NULL;
2149 memset(ntlmssph->session_key, 0, NTLMSSP_KEY_LEN);
2151 /* Setup a new tree for the NTLMSSP payload */
2153 tf = proto_tree_add_item (tree,
2155 tvb, offset, -1, ENC_NA);
2157 ntlmssp_tree = proto_item_add_subtree (tf,
2162 * Catch the ReportedBoundsError exception; the stuff we've been
2163 * handed doesn't necessarily run to the end of the packet, it's
2164 * an item inside a packet, so if it happens to be malformed (or
2165 * we, or a dissector we call, has a bug), so that an exception
2166 * is thrown, we want to report the error, but return and let
2167 * our caller dissect the rest of the packet.
2169 * If it gets a BoundsError, we can stop, as there's nothing more
2170 * in the packet after our blob to see, so we just re-throw the
2173 pd_save = pinfo->private_data;
2175 /* NTLMSSP constant */
2176 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth,
2177 tvb, offset, 8, ENC_ASCII|ENC_NA);
2180 /* NTLMSSP Message Type */
2181 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_message_type,
2182 tvb, offset, 4, ENC_LITTLE_ENDIAN);
2183 ntlmssph->type = tvb_get_letohl (tvb, offset);
2186 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ", ", "%s",
2187 val_to_str_const(ntlmssph->type,
2188 ntlmssp_message_types,
2189 "Unknown NTLMSSP message type"));
2191 /* Call the appropriate dissector based on the Message Type */
2192 switch (ntlmssph->type) {
2194 case NTLMSSP_NEGOTIATE:
2195 dissect_ntlmssp_negotiate (tvb, offset, ntlmssp_tree, ntlmssph);
2198 case NTLMSSP_CHALLENGE:
2199 dissect_ntlmssp_challenge (tvb, pinfo, offset, ntlmssp_tree, ntlmssph);
2203 dissect_ntlmssp_auth (tvb, pinfo, offset, ntlmssp_tree, ntlmssph);
2207 /* Unrecognized message type */
2208 proto_tree_add_text (ntlmssp_tree, tvb, offset, -1,
2209 "Unrecognized NTLMSSP Message");
2212 } CATCH_NONFATAL_ERRORS {
2213 /* Restore the private_data structure in case one of the
2214 * called dissectors modified it (and, due to the exception,
2215 * was unable to restore it).
2217 pinfo->private_data = pd_save;
2218 show_exception(tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
2221 tap_queue_packet(ntlmssp_tap, pinfo, ntlmssph);
2225 dissect_ntlmssp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data _U_)
2227 if (tvb_memeql(tvb, 0, "NTLMSSP", 8) == 0) {
2228 dissect_ntlmssp(tvb, pinfo, parent_tree);
2237 * See page 45 of "DCE/RPC over SMB" by Luke Kenneth Casson Leighton.
2240 decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
2241 packet_info *pinfo, proto_tree *tree, gpointer key)
2243 proto_tree *decr_tree;
2245 conversation_t *conversation;
2247 rc4_state_struct *rc4_state;
2248 rc4_state_struct *rc4_state_peer;
2249 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
2252 guint8 calculated_md5[NTLMSSP_KEY_LEN];
2253 ntlmssp_info *conv_ntlmssp_info;
2254 ntlmssp_packet_info *packet_ntlmssp_info;
2255 int decrypted_offset = 0;
2257 ntlmssp_packet_info *stored_packet_ntlmssp_info = NULL;
2259 packet_ntlmssp_info = (ntlmssp_packet_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_ntlmssp, NTLMSSP_PACKET_INFO_KEY);
2260 if (packet_ntlmssp_info == NULL) {
2261 /* We don't have data for this packet */
2264 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
2265 pinfo->ptype, pinfo->srcport,
2266 pinfo->destport, 0);
2267 if (conversation == NULL) {
2268 /* There is no conversation, thus no encryption state */
2271 conv_ntlmssp_info = (ntlmssp_info *)conversation_get_proto_data(conversation,
2273 if (conv_ntlmssp_info == NULL) {
2274 /* There is no NTLMSSP state tied to the conversation */
2279 stored_packet_ntlmssp_info = (ntlmssp_packet_info *)g_hash_table_lookup(hash_packet, key);
2281 if (stored_packet_ntlmssp_info != NULL && stored_packet_ntlmssp_info->verifier_decrypted == TRUE) {
2282 /* Mat TBD fprintf(stderr, "Found a already decrypted packet\n");*/
2283 /* In Theory it's aleady the case, and we should be more clever ... like just copying buffers ...*/
2284 packet_ntlmssp_info = stored_packet_ntlmssp_info;
2287 if (!packet_ntlmssp_info->verifier_decrypted) {
2288 if (conv_ntlmssp_info->rc4_state_initialized != 1) {
2289 /* The crypto sybsystem is not initialized. This means that either
2290 the conversation did not include a challenge, or we are doing
2291 something other than NTLMSSP v1 */
2294 if (conv_ntlmssp_info->server_dest_port == pinfo->destport) {
2295 /* client talk to server */
2296 rc4_state = get_encrypted_state(pinfo, 1);
2297 sign_key = get_sign_key(pinfo, 1);
2298 rc4_state_peer = get_encrypted_state(pinfo, 0);
2300 rc4_state = get_encrypted_state(pinfo, 0);
2301 sign_key = get_sign_key(pinfo, 0);
2302 rc4_state_peer = get_encrypted_state(pinfo, 1);
2305 if (rc4_state == NULL || rc4_state_peer == NULL) {
2306 /* There is no encryption state, so we cannot decrypt */
2310 /* Setup the buffer to decrypt to */
2311 tvb_memcpy(tvb, packet_ntlmssp_info->verifier,
2312 offset, MIN(encrypted_block_length, sizeof(packet_ntlmssp_info->verifier)));
2314 /*if (!(NTLMSSP_NEGOTIATE_KEY_EXCH & packet_ntlmssp_info->flags)) {*/
2315 if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY) {
2316 if ((NTLMSSP_NEGOTIATE_KEY_EXCH & conv_ntlmssp_info->flags)) {
2317 /* The spec says that if we have have a key exchange then we have a the signature that is crypted
2318 * otherwise it's just a hmac_md5(keysign, concat(message, sequence))[0..7]
2320 crypt_rc4(rc4_state, packet_ntlmssp_info->verifier, 8);
2323 * Try to check the HMAC MD5 of the message against those calculated works great with LDAP payload but
2324 * don't with DCE/RPC calls.
2325 * Some analysis need to be done ...
2327 if (sign_key != NULL) {
2328 check_buf = (guint8 *)wmem_alloc(wmem_packet_scope(), packet_ntlmssp_info->payload_len+4);
2329 tvb_memcpy(tvb, &sequence, offset+8, 4);
2330 memcpy(check_buf, &sequence, 4);
2331 memcpy(check_buf+4, packet_ntlmssp_info->decrypted_payload, packet_ntlmssp_info->payload_len);
2332 md5_hmac(check_buf, (int)(packet_ntlmssp_info->payload_len+4), sign_key, NTLMSSP_KEY_LEN, calculated_md5);
2334 printnbyte(packet_ntlmssp_info->verifier, 8, "HMAC from packet: ", "\n");
2335 printnbyte(calculated_md5, 8, "HMAC : ", "\n");
2340 /* The packet has a PAD then a checksum then a sequence and they are encoded in this order so we can decrypt all at once */
2341 /* Do the actual decryption of the verifier */
2342 crypt_rc4(rc4_state, packet_ntlmssp_info->verifier,
2343 encrypted_block_length);
2348 /* We setup a temporary buffer so we can re-encrypt the payload after
2349 decryption. This is to update the opposite peer's RC4 state
2350 This is not needed when we just have EXTENDED SECURITY because the signature is not crypted
2351 and it's also not needed when we have key exchange because server and client have independent keys */
2352 if (!(NTLMSSP_NEGOTIATE_KEY_EXCH & conv_ntlmssp_info->flags) && !(NTLMSSP_NEGOTIATE_EXTENDED_SECURITY & conv_ntlmssp_info->flags)) {
2353 peer_block = (guint8 *)wmem_memdup(wmem_packet_scope(), packet_ntlmssp_info->verifier, encrypted_block_length);
2354 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
2357 /* Mark the packet as decrypted so that subsequent attempts to dissect
2358 the packet use the already decrypted payload instead of attempting
2360 packet_ntlmssp_info->verifier_decrypted = TRUE;
2363 /* Show the decrypted buffer in a new window */
2364 decr_tvb = tvb_new_child_real_data(tvb, packet_ntlmssp_info->verifier,
2365 encrypted_block_length,
2366 encrypted_block_length);
2367 add_new_data_source(pinfo, decr_tvb,
2368 "Decrypted NTLMSSP Verifier");
2370 /* Show the decrypted payload in the tree */
2371 tf = proto_tree_add_text(tree, decr_tvb, 0, -1,
2372 "Decrypted Verifier (%d byte%s)",
2373 encrypted_block_length,
2374 plurality(encrypted_block_length, "", "s"));
2375 decr_tree = proto_item_add_subtree (tf, ett_ntlmssp);
2377 if (( conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY)) {
2378 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_hmacmd5,
2379 decr_tvb, decrypted_offset, 8, ENC_NA);
2380 decrypted_offset += 8;
2382 /* Incrementing sequence number of DCE conversation */
2383 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_sequence,
2384 decr_tvb, decrypted_offset, 4, ENC_NA);
2387 /* RANDOM PAD usually it's 0 */
2388 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_randompad,
2389 decr_tvb, decrypted_offset, 4, ENC_LITTLE_ENDIAN);
2390 decrypted_offset += 4;
2392 /* CRC32 of the DCE fragment data */
2393 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_crc32,
2394 decr_tvb, decrypted_offset, 4, ENC_LITTLE_ENDIAN);
2395 decrypted_offset += 4;
2397 /* Incrementing sequence number of DCE conversation */
2398 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_sequence,
2399 decr_tvb, decrypted_offset, 4, ENC_NA);
2403 /* Used when NTLMSSP is done over DCE/RPC because in this case verifier and real payload are not contigious*/
2405 dissect_ntlmssp_payload_only(tvbuff_t *tvb, packet_info *pinfo, _U_ proto_tree *tree, void *data _U_)
2407 volatile int offset = 0;
2408 proto_tree *volatile ntlmssp_tree = NULL;
2409 guint32 encrypted_block_length;
2412 /* the magic ntlm is the identifier of a NTLMSSP packet that's 00 00 00 01
2414 encrypted_block_length = tvb_length (tvb);
2415 /* signature + seq + real payload */
2417 /* Setup a new tree for the NTLMSSP payload */
2420 tf = proto_tree_add_item (tree,
2422 tvb, offset, -1, ENC_NA);
2424 ntlmssp_tree = proto_item_add_subtree (tf,
2429 * Catch the ReportedBoundsError exception; the stuff we've been
2430 * handed doesn't necessarily run to the end of the packet, it's
2431 * an item inside a packet, so if it happens to be malformed (or
2432 * we, or a dissector we call, has a bug), so that an exception
2433 * is thrown, we want to report the error, but return and let
2434 * our caller dissect the rest of the packet.
2436 * If it gets a BoundsError, we can stop, as there's nothing more
2437 * in the packet after our blob to see, so we just re-throw the
2440 pd_save = pinfo->private_data;
2442 /* Version number */
2444 /* Try to decrypt */
2445 decrypt_data_payload (tvb, offset, encrypted_block_length, pinfo, ntlmssp_tree, NULL);
2446 /* let's try to hook ourselves here */
2448 } CATCH_NONFATAL_ERRORS {
2449 /* Restore the private_data structure in case one of the
2450 * called dissectors modified it (and, due to the exception,
2451 * was unable to restore it).
2453 pinfo->private_data = pd_save;
2454 show_exception(tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
2460 /* Used when NTLMSSP is done over DCE/RPC because in this case verifier and real payload are not contigious
2461 * But in fact this function could be merged with wrap_dissect_ntlmssp_verf because it's only used there
2464 dissect_ntlmssp_verf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
2466 volatile int offset = 0;
2467 proto_tree *volatile ntlmssp_tree = NULL;
2468 proto_item *tf = NULL;
2469 guint32 verifier_length;
2470 guint32 encrypted_block_length;
2473 verifier_length = tvb_length (tvb);
2474 encrypted_block_length = verifier_length - 4;
2476 if (encrypted_block_length < 12) {
2477 /* Don't know why this would happen, but if it does, don't even bother
2478 attempting decryption/dissection */
2479 return offset + verifier_length;
2482 /* Setup a new tree for the NTLMSSP payload */
2484 tf = proto_tree_add_item (tree,
2486 tvb, offset, -1, ENC_NA);
2488 ntlmssp_tree = proto_item_add_subtree (tf,
2493 * Catch the ReportedBoundsError exception; the stuff we've been
2494 * handed doesn't necessarily run to the end of the packet, it's
2495 * an item inside a packet, so if it happens to be malformed (or
2496 * we, or a dissector we call, has a bug), so that an exception
2497 * is thrown, we want to report the error, but return and let
2498 * our caller dissect the rest of the packet.
2500 * If it gets a BoundsError, we can stop, as there's nothing more
2501 * in the packet after our blob to see, so we just re-throw the
2504 pd_save = pinfo->private_data;
2506 /* Version number */
2507 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_vers,
2508 tvb, offset, 4, ENC_LITTLE_ENDIAN);
2511 /* Encrypted body */
2512 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_body,
2513 tvb, offset, encrypted_block_length, ENC_NA);
2515 /* Try to decrypt */
2516 decrypt_verifier (tvb, offset, encrypted_block_length, pinfo, ntlmssp_tree, NULL);
2517 /* let's try to hook ourselves here */
2520 offset += encrypted_block_length;
2521 } CATCH_NONFATAL_ERRORS {
2522 /* Restore the private_data structure in case one of the
2523 * called dissectors modified it (and, due to the exception,
2524 * was unable to restore it).
2526 pinfo->private_data = pd_save;
2527 show_exception(tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE);
2534 wrap_dissect_ntlmssp_payload_only(tvbuff_t *tvb, tvbuff_t *auth_tvb _U_,
2535 int offset, packet_info *pinfo, dcerpc_auth_info *auth_info _U_)
2539 data_tvb = tvb_new_subset_remaining(tvb, offset);
2540 dissect_ntlmssp_payload_only(data_tvb, pinfo, NULL, NULL);
2541 return pinfo->gssapi_decrypted_tvb;
2546 dissect_ntlmssp_encrypted_payload(tvbuff_t *data_tvb,
2547 tvbuff_t *auth_tvb _U_,
2550 dcerpc_auth_info *auth_info _U_)
2552 /* gssapi_decrypted_tvb = NULL */
2553 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
2555 conversation_t *conversation;
2556 guint32 encrypted_block_length;
2557 rc4_state_struct *rc4_state;
2558 rc4_state_struct *rc4_state_peer;
2559 ntlmssp_info *conv_ntlmssp_info = NULL;
2560 ntlmssp_packet_info *packet_ntlmssp_info;
2562 encrypted_block_length = tvb_length_remaining (data_tvb, offset);
2564 fprintf(stderr, "Called dissect_ntlmssp_encrypted_payload\n");
2565 /* Check to see if we already have state for this packet */
2566 packet_ntlmssp_info = p_get_proto_data(wmem_file_scope(), pinfo, proto_ntlmssp, NTLMSSP_PACKET_INFO_KEY);
2567 if (packet_ntlmssp_info == NULL) {
2568 /* We don't have any packet state, so create one */
2569 packet_ntlmssp_info = wmem_new0(wmem_file_scope(), ntlmssp_packet_info);
2570 p_add_proto_data(wmem_file_scope(), pinfo, proto_ntlmssp, NTLMSSP_PACKET_INFO_KEY, packet_ntlmssp_info);
2573 if (!packet_ntlmssp_info->payload_decrypted) {
2574 /* Pull the challenge info from the conversation */
2575 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
2576 pinfo->ptype, pinfo->srcport,
2577 pinfo->destport, 0);
2578 if (conversation == NULL) {
2579 /* There is no conversation, thus no encryption state */
2583 conv_ntlmssp_info = conversation_get_proto_data(conversation,
2585 if (conv_ntlmssp_info == NULL) {
2586 /* There is no NTLMSSP state tied to the conversation */
2589 /* Get the pair of RC4 state structures. One is used for to decrypt the
2590 payload. The other is used to re-encrypt the payload to represent
2592 if (conv_ntlmssp_info->server_dest_port == pinfo->destport) {
2593 rc4_state = get_encrypted_state(pinfo, 1);
2594 rc4_state_peer = get_encrypted_state(pinfo, 0);
2596 rc4_state = get_encrypted_state(pinfo, 0);
2597 rc4_state_peer = get_encrypted_state(pinfo, 1);
2600 if (rc4_state == NULL || rc4_state_peer == NULL) {
2601 /* There is no encryption state, so we cannot decrypt */
2605 /* Store the decrypted contents in the packet state struct
2606 (of course at this point, they aren't decrypted yet) */
2607 packet_ntlmssp_info->decrypted_payload = tvb_memdup(NULL, data_tvb, offset,
2608 encrypted_block_length);
2609 decrypted_payloads = g_slist_prepend(decrypted_payloads,
2610 packet_ntlmssp_info->decrypted_payload);
2612 /* Do the decryption of the payload */
2613 crypt_rc4(rc4_state, packet_ntlmssp_info->decrypted_payload,
2614 encrypted_block_length);
2616 /* We setup a temporary buffer so we can re-encrypt the payload after
2617 decryption. This is to update the opposite peer's RC4 state */
2618 peer_block = wmem_memdup(wmem_packet_scope(), packet_ntlmssp_info->decrypted_payload, encrypted_block_length);
2619 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
2621 packet_ntlmssp_info->payload_decrypted = TRUE;
2624 /* Show the decrypted buffer in a new window */
2625 decr_tvb = tvb_new_child_real_data(data_tvb, packet_ntlmssp_info->decrypted_payload,
2626 encrypted_block_length,
2627 encrypted_block_length);
2629 offset += encrypted_block_length;
2636 free_payload(gpointer decrypted_payload, gpointer user_data _U_)
2638 g_free(decrypted_payload);
2642 header_hash(gconstpointer pointer)
2644 guint32 crc = ~crc32c_calculate(pointer, NTLMSSP_KEY_LEN, CRC32C_PRELOAD);
2645 /* Mat TBD fprintf(stderr, "Val: %u\n", crc);*/
2650 header_equal(gconstpointer pointer1, gconstpointer pointer2)
2652 if (!memcmp(pointer1, pointer2, 16)) {
2661 ntlmssp_init_protocol(void)
2664 * Free the decrypted payloads, and then free the list of decrypted
2667 if (decrypted_payloads != NULL) {
2668 g_slist_foreach(decrypted_payloads, free_payload, NULL);
2669 g_slist_free(decrypted_payloads);
2670 decrypted_payloads = NULL;
2673 if (hash_packet != NULL) {
2674 g_hash_table_remove_all(hash_packet);
2676 hash_packet = g_hash_table_new(header_hash, header_equal);
2683 wrap_dissect_ntlmssp(tvbuff_t *tvb, int offset, packet_info *pinfo,
2684 proto_tree *tree, dcerpc_info *di _U_, guint8 *drep _U_)
2688 auth_tvb = tvb_new_subset_remaining(tvb, offset);
2690 dissect_ntlmssp(auth_tvb, pinfo, tree);
2692 return tvb_length_remaining(tvb, offset);
2696 wrap_dissect_ntlmssp_verf(tvbuff_t *tvb, int offset, packet_info *pinfo,
2697 proto_tree *tree, dcerpc_info *di _U_, guint8 *drep _U_)
2701 auth_tvb = tvb_new_subset_remaining(tvb, offset);
2702 return dissect_ntlmssp_verf(auth_tvb, pinfo, tree, NULL);
2705 static dcerpc_auth_subdissector_fns ntlmssp_sign_fns = {
2706 wrap_dissect_ntlmssp, /* Bind */
2707 wrap_dissect_ntlmssp, /* Bind ACK */
2708 wrap_dissect_ntlmssp, /* AUTH3 */
2709 wrap_dissect_ntlmssp_verf, /* Request verifier */
2710 wrap_dissect_ntlmssp_verf, /* Response verifier */
2711 NULL, /* Request data */
2712 NULL /* Response data */
2715 static dcerpc_auth_subdissector_fns ntlmssp_seal_fns = {
2716 wrap_dissect_ntlmssp, /* Bind */
2717 wrap_dissect_ntlmssp, /* Bind ACK */
2718 wrap_dissect_ntlmssp, /* AUTH3 */
2719 wrap_dissect_ntlmssp_verf, /* Request verifier */
2720 wrap_dissect_ntlmssp_verf, /* Response verifier */
2721 wrap_dissect_ntlmssp_payload_only, /* Request data */
2722 wrap_dissect_ntlmssp_payload_only /* Response data */
2726 proto_register_ntlmssp(void)
2729 static hf_register_info hf[] = {
2731 { "NTLMSSP identifier", "ntlmssp.identifier",
2732 FT_STRING, BASE_NONE, NULL, 0x0,
2735 { &hf_ntlmssp_message_type,
2736 { "NTLM Message Type", "ntlmssp.messagetype",
2737 FT_UINT32, BASE_HEX, VALS(ntlmssp_message_types), 0x0,
2740 { &hf_ntlmssp_negotiate_flags,
2741 { "Negotiate Flags", "ntlmssp.negotiateflags",
2742 FT_UINT32, BASE_HEX, NULL, 0x0,
2745 { &hf_ntlmssp_negotiate_flags_01,
2746 { "Negotiate UNICODE", "ntlmssp.negotiateunicode",
2747 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_UNICODE,
2750 { &hf_ntlmssp_negotiate_flags_02,
2751 { "Negotiate OEM", "ntlmssp.negotiateoem",
2752 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_OEM,
2755 { &hf_ntlmssp_negotiate_flags_04,
2756 { "Request Target", "ntlmssp.requesttarget",
2757 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_REQUEST_TARGET,
2760 { &hf_ntlmssp_negotiate_flags_08,
2761 { "Request 0x00000008", "ntlmssp.negotiate00000008",
2762 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00000008,
2765 { &hf_ntlmssp_negotiate_flags_10,
2766 { "Negotiate Sign", "ntlmssp.negotiatesign",
2767 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_SIGN,
2770 { &hf_ntlmssp_negotiate_flags_20,
2771 { "Negotiate Seal", "ntlmssp.negotiateseal",
2772 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_SEAL,
2775 { &hf_ntlmssp_negotiate_flags_40,
2776 { "Negotiate Datagram", "ntlmssp.negotiatedatagram",
2777 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_DATAGRAM,
2780 { &hf_ntlmssp_negotiate_flags_80,
2781 { "Negotiate Lan Manager Key", "ntlmssp.negotiatelmkey",
2782 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_LM_KEY,
2785 { &hf_ntlmssp_negotiate_flags_100,
2786 { "Negotiate 0x00000100", "ntlmssp.negotiate00000100",
2787 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00000100,
2790 { &hf_ntlmssp_negotiate_flags_200,
2791 { "Negotiate NTLM key", "ntlmssp.negotiatentlm",
2792 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_NTLM,
2795 { &hf_ntlmssp_negotiate_flags_400,
2796 { "Negotiate NT Only", "ntlmssp.negotiatentonly",
2797 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_NT_ONLY,
2800 { &hf_ntlmssp_negotiate_flags_800,
2801 { "Negotiate Anonymous", "ntlmssp.negotiateanonymous",
2802 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_ANONYMOUS,
2805 { &hf_ntlmssp_negotiate_flags_1000,
2806 { "Negotiate OEM Domain Supplied", "ntlmssp.negotiateoemdomainsupplied",
2807 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED,
2810 { &hf_ntlmssp_negotiate_flags_2000,
2811 { "Negotiate OEM Workstation Supplied", "ntlmssp.negotiateoemworkstationsupplied",
2812 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED,
2815 { &hf_ntlmssp_negotiate_flags_4000,
2816 { "Negotiate 0x00004000", "ntlmssp.negotiate00004000",
2817 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00004000,
2820 { &hf_ntlmssp_negotiate_flags_8000,
2821 { "Negotiate Always Sign", "ntlmssp.negotiatealwayssign",
2822 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_ALWAYS_SIGN,
2825 { &hf_ntlmssp_negotiate_flags_10000,
2826 { "Target Type Domain", "ntlmssp.targettypedomain",
2827 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_TARGET_TYPE_DOMAIN,
2830 { &hf_ntlmssp_negotiate_flags_20000,
2831 { "Target Type Server", "ntlmssp.targettypeserver",
2832 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_TARGET_TYPE_SERVER,
2835 { &hf_ntlmssp_negotiate_flags_40000,
2836 { "Target Type Share", "ntlmssp.targettypeshare",
2837 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_TARGET_TYPE_SHARE,
2841 /* Negotiate Flags */
2842 { &hf_ntlmssp_negotiate_flags_80000,
2843 { "Negotiate Extended Security", "ntlmssp.negotiatentlm2",
2844 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_EXTENDED_SECURITY,
2847 { &hf_ntlmssp_negotiate_flags_100000,
2848 { "Negotiate Identify", "ntlmssp.negotiateidentify",
2849 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_IDENTIFY,
2852 { &hf_ntlmssp_negotiate_flags_200000,
2853 { "Negotiate 0x00200000", "ntlmssp.negotiatent00200000",
2854 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00200000,
2857 { &hf_ntlmssp_negotiate_flags_400000,
2858 { "Request Non-NT Session", "ntlmssp.requestnonntsession",
2859 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_REQUEST_NON_NT_SESSION,
2862 { &hf_ntlmssp_negotiate_flags_800000,
2863 { "Negotiate Target Info", "ntlmssp.negotiatetargetinfo",
2864 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_TARGET_INFO,
2867 { &hf_ntlmssp_negotiate_flags_1000000,
2868 { "Negotiate 0x01000000", "ntlmssp.negotiatent01000000",
2869 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_01000000,
2872 { &hf_ntlmssp_negotiate_flags_2000000,
2873 { "Negotiate Version", "ntlmssp.negotiateversion",
2874 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_VERSION,
2877 { &hf_ntlmssp_negotiate_flags_4000000,
2878 { "Negotiate 0x04000000", "ntlmssp.negotiatent04000000",
2879 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_04000000,
2882 { &hf_ntlmssp_negotiate_flags_8000000,
2883 { "Negotiate 0x08000000", "ntlmssp.negotiatent08000000",
2884 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_08000000,
2887 { &hf_ntlmssp_negotiate_flags_10000000,
2888 { "Negotiate 0x10000000", "ntlmssp.negotiatent10000000",
2889 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_10000000,
2892 { &hf_ntlmssp_negotiate_flags_20000000,
2893 { "Negotiate 128", "ntlmssp.negotiate128",
2894 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_128,
2895 "128-bit encryption is supported", HFILL }
2897 { &hf_ntlmssp_negotiate_flags_40000000,
2898 { "Negotiate Key Exchange", "ntlmssp.negotiatekeyexch",
2899 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_KEY_EXCH,
2902 { &hf_ntlmssp_negotiate_flags_80000000,
2903 { "Negotiate 56", "ntlmssp.negotiate56",
2904 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_56,
2905 "56-bit encryption is supported", HFILL }
2908 { &hf_ntlmssp_negotiate_workstation_strlen,
2909 { "Calling workstation name length", "ntlmssp.negotiate.callingworkstation.strlen",
2910 FT_UINT16, BASE_DEC, NULL, 0x0,
2915 { &hf_ntlmssp_negotiate_workstation_maxlen,
2916 { "Calling workstation name max length", "ntlmssp.negotiate.callingworkstation.maxlen",
2917 FT_UINT16, BASE_DEC, NULL, 0x0,
2922 { &hf_ntlmssp_negotiate_workstation_buffer,
2923 { "Calling workstation name buffer", "ntlmssp.negotiate.callingworkstation.buffer",
2924 FT_UINT32, BASE_HEX, NULL, 0x0,
2928 { &hf_ntlmssp_negotiate_workstation,
2929 { "Calling workstation name", "ntlmssp.negotiate.callingworkstation",
2930 FT_STRING, BASE_NONE, NULL, 0x0,
2934 { &hf_ntlmssp_negotiate_domain_strlen,
2935 { "Calling workstation domain length", "ntlmssp.negotiate.domain.strlen",
2936 FT_UINT16, BASE_DEC, NULL, 0x0,
2941 { &hf_ntlmssp_negotiate_domain_maxlen,
2942 { "Calling workstation domain max length", "ntlmssp.negotiate.domain.maxlen",
2943 FT_UINT16, BASE_DEC, NULL, 0x0,
2948 { &hf_ntlmssp_negotiate_domain_buffer,
2949 { "Calling workstation domain buffer", "ntlmssp.negotiate.domain.buffer",
2950 FT_UINT32, BASE_HEX, NULL, 0x0,
2954 { &hf_ntlmssp_negotiate_domain,
2955 { "Calling workstation domain", "ntlmssp.negotiate.domain",
2956 FT_STRING, BASE_NONE, NULL, 0x0,
2959 { &hf_ntlmssp_ntlm_client_challenge,
2960 { "NTLM Client Challenge", "ntlmssp.ntlmclientchallenge",
2961 FT_BYTES, BASE_NONE, NULL, 0x0,
2964 { &hf_ntlmssp_ntlm_server_challenge,
2965 { "NTLM Server Challenge", "ntlmssp.ntlmserverchallenge",
2966 FT_BYTES, BASE_NONE, NULL, 0x0,
2969 { &hf_ntlmssp_reserved,
2970 { "Reserved", "ntlmssp.reserved",
2971 FT_BYTES, BASE_NONE, NULL, 0x0,
2975 { &hf_ntlmssp_challenge_target_name,
2976 { "Target Name", "ntlmssp.challenge.target_name",
2977 FT_STRING, BASE_NONE, NULL, 0x0,
2980 { &hf_ntlmssp_auth_domain,
2981 { "Domain name", "ntlmssp.auth.domain",
2982 FT_STRING, BASE_NONE, NULL, 0x0,
2985 { &hf_ntlmssp_auth_username,
2986 { "User name", "ntlmssp.auth.username",
2987 FT_STRING, BASE_NONE, NULL, 0x0,
2990 { &hf_ntlmssp_auth_hostname,
2991 { "Host name", "ntlmssp.auth.hostname",
2992 FT_STRING, BASE_NONE, NULL, 0x0,
2995 { &hf_ntlmssp_auth_lmresponse,
2996 { "Lan Manager Response", "ntlmssp.auth.lmresponse",
2997 FT_BYTES, BASE_NONE, NULL, 0x0,
3000 { &hf_ntlmssp_auth_ntresponse,
3001 { "NTLM Response", "ntlmssp.auth.ntresponse",
3002 FT_BYTES, BASE_NONE, NULL, 0x0,
3005 { &hf_ntlmssp_auth_sesskey,
3006 { "Session Key", "ntlmssp.auth.sesskey",
3007 FT_BYTES, BASE_NONE, NULL, 0x0,
3010 { &hf_ntlmssp_string_len,
3011 { "Length", "ntlmssp.string.length",
3012 FT_UINT16, BASE_DEC, NULL, 0x0,
3015 { &hf_ntlmssp_string_maxlen,
3016 { "Maxlen", "ntlmssp.string.maxlen",
3017 FT_UINT16, BASE_DEC, NULL, 0x0,
3020 { &hf_ntlmssp_string_offset,
3021 { "Offset", "ntlmssp.string.offset",
3022 FT_UINT32, BASE_DEC, NULL, 0x0,
3025 { &hf_ntlmssp_blob_len,
3026 { "Length", "ntlmssp.blob.length",
3027 FT_UINT16, BASE_DEC, NULL, 0x0,
3030 { &hf_ntlmssp_blob_maxlen,
3031 { "Maxlen", "ntlmssp.blob.maxlen",
3032 FT_UINT16, BASE_DEC, NULL, 0x0,
3035 { &hf_ntlmssp_blob_offset,
3036 { "Offset", "ntlmssp.blob.offset",
3037 FT_UINT32, BASE_DEC, NULL, 0x0,
3040 { &hf_ntlmssp_version,
3041 { "Version", "ntlmssp.version",
3042 FT_NONE, BASE_NONE, NULL, 0x0,
3045 { &hf_ntlmssp_version_major,
3046 { "Major Version", "ntlmssp.version.major",
3047 FT_UINT8, BASE_DEC, NULL, 0x0,
3050 { &hf_ntlmssp_version_minor,
3051 { "Minor Version", "ntlmssp.version.minor",
3052 FT_UINT8, BASE_DEC, NULL, 0x0,
3055 { &hf_ntlmssp_version_build_number,
3056 { "Build Number", "ntlmssp.version.build_number",
3057 FT_UINT16, BASE_DEC, NULL, 0x0,
3060 { &hf_ntlmssp_version_ntlm_current_revision,
3061 { "NTLM Current Revision", "ntlmssp.version.ntlm_current_revision",
3062 FT_UINT8, BASE_DEC, NULL, 0x0,
3067 { &hf_ntlmssp_challenge_target_info,
3068 { "Target Info", "ntlmssp.challenge.target_info",
3069 FT_NONE, BASE_NONE, NULL, 0x0,
3072 { &hf_ntlmssp_challenge_target_info_len,
3073 { "Length", "ntlmssp.challenge.target_info.length",
3074 FT_UINT16, BASE_DEC, NULL, 0x0,
3077 { &hf_ntlmssp_challenge_target_info_maxlen,
3078 { "Maxlen", "ntlmssp.challenge.target_info.maxlen",
3079 FT_UINT16, BASE_DEC, NULL, 0x0,
3082 { &hf_ntlmssp_challenge_target_info_offset,
3083 { "Offset", "ntlmssp.challenge.target_info.offset",
3084 FT_UINT32, BASE_DEC, NULL, 0x0,
3088 { &hf_ntlmssp_challenge_target_info_item_type,
3089 { "Target Info Item Type", "ntlmssp.challenge.target_info.item.type",
3090 FT_UINT16, BASE_HEX | BASE_EXT_STRING, &ntlm_name_types_ext, 0x0,
3093 { &hf_ntlmssp_challenge_target_info_item_len,
3094 { "Target Info Item Length", "ntlmssp.challenge.target_info.item.length",
3095 FT_UINT16, BASE_DEC, NULL, 0x0,
3099 { &hf_ntlmssp_challenge_target_info_end,
3100 { "List End", "ntlmssp.challenge.target_info.end",
3101 FT_NONE, BASE_NONE, NULL, 0x0,
3104 { &hf_ntlmssp_challenge_target_info_nb_computer_name,
3105 { "NetBIOS Computer Name", "ntlmssp.challenge.target_info.nb_computer_name",
3106 FT_STRING, BASE_NONE, NULL, 0x0,
3107 "Server NetBIOS Computer Name", HFILL }
3109 { &hf_ntlmssp_challenge_target_info_nb_domain_name,
3110 { "NetBIOS Domain Name", "ntlmssp.challenge.target_info.nb_domain_name",
3111 FT_STRING, BASE_NONE, NULL, 0x0,
3112 "Server NetBIOS Domain Name", HFILL }
3114 { &hf_ntlmssp_challenge_target_info_dns_computer_name,
3115 { "DNS Computer Name", "ntlmssp.challenge.target_info.dns_computer_name",
3116 FT_STRING, BASE_NONE, NULL, 0x0,
3119 { &hf_ntlmssp_challenge_target_info_dns_domain_name,
3120 { "DNS Domain Name", "ntlmssp.challenge.target_info.dns_domain_name",
3121 FT_STRING, BASE_NONE, NULL, 0x0,
3124 { &hf_ntlmssp_challenge_target_info_dns_tree_name,
3125 { "DNS Tree Name", "ntlmssp.challenge.target_info.dns_tree_name",
3126 FT_STRING, BASE_NONE, NULL, 0x0,
3129 { &hf_ntlmssp_challenge_target_info_flags,
3130 { "Flags", "ntlmssp.challenge.target_info.flags",
3131 FT_UINT32, BASE_HEX, NULL, 0x0,
3134 { &hf_ntlmssp_challenge_target_info_timestamp,
3135 { "Timestamp", "ntlmssp.challenge.target_info.timestamp",
3136 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0,
3139 { &hf_ntlmssp_challenge_target_info_restrictions,
3140 { "Restrictions", "ntlmssp.challenge.target_info.restrictions",
3141 FT_BYTES, BASE_NONE, NULL, 0,
3144 { &hf_ntlmssp_challenge_target_info_target_name,
3145 { "Target Name", "ntlmssp.challenge.target_info.target_name",
3146 FT_STRING, BASE_NONE, NULL, 0x0,
3149 { &hf_ntlmssp_challenge_target_info_channel_bindings,
3150 { "Channel Bindings", "ntlmssp.challenge.target_info.channel_bindings",
3151 FT_BYTES, BASE_NONE, NULL, 0x0,
3155 { &hf_ntlmssp_ntlmv2_response_item_type,
3156 { "NTLMV2 Response Item Type", "ntlmssp.ntlmv2_response.item.type",
3157 FT_UINT16, BASE_HEX | BASE_EXT_STRING, &ntlm_name_types_ext, 0x0,
3160 { &hf_ntlmssp_ntlmv2_response_item_len,
3161 { "NTLMV2 Response Item Length", "ntlmssp.ntlmv2_response.item.length",
3162 FT_UINT16, BASE_DEC, NULL, 0x0,
3166 { &hf_ntlmssp_ntlmv2_response_end,
3167 { "List End", "ntlmssp.ntlmv2_response.end",
3168 FT_NONE, BASE_NONE, NULL, 0x0,
3171 { &hf_ntlmssp_ntlmv2_response_nb_computer_name,
3172 { "NetBIOS Computer Name", "ntlmssp.ntlmv2_response.nb_computer_name",
3173 FT_STRING, BASE_NONE, NULL, 0x0,
3174 "Server NetBIOS Computer Name", HFILL }
3176 { &hf_ntlmssp_ntlmv2_response_nb_domain_name,
3177 { "NetBIOS Domain Name", "ntlmssp.ntlmv2_response.nb_domain_name",
3178 FT_STRING, BASE_NONE, NULL, 0x0,
3179 "Server NetBIOS Domain Name", HFILL }
3181 { &hf_ntlmssp_ntlmv2_response_dns_computer_name,
3182 { "DNS Computer Name", "ntlmssp.ntlmv2_response.dns_computer_name",
3183 FT_STRING, BASE_NONE, NULL, 0x0,
3186 { &hf_ntlmssp_ntlmv2_response_dns_domain_name,
3187 { "DNS Domain Name", "ntlmssp.ntlmv2_response.dns_domain_name",
3188 FT_STRING, BASE_NONE, NULL, 0x0,
3191 { &hf_ntlmssp_ntlmv2_response_dns_tree_name,
3192 { "DNS Tree Name", "ntlmssp.ntlmv2_response.dns_tree_name",
3193 FT_STRING, BASE_NONE, NULL, 0x0,
3196 { &hf_ntlmssp_ntlmv2_response_flags,
3197 { "Flags", "ntlmssp.ntlmv2_response.flags",
3198 FT_UINT32, BASE_HEX, NULL, 0x0,
3201 { &hf_ntlmssp_ntlmv2_response_timestamp,
3202 { "Timestamp", "ntlmssp.ntlmv2_response.timestamp",
3203 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0,
3206 { &hf_ntlmssp_ntlmv2_response_restrictions,
3207 { "Restrictions", "ntlmssp.ntlmv2_response.restrictions",
3208 FT_BYTES, BASE_NONE, NULL, 0,
3211 { &hf_ntlmssp_ntlmv2_response_target_name,
3212 { "Target Name", "ntlmssp.ntlmv2_response.target_name",
3213 FT_STRING, BASE_NONE, NULL, 0x0,
3216 { &hf_ntlmssp_ntlmv2_response_channel_bindings,
3217 { "Channel Bindings", "ntlmssp.ntlmv2_response.channel_bindings",
3218 FT_BYTES, BASE_NONE, NULL, 0x0,
3222 { &hf_ntlmssp_message_integrity_code,
3223 { "MIC", "ntlmssp.authenticate.mic",
3224 FT_BYTES, BASE_NONE, NULL, 0x0,
3225 "Message Integrity Code", HFILL}
3228 { "NTLMSSP Verifier", "ntlmssp.verf",
3229 FT_NONE, BASE_NONE, NULL, 0x0,
3232 { &hf_ntlmssp_verf_vers,
3233 { "Version Number", "ntlmssp.verf.vers",
3234 FT_UINT32, BASE_DEC, NULL, 0x0,
3237 { &hf_ntlmssp_verf_body,
3238 { "Verifier Body", "ntlmssp.verf.body",
3239 FT_BYTES, BASE_NONE, NULL, 0x0,
3243 { &hf_ntlmssp_decrypted_payload,
3244 { "NTLM Decrypted Payload", "ntlmssp.decrypted_payload",
3245 FT_BYTES, BASE_NONE, NULL, 0x0,
3249 { &hf_ntlmssp_verf_randompad,
3250 { "Random Pad", "ntlmssp.verf.randompad",
3251 FT_UINT32, BASE_HEX, NULL, 0x0,
3254 { &hf_ntlmssp_verf_crc32,
3255 { "Verifier CRC32", "ntlmssp.verf.crc32",
3256 FT_UINT32, BASE_HEX, NULL, 0x0,
3259 { &hf_ntlmssp_verf_hmacmd5,
3260 { "HMAC MD5", "ntlmssp.verf.hmacmd5",
3261 FT_BYTES, BASE_NONE, NULL, 0x0,
3264 { &hf_ntlmssp_verf_sequence,
3265 { "Sequence", "ntlmssp.verf.sequence",
3266 FT_BYTES, BASE_NONE, NULL, 0x0,
3270 { &hf_ntlmssp_ntlmv2_response,
3271 { "NTLMv2 Response", "ntlmssp.ntlmv2_response",
3272 FT_BYTES, BASE_NONE, NULL, 0x0,
3275 { &hf_ntlmssp_ntlmv2_response_ntproofstr,
3276 { "NTProofStr", "ntlmssp.ntlmv2_response.ntproofstr",
3277 FT_BYTES, BASE_NONE, NULL, 0x0,
3278 "The HMAC-MD5 of the challenge", HFILL }
3280 { &hf_ntlmssp_ntlmv2_response_rversion,
3281 { "Response Version", "ntlmssp.ntlmv2_response.rversion",
3282 FT_UINT8, BASE_DEC, NULL, 0x0,
3283 "The 1-byte response version, currently set to 1", HFILL }
3285 { &hf_ntlmssp_ntlmv2_response_hirversion,
3286 { "Hi Response Version", "ntlmssp.ntlmv2_response.hirversion",
3287 FT_UINT8, BASE_DEC, NULL, 0x0,
3288 "The 1-byte highest response version understood by the client, currently set to 1", HFILL }
3290 { &hf_ntlmssp_ntlmv2_response_z,
3291 { "Z", "ntlmssp.ntlmv2_response.z",
3292 FT_BYTES, BASE_NONE, NULL, 0x0,
3293 "byte array of zero bytes", HFILL }
3295 { &hf_ntlmssp_ntlmv2_response_pad,
3296 { "padding", "ntlmssp.ntlmv2_response.pad",
3297 FT_BYTES, BASE_NONE, NULL, 0x0,
3300 { &hf_ntlmssp_ntlmv2_response_time,
3301 { "Time", "ntlmssp.ntlmv2_response.time",
3302 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0,
3303 "The 8-byte little-endian time in UTC", HFILL }
3305 { &hf_ntlmssp_ntlmv2_response_chal,
3306 { "Client Challenge", "ntlmssp.ntlmv2_response.chal",
3307 FT_BYTES, BASE_NONE, NULL, 0x0,
3308 "The 8-byte challenge message generated by the client", HFILL }
3313 static gint *ett[] = {
3315 &ett_ntlmssp_negotiate_flags,
3316 &ett_ntlmssp_string,
3318 &ett_ntlmssp_version,
3319 &ett_ntlmssp_challenge_target_info,
3320 &ett_ntlmssp_challenge_target_info_item,
3321 &ett_ntlmssp_ntlmv2_response,
3322 &ett_ntlmssp_ntlmv2_response_item,
3324 static ei_register_info ei[] = {
3325 { &ei_ntlmssp_v2_key_too_long, { "ntlmssp.v2_key_too_long", PI_UNDECODED, PI_WARN, "NTLM v2 key is too long", EXPFILL }},
3326 { &ei_ntlmssp_blob_len_too_long, { "ntlmssp.blob.length.too_long", PI_UNDECODED, PI_WARN, "Session blob length too long", EXPFILL }},
3327 { &ei_ntlmssp_target_info_attr, { "ntlmssp.target_info_attr.unknown", PI_UNDECODED, PI_WARN, "unknown NTLMSSP Target Info Attribute", EXPFILL }},
3329 module_t *ntlmssp_module;
3330 expert_module_t* expert_ntlmssp;
3332 proto_ntlmssp = proto_register_protocol (
3333 "NTLM Secure Service Provider", /* name */
3334 "NTLMSSP", /* short name */
3335 "ntlmssp" /* abbrev */
3337 proto_register_field_array (proto_ntlmssp, hf, array_length (hf));
3338 proto_register_subtree_array (ett, array_length (ett));
3339 expert_ntlmssp = expert_register_protocol(proto_ntlmssp);
3340 expert_register_field_array(expert_ntlmssp, ei, array_length(ei));
3341 register_init_routine(&ntlmssp_init_protocol);
3343 ntlmssp_module = prefs_register_protocol(proto_ntlmssp, NULL);
3345 prefs_register_string_preference(ntlmssp_module, "nt_password",
3347 "NT Password (used to decrypt payloads)",
3350 register_dissector("ntlmssp", dissect_ntlmssp, proto_ntlmssp);
3351 new_register_dissector("ntlmssp_payload", dissect_ntlmssp_payload, proto_ntlmssp);
3352 new_register_dissector("ntlmssp_data_only", dissect_ntlmssp_payload_only, proto_ntlmssp);
3353 new_register_dissector("ntlmssp_verf", dissect_ntlmssp_verf, proto_ntlmssp);
3357 proto_reg_handoff_ntlmssp(void)
3359 dissector_handle_t ntlmssp_handle, ntlmssp_wrap_handle;
3361 /* Register protocol with the GSS-API module */
3363 ntlmssp_handle = find_dissector("ntlmssp");
3364 ntlmssp_wrap_handle = find_dissector("ntlmssp_verf");
3365 gssapi_init_oid("1.3.6.1.4.1.311.2.2.10", proto_ntlmssp, ett_ntlmssp,
3366 ntlmssp_handle, ntlmssp_wrap_handle,
3367 "NTLMSSP - Microsoft NTLM Security Support Provider");
3369 /* Register authenticated pipe dissector */
3372 * XXX - the verifiers here seem to have a version of 1 and a body of all
3375 * XXX - DCE_C_AUTHN_LEVEL_CONNECT is, according to the DCE RPC 1.1
3376 * spec, upgraded to DCE_C_AUTHN_LEVEL_PKT. Should we register
3377 * any other levels here?
3379 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_CONNECT,
3380 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
3383 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT,
3384 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
3387 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
3388 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
3391 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
3392 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
3394 ntlmssp_tap = register_tap("ntlmssp");
3396 heur_dissector_add("credssp", dissect_ntlmssp_heur, proto_ntlmssp);
3401 * Editor modelines - http://www.wireshark.org/tools/modelines.html
3406 * indent-tabs-mode: nil
3409 * vi: set shiftwidth=2 tabstop=8 expandtab:
3410 * :indentSize=2:tabSize=8:noTabs=true: