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>
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1998 Gerald Combs
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 /* Just set me to activate debug #define DEBUG_NTLMSSP */
37 #include <epan/packet.h>
39 #include "packet-windows-common.h"
40 #include "packet-smb-common.h"
41 #include "packet-frame.h"
42 #include <epan/asn1.h>
43 #include "packet-kerberos.h"
44 #include <epan/prefs.h>
45 #include <epan/emem.h>
47 #include <epan/expert.h>
48 #include <epan/crypt/rc4.h>
49 #include <epan/crypt/md4.h>
50 #include <epan/crypt/md5.h>
51 #include <epan/crypt/des.h>
52 #include "packet-dcerpc.h"
53 #include "packet-gssapi.h"
54 #include <wsutil/crc32.h>
56 #include "packet-ntlmssp.h"
58 static int ntlmssp_tap = -1;
60 #define CLIENT_SIGN_TEXT "session key to client-to-server signing key magic constant"
61 #define CLIENT_SEAL_TEXT "session key to client-to-server sealing key magic constant"
62 #define SERVER_SIGN_TEXT "session key to server-to-client signing key magic constant"
63 #define SERVER_SEAL_TEXT "session key to server-to-client sealing key magic constant"
65 static const value_string ntlmssp_message_types[] = {
66 { NTLMSSP_NEGOTIATE, "NTLMSSP_NEGOTIATE" },
67 { NTLMSSP_CHALLENGE, "NTLMSSP_CHALLENGE" },
68 { NTLMSSP_AUTH, "NTLMSSP_AUTH" },
69 { NTLMSSP_UNKNOWN, "NTLMSSP_UNKNOWN" },
73 typedef struct _md4_pass {
74 guint8 md4[NTLMSSP_KEY_LEN];
77 static 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";
78 static GHashTable* hash_packet = NULL;
81 * NTLMSSP negotiation flags
86 * http://davenport.sourceforge.net/ntlm.html
88 * although that document says that:
90 * 0x00010000 is "Target Type Domain";
91 * 0x00020000 is "Target Type Server"
92 * 0x00040000 is "Target Type Share";
94 * and that 0x00100000, 0x00200000, and 0x00400000 are
95 * "Request Init Response", "Request Accept Response", and
96 * "Request Non-NT Session Key", rather than those values shifted
97 * right one having those interpretations.
99 * UPDATE: Further information obtained from [MS-NLMP]:
100 * NT LAN Manager (NTLM) Authentication Protocol Specification
101 * http://msdn2.microsoft.com/en-us/library/cc236621.aspx
104 #define NTLMSSP_NEGOTIATE_UNICODE 0x00000001
105 #define NTLMSSP_NEGOTIATE_OEM 0x00000002
106 #define NTLMSSP_REQUEST_TARGET 0x00000004
107 #define NTLMSSP_NEGOTIATE_00000008 0x00000008
108 #define NTLMSSP_NEGOTIATE_SIGN 0x00000010
109 #define NTLMSSP_NEGOTIATE_SEAL 0x00000020
110 #define NTLMSSP_NEGOTIATE_DATAGRAM 0x00000040
111 #define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080
112 #define NTLMSSP_NEGOTIATE_00000100 0x00000100
113 #define NTLMSSP_NEGOTIATE_NTLM 0x00000200
114 #define NTLMSSP_NEGOTIATE_NT_ONLY 0x00000400
115 #define NTLMSSP_NEGOTIATE_00000800 0x00000800
116 #define NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED 0x00001000
117 #define NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED 0x00002000
118 #define NTLMSSP_NEGOTIATE_00004000 0x00004000
119 #define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000
120 #define NTLMSSP_TARGET_TYPE_DOMAIN 0x00010000
121 #define NTLMSSP_TARGET_TYPE_SERVER 0x00020000
122 #define NTLMSSP_TARGET_TYPE_SHARE 0x00040000
123 #define NTLMSSP_NEGOTIATE_EXTENDED_SECURITY 0x00080000
124 #define NTLMSSP_NEGOTIATE_IDENTIFY 0x00100000
125 #define NTLMSSP_NEGOTIATE_00200000 0x00200000
126 #define NTLMSSP_REQUEST_NON_NT_SESSION 0x00400000
127 #define NTLMSSP_NEGOTIATE_TARGET_INFO 0x00800000
128 #define NTLMSSP_NEGOTIATE_01000000 0x01000000
129 #define NTLMSSP_NEGOTIATE_VERSION 0x02000000
130 #define NTLMSSP_NEGOTIATE_04000000 0x04000000
131 #define NTLMSSP_NEGOTIATE_08000000 0x08000000
132 #define NTLMSSP_NEGOTIATE_10000000 0x10000000
133 #define NTLMSSP_NEGOTIATE_128 0x20000000
134 #define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000
135 #define NTLMSSP_NEGOTIATE_56 0x80000000
137 static int proto_ntlmssp = -1;
138 static int hf_ntlmssp_auth = -1;
139 static int hf_ntlmssp_message_type = -1;
140 static int hf_ntlmssp_negotiate_flags = -1;
141 static int hf_ntlmssp_negotiate_flags_01 = -1;
142 static int hf_ntlmssp_negotiate_flags_02 = -1;
143 static int hf_ntlmssp_negotiate_flags_04 = -1;
144 static int hf_ntlmssp_negotiate_flags_08 = -1;
145 static int hf_ntlmssp_negotiate_flags_10 = -1;
146 static int hf_ntlmssp_negotiate_flags_20 = -1;
147 static int hf_ntlmssp_negotiate_flags_40 = -1;
148 static int hf_ntlmssp_negotiate_flags_80 = -1;
149 static int hf_ntlmssp_negotiate_flags_100 = -1;
150 static int hf_ntlmssp_negotiate_flags_200 = -1;
151 static int hf_ntlmssp_negotiate_flags_400 = -1;
152 static int hf_ntlmssp_negotiate_flags_800 = -1;
153 static int hf_ntlmssp_negotiate_flags_1000 = -1;
154 static int hf_ntlmssp_negotiate_flags_2000 = -1;
155 static int hf_ntlmssp_negotiate_flags_4000 = -1;
156 static int hf_ntlmssp_negotiate_flags_8000 = -1;
157 static int hf_ntlmssp_negotiate_flags_10000 = -1;
158 static int hf_ntlmssp_negotiate_flags_20000 = -1;
159 static int hf_ntlmssp_negotiate_flags_40000 = -1;
160 static int hf_ntlmssp_negotiate_flags_80000 = -1;
161 static int hf_ntlmssp_negotiate_flags_100000 = -1;
162 static int hf_ntlmssp_negotiate_flags_200000 = -1;
163 static int hf_ntlmssp_negotiate_flags_400000 = -1;
164 static int hf_ntlmssp_negotiate_flags_800000 = -1;
165 static int hf_ntlmssp_negotiate_flags_1000000 = -1;
166 static int hf_ntlmssp_negotiate_flags_2000000 = -1;
167 static int hf_ntlmssp_negotiate_flags_4000000 = -1;
168 static int hf_ntlmssp_negotiate_flags_8000000 = -1;
169 static int hf_ntlmssp_negotiate_flags_10000000 = -1;
170 static int hf_ntlmssp_negotiate_flags_20000000 = -1;
171 static int hf_ntlmssp_negotiate_flags_40000000 = -1;
172 static int hf_ntlmssp_negotiate_flags_80000000 = -1;
173 static int hf_ntlmssp_negotiate_workstation_strlen = -1;
174 static int hf_ntlmssp_negotiate_workstation_maxlen = -1;
175 static int hf_ntlmssp_negotiate_workstation_buffer = -1;
176 static int hf_ntlmssp_negotiate_workstation = -1;
177 static int hf_ntlmssp_negotiate_domain_strlen = -1;
178 static int hf_ntlmssp_negotiate_domain_maxlen = -1;
179 static int hf_ntlmssp_negotiate_domain_buffer = -1;
180 static int hf_ntlmssp_negotiate_domain = -1;
181 static int hf_ntlmssp_ntlm_server_challenge = -1;
182 static int hf_ntlmssp_ntlm_client_challenge = -1;
183 static int hf_ntlmssp_reserved = -1;
184 static int hf_ntlmssp_challenge_target_name = -1;
185 static int hf_ntlmssp_auth_username = -1;
186 static int hf_ntlmssp_auth_domain = -1;
187 static int hf_ntlmssp_auth_hostname = -1;
188 static int hf_ntlmssp_auth_lmresponse = -1;
189 static int hf_ntlmssp_auth_ntresponse = -1;
190 static int hf_ntlmssp_auth_sesskey = -1;
191 static int hf_ntlmssp_string_len = -1;
192 static int hf_ntlmssp_string_maxlen = -1;
193 static int hf_ntlmssp_string_offset = -1;
194 static int hf_ntlmssp_blob_len = -1;
195 static int hf_ntlmssp_blob_maxlen = -1;
196 static int hf_ntlmssp_blob_offset = -1;
197 static int hf_ntlmssp_version = -1;
198 static int hf_ntlmssp_version_major = -1;
199 static int hf_ntlmssp_version_minor = -1;
200 static int hf_ntlmssp_version_build_number = -1;
201 static int hf_ntlmssp_version_ntlm_current_revision = -1;
203 static int hf_ntlmssp_challenge_target_info = -1;
204 static int hf_ntlmssp_challenge_target_info_len = -1;
205 static int hf_ntlmssp_challenge_target_info_maxlen = -1;
206 static int hf_ntlmssp_challenge_target_info_offset = -1;
208 static int hf_ntlmssp_challenge_target_info_item_type = -1;
209 static int hf_ntlmssp_challenge_target_info_item_len = -1;
211 static int hf_ntlmssp_challenge_target_info_end = -1;
212 static int hf_ntlmssp_challenge_target_info_nb_computer_name = -1;
213 static int hf_ntlmssp_challenge_target_info_nb_domain_name = -1;
214 static int hf_ntlmssp_challenge_target_info_dns_computer_name = -1;
215 static int hf_ntlmssp_challenge_target_info_dns_domain_name = -1;
216 static int hf_ntlmssp_challenge_target_info_dns_tree_name = -1;
217 static int hf_ntlmssp_challenge_target_info_flags = -1;
218 static int hf_ntlmssp_challenge_target_info_timestamp = -1;
219 static int hf_ntlmssp_challenge_target_info_restrictions = -1;
220 static int hf_ntlmssp_challenge_target_info_target_name =-1;
221 static int hf_ntlmssp_challenge_target_info_channel_bindings =-1;
223 static int hf_ntlmssp_ntlmv2_response_item_type = -1;
224 static int hf_ntlmssp_ntlmv2_response_item_len = -1;
226 static int hf_ntlmssp_ntlmv2_response_end = -1;
227 static int hf_ntlmssp_ntlmv2_response_nb_computer_name = -1;
228 static int hf_ntlmssp_ntlmv2_response_nb_domain_name = -1;
229 static int hf_ntlmssp_ntlmv2_response_dns_computer_name = -1;
230 static int hf_ntlmssp_ntlmv2_response_dns_domain_name = -1;
231 static int hf_ntlmssp_ntlmv2_response_dns_tree_name = -1;
232 static int hf_ntlmssp_ntlmv2_response_flags = -1;
233 static int hf_ntlmssp_ntlmv2_response_timestamp = -1;
234 static int hf_ntlmssp_ntlmv2_response_restrictions = -1;
235 static int hf_ntlmssp_ntlmv2_response_target_name =-1;
236 static int hf_ntlmssp_ntlmv2_response_channel_bindings =-1;
238 static int hf_ntlmssp_message_integrity_code = -1;
239 static int hf_ntlmssp_verf = -1;
240 static int hf_ntlmssp_verf_vers = -1;
241 static int hf_ntlmssp_verf_body = -1;
242 static int hf_ntlmssp_verf_randompad = -1;
243 static int hf_ntlmssp_verf_hmacmd5 = -1;
244 static int hf_ntlmssp_verf_crc32 = -1;
245 static int hf_ntlmssp_verf_sequence = -1;
246 static int hf_ntlmssp_decrypted_payload = -1;
248 static int hf_ntlmssp_ntlmv2_response = -1;
249 static int hf_ntlmssp_ntlmv2_response_hmac = -1;
250 static int hf_ntlmssp_ntlmv2_response_header = -1;
251 static int hf_ntlmssp_ntlmv2_response_reserved = -1;
252 static int hf_ntlmssp_ntlmv2_response_time = -1;
253 static int hf_ntlmssp_ntlmv2_response_chal = -1;
254 static int hf_ntlmssp_ntlmv2_response_unknown = -1;
256 static gint ett_ntlmssp = -1;
257 static gint ett_ntlmssp_negotiate_flags = -1;
258 static gint ett_ntlmssp_string = -1;
259 static gint ett_ntlmssp_blob = -1;
260 static gint ett_ntlmssp_version = -1;
261 static gint ett_ntlmssp_challenge_target_info = -1;
262 static gint ett_ntlmssp_challenge_target_info_item = -1;
263 static gint ett_ntlmssp_ntlmv2_response = -1;
264 static gint ett_ntlmssp_ntlmv2_response_item = -1;
266 /* Configuration variables */
267 const char *gbl_nt_password = NULL;
269 #define MAX_BLOB_SIZE 10240
270 typedef struct _ntlmssp_blob {
272 guint8 contents[MAX_BLOB_SIZE];
275 /* Used in the conversation function */
276 typedef struct _ntlmssp_info {
279 rc4_state_struct rc4_state_client;
280 rc4_state_struct rc4_state_server;
281 guint8 sign_key_client[NTLMSSP_KEY_LEN];
282 guint8 sign_key_server[NTLMSSP_KEY_LEN];
283 guint32 server_dest_port;
284 unsigned char server_challenge[8];
285 unsigned char client_challenge[8];
286 int rc4_state_initialized;
287 ntlmssp_blob ntlm_response;
288 ntlmssp_blob lm_response;
291 /* If this struct exists in the payload_decrypt, then we have already
293 typedef struct _ntlmssp_packet_info {
294 guint8 *decrypted_payload;
296 guint8 verifier[NTLMSSP_KEY_LEN];
297 gboolean payload_decrypted;
298 gboolean verifier_decrypted;
299 } ntlmssp_packet_info;
302 static void printnbyte(const guint8* tab, int nb, const char* txt, const char* txt2)
305 fprintf(stderr, "%s ", txt);
308 fprintf(stderr, "%02X ", *(tab+i));
310 fprintf(stderr, "%s", txt2);
313 static void printnchar(const guint8* tab, int nb, char* txt, char* txt2)
316 fprintf(stderr, "%s ", txt);
319 fprintf(stderr, "%c", *(tab+i));
321 fprintf(stderr, "%s", txt2);
325 static void printnbyte(const guint8* tab _U_, int nb _U_, const char* txt _U_, const char* txt2 _U_)
331 * GSlist of decrypted payloads.
333 static GSList *decrypted_payloads;
337 LEBE_Convert(int value)
341 a = value&0x000000FF;
342 b = (value&0x0000FF00) >> 8;
343 c = (value&0x00FF0000) >> 16;
344 d = (value&0xFF000000) >> 24;
345 return (a << 24) | (b << 16) | (c << 8) | d;
350 Perform a DES encryption with a 16 bit key and 8bit data item.
351 It's in fact 3 susbsequent call to crypt_des_ecb with a 7 bit key.
352 Missing bits for the key are replaced by 0;
353 Returns output in response, which is expected to be 24 bytes.
356 crypt_des_ecb_long(guint8 *response,
360 guint8 pw21[21]; /* 21 bytes place for the needed key */
362 memset(pw21, 0, sizeof(pw21));
363 memcpy(pw21, key, 16);
365 memset(response, 0, 24);
366 /* crypt_des_ecb(data, key)*/
367 crypt_des_ecb(response, data, pw21, 1);
368 crypt_des_ecb(response + 8, data, pw21 + 7, 1);
369 crypt_des_ecb(response + 16, data, pw21 + 14, 1);
375 Generate a challenge response, given an eight byte challenge and
376 either the NT or the Lan Manager password hash (16 bytes).
377 Returns output in response, which is expected to be 24 bytes.
380 ntlmssp_generate_challenge_response(guint8 *response,
381 const guint8 *passhash,
382 const guint8 *challenge)
384 guint8 pw21[21]; /* Password hash padded to 21 bytes */
386 memset(pw21, 0x0, sizeof(pw21));
387 memcpy(pw21, passhash, 16);
389 memset(response, 0, 24);
391 crypt_des_ecb(response, challenge, pw21, 1);
392 crypt_des_ecb(response + 8, challenge, pw21 + 7, 1);
393 crypt_des_ecb(response + 16, challenge, pw21 + 14, 1);
399 /* Ultra simple ainsi to unicode converter, will only work for ascii password ...*/
401 str_to_unicode(const char *nt_password, char *nt_password_unicode)
406 password_len = strlen(nt_password);
407 if (nt_password_unicode != NULL) {
408 for (i=0; i<(password_len); i++) {
409 nt_password_unicode[i*2]=nt_password[i];
410 nt_password_unicode[i*2+1]=0;
412 nt_password_unicode[2*password_len]='\0';
416 /* This function generate the Key Exchange Key
417 * Depending on the flags this key will either be used to crypt the exported session key
418 * or will be used directly as exported session key.
419 * Exported session key is the key that will be used for sealing and signing communication*/
422 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)
424 guint8 basekey[NTLMSSP_KEY_LEN];
427 memset(keyexchangekey, 0, NTLMSSP_KEY_LEN);
428 memset(basekey, 0, NTLMSSP_KEY_LEN);
429 /* sessionbasekey is either derived from lm_password_hash or from nt_password_hash depending on the key type negotiated */
430 memcpy(basekey, sessionbasekey, 8);
431 memset(basekey, 0xBD, 8);
432 if (flags&NTLMSSP_NEGOTIATE_LM_KEY) {
434 crypt_des_ecb(keyexchangekey, lm_challenge_response, basekey, 1);
435 crypt_des_ecb(keyexchangekey+8, lm_challenge_response, basekey+7, 1);
438 if (flags&NTLMSSP_REQUEST_NON_NT_SESSION) {
439 /*People from samba tends to use the same function in this case than in the previous one but with 0 data
440 * it's not clear that it produce the good result
441 * memcpy(keyexchangekey, lm_hash, 8);
442 * Let's trust samba implementation it mights seem weird but they are more often rights than the spec !
444 memset(zeros, 0, 24);
445 crypt_des_ecb(keyexchangekey, zeros, basekey, 3);
446 crypt_des_ecb(keyexchangekey+8, zeros, basekey+7, 1);
449 /* it is stated page 65 of NTLM SSP spec that sessionbasekey should be encrypted with hmac_md5 using the concact of both challenge
450 * when it's NTLM v1 + extended security but it turns out to be wrong !
452 memcpy(keyexchangekey, sessionbasekey, NTLMSSP_KEY_LEN);
457 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
459 get_md4pass_list(md4_pass** p_pass_list, const char* nt_password)
464 unsigned char nt_password_hash[NTLMSSP_KEY_LEN];
465 char nt_password_unicode[256];
473 read_keytab_file_from_preferences();
475 for (ek=enc_key_list; ek; ek=ek->next) {
476 if (ek->keylength == NTLMSSP_KEY_LEN) {
480 memset(nt_password_unicode, 0, sizeof(nt_password_unicode));
481 memset(nt_password_hash, 0, NTLMSSP_KEY_LEN);
482 if ((nt_password[0] != '\0') && (strlen(nt_password) < 129)) {
485 password_len = (int)strlen(nt_password);
486 str_to_unicode(nt_password, nt_password_unicode);
487 crypt_md4(nt_password_hash, nt_password_unicode, password_len*2);
490 /* Unable to calculate the session key without a password or if password is more than 128 char ......*/
494 *p_pass_list = ep_alloc(nb_pass*sizeof(md4_pass));
495 pass_list = *p_pass_list;
497 if (memcmp(nt_password_hash, gbl_zeros, NTLMSSP_KEY_LEN) != 0) {
498 memcpy(pass_list[i].md4, nt_password_hash, NTLMSSP_KEY_LEN);
501 for (ek=enc_key_list; ek; ek=ek->next) {
502 if (ek->keylength == NTLMSSP_KEY_LEN) {
503 memcpy(pass_list[i].md4, ek->keyvalue, NTLMSSP_KEY_LEN);
511 /* Create an NTLMSSP version 2 key
514 create_ntlmssp_v2_key(const char *nt_password _U_, const guint8 *serverchallenge , const guint8 *clientchallenge ,
515 guint8 *sessionkey , const guint8 *encryptedsessionkey , int flags ,
516 const ntlmssp_blob *ntlm_response, const ntlmssp_blob *lm_response _U_, ntlmssp_header_t *ntlmssph)
518 char domain_name_unicode[256];
519 char user_uppercase[256];
521 /*guint8 md4[NTLMSSP_KEY_LEN];*/
522 unsigned char nt_password_hash[NTLMSSP_KEY_LEN];
523 unsigned char nt_proof[NTLMSSP_KEY_LEN];
524 unsigned char ntowf[NTLMSSP_KEY_LEN];
525 guint8 sessionbasekey[NTLMSSP_KEY_LEN];
526 guint8 keyexchangekey[NTLMSSP_KEY_LEN];
527 guint8 lm_challenge_response[24];
530 rc4_state_struct rc4state;
533 md4_pass *pass_list = NULL;
535 gboolean found = FALSE;
537 /* We are going to try password encrypted in keytab as well, it's an idean of Stefan Metzmacher <metze@samba.org>
538 * The idea is to be able to test all the key of domain in once and to be able to decode the NTLM dialogs */
540 memset(sessionkey, 0, NTLMSSP_KEY_LEN);
541 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
542 nb_pass = get_md4pass_list(&pass_list, nt_password);
545 memset(user_uppercase, 0, 256);
546 user_len = strlen(ntlmssph->acct_name);
547 if (user_len < 129) {
549 str_to_unicode(ntlmssph->acct_name, buf);
550 for (j = 0; j < (2*user_len); j++) {
551 if (buf[j] != '\0') {
552 user_uppercase[j] = toupper(buf[j]);
557 /* Unable to calculate the session not enought space in buffer, note this is unlikely to happen but ......*/
560 domain_len = strlen(ntlmssph->domain_name);
561 if (domain_len < 129) {
562 str_to_unicode(ntlmssph->domain_name, domain_name_unicode);
565 /* Unable to calculate the session not enought space in buffer, note this is unlikely to happen but ......*/
568 while (i < nb_pass) {
570 fprintf(stderr, "Turn %d, ", i);
572 memcpy(nt_password_hash, pass_list[i].md4, NTLMSSP_KEY_LEN);
573 printnbyte(nt_password_hash, NTLMSSP_KEY_LEN, "Current NT password hash: ", "\n");
575 /* ntowf computation */
577 memcpy(buf, user_uppercase, user_len*2);
578 memcpy(buf+user_len*2, domain_name_unicode, domain_len*2);
579 md5_hmac(buf, domain_len*2+user_len*2, nt_password_hash, NTLMSSP_KEY_LEN, ntowf);
580 printnbyte(ntowf, NTLMSSP_KEY_LEN, "NTOWF: ", "\n");
584 memcpy(buf, serverchallenge, 8);
585 memcpy(buf+8, clientchallenge, 8);
586 md5_hmac(buf, NTLMSSP_KEY_LEN, ntowf, NTLMSSP_KEY_LEN, lm_challenge_response);
587 memcpy(lm_challenge_response+NTLMSSP_KEY_LEN, clientchallenge, 8);
588 printnbyte(lm_challenge_response, 24, "LM Response: ", "\n");
590 /* NT proof = First NTLMSSP_KEY_LEN bytes of NT response */
592 memcpy(buf, serverchallenge, 8);
593 memcpy(buf+8, ntlm_response->contents+NTLMSSP_KEY_LEN, ntlm_response->length-NTLMSSP_KEY_LEN);
594 md5_hmac(buf, ntlm_response->length-8, ntowf, NTLMSSP_KEY_LEN, nt_proof);
595 printnbyte(nt_proof, NTLMSSP_KEY_LEN, "NT proof: ", "\n");
596 if (!memcmp(nt_proof, ntlm_response->contents, NTLMSSP_KEY_LEN)) {
605 md5_hmac(nt_proof, NTLMSSP_KEY_LEN, ntowf, NTLMSSP_KEY_LEN, sessionbasekey);
606 get_keyexchange_key(keyexchangekey, sessionbasekey, lm_challenge_response, flags);
607 /* now decrypt session key if needed and setup sessionkey for decrypting further communications */
608 if (flags & NTLMSSP_NEGOTIATE_KEY_EXCH)
610 memcpy(sessionkey, encryptedsessionkey, NTLMSSP_KEY_LEN);
611 crypt_rc4_init(&rc4state, keyexchangekey, NTLMSSP_KEY_LEN);
612 crypt_rc4(&rc4state, sessionkey, NTLMSSP_KEY_LEN);
616 memcpy(sessionkey, keyexchangekey, NTLMSSP_KEY_LEN);
619 memcpy(ntlmssph->session_key, sessionkey, NTLMSSP_KEY_LEN);
622 /* Create an NTLMSSP version 1 key
623 * That is more complicated logic and methods and user challenge as well.
624 * password points to the ANSI password to encrypt, challenge points to
625 * the 8 octet challenge string
628 create_ntlmssp_v1_key(const char *nt_password, const guint8 *serverchallenge, const guint8 *clientchallenge,
629 guint8 *sessionkey, const guint8 *encryptedsessionkey, int flags,
630 const guint8 *ref_nt_challenge_response, const guint8 *ref_lm_challenge_response,
631 ntlmssp_header_t *ntlmssph)
633 unsigned char lm_password_upper[NTLMSSP_KEY_LEN];
634 unsigned char lm_password_hash[NTLMSSP_KEY_LEN];
635 unsigned char nt_password_hash[NTLMSSP_KEY_LEN];
636 unsigned char challenges_hash[NTLMSSP_KEY_LEN];
637 unsigned char challenges_hash_first8[8];
638 unsigned char challenges[NTLMSSP_KEY_LEN];
639 guint8 md4[NTLMSSP_KEY_LEN];
641 guint8 sessionbasekey[NTLMSSP_KEY_LEN];
642 guint8 keyexchangekey[NTLMSSP_KEY_LEN];
643 guint8 lm_challenge_response[24];
644 guint8 nt_challenge_response[24];
645 rc4_state_struct rc4state;
646 md5_state_t md5state;
647 char nt_password_unicode[256];
650 gboolean found = FALSE;
651 md4_pass *pass_list = NULL;
653 static const unsigned char lmhash_key[] =
654 {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
656 memset(sessionkey, 0, NTLMSSP_KEY_LEN);
657 memset(lm_password_upper, 0, sizeof(lm_password_upper));
658 /* lm auth/lm session == (!NTLM_NEGOTIATE_NT_ONLY && NTLMSSP_NEGOTIATE_LM_KEY) || ! (EXTENDED_SECURITY) || ! NTLMSSP_NEGOTIATE_NTLM*/
659 /* Create a Lan Manager hash of the input password */
660 if (nt_password[0] != '\0') {
661 password_len = strlen(nt_password);
662 /*Do not forget to free nt_password_nt*/
663 str_to_unicode(nt_password, nt_password_unicode);
664 crypt_md4(nt_password_hash, nt_password_unicode, password_len*2);
665 /* Truncate password if too long */
666 if (password_len > NTLMSSP_KEY_LEN)
667 password_len = NTLMSSP_KEY_LEN;
668 for (i = 0; i < password_len; i++) {
669 lm_password_upper[i] = toupper(nt_password[i]);
674 /* Unable to calculate the session key without a password ... and we will not use one for a keytab*/
675 if (!(flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY)) {
679 if ((flags & NTLMSSP_NEGOTIATE_LM_KEY && !(flags & NTLMSSP_NEGOTIATE_NT_ONLY)) || !(flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY) || !(flags & NTLMSSP_NEGOTIATE_NTLM)) {
680 crypt_des_ecb(lm_password_hash, lmhash_key, lm_password_upper, 1);
681 crypt_des_ecb(lm_password_hash+8, lmhash_key, lm_password_upper+7, 1);
682 ntlmssp_generate_challenge_response(lm_challenge_response,
683 lm_password_hash, serverchallenge);
684 memcpy(sessionbasekey, lm_password_hash, NTLMSSP_KEY_LEN);
688 memset(lm_challenge_response, 0, 24);
689 if (flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY) {
690 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
691 nb_pass = get_md4pass_list(&pass_list, nt_password);
694 while (i < nb_pass) {
695 /*fprintf(stderr, "Turn %d, ", i);*/
696 memcpy(nt_password_hash, pass_list[i].md4, NTLMSSP_KEY_LEN);
697 /*printnbyte(nt_password_hash, NTLMSSP_KEY_LEN, "Current NT password hash: ", "\n");*/
699 memcpy(lm_challenge_response, clientchallenge, 8);
701 md5_append(&md5state, serverchallenge, 8);
702 md5_append(&md5state, clientchallenge, 8);
703 md5_finish(&md5state, challenges_hash);
704 memcpy(challenges_hash_first8, challenges_hash, 8);
705 crypt_des_ecb_long(nt_challenge_response, nt_password_hash, challenges_hash_first8);
706 if (!memcmp(ref_nt_challenge_response, nt_challenge_response, 24)) {
713 crypt_des_ecb_long(nt_challenge_response, nt_password_hash, serverchallenge);
714 if (flags & NTLMSSP_NEGOTIATE_NT_ONLY) {
715 memcpy(lm_challenge_response, nt_challenge_response, 24);
718 crypt_des_ecb_long(lm_challenge_response, lm_password_hash, serverchallenge);
720 if (!memcmp(ref_nt_challenge_response, nt_challenge_response, 24) && !memcmp(ref_lm_challenge_response, lm_challenge_response, 24)) {
724 /* So it's clearly not like this that's put into NTLMSSP doc but after some digging into samba code I'm quite confident
725 * that sessionbasekey should be based md4(nt_password_hash) only in the case of some NT auth
726 * Otherwise it should be lm_password_hash ...*/
727 crypt_md4(md4, nt_password_hash, NTLMSSP_KEY_LEN);
728 if (flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY) {
729 memcpy(challenges, serverchallenge, 8);
730 memcpy(challenges+8, clientchallenge, 8);
731 /*md5_hmac(text, text_len, key, key_len, digest);*/
732 md5_hmac(challenges, NTLMSSP_KEY_LEN, md4, NTLMSSP_KEY_LEN, sessionbasekey);
735 memcpy(sessionbasekey, md4, NTLMSSP_KEY_LEN);
743 get_keyexchange_key(keyexchangekey, sessionbasekey, lm_challenge_response, flags);
744 memset(sessionkey, 0, NTLMSSP_KEY_LEN);
745 /*printnbyte(nt_challenge_response, 24, "NT challenge response", "\n");
746 printnbyte(lm_challenge_response, 24, "LM challenge response", "\n");*/
747 /* now decrypt session key if needed and setup sessionkey for decrypting further communications */
748 if (flags & NTLMSSP_NEGOTIATE_KEY_EXCH)
750 memcpy(sessionkey, encryptedsessionkey, NTLMSSP_KEY_LEN);
751 crypt_rc4_init(&rc4state, keyexchangekey, NTLMSSP_KEY_LEN);
752 crypt_rc4(&rc4state, sessionkey, NTLMSSP_KEY_LEN);
756 memcpy(sessionkey, keyexchangekey, NTLMSSP_KEY_LEN);
758 memcpy(ntlmssph->session_key, sessionkey, NTLMSSP_KEY_LEN);
762 get_siging_key(guint8 *sign_key_server, guint8* sign_key_client, const guint8 key[NTLMSSP_KEY_LEN], int keylen)
764 md5_state_t md5state;
765 md5_state_t md5state2;
767 memset(sign_key_client, 0, NTLMSSP_KEY_LEN);
768 memset(sign_key_server, 0, NTLMSSP_KEY_LEN);
770 md5_append(&md5state, key, keylen);
771 md5_append(&md5state, CLIENT_SIGN_TEXT, strlen(CLIENT_SIGN_TEXT)+1);
772 md5_finish(&md5state, sign_key_client);
773 md5_init(&md5state2);
774 md5_append(&md5state2, key, keylen);
775 md5_append(&md5state2, SERVER_SIGN_TEXT, strlen(SERVER_SIGN_TEXT)+1);
776 md5_finish(&md5state2, sign_key_server);
780 /* We return either a 128 or 64 bit key
783 get_sealing_rc4key(const guint8 exportedsessionkey[NTLMSSP_KEY_LEN] , const int flags , int *keylen ,
784 guint8 *clientsealkey , guint8 *serversealkey)
786 md5_state_t md5state;
787 md5_state_t md5state2;
789 memset(clientsealkey, 0, NTLMSSP_KEY_LEN);
790 memset(serversealkey, 0, NTLMSSP_KEY_LEN);
791 memcpy(clientsealkey, exportedsessionkey, NTLMSSP_KEY_LEN);
792 if (flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY)
794 if (flags & NTLMSSP_NEGOTIATE_128)
796 /* The exportedsessionkey has already the good length just update the length*/
801 if (flags & NTLMSSP_NEGOTIATE_56)
803 memset(clientsealkey+7, 0, 9);
808 memset(clientsealkey+5, 0, 11);
812 memcpy(serversealkey, clientsealkey, NTLMSSP_KEY_LEN);
814 md5_append(&md5state, clientsealkey,*keylen);
815 md5_append(&md5state, CLIENT_SEAL_TEXT, strlen(CLIENT_SEAL_TEXT)+1);
816 md5_finish(&md5state, clientsealkey);
817 md5_init(&md5state2);
818 md5_append(&md5state2, serversealkey,*keylen);
819 md5_append(&md5state2, SERVER_SEAL_TEXT, strlen(SERVER_SEAL_TEXT)+1);
820 md5_finish(&md5state2, serversealkey);
824 if (flags & NTLMSSP_NEGOTIATE_128)
826 /* The exportedsessionkey has already the good length just update the length*/
832 if (flags & NTLMSSP_NEGOTIATE_56)
834 memset(clientsealkey+7, 0, 9);
838 memset(clientsealkey+5, 0, 11);
839 clientsealkey[5]=0xe5;
840 clientsealkey[6]=0x38;
841 clientsealkey[7]=0xb0;
844 memcpy(serversealkey, clientsealkey,*keylen);
847 /* Create an NTLMSSP version 1 key.
848 * password points to the ANSI password to encrypt, challenge points to
849 * the 8 octet challenge string, key128 will do a 128 bit key if set to 1,
850 * otherwise it will do a 40 bit key. The result is stored in
851 * sspkey (expected to be NTLMSSP_KEY_LEN octets)
853 /* dissect a string - header area contains:
856 four byte offset of string in data area
857 The function returns the offset at the end of the string header,
858 but the 'end' parameter returns the offset of the end of the string itself
859 The 'start' parameter returns the offset of the beginning of the string
860 If there's no string, just use the offset of the end of the tvb as start/end.
863 dissect_ntlmssp_string (tvbuff_t *tvb, int offset,
864 proto_tree *ntlmssp_tree,
865 gboolean unicode_strings,
866 int string_hf, int *start, int *end,
867 const char **stringp)
869 proto_tree *tree = NULL;
870 proto_item *tf = NULL;
871 gint16 string_length = tvb_get_letohs(tvb, offset);
872 gint16 string_maxlen = tvb_get_letohs(tvb, offset+2);
873 gint32 string_offset = tvb_get_letohl(tvb, offset+4);
874 const char *string_text = NULL;
878 *start = (string_offset > offset+8 ? string_offset : (signed)tvb_reported_length(tvb));
879 if (0 == string_length) {
882 proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
889 bc = result_length = string_length;
890 string_text = get_unicode_or_ascii_string(tvb, &string_offset,
891 unicode_strings, &result_length,
894 if (stringp != NULL) {
895 if (!string_text) string_text = ""; /* Make sure we don't blow up later */
897 *stringp = string_text;
901 tf = proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
902 string_offset, result_length, string_text);
903 tree = proto_item_add_subtree(tf, ett_ntlmssp_string);
905 proto_tree_add_uint(tree, hf_ntlmssp_string_len,
906 tvb, offset, 2, string_length);
908 proto_tree_add_uint(tree, hf_ntlmssp_string_maxlen,
909 tvb, offset, 2, string_maxlen);
911 proto_tree_add_uint(tree, hf_ntlmssp_string_offset,
912 tvb, offset, 4, string_offset);
915 *end = string_offset + string_length;
919 /* dissect a generic blob - header area contains:
922 four byte offset of blob in data area
923 The function returns the offset at the end of the blob header,
924 but the 'end' parameter returns the offset of the end of the blob itself
927 dissect_ntlmssp_blob (tvbuff_t *tvb, int offset,
928 proto_tree *ntlmssp_tree,
929 int blob_hf, int *end, ntlmssp_blob *result)
931 proto_item *tf = NULL;
932 proto_tree *tree = NULL;
933 guint16 blob_length = tvb_get_letohs(tvb, offset);
934 guint16 blob_maxlen = tvb_get_letohs(tvb, offset+2);
935 guint32 blob_offset = tvb_get_letohl(tvb, offset+4);
937 if (0 == blob_length) {
938 *end = (blob_offset > ((guint)offset)+8 ? blob_offset : ((guint)offset)+8);
940 proto_tree_add_text(ntlmssp_tree, tvb, offset, 8, "%s: Empty",
941 proto_registrar_get_name(blob_hf));
946 tf = proto_tree_add_item (ntlmssp_tree, blob_hf, tvb,
947 blob_offset, blob_length, ENC_NA);
948 tree = proto_item_add_subtree(tf, ett_ntlmssp_blob);
950 proto_tree_add_uint(tree, hf_ntlmssp_blob_len,
951 tvb, offset, 2, blob_length);
953 proto_tree_add_uint(tree, hf_ntlmssp_blob_maxlen,
954 tvb, offset, 2, blob_maxlen);
956 proto_tree_add_uint(tree, hf_ntlmssp_blob_offset,
957 tvb, offset, 4, blob_offset);
960 *end = blob_offset + blob_length;
962 if (result != NULL) {
963 result->length = blob_length;
964 memset(result->contents, 0, MAX_BLOB_SIZE);
965 if (blob_length < MAX_BLOB_SIZE)
967 tvb_memcpy(tvb, result->contents, blob_offset, blob_length);
968 if (blob_hf == hf_ntlmssp_auth_lmresponse &&
969 !(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)))
971 proto_tree_add_item (ntlmssp_tree,
972 hf_ntlmssp_ntlm_client_challenge,
973 tvb, blob_offset, 8, ENC_NA);
976 expert_add_info_format(NULL, tf, PI_WARN, PI_UNDECODED,
977 "NTLM v2 key is %d bytes long, too big for our %d buffer", blob_length, MAX_BLOB_SIZE);
981 /* If we are dissecting the NTLM response and it is a NTLMv2
982 response call the appropriate dissector. */
984 if (blob_hf == hf_ntlmssp_auth_ntresponse && blob_length > 24)
986 proto_tree_add_item (ntlmssp_tree,
987 hf_ntlmssp_ntlm_client_challenge,
988 tvb, blob_offset+32, 8, ENC_NA);
989 dissect_ntlmv2_response(tvb, tree, blob_offset, blob_length);
996 dissect_ntlmssp_negotiate_flags (tvbuff_t *tvb, int offset,
997 proto_tree *ntlmssp_tree,
998 guint32 negotiate_flags)
1000 proto_tree *negotiate_flags_tree = NULL;
1001 proto_item *tf = NULL;
1004 tf = proto_tree_add_uint (ntlmssp_tree,
1005 hf_ntlmssp_negotiate_flags,
1006 tvb, offset, 4, negotiate_flags);
1007 negotiate_flags_tree = proto_item_add_subtree (tf, ett_ntlmssp_negotiate_flags);
1010 proto_tree_add_boolean (negotiate_flags_tree,
1011 hf_ntlmssp_negotiate_flags_80000000,
1012 tvb, offset, 4, negotiate_flags);
1013 proto_tree_add_boolean (negotiate_flags_tree,
1014 hf_ntlmssp_negotiate_flags_40000000,
1015 tvb, offset, 4, negotiate_flags);
1016 proto_tree_add_boolean (negotiate_flags_tree,
1017 hf_ntlmssp_negotiate_flags_20000000,
1018 tvb, offset, 4, negotiate_flags);
1019 proto_tree_add_boolean (negotiate_flags_tree,
1020 hf_ntlmssp_negotiate_flags_10000000,
1021 tvb, offset, 4, negotiate_flags);
1022 proto_tree_add_boolean (negotiate_flags_tree,
1023 hf_ntlmssp_negotiate_flags_8000000,
1024 tvb, offset, 4, negotiate_flags);
1025 proto_tree_add_boolean (negotiate_flags_tree,
1026 hf_ntlmssp_negotiate_flags_4000000,
1027 tvb, offset, 4, negotiate_flags);
1028 proto_tree_add_boolean (negotiate_flags_tree,
1029 hf_ntlmssp_negotiate_flags_2000000,
1030 tvb, offset, 4, negotiate_flags);
1031 proto_tree_add_boolean (negotiate_flags_tree,
1032 hf_ntlmssp_negotiate_flags_1000000,
1033 tvb, offset, 4, negotiate_flags);
1034 proto_tree_add_boolean (negotiate_flags_tree,
1035 hf_ntlmssp_negotiate_flags_800000,
1036 tvb, offset, 4, negotiate_flags);
1037 proto_tree_add_boolean (negotiate_flags_tree,
1038 hf_ntlmssp_negotiate_flags_400000,
1039 tvb, offset, 4, negotiate_flags);
1040 proto_tree_add_boolean (negotiate_flags_tree,
1041 hf_ntlmssp_negotiate_flags_200000,
1042 tvb, offset, 4, negotiate_flags);
1043 proto_tree_add_boolean (negotiate_flags_tree,
1044 hf_ntlmssp_negotiate_flags_100000,
1045 tvb, offset, 4, negotiate_flags);
1046 proto_tree_add_boolean (negotiate_flags_tree,
1047 hf_ntlmssp_negotiate_flags_80000,
1048 tvb, offset, 4, negotiate_flags);
1049 proto_tree_add_boolean (negotiate_flags_tree,
1050 hf_ntlmssp_negotiate_flags_40000,
1051 tvb, offset, 4, negotiate_flags);
1052 proto_tree_add_boolean (negotiate_flags_tree,
1053 hf_ntlmssp_negotiate_flags_20000,
1054 tvb, offset, 4, negotiate_flags);
1055 proto_tree_add_boolean (negotiate_flags_tree,
1056 hf_ntlmssp_negotiate_flags_10000,
1057 tvb, offset, 4, negotiate_flags);
1058 proto_tree_add_boolean (negotiate_flags_tree,
1059 hf_ntlmssp_negotiate_flags_8000,
1060 tvb, offset, 4, negotiate_flags);
1061 proto_tree_add_boolean (negotiate_flags_tree,
1062 hf_ntlmssp_negotiate_flags_4000,
1063 tvb, offset, 4, negotiate_flags);
1064 proto_tree_add_boolean (negotiate_flags_tree,
1065 hf_ntlmssp_negotiate_flags_2000,
1066 tvb, offset, 4, negotiate_flags);
1067 proto_tree_add_boolean (negotiate_flags_tree,
1068 hf_ntlmssp_negotiate_flags_1000,
1069 tvb, offset, 4, negotiate_flags);
1070 proto_tree_add_boolean (negotiate_flags_tree,
1071 hf_ntlmssp_negotiate_flags_800,
1072 tvb, offset, 4, negotiate_flags);
1073 proto_tree_add_boolean (negotiate_flags_tree,
1074 hf_ntlmssp_negotiate_flags_400,
1075 tvb, offset, 4, negotiate_flags);
1076 proto_tree_add_boolean (negotiate_flags_tree,
1077 hf_ntlmssp_negotiate_flags_200,
1078 tvb, offset, 4, negotiate_flags);
1079 proto_tree_add_boolean (negotiate_flags_tree,
1080 hf_ntlmssp_negotiate_flags_100,
1081 tvb, offset, 4, negotiate_flags);
1082 proto_tree_add_boolean (negotiate_flags_tree,
1083 hf_ntlmssp_negotiate_flags_80,
1084 tvb, offset, 4, negotiate_flags);
1085 proto_tree_add_boolean (negotiate_flags_tree,
1086 hf_ntlmssp_negotiate_flags_40,
1087 tvb, offset, 4, negotiate_flags);
1088 proto_tree_add_boolean (negotiate_flags_tree,
1089 hf_ntlmssp_negotiate_flags_20,
1090 tvb, offset, 4, negotiate_flags);
1091 proto_tree_add_boolean (negotiate_flags_tree,
1092 hf_ntlmssp_negotiate_flags_10,
1093 tvb, offset, 4, negotiate_flags);
1094 proto_tree_add_boolean (negotiate_flags_tree,
1095 hf_ntlmssp_negotiate_flags_08,
1096 tvb, offset, 4, negotiate_flags);
1097 proto_tree_add_boolean (negotiate_flags_tree,
1098 hf_ntlmssp_negotiate_flags_04,
1099 tvb, offset, 4, negotiate_flags);
1100 proto_tree_add_boolean (negotiate_flags_tree,
1101 hf_ntlmssp_negotiate_flags_02,
1102 tvb, offset, 4, negotiate_flags);
1103 proto_tree_add_boolean (negotiate_flags_tree,
1104 hf_ntlmssp_negotiate_flags_01,
1105 tvb, offset, 4, negotiate_flags);
1107 return (offset + 4);
1110 /* Dissect "version" */
1113 0 Major Version Number 1 byte
1114 1 Minor Version Number 1 byte
1115 2 Build Number short(LE)
1116 3 (Reserved) 3 bytes
1117 4 NTLM Current Revision 1 byte
1121 dissect_ntlmssp_version(tvbuff_t *tvb, int offset,
1122 proto_tree *ntlmssp_tree)
1126 proto_tree *version_tree;
1127 tf = proto_tree_add_none_format(ntlmssp_tree, hf_ntlmssp_version, tvb, offset, 8,
1128 "Version %u.%u (Build %u); NTLM Current Revision %u",
1129 tvb_get_guint8(tvb, offset),
1130 tvb_get_guint8(tvb, offset+1),
1131 tvb_get_letohs(tvb, offset+2),
1132 tvb_get_guint8(tvb, offset+7));
1133 version_tree = proto_item_add_subtree (tf, ett_ntlmssp_version);
1134 proto_tree_add_item(version_tree, hf_ntlmssp_version_major , tvb, offset , 1, ENC_NA);
1135 proto_tree_add_item(version_tree, hf_ntlmssp_version_minor , tvb, offset+1, 1, ENC_NA);
1136 proto_tree_add_item(version_tree, hf_ntlmssp_version_build_number , tvb, offset+2, 2, ENC_LITTLE_ENDIAN);
1137 proto_tree_add_item(version_tree, hf_ntlmssp_version_ntlm_current_revision, tvb, offset+7, 1, ENC_NA);
1142 /* Dissect a NTLM response. This is documented at
1143 http://ubiqx.org/cifs/SMB.html#SMB.8, para 2.8.5.3 */
1145 /* Attribute types */
1147 * XXX - the davenport document says that a type of 5 has been seen,
1148 * "apparently containing the 'parent' DNS domain for servers in
1150 * XXX: MS-NLMP info is newer than Davenport info;
1151 * The attribute type list and the attribute names below are
1152 * based upon MS-NLMP.
1155 #define NTLM_TARGET_INFO_END 0x0000
1156 #define NTLM_TARGET_INFO_NB_COMPUTER_NAME 0x0001
1157 #define NTLM_TARGET_INFO_NB_DOMAIN_NAME 0x0002
1158 #define NTLM_TARGET_INFO_DNS_COMPUTER_NAME 0x0003
1159 #define NTLM_TARGET_INFO_DNS_DOMAIN_NAME 0x0004
1160 #define NTLM_TARGET_INFO_DNS_TREE_NAME 0x0005
1161 #define NTLM_TARGET_INFO_FLAGS 0x0006
1162 #define NTLM_TARGET_INFO_TIMESTAMP 0x0007
1163 #define NTLM_TARGET_INFO_RESTRICTIONS 0x0008
1164 #define NTLM_TARGET_INFO_TARGET_NAME 0x0009
1165 #define NTLM_TARGET_INFO_CHANNEL_BINDINGS 0x000A
1167 static const value_string ntlm_name_types[] = {
1168 { NTLM_TARGET_INFO_END, "End of list" },
1169 { NTLM_TARGET_INFO_NB_COMPUTER_NAME, "NetBIOS computer name" },
1170 { NTLM_TARGET_INFO_NB_DOMAIN_NAME, "NetBIOS domain name" },
1171 { NTLM_TARGET_INFO_DNS_COMPUTER_NAME, "DNS computer name" },
1172 { NTLM_TARGET_INFO_DNS_DOMAIN_NAME, "DNS domain name" },
1173 { NTLM_TARGET_INFO_DNS_TREE_NAME, "DNS tree name" },
1174 { NTLM_TARGET_INFO_FLAGS, "Flags" },
1175 { NTLM_TARGET_INFO_TIMESTAMP, "Timestamp" },
1176 { NTLM_TARGET_INFO_RESTRICTIONS, "Restrictions" },
1177 { NTLM_TARGET_INFO_TARGET_NAME, "Target Name"},
1178 { NTLM_TARGET_INFO_CHANNEL_BINDINGS, "Channel Bindings"},
1182 /* The following *must* match the order of the list of attribute types */
1183 /* Assumption: values in the list are a sequence starting with 0 and */
1184 /* with no gaps allowing a direct access of the array by attribute type */
1185 static int *ntlmssp_hf_challenge_target_info_hf_ptr_array[] = {
1186 &hf_ntlmssp_challenge_target_info_end,
1187 &hf_ntlmssp_challenge_target_info_nb_computer_name,
1188 &hf_ntlmssp_challenge_target_info_nb_domain_name,
1189 &hf_ntlmssp_challenge_target_info_dns_computer_name,
1190 &hf_ntlmssp_challenge_target_info_dns_domain_name,
1191 &hf_ntlmssp_challenge_target_info_dns_tree_name,
1192 &hf_ntlmssp_challenge_target_info_flags,
1193 &hf_ntlmssp_challenge_target_info_timestamp,
1194 &hf_ntlmssp_challenge_target_info_restrictions,
1195 &hf_ntlmssp_challenge_target_info_target_name,
1196 &hf_ntlmssp_challenge_target_info_channel_bindings
1199 static int *ntlmssp_hf_ntlmv2_response_hf_ptr_array[] = {
1200 &hf_ntlmssp_ntlmv2_response_end,
1201 &hf_ntlmssp_ntlmv2_response_nb_computer_name,
1202 &hf_ntlmssp_ntlmv2_response_nb_domain_name,
1203 &hf_ntlmssp_ntlmv2_response_dns_computer_name,
1204 &hf_ntlmssp_ntlmv2_response_dns_domain_name,
1205 &hf_ntlmssp_ntlmv2_response_dns_tree_name,
1206 &hf_ntlmssp_ntlmv2_response_flags,
1207 &hf_ntlmssp_ntlmv2_response_timestamp,
1208 &hf_ntlmssp_ntlmv2_response_restrictions,
1209 &hf_ntlmssp_ntlmv2_response_target_name,
1210 &hf_ntlmssp_ntlmv2_response_channel_bindings
1213 typedef struct _tif {
1216 int *hf_item_length;
1217 int **hf_attr_array_p;
1220 static tif_t ntlmssp_challenge_target_info_tif = {
1221 &ett_ntlmssp_challenge_target_info_item,
1222 &hf_ntlmssp_challenge_target_info_item_type,
1223 &hf_ntlmssp_challenge_target_info_item_len,
1224 ntlmssp_hf_challenge_target_info_hf_ptr_array
1227 static tif_t ntlmssp_ntlmv2_response_tif = {
1228 &ett_ntlmssp_ntlmv2_response_item,
1229 &hf_ntlmssp_ntlmv2_response_item_type,
1230 &hf_ntlmssp_ntlmv2_response_item_len,
1231 ntlmssp_hf_ntlmv2_response_hf_ptr_array
1235 dissect_ntlmssp_target_info_list(tvbuff_t *tvb, proto_tree *tree,
1236 guint32 target_info_offset, guint16 target_info_length,
1239 guint32 item_offset;
1241 guint16 item_length;
1244 /* Now enumerate through the individual items in the list */
1245 item_offset = target_info_offset;
1247 while (item_offset < (target_info_offset + target_info_length)) {
1248 proto_item *target_info_tf;
1249 proto_tree *target_info_tree;
1250 guint32 content_offset;
1251 guint16 content_length;
1252 guint32 type_offset;
1255 int **hf_array_p = tif_p->hf_attr_array_p;
1258 type_offset = item_offset;
1259 item_type = tvb_get_letohs(tvb, type_offset);
1261 /* Content length */
1262 len_offset = type_offset + 2;
1263 content_length = tvb_get_letohs(tvb, len_offset);
1266 content_offset = len_offset + 2;
1267 item_length = content_length + 4;
1269 target_info_tf = proto_tree_add_text(tree, tvb, item_offset, item_length, "Attribute: %s",
1270 val_to_str(item_type, ntlm_name_types, "Unknown (%d)"));
1272 target_info_tree = proto_item_add_subtree (target_info_tf, *tif_p->ett);
1273 proto_tree_add_item (target_info_tree, *tif_p->hf_item_type, tvb, type_offset, 2, ENC_LITTLE_ENDIAN);
1274 proto_tree_add_item (target_info_tree, *tif_p->hf_item_length, tvb, len_offset, 2, ENC_LITTLE_ENDIAN);
1276 switch (item_type) {
1277 case NTLM_TARGET_INFO_NB_COMPUTER_NAME:
1278 case NTLM_TARGET_INFO_NB_DOMAIN_NAME:
1279 case NTLM_TARGET_INFO_DNS_COMPUTER_NAME:
1280 case NTLM_TARGET_INFO_DNS_DOMAIN_NAME:
1281 case NTLM_TARGET_INFO_DNS_TREE_NAME:
1282 case NTLM_TARGET_INFO_TARGET_NAME:
1283 if (content_length > 0) {
1286 text = tvb_get_ephemeral_unicode_string(tvb, content_offset, content_length, ENC_LITTLE_ENDIAN);
1287 proto_tree_add_string(target_info_tree, *hf_array_p[item_type],
1288 tvb, content_offset, content_length, text);
1289 proto_item_append_text(target_info_tf, ": %s", text);
1293 case NTLM_TARGET_INFO_FLAGS:
1294 proto_tree_add_item(target_info_tree, *hf_array_p[item_type],
1295 tvb, content_offset, content_length, ENC_LITTLE_ENDIAN);
1298 case NTLM_TARGET_INFO_TIMESTAMP:
1299 dissect_nt_64bit_time(tvb, target_info_tree, content_offset, *hf_array_p[item_type]);
1302 case NTLM_TARGET_INFO_RESTRICTIONS:
1303 case NTLM_TARGET_INFO_CHANNEL_BINDINGS:
1304 proto_tree_add_item(target_info_tree, *hf_array_p[item_type],
1305 tvb, content_offset, content_length, ENC_NA);
1312 item_offset += item_length;
1317 dissect_ntlmv2_response(tvbuff_t *tvb, proto_tree *tree, int offset, int len)
1319 proto_item *ntlmv2_item = NULL;
1320 proto_tree *ntlmv2_tree = NULL;
1323 /* Dissect NTLMv2 bits&pieces */
1324 orig_offset = offset;
1327 ntlmv2_item = proto_tree_add_item(
1328 tree, hf_ntlmssp_ntlmv2_response, tvb,
1329 offset, len, ENC_NA);
1330 ntlmv2_tree = proto_item_add_subtree(
1331 ntlmv2_item, ett_ntlmssp_ntlmv2_response);
1334 proto_tree_add_item(
1335 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_hmac, tvb,
1336 offset, 16, ENC_NA);
1340 proto_tree_add_item(
1341 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_header, tvb,
1342 offset, 4, ENC_LITTLE_ENDIAN);
1346 proto_tree_add_item(
1347 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_reserved, tvb,
1348 offset, 4, ENC_LITTLE_ENDIAN);
1352 offset = dissect_nt_64bit_time(
1353 tvb, ntlmv2_tree, offset, hf_ntlmssp_ntlmv2_response_time);
1355 proto_tree_add_item(
1356 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_chal, tvb,
1361 proto_tree_add_item(
1362 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_unknown, tvb,
1363 offset, 4, ENC_LITTLE_ENDIAN);
1367 /* Variable length list of attributes */
1369 * XXX - Windows puts one or more sets of 4 bytes of additional stuff (all zeros ?)
1370 * at the end of the attributes.
1371 * Samba's smbclient doesn't.
1372 * Both of them appear to be able to connect to W2K SMB
1374 * The additional stuff will be dissected as extra "end" attributes.
1377 dissect_ntlmssp_target_info_list(tvb, ntlmv2_tree,
1378 offset, len - (offset - orig_offset),
1379 &ntlmssp_ntlmv2_response_tif);
1384 /* tapping into ntlmssph not yet implemented */
1386 dissect_ntlmssp_negotiate (tvbuff_t *tvb, int offset, proto_tree *ntlmssp_tree, ntlmssp_header_t *ntlmssph _U_)
1388 guint32 negotiate_flags;
1394 /* NTLMSSP Negotiate Flags */
1395 negotiate_flags = tvb_get_letohl (tvb, offset);
1396 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
1400 * XXX - the davenport document says that these might not be
1401 * sent at all, presumably meaning the length of the message
1402 * isn't enough to contain them.
1404 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
1405 hf_ntlmssp_negotiate_domain,
1406 &data_start, &data_end, NULL);
1408 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
1409 hf_ntlmssp_negotiate_workstation,
1410 &item_start, &item_end, NULL);
1411 data_start = MIN(data_start, item_start);
1412 data_end = MAX(data_end, item_end);
1414 /* If there are more bytes before the data block dissect a version field
1415 if NTLMSSP_NEGOTIATE_VERSION is set in the flags (see MS-NLMP) */
1416 if (offset < data_start) {
1417 if (negotiate_flags & NTLMSSP_NEGOTIATE_VERSION)
1418 offset = dissect_ntlmssp_version(tvb, offset, ntlmssp_tree);
1425 dissect_ntlmssp_challenge_target_info_blob (tvbuff_t *tvb, int offset,
1426 proto_tree *ntlmssp_tree,
1429 guint16 challenge_target_info_length = tvb_get_letohs(tvb, offset);
1430 guint16 challenge_target_info_maxlen = tvb_get_letohs(tvb, offset+2);
1431 guint32 challenge_target_info_offset = tvb_get_letohl(tvb, offset+4);
1432 proto_item *tf = NULL;
1433 proto_tree *challenge_target_info_tree = NULL;
1435 /* the target info list is just a blob */
1436 if (0 == challenge_target_info_length) {
1437 *end = (challenge_target_info_offset > ((guint)offset)+8 ? challenge_target_info_offset : ((guint)offset)+8);
1439 proto_tree_add_text(ntlmssp_tree, tvb, offset, 8,
1440 "Target Info List: Empty");
1445 tf = proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_challenge_target_info, tvb,
1446 challenge_target_info_offset, challenge_target_info_length, ENC_NA);
1447 challenge_target_info_tree = proto_item_add_subtree(tf, ett_ntlmssp_challenge_target_info);
1449 proto_tree_add_uint(challenge_target_info_tree, hf_ntlmssp_challenge_target_info_len,
1450 tvb, offset, 2, challenge_target_info_length);
1452 proto_tree_add_uint(challenge_target_info_tree, hf_ntlmssp_challenge_target_info_maxlen,
1453 tvb, offset, 2, challenge_target_info_maxlen);
1455 proto_tree_add_uint(challenge_target_info_tree, hf_ntlmssp_challenge_target_info_offset,
1456 tvb, offset, 4, challenge_target_info_offset);
1459 dissect_ntlmssp_target_info_list(tvb, challenge_target_info_tree,
1460 challenge_target_info_offset, challenge_target_info_length,
1461 &ntlmssp_challenge_target_info_tif);
1463 *end = challenge_target_info_offset + challenge_target_info_length;
1467 /* tapping into ntlmssph not yet implemented */
1469 dissect_ntlmssp_challenge (tvbuff_t *tvb, packet_info *pinfo, int offset,
1470 proto_tree *ntlmssp_tree, ntlmssp_header_t *ntlmssph _U_)
1472 guint32 negotiate_flags;
1473 int item_start, item_end;
1474 int data_start, data_end; /* MIN and MAX seen */
1475 guint8 clientkey[NTLMSSP_KEY_LEN]; /* NTLMSSP cipher key for client */
1476 guint8 serverkey[NTLMSSP_KEY_LEN]; /* NTLMSSP cipher key for server*/
1477 ntlmssp_info *conv_ntlmssp_info = NULL;
1478 conversation_t *conversation;
1479 gboolean unicode_strings = FALSE;
1481 guint8 sspkey[NTLMSSP_KEY_LEN]; /* NTLMSSP cipher key */
1482 int ssp_key_len; /* Either 8 or 16 (40 bit or 128) */
1484 /* need to find unicode flag */
1485 negotiate_flags = tvb_get_letohl (tvb, offset+8);
1486 if (negotiate_flags & NTLMSSP_NEGOTIATE_UNICODE)
1487 unicode_strings = TRUE;
1491 * XXX - the davenport document (and MS-NLMP) calls this "Target Name",
1492 * presumably because non-domain targets are supported.
1493 * XXX - Original name "domain" changed to "target_name" to match MS-NLMP
1495 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, unicode_strings,
1496 hf_ntlmssp_challenge_target_name,
1497 &item_start, &item_end, NULL);
1498 data_start = item_start;
1499 data_end = item_end;
1501 /* NTLMSSP Negotiate Flags */
1502 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
1505 /* NTLMSSP NT Lan Manager Challenge */
1506 proto_tree_add_item (ntlmssp_tree,
1507 hf_ntlmssp_ntlm_server_challenge,
1508 tvb, offset, 8, ENC_NA);
1511 * Store the flags and the RC4 state information with the conversation,
1512 * as they're needed in order to dissect subsequent messages.
1514 conversation = find_or_create_conversation(pinfo);
1516 tvb_memcpy(tvb, tmp, offset, 8); /* challenge */
1517 /* We can face more than one NTLM exchange over the same couple of IP and ports ...*/
1518 conv_ntlmssp_info = conversation_get_proto_data(conversation, proto_ntlmssp);
1519 /* XXX: The following code is (re)executed every time a particular frame is dissected
1520 * (in whatever order). Thus it seems to me that "multiple exchanges" might not be
1521 * handled well depending on the order that frames are visited after the initial dissection.
1523 if (!conv_ntlmssp_info || memcmp(tmp, conv_ntlmssp_info->server_challenge, 8) != 0) {
1524 conv_ntlmssp_info = se_alloc(sizeof(ntlmssp_info));
1525 /* Insert the flags into the conversation */
1526 conv_ntlmssp_info->flags = negotiate_flags;
1527 /* Insert the RC4 state information into the conversation */
1528 tvb_memcpy(tvb, conv_ntlmssp_info->server_challenge, offset, 8);
1529 conv_ntlmssp_info->is_auth_ntlm_v2 = 0;
1530 /* Between the challenge and the user provided password, we can build the
1531 NTLMSSP key and initialize the cipher if we are not in EXTENDED SECURITY
1532 in this case we need the client challenge as well*/
1533 /* BTW this is true just if we are in LM Authentification if not the logic is a bit different.
1534 * Right now it's not very clear what is LM Authentification it __seems__ to be when
1535 * NEGOTIATE NT ONLY is not set and NEGOSIATE EXTENDED SECURITY is not set as well*/
1536 if (!(conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY))
1538 conv_ntlmssp_info->rc4_state_initialized = 0;
1539 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);
1540 if (memcmp(sspkey, gbl_zeros, NTLMSSP_KEY_LEN) != 0) {
1541 get_sealing_rc4key(sspkey, conv_ntlmssp_info->flags, &ssp_key_len, clientkey, serverkey);
1542 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_client, sspkey, ssp_key_len);
1543 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_server, sspkey, ssp_key_len);
1544 conv_ntlmssp_info->server_dest_port = pinfo->destport;
1545 conv_ntlmssp_info->rc4_state_initialized = 1;
1549 conversation_add_proto_data(conversation, proto_ntlmssp, conv_ntlmssp_info);
1553 /* If no more bytes (ie: no "reserved", ...) before start of data block, then return */
1554 /* XXX: According to Davenport "This form is seen in older Win9x-based systems" */
1555 /* Also: I've seen a capture with an HTTP CONNECT proxy-authentication */
1556 /* message wherein the challenge from the proxy has this form. */
1557 if (offset >= data_start) {
1561 /* Reserved (function not completely known) */
1563 * XXX - SSP key? The davenport document says
1565 * The context field is typically populated when Negotiate Local
1566 * Call is set. It contains an SSPI context handle, which allows
1567 * the client to "short-circuit" authentication and effectively
1568 * circumvent responding to the challenge. Physically, the context
1569 * is two long values. This is covered in greater detail later,
1570 * in the "Local Authentication" section.
1572 * It also says that that information may be omitted.
1574 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_reserved,
1575 tvb, offset, 8, ENC_NA);
1579 * The presence or absence of this field is not obviously correlated
1580 * with any flags in the previous NEGOTIATE message or in this
1581 * message (other than the "Workstation Supplied" and "Domain
1582 * Supplied" flags in the NEGOTIATE message, at least in the capture
1583 * I've seen - but those also correlate with the presence of workstation
1584 * and domain name fields, so it doesn't seem to make sense that they
1585 * actually *indicate* whether the subsequent CHALLENGE has an
1588 if (offset < data_start) {
1589 offset = dissect_ntlmssp_challenge_target_info_blob(tvb, offset, ntlmssp_tree, &item_end);
1590 /* XXX: This code assumes that the address list in the data block */
1591 /* is always after the target name. Is this OK ? */
1592 data_end = MAX(data_end, item_end);
1595 /* If there are more bytes before the data block dissect a version field
1596 if NTLMSSP_NEGOTIATE_VERSION is set in the flags (see MS-NLMP) */
1597 if (offset < data_start) {
1598 if (negotiate_flags & NTLMSSP_NEGOTIATE_VERSION)
1599 offset = dissect_ntlmssp_version(tvb, offset, ntlmssp_tree);
1602 return MAX(offset, data_end);
1606 dissect_ntlmssp_auth (tvbuff_t *tvb, packet_info *pinfo, int offset,
1607 proto_tree *ntlmssp_tree, ntlmssp_header_t *ntlmssph)
1609 int item_start, item_end;
1610 int data_start, data_end = 0;
1611 guint32 negotiate_flags;
1612 guint8 sspkey[NTLMSSP_KEY_LEN]; /* exported session key */
1613 guint8 clientkey[NTLMSSP_KEY_LEN]; /* NTLMSSP cipher key for client */
1614 guint8 serverkey[NTLMSSP_KEY_LEN]; /* NTLMSSP cipher key for server*/
1615 guint8 encryptedsessionkey[NTLMSSP_KEY_LEN];
1616 ntlmssp_blob sessionblob;
1617 gboolean unicode_strings = FALSE;
1618 ntlmssp_info *conv_ntlmssp_info;
1619 conversation_t *conversation;
1623 * Get flag info from the original negotiate message, if any.
1624 * This is because the flag information is sometimes missing from
1625 * the AUTHENTICATE message, so we can't figure out whether
1626 * strings are Unicode or not by looking at *our* flags.
1627 * XXX it seems it's more from the CHALLENGE message, which is more clever in fact
1628 * because the server can change some flags.
1629 * But according to MS NTLMSSP doc it's not that simple.
1630 * In case of Conection less mode AUTHENTICATE flags should be used because they
1631 * reprensent the choice of the client after having been informed of options of the
1632 * server in the CHALLENGE message.
1633 * In Connection mode then the CHALLENGE flags should (must ?) be used
1634 * XXX: MS-NLMP says the flag field in the AUTHENTICATE message "contains the set of bit
1635 * flags (section 2.2.2.5) negotiated in the previous messages."
1636 * I read that to mean that the flags for in connection-mode AUTHENTICATE also represent
1637 * the choice of the client (for the flags which are negotiated).
1638 * XXX: In the absence of CHALLENGE flags, as a last resort we'll use the flags
1639 * (if available) from this AUTHENTICATE message.
1640 * I've seen a capture which does an HTTP CONNECT which:
1641 * - has the NEGOTIATE & CHALLENGE messages in one TCP connection;
1642 * - has the AUTHENTICATE message in a second TCP connection;
1643 * (The authentication aparently succeeded).
1645 conv_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1646 if (conv_ntlmssp_info == NULL) {
1648 * There isn't any. Is there any from this conversation? If so,
1649 * it means this is the first time we've dissected this frame, so
1650 * we should give it flag info.
1652 /* XXX: Create conv_ntlmssp_info & etc if no previous CHALLENGE seen */
1653 /* so we'll have a place to store flags. */
1654 /* This is a bit brute-force but looks like it will be OK. */
1655 conversation = find_or_create_conversation(pinfo);
1656 conv_ntlmssp_info = conversation_get_proto_data(conversation, proto_ntlmssp);
1657 if (conv_ntlmssp_info == NULL) {
1658 conv_ntlmssp_info = se_alloc0(sizeof(ntlmssp_info));
1659 conversation_add_proto_data(conversation, proto_ntlmssp, conv_ntlmssp_info);
1661 /* XXX: The *conv_ntlmssp_info struct attached to the frame is the
1662 same as the one attached to the conversation. That is: *both* point to
1663 the exact same struct in memory. Is this what is indended ? */
1664 p_add_proto_data(pinfo->fd, proto_ntlmssp, conv_ntlmssp_info);
1667 if (conv_ntlmssp_info != NULL) {
1668 if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_UNICODE)
1669 unicode_strings = TRUE;
1673 * Sometimes the session key and flags are missing.
1674 * Sometimes the session key is present but the flags are missing.
1675 * XXX Who stay so ? Reading spec I would rather say the opposite: flags are
1676 * always present, session information are always there as well but sometime
1677 * session information could be null (in case of no session)
1678 * Sometimes they're both present.
1680 * This does not correlate with any flags in the previous CHALLENGE
1681 * message, and only correlates with "Negotiate Unicode", "Workstation
1682 * Supplied", and "Domain Supplied" in the NEGOTIATE message - but
1683 * those don't make sense as flags to use to determine this.
1685 * So we check all of the descriptors to figure out where the data
1686 * area begins, and if the session key or the flags would be in the
1687 * middle of the data area, we assume the field in question is
1690 * XXX - Reading Davenport and MS-NLMP: as I see it the possibilities are:
1691 * a. No session-key; no flags; no version ("Win9x")
1692 * b. Session-key & flags.
1693 * c. Session-key, flags & version.
1694 * In cases b and c the session key may be "null".
1698 /* Lan Manager response */
1699 data_start = tvb_get_letohl(tvb, offset+4);
1700 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
1701 hf_ntlmssp_auth_lmresponse,
1703 conv_ntlmssp_info == NULL ? NULL :
1704 &conv_ntlmssp_info->lm_response);
1705 data_end = MAX(data_end, item_end);
1708 item_start = tvb_get_letohl(tvb, offset+4);
1709 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
1710 hf_ntlmssp_auth_ntresponse,
1712 conv_ntlmssp_info == NULL ? NULL :
1713 &conv_ntlmssp_info->ntlm_response);
1714 if (conv_ntlmssp_info != NULL && conv_ntlmssp_info->ntlm_response.length > 24) {
1715 memcpy(conv_ntlmssp_info->client_challenge, conv_ntlmssp_info->ntlm_response.contents+32, 8);
1717 data_start = MIN(data_start, item_start);
1718 data_end = MAX(data_end, item_end);
1719 if (conv_ntlmssp_info != NULL)
1721 if (conv_ntlmssp_info->ntlm_response.length > 24)
1723 conv_ntlmssp_info->is_auth_ntlm_v2 = 1;
1727 conv_ntlmssp_info->is_auth_ntlm_v2 = 0;
1732 item_start = tvb_get_letohl(tvb, offset+4);
1733 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
1735 hf_ntlmssp_auth_domain,
1736 &item_start, &item_end, &(ntlmssph->domain_name));
1737 /*ntlmssph->domain_name_len = item_end-item_start;*/
1738 data_start = MIN(data_start, item_start);
1739 data_end = MAX(data_end, item_end);
1742 item_start = tvb_get_letohl(tvb, offset+4);
1743 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
1745 hf_ntlmssp_auth_username,
1746 &item_start, &item_end, &(ntlmssph->acct_name));
1747 /*ntlmssph->acct_name_len = item_end-item_start;*/
1748 data_start = MIN(data_start, item_start);
1749 data_end = MAX(data_end, item_end);
1751 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ", ", "User: %s\\%s",
1752 ntlmssph->domain_name, ntlmssph->acct_name);
1755 item_start = tvb_get_letohl(tvb, offset+4);
1756 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
1758 hf_ntlmssp_auth_hostname,
1759 &item_start, &item_end, &(ntlmssph->host_name));
1760 data_start = MIN(data_start, item_start);
1761 data_end = MAX(data_end, item_end);
1763 memset(sessionblob.contents, 0, MAX_BLOB_SIZE);
1764 sessionblob.length = 0;
1765 if (offset < data_start) {
1767 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
1768 hf_ntlmssp_auth_sesskey,
1769 &item_end, &sessionblob);
1770 data_end = MAX(data_end, item_end);
1773 if (offset < data_start) {
1774 /* NTLMSSP Negotiate Flags */
1775 negotiate_flags = tvb_get_letohl (tvb, offset);
1776 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
1778 /* If no previous flags seen (ie: no previous CHALLENGE) use flags
1779 from the AUTHENTICATE message).
1780 Assumption: (flags == 0) means flags not previously seen */
1781 if ((conv_ntlmssp_info != NULL) && (conv_ntlmssp_info->flags == 0)) {
1782 conv_ntlmssp_info->flags = negotiate_flags;
1785 negotiate_flags = 0;
1787 /* If there are more bytes before the data block dissect a version field
1788 if NTLMSSP_NEGOTIATE_VERSION is set in the flags (see MS-NLMP) */
1789 if (offset < data_start) {
1790 if (negotiate_flags & NTLMSSP_NEGOTIATE_VERSION)
1791 offset = dissect_ntlmssp_version(tvb, offset, ntlmssp_tree);
1794 /* If there are still more bytes before the data block dissect an MIC (message integrity_code) field */
1796 if (offset < data_start) {
1797 proto_tree_add_item(ntlmssp_tree, hf_ntlmssp_message_integrity_code, tvb, offset, 16, ENC_NA);
1801 if (sessionblob.length > NTLMSSP_KEY_LEN) {
1802 expert_add_info_format(pinfo, NULL, PI_WARN, PI_UNDECODED, "Session blob length too long: %u", sessionblob.length);
1803 } else if (sessionblob.length != 0) {
1804 memcpy(encryptedsessionkey, sessionblob.contents, sessionblob.length);
1805 /* Try to attach to an existing conversation if not then it's useless to try to do so
1806 * because we are missing important information (ie. server challenge)
1808 if (conv_ntlmssp_info) {
1809 /* If we are in EXTENDED SECURITY then we can now initialize cipher */
1810 if ((conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY))
1812 conv_ntlmssp_info->rc4_state_initialized = 0;
1813 if (conv_ntlmssp_info->is_auth_ntlm_v2) {
1814 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);
1818 memcpy(conv_ntlmssp_info->client_challenge, conv_ntlmssp_info->lm_response.contents, 8);
1819 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);
1821 /* ssp is the exported session key */
1822 if (memcmp(sspkey, gbl_zeros, NTLMSSP_KEY_LEN) != 0) {
1823 get_sealing_rc4key(sspkey, conv_ntlmssp_info->flags, &ssp_key_len, clientkey, serverkey);
1824 get_siging_key((guint8*)&conv_ntlmssp_info->sign_key_server, (guint8*)&conv_ntlmssp_info->sign_key_client, sspkey, ssp_key_len);
1825 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_server, serverkey, ssp_key_len);
1826 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_client, clientkey, ssp_key_len);
1827 conv_ntlmssp_info->server_dest_port = pinfo->destport;
1828 conv_ntlmssp_info->rc4_state_initialized = 1;
1833 return MAX(offset, data_end);
1837 get_sign_key(packet_info *pinfo, int cryptpeer)
1839 conversation_t *conversation;
1840 ntlmssp_info *conv_ntlmssp_info;
1842 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1843 pinfo->ptype, pinfo->srcport,
1844 pinfo->destport, 0);
1845 if (conversation == NULL) {
1846 /* We don't have a conversation. In this case, stop processing
1847 because we do not have enough info to decrypt the payload */
1851 /* We have a conversation, check for encryption state */
1852 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1854 if (conv_ntlmssp_info == NULL) {
1855 /* No encryption state tied to the conversation. Therefore, we
1856 cannot decrypt the payload */
1860 /* We have the encryption state in the conversation. So return the
1861 crypt state tied to the requested peer
1863 if (cryptpeer == 1) {
1864 return (guint8*)&conv_ntlmssp_info->sign_key_client;
1866 return (guint8*)&conv_ntlmssp_info->sign_key_server;
1873 * Get the encryption state tied to this conversation. cryptpeer indicates
1874 * whether to retrieve the client key (1) or the server key (0)
1876 static rc4_state_struct *
1877 get_encrypted_state(packet_info *pinfo, int cryptpeer)
1879 conversation_t *conversation;
1880 ntlmssp_info *conv_ntlmssp_info;
1882 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1883 pinfo->ptype, pinfo->srcport,
1884 pinfo->destport, 0);
1885 if (conversation == NULL) {
1886 /* We don't have a conversation. In this case, stop processing
1887 because we do not have enough info to decrypt the payload */
1891 /* We have a conversation, check for encryption state */
1892 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1894 if (conv_ntlmssp_info == NULL) {
1895 /* No encryption state tied to the conversation. Therefore, we
1896 cannot decrypt the payload */
1900 /* We have the encryption state in the conversation. So return the
1901 crypt state tied to the requested peer
1903 if (cryptpeer == 1) {
1904 return &conv_ntlmssp_info->rc4_state_client;
1906 return &conv_ntlmssp_info->rc4_state_server;
1913 decrypt_data_payload(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
1914 packet_info *pinfo, proto_tree *tree _U_, gpointer key);
1916 decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
1917 packet_info *pinfo, proto_tree *tree, gpointer key);
1921 dissect_ntlmssp_encrypted_payload(tvbuff_t *data_tvb,
1922 tvbuff_t *auth_tvb _U_,
1925 dcerpc_auth_info *auth_info _U_)
1929 dissect_ntlmssp_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1931 volatile int offset = 0;
1932 proto_tree *volatile ntlmssp_tree = NULL;
1933 proto_item *tf = NULL;
1935 guint32 encrypted_block_length;
1936 guint8 key[NTLMSSP_KEY_LEN];
1937 /* the magic ntlm is the identifier of a NTLMSSP packet that's 00 00 00 01 */
1938 guint32 ntlm_magic_size = 4;
1939 guint32 ntlm_signature_size = 8;
1940 guint32 ntlm_seq_size = 4;
1943 length = tvb_length (tvb);
1944 /* signature + seq + real payload */
1945 encrypted_block_length = length - ntlm_magic_size;
1947 if (encrypted_block_length < (ntlm_signature_size + ntlm_seq_size)) {
1948 /* Don't know why this would happen, but if it does, don't even bother
1949 attempting decryption/dissection */
1950 return offset + length;
1953 /* Setup a new tree for the NTLMSSP payload */
1955 tf = proto_tree_add_item (tree,
1957 tvb, offset, -1, ENC_NA);
1959 ntlmssp_tree = proto_item_add_subtree (tf,
1964 * Catch the ReportedBoundsError exception; the stuff we've been
1965 * handed doesn't necessarily run to the end of the packet, it's
1966 * an item inside a packet, so if it happens to be malformed (or
1967 * we, or a dissector we call, has a bug), so that an exception
1968 * is thrown, we want to report the error, but return and let
1969 * our caller dissect the rest of the packet.
1971 * If it gets a BoundsError, we can stop, as there's nothing more
1972 * in the packet after our blob to see, so we just re-throw the
1975 pd_save = pinfo->private_data;
1977 /* Version number */
1978 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_vers,
1979 tvb, offset, 4, ENC_LITTLE_ENDIAN);
1982 /* Encrypted body */
1983 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_body,
1984 tvb, offset, ntlm_signature_size + ntlm_seq_size, ENC_NA);
1985 tvb_memcpy(tvb, key, offset, ntlm_signature_size + ntlm_seq_size);
1986 /* Try to decrypt */
1987 decrypt_data_payload (tvb, offset+(ntlm_signature_size + ntlm_seq_size), encrypted_block_length-(ntlm_signature_size + ntlm_seq_size), pinfo, ntlmssp_tree, key);
1988 decrypt_verifier (tvb, offset, ntlm_signature_size + ntlm_seq_size, pinfo, ntlmssp_tree, key);
1989 /* let's try to hook ourselves here */
1992 } CATCH(BoundsError) {
1994 } CATCH(ReportedBoundsError) {
1995 /* Restore the private_data structure in case one of the
1996 * called dissectors modified it (and, due to the exception,
1997 * was unable to restore it).
1999 pinfo->private_data = pd_save;
2000 show_reported_bounds_error(tvb, pinfo, tree);
2007 decrypt_data_payload(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
2008 packet_info *pinfo, proto_tree *tree _U_, gpointer key)
2010 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
2011 ntlmssp_packet_info *packet_ntlmssp_info;
2012 ntlmssp_packet_info *stored_packet_ntlmssp_info = NULL;
2014 /* Check to see if we already have state for this packet */
2015 packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
2016 if (packet_ntlmssp_info == NULL) {
2017 /* We don't have any packet state, so create one */
2018 packet_ntlmssp_info = se_alloc0(sizeof(ntlmssp_packet_info));
2019 p_add_proto_data(pinfo->fd, proto_ntlmssp, packet_ntlmssp_info);
2021 if (!packet_ntlmssp_info->payload_decrypted) {
2022 conversation_t *conversation;
2023 ntlmssp_info *conv_ntlmssp_info;
2025 /* Pull the challenge info from the conversation */
2026 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
2027 pinfo->ptype, pinfo->srcport,
2028 pinfo->destport, 0);
2029 if (conversation == NULL) {
2030 /* There is no conversation, thus no encryption state */
2034 conv_ntlmssp_info = conversation_get_proto_data(conversation,
2036 if (conv_ntlmssp_info == NULL) {
2037 /* There is no NTLMSSP state tied to the conversation */
2040 if (conv_ntlmssp_info->rc4_state_initialized != 1) {
2041 /* The crypto sybsystem is not initialized. This means that either
2042 the conversation did not include a challenge, or that we do not have the right password */
2046 stored_packet_ntlmssp_info = g_hash_table_lookup(hash_packet, key);
2048 if (stored_packet_ntlmssp_info != NULL && stored_packet_ntlmssp_info->payload_decrypted == TRUE) {
2049 /* Mat TBD (stderr, "Found a already decrypted packet\n");*/
2050 memcpy(packet_ntlmssp_info, stored_packet_ntlmssp_info, sizeof(ntlmssp_packet_info));
2051 /* Mat TBD printnbyte(packet_ntlmssp_info->decrypted_payload, encrypted_block_length, "Data: ", "\n");*/
2054 rc4_state_struct *rc4_state;
2055 rc4_state_struct *rc4_state_peer;
2057 /* Get the pair of RC4 state structures. One is used for to decrypt the
2058 payload. The other is used to re-encrypt the payload to represent
2060 if (conv_ntlmssp_info->server_dest_port == pinfo->destport) {
2062 rc4_state = get_encrypted_state(pinfo, 1);
2063 rc4_state_peer = get_encrypted_state(pinfo, 0);
2066 rc4_state = get_encrypted_state(pinfo, 0);
2067 rc4_state_peer = get_encrypted_state(pinfo, 1);
2070 if (rc4_state == NULL) {
2071 /* There is no encryption state, so we cannot decrypt */
2075 /* Store the decrypted contents in the packet state struct
2076 (of course at this point, they aren't decrypted yet) */
2077 packet_ntlmssp_info->decrypted_payload = tvb_memdup(tvb, offset,
2078 encrypted_block_length);
2079 packet_ntlmssp_info->payload_len = encrypted_block_length;
2080 decrypted_payloads = g_slist_prepend(decrypted_payloads,
2081 packet_ntlmssp_info->decrypted_payload);
2083 g_hash_table_insert(hash_packet, key, packet_ntlmssp_info);
2086 /* Do the decryption of the payload */
2087 crypt_rc4(rc4_state, packet_ntlmssp_info->decrypted_payload,
2088 encrypted_block_length);
2089 /* decrypt the verifier */
2090 /*printnchar(packet_ntlmssp_info->decrypted_payload, encrypted_block_length, "data: ", "\n");*/
2091 /* We setup a temporary buffer so we can re-encrypt the payload after
2092 decryption. This is to update the opposite peer's RC4 state
2093 it's usefull when we have only one key for both conversation
2094 in case of KEY_EXCH we have independant key so this is not needed*/
2095 if (!(NTLMSSP_NEGOTIATE_KEY_EXCH & conv_ntlmssp_info->flags)) {
2097 peer_block = ep_memdup(packet_ntlmssp_info->decrypted_payload, encrypted_block_length);
2098 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
2101 packet_ntlmssp_info->payload_decrypted = TRUE;
2105 /* Show the decrypted buffer in a new window */
2106 decr_tvb = tvb_new_child_real_data(tvb, packet_ntlmssp_info->decrypted_payload,
2107 encrypted_block_length,
2108 encrypted_block_length);
2110 add_new_data_source(pinfo, decr_tvb,
2112 pinfo->gssapi_decrypted_tvb = decr_tvb;
2116 dissect_ntlmssp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2118 volatile int offset = 0;
2119 proto_tree *volatile ntlmssp_tree = NULL;
2120 proto_item *tf = NULL;
2121 ntlmssp_header_t *ntlmssph;
2124 ntlmssph = ep_alloc(sizeof(ntlmssp_header_t));
2126 ntlmssph->domain_name = NULL;
2127 ntlmssph->acct_name = NULL;
2128 ntlmssph->host_name = NULL;
2129 memset(ntlmssph->session_key, 0, NTLMSSP_KEY_LEN);
2131 /* Setup a new tree for the NTLMSSP payload */
2133 tf = proto_tree_add_item (tree,
2135 tvb, offset, -1, ENC_NA);
2137 ntlmssp_tree = proto_item_add_subtree (tf,
2142 * Catch the ReportedBoundsError exception; the stuff we've been
2143 * handed doesn't necessarily run to the end of the packet, it's
2144 * an item inside a packet, so if it happens to be malformed (or
2145 * we, or a dissector we call, has a bug), so that an exception
2146 * is thrown, we want to report the error, but return and let
2147 * our caller dissect the rest of the packet.
2149 * If it gets a BoundsError, we can stop, as there's nothing more
2150 * in the packet after our blob to see, so we just re-throw the
2153 pd_save = pinfo->private_data;
2155 /* NTLMSSP constant */
2156 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth,
2157 tvb, offset, 8, ENC_ASCII|ENC_NA);
2160 /* NTLMSSP Message Type */
2161 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_message_type,
2162 tvb, offset, 4, ENC_LITTLE_ENDIAN);
2163 ntlmssph->type = tvb_get_letohl (tvb, offset);
2166 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ", ", "%s",
2167 val_to_str_const(ntlmssph->type,
2168 ntlmssp_message_types,
2169 "Unknown NTLMSSP message type"));
2171 /* Call the appropriate dissector based on the Message Type */
2172 switch (ntlmssph->type) {
2174 case NTLMSSP_NEGOTIATE:
2175 offset = dissect_ntlmssp_negotiate (tvb, offset, ntlmssp_tree, ntlmssph);
2178 case NTLMSSP_CHALLENGE:
2179 offset = dissect_ntlmssp_challenge (tvb, pinfo, offset, ntlmssp_tree, ntlmssph);
2183 offset = dissect_ntlmssp_auth (tvb, pinfo, offset, ntlmssp_tree, ntlmssph);
2187 /* Unrecognized message type */
2188 proto_tree_add_text (ntlmssp_tree, tvb, offset, -1,
2189 "Unrecognized NTLMSSP Message");
2192 } CATCH(BoundsError) {
2194 } CATCH(ReportedBoundsError) {
2195 /* Restore the private_data structure in case one of the
2196 * called dissectors modified it (and, due to the exception,
2197 * was unable to restore it).
2199 pinfo->private_data = pd_save;
2200 show_reported_bounds_error(tvb, pinfo, tree);
2203 tap_queue_packet(ntlmssp_tap, pinfo, ntlmssph);
2207 dissect_ntlmssp_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree, void *data _U_)
2209 if (tvb_memeql(tvb, 0, "NTLMSSP", 8) == 0) {
2210 dissect_ntlmssp(tvb, pinfo, parent_tree);
2219 * See page 45 of "DCE/RPC over SMB" by Luke Kenneth Casson Leighton.
2222 decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
2223 packet_info *pinfo, proto_tree *tree, gpointer key)
2225 proto_tree *decr_tree;
2227 conversation_t *conversation;
2229 rc4_state_struct *rc4_state;
2230 rc4_state_struct *rc4_state_peer;
2231 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
2234 guint8 calculated_md5[NTLMSSP_KEY_LEN];
2235 ntlmssp_info *conv_ntlmssp_info;
2236 ntlmssp_packet_info *packet_ntlmssp_info;
2237 int decrypted_offset = 0;
2239 ntlmssp_packet_info *stored_packet_ntlmssp_info = NULL;
2241 packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
2242 if (packet_ntlmssp_info == NULL) {
2243 /* We don't have data for this packet */
2246 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
2247 pinfo->ptype, pinfo->srcport,
2248 pinfo->destport, 0);
2249 if (conversation == NULL) {
2250 /* There is no conversation, thus no encryption state */
2253 conv_ntlmssp_info = conversation_get_proto_data(conversation,
2255 if (conv_ntlmssp_info == NULL) {
2256 /* There is no NTLMSSP state tied to the conversation */
2261 stored_packet_ntlmssp_info = g_hash_table_lookup(hash_packet, key);
2263 if (stored_packet_ntlmssp_info != NULL && stored_packet_ntlmssp_info->verifier_decrypted == TRUE) {
2264 /* Mat TBD fprintf(stderr, "Found a already decrypted packet\n");*/
2265 /* In Theory it's aleady the case, and we should be more clever ... like just copying buffers ...*/
2266 packet_ntlmssp_info = stored_packet_ntlmssp_info;
2269 if (!packet_ntlmssp_info->verifier_decrypted) {
2270 if (conv_ntlmssp_info->rc4_state_initialized != 1) {
2271 /* The crypto sybsystem is not initialized. This means that either
2272 the conversation did not include a challenge, or we are doing
2273 something other than NTLMSSP v1 */
2276 if (conv_ntlmssp_info->server_dest_port == pinfo->destport) {
2277 /* client talk to server */
2278 rc4_state = get_encrypted_state(pinfo, 1);
2279 sign_key = get_sign_key(pinfo, 1);
2280 rc4_state_peer = get_encrypted_state(pinfo, 0);
2282 rc4_state = get_encrypted_state(pinfo, 0);
2283 sign_key = get_sign_key(pinfo, 0);
2284 rc4_state_peer = get_encrypted_state(pinfo, 1);
2287 if (rc4_state == NULL || rc4_state_peer == NULL) {
2288 /* There is no encryption state, so we cannot decrypt */
2292 /* Setup the buffer to decrypt to */
2293 tvb_memcpy(tvb, packet_ntlmssp_info->verifier,
2294 offset, encrypted_block_length);
2296 /*if (!(NTLMSSP_NEGOTIATE_KEY_EXCH & packet_ntlmssp_info->flags)) {*/
2297 if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY) {
2298 if ((NTLMSSP_NEGOTIATE_KEY_EXCH & conv_ntlmssp_info->flags)) {
2299 /* The spec says that if we have have a key exchange then we have a the signature that is crypted
2300 * otherwise it's just a hmac_md5(keysign, concat(message, sequence))[0..7]
2302 crypt_rc4(rc4_state, packet_ntlmssp_info->verifier, 8);
2305 * Try to check the HMAC MD5 of the message against those calculated works great with LDAP payload but
2306 * don't with DCE/RPC calls.
2307 * Some analysis need to be done ...
2309 if (sign_key != NULL) {
2310 check_buf = ep_alloc(packet_ntlmssp_info->payload_len+4);
2311 tvb_memcpy(tvb, &sequence, offset+8, 4);
2312 memcpy(check_buf, &sequence, 4);
2313 memcpy(check_buf+4, packet_ntlmssp_info->decrypted_payload, packet_ntlmssp_info->payload_len);
2314 md5_hmac(check_buf, (int)(packet_ntlmssp_info->payload_len+4), sign_key, NTLMSSP_KEY_LEN, calculated_md5);
2316 printnbyte(packet_ntlmssp_info->verifier, 8, "HMAC from packet: ", "\n");
2317 printnbyte(calculated_md5, 8, "HMAC : ", "\n");
2322 /* 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 */
2323 /* Do the actual decryption of the verifier */
2324 crypt_rc4(rc4_state, packet_ntlmssp_info->verifier,
2325 encrypted_block_length);
2330 /* We setup a temporary buffer so we can re-encrypt the payload after
2331 decryption. This is to update the opposite peer's RC4 state
2332 This is not needed when we just have EXTENDED SECURITY because the signature is not crypted
2333 and it's also not needed when we have key exchange because server and client have independant keys */
2334 if (!(NTLMSSP_NEGOTIATE_KEY_EXCH & conv_ntlmssp_info->flags) && !(NTLMSSP_NEGOTIATE_EXTENDED_SECURITY & conv_ntlmssp_info->flags)) {
2335 peer_block = ep_memdup(packet_ntlmssp_info->verifier, encrypted_block_length);
2336 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
2339 /* Mark the packet as decrypted so that subsequent attempts to dissect
2340 the packet use the already decrypted payload instead of attempting
2342 packet_ntlmssp_info->verifier_decrypted = TRUE;
2345 /* Show the decrypted buffer in a new window */
2346 decr_tvb = tvb_new_child_real_data(tvb, packet_ntlmssp_info->verifier,
2347 encrypted_block_length,
2348 encrypted_block_length);
2349 add_new_data_source(pinfo, decr_tvb,
2350 "Decrypted NTLMSSP Verifier");
2352 /* Show the decrypted payload in the tree */
2353 tf = proto_tree_add_text(tree, decr_tvb, 0, -1,
2354 "Decrypted Verifier (%d byte%s)",
2355 encrypted_block_length,
2356 plurality(encrypted_block_length, "", "s"));
2357 decr_tree = proto_item_add_subtree (tf, ett_ntlmssp);
2359 if (( conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY)) {
2360 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_hmacmd5,
2361 decr_tvb, decrypted_offset, 8, ENC_NA);
2362 decrypted_offset += 8;
2366 /* Incrementing sequence number of DCE conversation */
2367 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_sequence,
2368 decr_tvb, decrypted_offset, 4, ENC_NA);
2369 decrypted_offset += 4;
2373 /* RANDOM PAD usually it's 0 */
2374 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_randompad,
2375 decr_tvb, decrypted_offset, 4, ENC_LITTLE_ENDIAN);
2376 decrypted_offset += 4;
2378 /* CRC32 of the DCE fragment data */
2379 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_crc32,
2380 decr_tvb, decrypted_offset, 4, ENC_LITTLE_ENDIAN);
2381 decrypted_offset += 4;
2383 /* Incrementing sequence number of DCE conversation */
2384 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_sequence,
2385 decr_tvb, decrypted_offset, 4, ENC_NA);
2386 decrypted_offset += 4;
2390 /* Used when NTLMSSP is done over DCE/RPC because in this case verifier and real payload are not contigious*/
2392 dissect_ntlmssp_payload_only(tvbuff_t *tvb, packet_info *pinfo, _U_ proto_tree *tree, void *data _U_)
2394 volatile int offset = 0;
2395 proto_tree *volatile ntlmssp_tree = NULL;
2396 guint32 encrypted_block_length;
2399 /* the magic ntlm is the identifier of a NTLMSSP packet that's 00 00 00 01
2401 encrypted_block_length = tvb_length (tvb);
2402 /* signature + seq + real payload */
2404 /* Setup a new tree for the NTLMSSP payload */
2407 tf = proto_tree_add_item (tree,
2409 tvb, offset, -1, ENC_NA);
2411 ntlmssp_tree = proto_item_add_subtree (tf,
2416 * Catch the ReportedBoundsError exception; the stuff we've been
2417 * handed doesn't necessarily run to the end of the packet, it's
2418 * an item inside a packet, so if it happens to be malformed (or
2419 * we, or a dissector we call, has a bug), so that an exception
2420 * is thrown, we want to report the error, but return and let
2421 * our caller dissect the rest of the packet.
2423 * If it gets a BoundsError, we can stop, as there's nothing more
2424 * in the packet after our blob to see, so we just re-throw the
2427 pd_save = pinfo->private_data;
2429 /* Version number */
2431 /* Try to decrypt */
2432 decrypt_data_payload (tvb, offset, encrypted_block_length, pinfo, ntlmssp_tree, NULL);
2433 /* let's try to hook ourselves here */
2435 } CATCH(BoundsError) {
2437 } CATCH(ReportedBoundsError) {
2438 /* Restore the private_data structure in case one of the
2439 * called dissectors modified it (and, due to the exception,
2440 * was unable to restore it).
2442 pinfo->private_data = pd_save;
2443 show_reported_bounds_error(tvb, pinfo, tree);
2449 /* Used when NTLMSSP is done over DCE/RPC because in this case verifier and real payload are not contigious
2450 * But in fact this function could be merged with wrap_dissect_ntlmssp_verf because it's only used there
2453 dissect_ntlmssp_verf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
2455 volatile int offset = 0;
2456 proto_tree *volatile ntlmssp_tree = NULL;
2457 proto_item *tf = NULL;
2458 guint32 verifier_length;
2459 guint32 encrypted_block_length;
2462 verifier_length = tvb_length (tvb);
2463 encrypted_block_length = verifier_length - 4;
2465 if (encrypted_block_length < 12) {
2466 /* Don't know why this would happen, but if it does, don't even bother
2467 attempting decryption/dissection */
2468 return offset + verifier_length;
2471 /* Setup a new tree for the NTLMSSP payload */
2473 tf = proto_tree_add_item (tree,
2475 tvb, offset, -1, ENC_NA);
2477 ntlmssp_tree = proto_item_add_subtree (tf,
2482 * Catch the ReportedBoundsError exception; the stuff we've been
2483 * handed doesn't necessarily run to the end of the packet, it's
2484 * an item inside a packet, so if it happens to be malformed (or
2485 * we, or a dissector we call, has a bug), so that an exception
2486 * is thrown, we want to report the error, but return and let
2487 * our caller dissect the rest of the packet.
2489 * If it gets a BoundsError, we can stop, as there's nothing more
2490 * in the packet after our blob to see, so we just re-throw the
2493 pd_save = pinfo->private_data;
2495 /* Version number */
2496 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_vers,
2497 tvb, offset, 4, ENC_LITTLE_ENDIAN);
2500 /* Encrypted body */
2501 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_body,
2502 tvb, offset, encrypted_block_length, ENC_NA);
2504 /* Try to decrypt */
2505 decrypt_verifier (tvb, offset, encrypted_block_length, pinfo, ntlmssp_tree, NULL);
2506 /* let's try to hook ourselves here */
2509 offset += encrypted_block_length;
2510 } CATCH(BoundsError) {
2512 } CATCH(ReportedBoundsError) {
2513 /* Restore the private_data structure in case one of the
2514 * called dissectors modified it (and, due to the exception,
2515 * was unable to restore it).
2517 pinfo->private_data = pd_save;
2518 show_reported_bounds_error(tvb, pinfo, tree);
2525 wrap_dissect_ntlmssp_payload_only(tvbuff_t *tvb, tvbuff_t *auth_tvb _U_,
2526 int offset, packet_info *pinfo, dcerpc_auth_info *auth_info _U_)
2530 data_tvb = tvb_new_subset(
2531 tvb, offset, tvb_length_remaining(tvb, offset),
2532 tvb_length_remaining(tvb, offset));
2533 dissect_ntlmssp_payload_only(data_tvb, pinfo, NULL, NULL);
2534 return pinfo->gssapi_decrypted_tvb;
2539 dissect_ntlmssp_encrypted_payload(tvbuff_t *data_tvb,
2540 tvbuff_t *auth_tvb _U_,
2543 dcerpc_auth_info *auth_info _U_)
2545 /* gssapi_decrypted_tvb = NULL */
2546 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
2548 conversation_t *conversation;
2549 guint32 encrypted_block_length;
2550 rc4_state_struct *rc4_state;
2551 rc4_state_struct *rc4_state_peer;
2552 ntlmssp_info *conv_ntlmssp_info = NULL;
2553 ntlmssp_packet_info *packet_ntlmssp_info;
2555 encrypted_block_length = tvb_length_remaining (data_tvb, offset);
2557 fprintf(stderr, "Called dissect_ntlmssp_encrypted_payload\n");
2558 /* Check to see if we already have state for this packet */
2559 packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
2560 if (packet_ntlmssp_info == NULL) {
2561 /* We don't have any packet state, so create one */
2562 packet_ntlmssp_info = se_alloc0(sizeof(ntlmssp_packet_info));
2563 p_add_proto_data(pinfo->fd, proto_ntlmssp, packet_ntlmssp_info);
2566 if (!packet_ntlmssp_info->payload_decrypted) {
2567 /* Pull the challenge info from the conversation */
2568 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
2569 pinfo->ptype, pinfo->srcport,
2570 pinfo->destport, 0);
2571 if (conversation == NULL) {
2572 /* There is no conversation, thus no encryption state */
2576 conv_ntlmssp_info = conversation_get_proto_data(conversation,
2578 if (conv_ntlmssp_info == NULL) {
2579 /* There is no NTLMSSP state tied to the conversation */
2582 /* Get the pair of RC4 state structures. One is used for to decrypt the
2583 payload. The other is used to re-encrypt the payload to represent
2585 if (conv_ntlmssp_info->server_dest_port == pinfo->destport) {
2586 rc4_state = get_encrypted_state(pinfo, 1);
2587 rc4_state_peer = get_encrypted_state(pinfo, 0);
2589 rc4_state = get_encrypted_state(pinfo, 0);
2590 rc4_state_peer = get_encrypted_state(pinfo, 1);
2593 if (rc4_state == NULL || rc4_state_peer == NULL) {
2594 /* There is no encryption state, so we cannot decrypt */
2598 /* Store the decrypted contents in the packet state struct
2599 (of course at this point, they aren't decrypted yet) */
2600 packet_ntlmssp_info->decrypted_payload = tvb_memdup(data_tvb, offset,
2601 encrypted_block_length);
2602 decrypted_payloads = g_slist_prepend(decrypted_payloads,
2603 packet_ntlmssp_info->decrypted_payload);
2605 /* Do the decryption of the payload */
2606 crypt_rc4(rc4_state, packet_ntlmssp_info->decrypted_payload,
2607 encrypted_block_length);
2609 /* We setup a temporary buffer so we can re-encrypt the payload after
2610 decryption. This is to update the opposite peer's RC4 state */
2611 peer_block = ep_memdup(packet_ntlmssp_info->decrypted_payload, encrypted_block_length);
2612 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
2614 packet_ntlmssp_info->payload_decrypted = TRUE;
2617 /* Show the decrypted buffer in a new window */
2618 decr_tvb = tvb_new_child_real_data(data_tvb, packet_ntlmssp_info->decrypted_payload,
2619 encrypted_block_length,
2620 encrypted_block_length);
2622 offset += encrypted_block_length;
2629 free_payload(gpointer decrypted_payload, gpointer user_data _U_)
2631 g_free(decrypted_payload);
2635 header_hash(gconstpointer pointer)
2637 guint32 crc = ~crc32c_calculate(pointer, NTLMSSP_KEY_LEN, CRC32C_PRELOAD);
2638 /* Mat TBD fprintf(stderr, "Val: %u\n", crc);*/
2643 header_equal(gconstpointer pointer1, gconstpointer pointer2)
2645 if (!memcmp(pointer1, pointer2, 16)) {
2654 ntlmssp_init_protocol(void)
2657 * Free the decrypted payloads, and then free the list of decrypted
2660 if (decrypted_payloads != NULL) {
2661 g_slist_foreach(decrypted_payloads, free_payload, NULL);
2662 g_slist_free(decrypted_payloads);
2663 decrypted_payloads = NULL;
2666 if (hash_packet != NULL) {
2667 g_hash_table_remove_all(hash_packet);
2669 hash_packet = g_hash_table_new(header_hash, header_equal);
2676 wrap_dissect_ntlmssp(tvbuff_t *tvb, int offset, packet_info *pinfo,
2677 proto_tree *tree, guint8 *drep _U_)
2681 auth_tvb = tvb_new_subset(
2682 tvb, offset, tvb_length_remaining(tvb, offset),
2683 tvb_length_remaining(tvb, offset));
2685 dissect_ntlmssp(auth_tvb, pinfo, tree);
2687 return tvb_length_remaining(tvb, offset);
2691 wrap_dissect_ntlmssp_verf(tvbuff_t *tvb, int offset, packet_info *pinfo,
2692 proto_tree *tree, guint8 *drep _U_)
2696 auth_tvb = tvb_new_subset(
2697 tvb, offset, tvb_length_remaining(tvb, offset),
2698 tvb_length_remaining(tvb, offset));
2699 return dissect_ntlmssp_verf(auth_tvb, pinfo, tree, NULL);
2702 static dcerpc_auth_subdissector_fns ntlmssp_sign_fns = {
2703 wrap_dissect_ntlmssp, /* Bind */
2704 wrap_dissect_ntlmssp, /* Bind ACK */
2705 wrap_dissect_ntlmssp, /* AUTH3 */
2706 wrap_dissect_ntlmssp_verf, /* Request verifier */
2707 wrap_dissect_ntlmssp_verf, /* Response verifier */
2708 NULL, /* Request data */
2709 NULL /* Response data */
2712 static dcerpc_auth_subdissector_fns ntlmssp_seal_fns = {
2713 wrap_dissect_ntlmssp, /* Bind */
2714 wrap_dissect_ntlmssp, /* Bind ACK */
2715 wrap_dissect_ntlmssp, /* AUTH3 */
2716 wrap_dissect_ntlmssp_verf, /* Request verifier */
2717 wrap_dissect_ntlmssp_verf, /* Response verifier */
2718 wrap_dissect_ntlmssp_payload_only, /* Request data */
2719 wrap_dissect_ntlmssp_payload_only /* Response data */
2723 proto_register_ntlmssp(void)
2726 static hf_register_info hf[] = {
2728 { "NTLMSSP identifier", "ntlmssp.identifier",
2729 FT_STRING, BASE_NONE, NULL, 0x0,
2732 { &hf_ntlmssp_message_type,
2733 { "NTLM Message Type", "ntlmssp.messagetype",
2734 FT_UINT32, BASE_HEX, VALS(ntlmssp_message_types), 0x0,
2737 { &hf_ntlmssp_negotiate_flags,
2738 { "Flags", "ntlmssp.negotiateflags",
2739 FT_UINT32, BASE_HEX, NULL, 0x0,
2742 { &hf_ntlmssp_negotiate_flags_01,
2743 { "Negotiate UNICODE", "ntlmssp.negotiateunicode",
2744 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_UNICODE,
2747 { &hf_ntlmssp_negotiate_flags_02,
2748 { "Negotiate OEM", "ntlmssp.negotiateoem",
2749 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_OEM,
2752 { &hf_ntlmssp_negotiate_flags_04,
2753 { "Request Target", "ntlmssp.requesttarget",
2754 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_REQUEST_TARGET,
2757 { &hf_ntlmssp_negotiate_flags_08,
2758 { "Request 0x00000008", "ntlmssp.negotiate00000008",
2759 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00000008,
2762 { &hf_ntlmssp_negotiate_flags_10,
2763 { "Negotiate Sign", "ntlmssp.negotiatesign",
2764 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_SIGN,
2767 { &hf_ntlmssp_negotiate_flags_20,
2768 { "Negotiate Seal", "ntlmssp.negotiateseal",
2769 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_SEAL,
2772 { &hf_ntlmssp_negotiate_flags_40,
2773 { "Negotiate Datagram", "ntlmssp.negotiatedatagram",
2774 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_DATAGRAM,
2777 { &hf_ntlmssp_negotiate_flags_80,
2778 { "Negotiate Lan Manager Key", "ntlmssp.negotiatelmkey",
2779 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_LM_KEY,
2782 { &hf_ntlmssp_negotiate_flags_100,
2783 { "Negotiate 0x00000100", "ntlmssp.negotiate00000100",
2784 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00000100,
2787 { &hf_ntlmssp_negotiate_flags_200,
2788 { "Negotiate NTLM key", "ntlmssp.negotiatentlm",
2789 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_NTLM,
2792 { &hf_ntlmssp_negotiate_flags_400,
2793 { "Negotiate NT Only", "ntlmssp.negotiatentonly",
2794 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_NT_ONLY,
2797 { &hf_ntlmssp_negotiate_flags_800,
2798 { "Negotiate 0x00000800", "ntlmssp.negotiate00000800",
2799 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00000800,
2802 { &hf_ntlmssp_negotiate_flags_1000,
2803 { "Negotiate OEM Domain Supplied", "ntlmssp.negotiateoemdomainsupplied",
2804 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED,
2807 { &hf_ntlmssp_negotiate_flags_2000,
2808 { "Negotiate OEM Workstation Supplied", "ntlmssp.negotiateoemworkstationsupplied",
2809 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED,
2812 { &hf_ntlmssp_negotiate_flags_4000,
2813 { "Negotiate 0x00004000", "ntlmssp.negotiate00004000",
2814 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00004000,
2817 { &hf_ntlmssp_negotiate_flags_8000,
2818 { "Negotiate Always Sign", "ntlmssp.negotiatealwayssign",
2819 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_ALWAYS_SIGN,
2822 { &hf_ntlmssp_negotiate_flags_10000,
2823 { "Target Type Domain", "ntlmssp.targettypedomain",
2824 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_TARGET_TYPE_DOMAIN,
2827 { &hf_ntlmssp_negotiate_flags_20000,
2828 { "Target Type Server", "ntlmssp.targettypeserver",
2829 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_TARGET_TYPE_SERVER,
2832 { &hf_ntlmssp_negotiate_flags_40000,
2833 { "Target Type Share", "ntlmssp.targettypeshare",
2834 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_TARGET_TYPE_SHARE,
2838 /* Negotiate Flags */
2839 { &hf_ntlmssp_negotiate_flags_80000,
2840 { "Negotiate Extended Security", "ntlmssp.negotiatentlm2",
2841 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_EXTENDED_SECURITY,
2844 { &hf_ntlmssp_negotiate_flags_100000,
2845 { "Negotiate Identify", "ntlmssp.negotiateidentify",
2846 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_IDENTIFY,
2849 { &hf_ntlmssp_negotiate_flags_200000,
2850 { "Negotiate 0x00200000", "ntlmssp.negotiatent00200000",
2851 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00200000,
2854 { &hf_ntlmssp_negotiate_flags_400000,
2855 { "Request Non-NT Session", "ntlmssp.requestnonntsession",
2856 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_REQUEST_NON_NT_SESSION,
2859 { &hf_ntlmssp_negotiate_flags_800000,
2860 { "Negotiate Target Info", "ntlmssp.negotiatetargetinfo",
2861 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_TARGET_INFO,
2864 { &hf_ntlmssp_negotiate_flags_1000000,
2865 { "Negotiate 0x01000000", "ntlmssp.negotiatent01000000",
2866 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_01000000,
2869 { &hf_ntlmssp_negotiate_flags_2000000,
2870 { "Negotiate Version", "ntlmssp.negotiateversion",
2871 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_VERSION,
2874 { &hf_ntlmssp_negotiate_flags_4000000,
2875 { "Negotiate 0x04000000", "ntlmssp.negotiatent04000000",
2876 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_04000000,
2879 { &hf_ntlmssp_negotiate_flags_8000000,
2880 { "Negotiate 0x08000000", "ntlmssp.negotiatent08000000",
2881 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_08000000,
2884 { &hf_ntlmssp_negotiate_flags_10000000,
2885 { "Negotiate 0x10000000", "ntlmssp.negotiatent10000000",
2886 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_10000000,
2889 { &hf_ntlmssp_negotiate_flags_20000000,
2890 { "Negotiate 128", "ntlmssp.negotiate128",
2891 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_128,
2892 "128-bit encryption is supported", HFILL }
2894 { &hf_ntlmssp_negotiate_flags_40000000,
2895 { "Negotiate Key Exchange", "ntlmssp.negotiatekeyexch",
2896 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_KEY_EXCH,
2899 { &hf_ntlmssp_negotiate_flags_80000000,
2900 { "Negotiate 56", "ntlmssp.negotiate56",
2901 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_56,
2902 "56-bit encryption is supported", HFILL }
2904 { &hf_ntlmssp_negotiate_workstation_strlen,
2905 { "Calling workstation name length", "ntlmssp.negotiate.callingworkstation.strlen",
2906 FT_UINT16, BASE_DEC, NULL, 0x0,
2909 { &hf_ntlmssp_negotiate_workstation_maxlen,
2910 { "Calling workstation name max length", "ntlmssp.negotiate.callingworkstation.maxlen",
2911 FT_UINT16, BASE_DEC, NULL, 0x0,
2914 { &hf_ntlmssp_negotiate_workstation_buffer,
2915 { "Calling workstation name buffer", "ntlmssp.negotiate.callingworkstation.buffer",
2916 FT_UINT32, BASE_HEX, NULL, 0x0,
2919 { &hf_ntlmssp_negotiate_workstation,
2920 { "Calling workstation name", "ntlmssp.negotiate.callingworkstation",
2921 FT_STRING, BASE_NONE, NULL, 0x0,
2924 { &hf_ntlmssp_negotiate_domain_strlen,
2925 { "Calling workstation domain length", "ntlmssp.negotiate.domain.strlen",
2926 FT_UINT16, BASE_DEC, NULL, 0x0,
2929 { &hf_ntlmssp_negotiate_domain_maxlen,
2930 { "Calling workstation domain max length", "ntlmssp.negotiate.domain.maxlen",
2931 FT_UINT16, BASE_DEC, NULL, 0x0,
2934 { &hf_ntlmssp_negotiate_domain_buffer,
2935 { "Calling workstation domain buffer", "ntlmssp.negotiate.domain.buffer",
2936 FT_UINT32, BASE_HEX, NULL, 0x0,
2939 { &hf_ntlmssp_negotiate_domain,
2940 { "Calling workstation domain", "ntlmssp.negotiate.domain",
2941 FT_STRING, BASE_NONE, NULL, 0x0,
2944 { &hf_ntlmssp_ntlm_client_challenge,
2945 { "NTLM Client Challenge", "ntlmssp.ntlmclientchallenge",
2946 FT_BYTES, BASE_NONE, NULL, 0x0,
2949 { &hf_ntlmssp_ntlm_server_challenge,
2950 { "NTLM Server Challenge", "ntlmssp.ntlmserverchallenge",
2951 FT_BYTES, BASE_NONE, NULL, 0x0,
2954 { &hf_ntlmssp_reserved,
2955 { "Reserved", "ntlmssp.reserved",
2956 FT_BYTES, BASE_NONE, NULL, 0x0,
2960 { &hf_ntlmssp_challenge_target_name,
2961 { "Target Name", "ntlmssp.challenge.target_name",
2962 FT_STRING, BASE_NONE, NULL, 0x0,
2965 { &hf_ntlmssp_auth_domain,
2966 { "Domain name", "ntlmssp.auth.domain",
2967 FT_STRING, BASE_NONE, NULL, 0x0,
2970 { &hf_ntlmssp_auth_username,
2971 { "User name", "ntlmssp.auth.username",
2972 FT_STRING, BASE_NONE, NULL, 0x0,
2975 { &hf_ntlmssp_auth_hostname,
2976 { "Host name", "ntlmssp.auth.hostname",
2977 FT_STRING, BASE_NONE, NULL, 0x0,
2980 { &hf_ntlmssp_auth_lmresponse,
2981 { "Lan Manager Response", "ntlmssp.auth.lmresponse",
2982 FT_BYTES, BASE_NONE, NULL, 0x0,
2985 { &hf_ntlmssp_auth_ntresponse,
2986 { "NTLM Response", "ntlmssp.auth.ntresponse",
2987 FT_BYTES, BASE_NONE, NULL, 0x0,
2990 { &hf_ntlmssp_auth_sesskey,
2991 { "Session Key", "ntlmssp.auth.sesskey",
2992 FT_BYTES, BASE_NONE, NULL, 0x0,
2995 { &hf_ntlmssp_string_len,
2996 { "Length", "ntlmssp.string.length",
2997 FT_UINT16, BASE_DEC, NULL, 0x0,
3000 { &hf_ntlmssp_string_maxlen,
3001 { "Maxlen", "ntlmssp.string.maxlen",
3002 FT_UINT16, BASE_DEC, NULL, 0x0,
3005 { &hf_ntlmssp_string_offset,
3006 { "Offset", "ntlmssp.string.offset",
3007 FT_UINT32, BASE_DEC, NULL, 0x0,
3010 { &hf_ntlmssp_blob_len,
3011 { "Length", "ntlmssp.blob.length",
3012 FT_UINT16, BASE_DEC, NULL, 0x0,
3015 { &hf_ntlmssp_blob_maxlen,
3016 { "Maxlen", "ntlmssp.blob.maxlen",
3017 FT_UINT16, BASE_DEC, NULL, 0x0,
3020 { &hf_ntlmssp_blob_offset,
3021 { "Offset", "ntlmssp.blob.offset",
3022 FT_UINT32, BASE_DEC, NULL, 0x0,
3025 { &hf_ntlmssp_version,
3026 { "Version", "ntlmssp.version",
3027 FT_NONE, BASE_NONE, NULL, 0x0,
3030 { &hf_ntlmssp_version_major,
3031 { "Major Version", "ntlmssp.version.major",
3032 FT_UINT8, BASE_DEC, NULL, 0x0,
3035 { &hf_ntlmssp_version_minor,
3036 { "Minor Version", "ntlmssp.version.minor",
3037 FT_UINT8, BASE_DEC, NULL, 0x0,
3040 { &hf_ntlmssp_version_build_number,
3041 { "Build Number", "ntlmssp.version.build_number",
3042 FT_UINT16, BASE_DEC, NULL, 0x0,
3045 { &hf_ntlmssp_version_ntlm_current_revision,
3046 { "NTLM Current Revision", "ntlmssp.version.ntlm_current_revision",
3047 FT_UINT8, BASE_DEC, NULL, 0x0,
3052 { &hf_ntlmssp_challenge_target_info,
3053 { "Target Info", "ntlmssp.challenge.target_info",
3054 FT_NONE, BASE_NONE, NULL, 0x0,
3057 { &hf_ntlmssp_challenge_target_info_len,
3058 { "Length", "ntlmssp.challenge.target_info.length",
3059 FT_UINT16, BASE_DEC, NULL, 0x0,
3062 { &hf_ntlmssp_challenge_target_info_maxlen,
3063 { "Maxlen", "ntlmssp.challenge.target_info.maxlen",
3064 FT_UINT16, BASE_DEC, NULL, 0x0,
3067 { &hf_ntlmssp_challenge_target_info_offset,
3068 { "Offset", "ntlmssp.challenge.target_info.offset",
3069 FT_UINT32, BASE_DEC, NULL, 0x0,
3073 { &hf_ntlmssp_challenge_target_info_item_type,
3074 { "Target Info Item Type", "ntlmssp.challenge.target_info.item.type",
3075 FT_UINT16, BASE_HEX, VALS(ntlm_name_types), 0x0,
3078 { &hf_ntlmssp_challenge_target_info_item_len,
3079 { "Target Info Item Length", "ntlmssp.challenge.target_info.item.length",
3080 FT_UINT16, BASE_DEC, NULL, 0x0,
3084 { &hf_ntlmssp_challenge_target_info_end,
3085 { "List End", "ntlmssp.challenge.target_info.end",
3086 FT_NONE, BASE_NONE, NULL, 0x0,
3089 { &hf_ntlmssp_challenge_target_info_nb_computer_name,
3090 { "NetBIOS Computer Name", "ntlmssp.challenge.target_info.nb_computer_name",
3091 FT_STRING, BASE_NONE, NULL, 0x0,
3092 "Server NetBIOS Computer Name", HFILL }
3094 { &hf_ntlmssp_challenge_target_info_nb_domain_name,
3095 { "NetBIOS Domain Name", "ntlmssp.challenge.target_info.nb_domain_name",
3096 FT_STRING, BASE_NONE, NULL, 0x0,
3097 "Server NetBIOS Domain Name", HFILL }
3099 { &hf_ntlmssp_challenge_target_info_dns_computer_name,
3100 { "DNS Computer Name", "ntlmssp.challenge.target_info.dns_computer_name",
3101 FT_STRING, BASE_NONE, NULL, 0x0,
3104 { &hf_ntlmssp_challenge_target_info_dns_domain_name,
3105 { "DNS Domain Name", "ntlmssp.challenge.target_info.dns_domain_name",
3106 FT_STRING, BASE_NONE, NULL, 0x0,
3109 { &hf_ntlmssp_challenge_target_info_dns_tree_name,
3110 { "DNS Tree Name", "ntlmssp.challenge.target_info.dns_tree_name",
3111 FT_STRING, BASE_NONE, NULL, 0x0,
3114 { &hf_ntlmssp_challenge_target_info_flags,
3115 { "Flags", "ntlmssp.challenge.target_info.flags",
3116 FT_UINT32, BASE_HEX, NULL, 0x0,
3119 { &hf_ntlmssp_challenge_target_info_timestamp,
3120 { "Timestamp", "ntlmssp.challenge.target_info.timestamp",
3121 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0,
3124 { &hf_ntlmssp_challenge_target_info_restrictions,
3125 { "Restrictions", "ntlmssp.challenge.target_info.restrictions",
3126 FT_BYTES, BASE_NONE, NULL, 0,
3129 { &hf_ntlmssp_challenge_target_info_target_name,
3130 { "Target Name", "ntlmssp.challenge.target_info.target_name",
3131 FT_STRING, BASE_NONE, NULL, 0x0,
3134 { &hf_ntlmssp_challenge_target_info_channel_bindings,
3135 { "Channel Bindings", "ntlmssp.challenge.target_info.channel_bindings",
3136 FT_BYTES, BASE_NONE, NULL, 0x0,
3140 { &hf_ntlmssp_ntlmv2_response_item_type,
3141 { "NTLMV2 Response Item Type", "ntlmssp.ntlmv2_response.item.type",
3142 FT_UINT16, BASE_HEX, VALS(ntlm_name_types), 0x0,
3145 { &hf_ntlmssp_ntlmv2_response_item_len,
3146 { "NTLMV2 Response Item Length", "ntlmssp.ntlmv2_response.item.length",
3147 FT_UINT16, BASE_DEC, NULL, 0x0,
3151 { &hf_ntlmssp_ntlmv2_response_end,
3152 { "List End", "ntlmssp.ntlmv2_response.end",
3153 FT_NONE, BASE_NONE, NULL, 0x0,
3156 { &hf_ntlmssp_ntlmv2_response_nb_computer_name,
3157 { "NetBIOS Computer Name", "ntlmssp.ntlmv2_response.nb_computer_name",
3158 FT_STRING, BASE_NONE, NULL, 0x0,
3159 "Server NetBIOS Computer Name", HFILL }
3161 { &hf_ntlmssp_ntlmv2_response_nb_domain_name,
3162 { "NetBIOS Domain Name", "ntlmssp.ntlmv2_response.nb_domain_name",
3163 FT_STRING, BASE_NONE, NULL, 0x0,
3164 "Server NetBIOS Domain Name", HFILL }
3166 { &hf_ntlmssp_ntlmv2_response_dns_computer_name,
3167 { "DNS Computer Name", "ntlmssp.ntlmv2_response.dns_computer_name",
3168 FT_STRING, BASE_NONE, NULL, 0x0,
3171 { &hf_ntlmssp_ntlmv2_response_dns_domain_name,
3172 { "DNS Domain Name", "ntlmssp.ntlmv2_response.dns_domain_name",
3173 FT_STRING, BASE_NONE, NULL, 0x0,
3176 { &hf_ntlmssp_ntlmv2_response_dns_tree_name,
3177 { "DNS Tree Name", "ntlmssp.ntlmv2_response.dns_tree_name",
3178 FT_STRING, BASE_NONE, NULL, 0x0,
3181 { &hf_ntlmssp_ntlmv2_response_flags,
3182 { "Flags", "ntlmssp.ntlmv2_response.flags",
3183 FT_UINT32, BASE_HEX, NULL, 0x0,
3186 { &hf_ntlmssp_ntlmv2_response_timestamp,
3187 { "Timestamp", "ntlmssp.ntlmv2_response.timestamp",
3188 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0,
3191 { &hf_ntlmssp_ntlmv2_response_restrictions,
3192 { "Restrictions", "ntlmssp.ntlmv2_response.restrictions",
3193 FT_BYTES, BASE_NONE, NULL, 0,
3196 { &hf_ntlmssp_ntlmv2_response_target_name,
3197 { "Target Name", "ntlmssp.ntlmv2_response.target_name",
3198 FT_STRING, BASE_NONE, NULL, 0x0,
3201 { &hf_ntlmssp_ntlmv2_response_channel_bindings,
3202 { "Channel Bindings", "ntlmssp.ntlmv2_response.channel_bindings",
3203 FT_BYTES, BASE_NONE, NULL, 0x0,
3207 { &hf_ntlmssp_message_integrity_code,
3208 { "MIC", "ntlmssp.authenticate.mic",
3209 FT_BYTES, BASE_NONE, NULL, 0x0,
3210 "Message Integrity Code", HFILL}
3213 { "NTLMSSP Verifier", "ntlmssp.verf",
3214 FT_NONE, BASE_NONE, NULL, 0x0,
3217 { &hf_ntlmssp_verf_vers,
3218 { "Version Number", "ntlmssp.verf.vers",
3219 FT_UINT32, BASE_DEC, NULL, 0x0,
3222 { &hf_ntlmssp_verf_body,
3223 { "Verifier Body", "ntlmssp.verf.body",
3224 FT_BYTES, BASE_NONE, NULL, 0x0,
3227 { &hf_ntlmssp_decrypted_payload,
3228 { "NTLM Decrypted Payload", "ntlmssp.decrypted_payload",
3229 FT_BYTES, BASE_NONE, NULL, 0x0,
3232 { &hf_ntlmssp_verf_randompad,
3233 { "Random Pad", "ntlmssp.verf.randompad",
3234 FT_UINT32, BASE_HEX, NULL, 0x0,
3237 { &hf_ntlmssp_verf_crc32,
3238 { "Verifier CRC32", "ntlmssp.verf.crc32",
3239 FT_UINT32, BASE_HEX, NULL, 0x0,
3242 { &hf_ntlmssp_verf_hmacmd5,
3243 { "HMAC MD5", "ntlmssp.verf.hmacmd5",
3244 FT_BYTES, BASE_NONE, NULL, 0x0,
3247 { &hf_ntlmssp_verf_sequence,
3248 { "Sequence", "ntlmssp.verf.sequence",
3249 FT_BYTES, BASE_NONE, NULL, 0x0,
3253 { &hf_ntlmssp_ntlmv2_response,
3254 { "NTLMv2 Response", "ntlmssp.ntlmv2_response",
3255 FT_BYTES, BASE_NONE, NULL, 0x0,
3258 { &hf_ntlmssp_ntlmv2_response_hmac,
3259 { "HMAC", "ntlmssp.ntlmv2_response.hmac",
3260 FT_BYTES, BASE_NONE, NULL, 0x0,
3263 { &hf_ntlmssp_ntlmv2_response_header,
3264 { "Header", "ntlmssp.ntlmv2_response.header",
3265 FT_UINT32, BASE_HEX, NULL, 0x0,
3268 { &hf_ntlmssp_ntlmv2_response_reserved,
3269 { "Reserved", "ntlmssp.ntlmv2_response.reserved",
3270 FT_UINT32, BASE_HEX, NULL, 0x0,
3273 { &hf_ntlmssp_ntlmv2_response_time,
3274 { "Time", "ntlmssp.ntlmv2_response.time",
3275 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0,
3278 { &hf_ntlmssp_ntlmv2_response_chal,
3279 { "Client challenge", "ntlmssp.ntlmv2_response.chal",
3280 FT_BYTES, BASE_NONE, NULL, 0x0,
3283 { &hf_ntlmssp_ntlmv2_response_unknown,
3284 { "Unknown", "ntlmssp.ntlmv2_response.unknown",
3285 FT_UINT32, BASE_HEX, NULL, 0x0,
3291 static gint *ett[] = {
3293 &ett_ntlmssp_negotiate_flags,
3294 &ett_ntlmssp_string,
3296 &ett_ntlmssp_version,
3297 &ett_ntlmssp_challenge_target_info,
3298 &ett_ntlmssp_challenge_target_info_item,
3299 &ett_ntlmssp_ntlmv2_response,
3300 &ett_ntlmssp_ntlmv2_response_item,
3302 module_t *ntlmssp_module;
3304 proto_ntlmssp = proto_register_protocol (
3305 "NTLM Secure Service Provider", /* name */
3306 "NTLMSSP", /* short name */
3307 "ntlmssp" /* abbrev */
3309 proto_register_field_array (proto_ntlmssp, hf, array_length (hf));
3310 proto_register_subtree_array (ett, array_length (ett));
3311 register_init_routine(&ntlmssp_init_protocol);
3313 ntlmssp_module = prefs_register_protocol(proto_ntlmssp, NULL);
3315 prefs_register_string_preference(ntlmssp_module, "nt_password",
3317 "NT Password (used to decrypt payloads)",
3320 register_dissector("ntlmssp", dissect_ntlmssp, proto_ntlmssp);
3321 new_register_dissector("ntlmssp_payload", dissect_ntlmssp_payload, proto_ntlmssp);
3322 new_register_dissector("ntlmssp_data_only", dissect_ntlmssp_payload_only, proto_ntlmssp);
3323 new_register_dissector("ntlmssp_verf", dissect_ntlmssp_verf, proto_ntlmssp);
3327 proto_reg_handoff_ntlmssp(void)
3329 dissector_handle_t ntlmssp_handle, ntlmssp_wrap_handle;
3331 /* Register protocol with the GSS-API module */
3333 ntlmssp_handle = find_dissector("ntlmssp");
3334 ntlmssp_wrap_handle = find_dissector("ntlmssp_verf");
3335 gssapi_init_oid("1.3.6.1.4.1.311.2.2.10", proto_ntlmssp, ett_ntlmssp,
3336 ntlmssp_handle, ntlmssp_wrap_handle,
3337 "NTLMSSP - Microsoft NTLM Security Support Provider");
3339 /* Register authenticated pipe dissector */
3342 * XXX - the verifiers here seem to have a version of 1 and a body of all
3345 * XXX - DCE_C_AUTHN_LEVEL_CONNECT is, according to the DCE RPC 1.1
3346 * spec, upgraded to DCE_C_AUTHN_LEVEL_PKT. Should we register
3347 * any other levels here?
3349 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_CONNECT,
3350 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
3353 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT,
3354 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
3357 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
3358 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
3361 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
3362 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
3364 ntlmssp_tap = register_tap("ntlmssp");
3366 heur_dissector_add("credssp", dissect_ntlmssp_heur, proto_ntlmssp);
3371 * Editor modelines - http://www.wireshark.org/tools/modelines.html
3376 * indent-tabs-mode: nil
3379 * vi: set shiftwidth=2 tabstop=8 expandtab:
3380 * :indentSize=2:tabSize=8:noTabs=true: