2 * Add-on for better NTLM v1/v2 handling
3 * Copyright 2009 Matthieu Patou <matthieu.patou@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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
39 #include <epan/packet.h>
41 #include "packet-windows-common.h"
42 #include "packet-smb-common.h"
43 #include "packet-frame.h"
44 #include <epan/asn1.h>
45 #include "packet-kerberos.h"
46 #include <epan/prefs.h>
47 #include <epan/emem.h>
49 #include <epan/crypt/crypt-rc4.h>
50 #include <epan/crypt/crypt-md4.h>
51 #include <epan/crypt/crypt-md5.h>
52 #include <epan/crypt/crypt-des.h>
53 #include "packet-dcerpc.h"
54 #include "packet-gssapi.h"
55 #include <epan/crc32.h>
57 #include "packet-ntlmssp.h"
59 static int ntlmssp_tap = -1;
63 #define NTLMSSP_NEGOTIATE 1
64 #define NTLMSSP_CHALLENGE 2
65 #define NTLMSSP_AUTH 3
66 #define NTLMSSP_UNKNOWN 4
67 #define CLIENT_SIGN_TEXT "session key to client-to-server signing key magic constant"
68 #define CLIENT_SEAL_TEXT "session key to client-to-server sealing key magic constant"
69 #define SERVER_SIGN_TEXT "session key to server-to-client signing key magic constant"
70 #define SERVER_SEAL_TEXT "session key to server-to-client sealing key magic constant"
72 static const value_string ntlmssp_message_types[] = {
73 { NTLMSSP_NEGOTIATE, "NTLMSSP_NEGOTIATE" },
74 { NTLMSSP_CHALLENGE, "NTLMSSP_CHALLENGE" },
75 { NTLMSSP_AUTH, "NTLMSSP_AUTH" },
76 { NTLMSSP_UNKNOWN, "NTLMSSP_UNKNOWN" },
80 typedef struct _md4_pass {
84 static unsigned char 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";
85 static GHashTable* hash_packet = NULL;
88 * NTLMSSP negotiation flags
93 * http://davenport.sourceforge.net/ntlm.html
95 * although that document says that:
97 * 0x00010000 is "Target Type Domain";
98 * 0x00020000 is "Target Type Server"
99 * 0x00040000 is "Target Type Share";
101 * and that 0x00100000, 0x00200000, and 0x00400000 are
102 * "Request Init Response", "Request Accept Response", and
103 * "Request Non-NT Session Key", rather than those values shifted
104 * right one having those interpretations.
106 * UPDATE: Further information obtained from [MS-NLMP]:
107 * NT LAN Manager (NTLM) Authentication Protocol Specification
108 * http://msdn2.microsoft.com/en-us/library/cc236621.aspx
111 #define NTLMSSP_NEGOTIATE_UNICODE 0x00000001
112 #define NTLMSSP_NEGOTIATE_OEM 0x00000002
113 #define NTLMSSP_REQUEST_TARGET 0x00000004
114 #define NTLMSSP_NEGOTIATE_00000008 0x00000008
115 #define NTLMSSP_NEGOTIATE_SIGN 0x00000010
116 #define NTLMSSP_NEGOTIATE_SEAL 0x00000020
117 #define NTLMSSP_NEGOTIATE_DATAGRAM 0x00000040
118 #define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080
119 #define NTLMSSP_NEGOTIATE_00000100 0x00000100
120 #define NTLMSSP_NEGOTIATE_NTLM 0x00000200
121 #define NTLMSSP_NEGOTIATE_NT_ONLY 0x00000400
122 #define NTLMSSP_NEGOTIATE_00000800 0x00000800
123 #define NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED 0x00001000
124 #define NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED 0x00002000
125 #define NTLMSSP_NEGOTIATE_00004000 0x00004000
126 #define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000
127 #define NTLMSSP_TARGET_TYPE_DOMAIN 0x00010000
128 #define NTLMSSP_TARGET_TYPE_SERVER 0x00020000
129 #define NTLMSSP_TARGET_TYPE_SHARE 0x00040000
130 #define NTLMSSP_NEGOTIATE_EXTENDED_SECURITY 0x00080000
131 #define NTLMSSP_NEGOTIATE_IDENTIFY 0x00100000
132 #define NTLMSSP_NEGOTIATE_00200000 0x00200000
133 #define NTLMSSP_REQUEST_NON_NT_SESSION 0x00400000
134 #define NTLMSSP_NEGOTIATE_TARGET_INFO 0x00800000
135 #define NTLMSSP_NEGOTIATE_01000000 0x01000000
136 #define NTLMSSP_NEGOTIATE_VERSION 0x02000000
137 #define NTLMSSP_NEGOTIATE_04000000 0x04000000
138 #define NTLMSSP_NEGOTIATE_08000000 0x08000000
139 #define NTLMSSP_NEGOTIATE_10000000 0x10000000
140 #define NTLMSSP_NEGOTIATE_128 0x20000000
141 #define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000
142 #define NTLMSSP_NEGOTIATE_56 0x80000000
144 static int proto_ntlmssp = -1;
145 static int hf_ntlmssp = -1;
146 static int hf_ntlmssp_auth = -1;
147 static int hf_ntlmssp_message_type = -1;
148 static int hf_ntlmssp_negotiate_flags = -1;
149 static int hf_ntlmssp_negotiate_flags_01 = -1;
150 static int hf_ntlmssp_negotiate_flags_02 = -1;
151 static int hf_ntlmssp_negotiate_flags_04 = -1;
152 static int hf_ntlmssp_negotiate_flags_08 = -1;
153 static int hf_ntlmssp_negotiate_flags_10 = -1;
154 static int hf_ntlmssp_negotiate_flags_20 = -1;
155 static int hf_ntlmssp_negotiate_flags_40 = -1;
156 static int hf_ntlmssp_negotiate_flags_80 = -1;
157 static int hf_ntlmssp_negotiate_flags_100 = -1;
158 static int hf_ntlmssp_negotiate_flags_200 = -1;
159 static int hf_ntlmssp_negotiate_flags_400 = -1;
160 static int hf_ntlmssp_negotiate_flags_800 = -1;
161 static int hf_ntlmssp_negotiate_flags_1000 = -1;
162 static int hf_ntlmssp_negotiate_flags_2000 = -1;
163 static int hf_ntlmssp_negotiate_flags_4000 = -1;
164 static int hf_ntlmssp_negotiate_flags_8000 = -1;
165 static int hf_ntlmssp_negotiate_flags_10000 = -1;
166 static int hf_ntlmssp_negotiate_flags_20000 = -1;
167 static int hf_ntlmssp_negotiate_flags_40000 = -1;
168 static int hf_ntlmssp_negotiate_flags_80000 = -1;
169 static int hf_ntlmssp_negotiate_flags_100000 = -1;
170 static int hf_ntlmssp_negotiate_flags_200000 = -1;
171 static int hf_ntlmssp_negotiate_flags_400000 = -1;
172 static int hf_ntlmssp_negotiate_flags_800000 = -1;
173 static int hf_ntlmssp_negotiate_flags_1000000 = -1;
174 static int hf_ntlmssp_negotiate_flags_2000000 = -1;
175 static int hf_ntlmssp_negotiate_flags_4000000 = -1;
176 static int hf_ntlmssp_negotiate_flags_8000000 = -1;
177 static int hf_ntlmssp_negotiate_flags_10000000 = -1;
178 static int hf_ntlmssp_negotiate_flags_20000000 = -1;
179 static int hf_ntlmssp_negotiate_flags_40000000 = -1;
180 static int hf_ntlmssp_negotiate_flags_80000000 = -1;
181 static int hf_ntlmssp_negotiate_workstation_strlen = -1;
182 static int hf_ntlmssp_negotiate_workstation_maxlen = -1;
183 static int hf_ntlmssp_negotiate_workstation_buffer = -1;
184 static int hf_ntlmssp_negotiate_workstation = -1;
185 static int hf_ntlmssp_negotiate_domain_strlen = -1;
186 static int hf_ntlmssp_negotiate_domain_maxlen = -1;
187 static int hf_ntlmssp_negotiate_domain_buffer = -1;
188 static int hf_ntlmssp_negotiate_domain = -1;
189 static int hf_ntlmssp_ntlm_server_challenge = -1;
190 static int hf_ntlmssp_ntlm_client_challenge = -1;
191 static int hf_ntlmssp_reserved = -1;
192 static int hf_ntlmssp_challenge_domain = -1;
193 static int hf_ntlmssp_auth_username = -1;
194 static int hf_ntlmssp_auth_domain = -1;
195 static int hf_ntlmssp_auth_hostname = -1;
196 static int hf_ntlmssp_auth_lmresponse = -1;
197 static int hf_ntlmssp_auth_ntresponse = -1;
198 static int hf_ntlmssp_auth_sesskey = -1;
199 static int hf_ntlmssp_string_len = -1;
200 static int hf_ntlmssp_string_maxlen = -1;
201 static int hf_ntlmssp_string_offset = -1;
202 static int hf_ntlmssp_blob_len = -1;
203 static int hf_ntlmssp_blob_maxlen = -1;
204 static int hf_ntlmssp_blob_offset = -1;
205 static int hf_ntlmssp_address_list = -1;
206 static int hf_ntlmssp_address_list_len = -1;
207 static int hf_ntlmssp_address_list_maxlen = -1;
208 static int hf_ntlmssp_address_list_offset = -1;
209 static int hf_ntlmssp_address_list_server_nb = -1;
210 static int hf_ntlmssp_address_list_domain_nb = -1;
211 static int hf_ntlmssp_address_list_server_dns = -1;
212 static int hf_ntlmssp_address_list_domain_dns = -1;
213 static int hf_ntlmssp_address_list_terminator = -1;
214 static int hf_ntlmssp_address_list_item_type = -1;
215 static int hf_ntlmssp_address_list_item_len = -1;
216 static int hf_ntlmssp_address_list_item_content = -1;
217 static int hf_ntlmssp_verf = -1;
218 static int hf_ntlmssp_verf_vers = -1;
219 static int hf_ntlmssp_verf_body = -1;
220 static int hf_ntlmssp_verf_randompad = -1;
221 static int hf_ntlmssp_verf_hmacmd5 = -1;
222 static int hf_ntlmssp_verf_crc32 = -1;
223 static int hf_ntlmssp_verf_sequence = -1;
224 static int hf_ntlmssp_decrypted_payload = -1;
225 static int hf_ntlmssp_ntlmv2_response = -1;
226 static int hf_ntlmssp_ntlmv2_response_hmac = -1;
227 static int hf_ntlmssp_ntlmv2_response_header = -1;
228 static int hf_ntlmssp_ntlmv2_response_reserved = -1;
229 static int hf_ntlmssp_ntlmv2_response_time = -1;
230 static int hf_ntlmssp_ntlmv2_response_chal = -1;
231 static int hf_ntlmssp_ntlmv2_response_unknown = -1;
232 static int hf_ntlmssp_ntlmv2_response_name = -1;
233 static int hf_ntlmssp_ntlmv2_response_name_type = -1;
234 static int hf_ntlmssp_ntlmv2_response_name_len = -1;
235 static int hf_ntlmssp_ntlmv2_response_restriction = -1;
236 static int hf_ntlmssp_ntlmv2_response_client_time = -1;
238 static gint ett_ntlmssp = -1;
239 static gint ett_ntlmssp_negotiate_flags = -1;
240 static gint ett_ntlmssp_string = -1;
241 static gint ett_ntlmssp_blob = -1;
242 static gint ett_ntlmssp_address_list = -1;
243 static gint ett_ntlmssp_address_list_item = -1;
244 static gint ett_ntlmssp_ntlmv2_response = -1;
245 static gint ett_ntlmssp_ntlmv2_response_name = -1;
247 /* Configuration variables */
248 static const char *nt_password = NULL;
250 #define MAX_BLOB_SIZE 256
251 typedef struct _ntlmssp_blob {
253 guint8 contents[MAX_BLOB_SIZE];
256 /* Used in the conversation function */
257 typedef struct _ntlmssp_info {
260 rc4_state_struct rc4_state_client;
261 rc4_state_struct rc4_state_server;
262 guint8 sign_key_client[16];
263 guint8 sign_key_server[16];
264 guint32 server_dest_port;
265 unsigned char server_challenge[8];
266 unsigned char client_challenge[8];
267 int rc4_state_initialized;
268 ntlmssp_blob ntlm_response;
269 ntlmssp_blob lm_response;
272 /* If this struct exists in the payload_decrypt, then we have already
274 typedef struct _ntlmssp_packet_info {
275 guint8 *decrypted_payload;
278 gboolean payload_decrypted;
279 gboolean verifier_decrypted;
280 } ntlmssp_packet_info;
283 static void printnbyte(const guint8* tab,int nb,char* txt,char* txt2)
286 fprintf(stderr,"%s ",txt);
289 fprintf(stderr,"%02hhX ",*(tab+i));
291 fprintf(stderr,"%s",txt2);
294 static void printnchar(const guint8* tab,int nb,char* txt,char* txt2)
297 fprintf(stderr,"%s ",txt);
300 fprintf(stderr,"%c",*(tab+i));
302 fprintf(stderr,"%s",txt2);
306 static void printnbyte(const guint8* tab _U_,int nb _U_, char* txt _U_,char* txt2 _U_)
311 * GSlist of decrypted payloads.
313 static GSList *decrypted_payloads;
315 int LEBE_Convert(int value)
320 b=(value&0x0000FF00) >> 8;
321 c=(value&0x00FF0000) >> 16;
322 d=(value&0xFF000000) >> 24;
323 return (a << 24) | (b << 16) | (c << 8) | d;
326 Perform a DES encryption with a 16 bit key and 8bit data item.
327 It's in fact 3 susbsequent call to crypt_des_ecb with a 7 bit key.
328 Missing bits for the key are replaced by 0;
329 Returns output in response, which is expected to be 24 bytes.
331 static int crypt_des_ecb_long(guint8 *response,
335 guint8 pw21[21]; /* 21 bytes place for the needed key */
337 memset(pw21, 0, sizeof(pw21));
338 memcpy(pw21, key, 16);
340 memset(response, 0, 24);
341 /* crypt_des_ecb(data,key)*/
342 crypt_des_ecb(response, data, pw21, 1);
343 crypt_des_ecb(response + 8, data, pw21 + 7, 1);
344 crypt_des_ecb(response + 16, data, pw21 + 14, 1);
349 Generate a challenge response, given an eight byte challenge and
350 either the NT or the Lan Manager password hash (16 bytes).
351 Returns output in response, which is expected to be 24 bytes.
353 static int ntlmssp_generate_challenge_response(guint8 *response,
354 const guint8 *passhash,
355 const guint8 *challenge)
357 guint8 pw21[21]; /* Password hash padded to 21 bytes */
359 memset(pw21, 0x0, sizeof(pw21));
360 memcpy(pw21, passhash, 16);
362 memset(response, 0, 24);
364 crypt_des_ecb(response, challenge, pw21, 1);
365 crypt_des_ecb(response + 8, challenge, pw21 + 7, 1);
366 crypt_des_ecb(response + 16, challenge, pw21 + 14, 1);
372 /* Ultra simple ainsi to unicode converter, will only work for ascii password ...*/
373 static void str_to_unicode(const char *nt_password, char *nt_password_unicode)
375 int password_len = 0;
378 password_len = strlen(nt_password);
379 if(nt_password_unicode != NULL)
381 for(i=0;i<(password_len);i++)
383 nt_password_unicode[i*2]=nt_password[i];
384 nt_password_unicode[i*2+1]=0;
387 nt_password_unicode[2*password_len]='\0';
390 /* This function generate the Key Exchange Key
391 * Depending on the flags this key will either be used to crypt the exported session key
392 * or will be used directly as exported session key.
393 * Exported session key is the key that will be used for sealing and signing communication*/
396 get_keyexchange_key(unsigned char keyexchangekey[16],const unsigned char sessionbasekey[16],const unsigned char lm_challenge_response[24],int flags)
401 memset(keyexchangekey,0,16);
402 memset(basekey,0,16);
403 /* sessionbasekey is either derived from lm_password_hash or from nt_password_hash depending on the key type negotiated */
404 memcpy(basekey,sessionbasekey,8);
405 memset(basekey,0xBD,8);
406 if(flags&NTLMSSP_NEGOTIATE_LM_KEY)
409 crypt_des_ecb(keyexchangekey,lm_challenge_response,basekey,1);
410 crypt_des_ecb(keyexchangekey+8,lm_challenge_response,basekey+7,1);
414 if(flags&NTLMSSP_REQUEST_NON_NT_SESSION)
416 /*People from samba tends to use the same function in this case than in the previous one but with 0 data
417 * it's not clear that it produce the good result
418 * memcpy(keyexchangekey,lm_hash,8);
419 * Let's trust samba implementation it mights seem weird but they are more often rights than the spec !
422 crypt_des_ecb(keyexchangekey,zeros,basekey,3);
423 crypt_des_ecb(keyexchangekey+8,zeros,basekey+7,1);
427 /* it is stated page 65 of NTLM SSP spec that sessionbasekey should be encrypted with hmac_md5 using the concact of both challenge
428 * when it's NTLM v1 + extended security but it turns out to be wrong !
430 memcpy(keyexchangekey,sessionbasekey,16);
435 get_md4pass_list(md4_pass** p_pass_list,const char* nt_password) {
438 unsigned char nt_password_hash[16];
439 int password_len = 0;
440 char nt_password_unicode[256];
444 for(ek=enc_key_list;ek;ek=ek->next){
445 if( ek->keylength == 16 ) {
449 memset(nt_password_hash,0,16);
450 if (nt_password[0] != '\0' && ( strlen(nt_password) < 129 )) {
452 password_len = strlen(nt_password);
453 str_to_unicode(nt_password,nt_password_unicode);
454 crypt_md4(nt_password_hash,nt_password_unicode,password_len*2);
457 /* Unable to calculate the session key without a password or if password is more than 128 char ......*/
461 *p_pass_list = ep_alloc(nb_pass*sizeof(md4_pass));
462 pass_list=*p_pass_list;
464 if( memcmp(nt_password_hash,zeros,16) != 0 ) {
465 memcpy(pass_list[i].md4,nt_password_hash,16);
468 for(ek=enc_key_list;ek;ek=ek->next){
469 if( ek->keylength == 16 ) {
470 memcpy(pass_list[i].md4,ek->keyvalue,16);
476 /* Create an NTLMSSP version 2
479 create_ntlmssp_v2_key(const char *nt_password, const guint8 *serverchallenge , const guint8 *clientchallenge ,
480 guint8 *sessionkey ,const guint8 *encryptedsessionkey , int flags , ntlmssp_blob ntlm_response, ntlmssp_blob lm_response _U_, ntlmssp_header_t *ntlmssph ) {
481 char domain_name_unicode[256];
482 char user_uppercase[256];
485 unsigned char nt_password_hash[16];
486 unsigned char nt_proof[16];
487 unsigned char ntowf[16];
488 guint8 sessionbasekey[16];
489 guint8 keyexchangekey[16];
490 guint8 lm_challenge_response[24];
493 rc4_state_struct rc4state;
500 /* We are going to try password encrypted in keytab as well, it's an idean of Stefan Metzmacher <metze@samba.org>
501 * The idea is to be able to test all the key of domain in once and to be able to decode the NTLM dialogs */
503 memset(sessionkey, 0, 16);
504 nb_pass = get_md4pass_list(&pass_list,nt_password);
506 memset(user_uppercase,0,256);
507 user_len = strlen(ntlmssph->acct_name);
508 if( user_len < 129 ) {
510 str_to_unicode(ntlmssph->acct_name,buf);
511 for (j = 0; j < (2*user_len); j++) {
512 if( buf[j] != '\0' ) {
513 user_uppercase[j] = toupper(buf[j]);
518 /* Unable to calculate the session not enought space in buffer, note this is unlikely to happen but ......*/
521 domain_len = strlen(ntlmssph->domain_name);
522 if( domain_len < 129 ) {
523 str_to_unicode(ntlmssph->domain_name,domain_name_unicode);
526 /* Unable to calculate the session not enought space in buffer, note this is unlikely to happen but ......*/
529 while (i < nb_pass ) {
530 /*fprintf(stderr,"Turn %d, ",i);*/
531 memcpy(nt_password_hash,pass_list[i].md4,16);
532 /*printnbyte(nt_password_hash,16,"Current NT password hash: ","\n");*/
534 /* ntowf computation */
536 memcpy(buf,user_uppercase,user_len*2);
537 memcpy(buf+user_len*2,domain_name_unicode,domain_len*2);
538 md5_hmac(buf,domain_len*2+user_len*2,nt_password_hash,16,ntowf);
541 memcpy(buf,serverchallenge,8);
542 memcpy(buf+8,clientchallenge,8);
543 md5_hmac(buf,16,ntowf,16,lm_challenge_response);
544 memcpy(lm_challenge_response+16,clientchallenge,8);
545 printnbyte(lm_challenge_response,24,"LM Response: ","\n");
547 /* NT proof = First 16 bytes of NT response */
549 memcpy(buf,serverchallenge,8);
550 memcpy(buf+8,ntlm_response.contents+16,ntlm_response.length-16);
551 md5_hmac(buf,ntlm_response.length-8,ntowf,16,nt_proof);
552 printnbyte(nt_proof,16,"NT proof: ","\n");
553 if( !memcmp(nt_proof,ntlm_response.contents,16) ) {
564 md5_hmac(nt_proof,16,ntowf,16,sessionbasekey);
565 get_keyexchange_key(keyexchangekey,sessionbasekey,lm_challenge_response,flags);
566 /* now decrypt session key if needed and setup sessionkey for decrypting further communications */
567 if (flags & NTLMSSP_NEGOTIATE_KEY_EXCH)
569 memcpy(sessionkey,encryptedsessionkey,16);
570 crypt_rc4_init(&rc4state,keyexchangekey,16);
571 crypt_rc4(&rc4state,sessionkey,16);
575 memcpy(sessionkey,keyexchangekey,16);
579 /* Create an NTLMSSP version 1 key
580 * That is more complicated logic and methods and user challenge as well.
581 * password points to the ANSI password to encrypt, challenge points to
582 * the 8 octet challenge string
585 create_ntlmssp_v1_key(const char *nt_password, const guint8 *serverchallenge, const guint8 *clientchallenge,
586 guint8 *sessionkey,const guint8 *encryptedsessionkey, int flags, const guint8 *ref_nt_challenge_response,const guint8 *ref_lm_challenge_response)
588 unsigned char lm_password_upper[16];
589 unsigned char lm_password_hash[16];
590 unsigned char nt_password_hash[16];
591 unsigned char challenges_hash[16];
592 unsigned char challenges_hash_first8[8];
593 unsigned char challenges[16];
596 guint8 sessionbasekey[16];
597 guint8 keyexchangekey[16];
598 guint8 lm_challenge_response[24];
599 guint8 nt_challenge_response[24];
600 rc4_state_struct rc4state;
601 md5_state_t md5state;
602 char nt_password_unicode[256];
607 unsigned char lmhash_key[] =
608 {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
610 memset(sessionkey, 0, 16);
611 memset(lm_password_upper, 0, sizeof(lm_password_upper));
612 /* lm auth/lm session == (!NTLM_NEGOTIATE_NT_ONLY && NTLMSSP_NEGOTIATE_LM_KEY) || ! (EXTENDED_SECURITY) || ! NTLMSSP_NEGOTIATE_NTLM*/
613 /* Create a Lan Manager hash of the input password */
614 if (nt_password[0] != '\0') {
615 password_len = strlen(nt_password);
616 /*Do not forget to free nt_password_nt*/
617 str_to_unicode(nt_password,nt_password_unicode);
618 crypt_md4(nt_password_hash,nt_password_unicode,password_len*2);
619 /* Truncate password if too long */
620 if (password_len > 16)
622 for (i = 0; i < password_len; i++) {
623 lm_password_upper[i] = toupper(nt_password[i]);
628 /* Unable to calculate the session key without a password ... and we will not use one for a keytab*/
629 if( !(flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY )) {
633 if((flags & NTLMSSP_NEGOTIATE_LM_KEY && !(flags & NTLMSSP_NEGOTIATE_NT_ONLY)) || !(flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY) || !(flags & NTLMSSP_NEGOTIATE_NTLM)) {
634 crypt_des_ecb(lm_password_hash, lmhash_key, lm_password_upper, 1);
635 crypt_des_ecb(lm_password_hash+8, lmhash_key, lm_password_upper+7, 1);
636 ntlmssp_generate_challenge_response(lm_challenge_response,
637 lm_password_hash, serverchallenge);
638 memcpy(sessionbasekey,lm_password_hash,16);
642 memset(lm_challenge_response,0,24);
643 if( flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY ) {
644 nb_pass = get_md4pass_list(&pass_list,nt_password);
646 while (i < nb_pass ) {
647 /*fprintf(stderr,"Turn %d, ",i);*/
648 memcpy(nt_password_hash,pass_list[i].md4,16);
649 /*printnbyte(nt_password_hash,16,"Current NT password hash: ","\n");*/
651 memcpy(lm_challenge_response,clientchallenge,8);
653 md5_append(&md5state,serverchallenge,8);
654 md5_append(&md5state,clientchallenge,8);
655 md5_finish(&md5state,challenges_hash);
656 memcpy(challenges_hash_first8,challenges_hash,8);
657 crypt_des_ecb_long(nt_challenge_response,nt_password_hash,challenges_hash_first8);
658 if( !memcmp(ref_nt_challenge_response,nt_challenge_response,24) ) {
665 crypt_des_ecb_long(nt_challenge_response,nt_password_hash,serverchallenge);
666 if( flags & NTLMSSP_NEGOTIATE_NT_ONLY ) {
667 memcpy(lm_challenge_response,nt_challenge_response,24);
670 crypt_des_ecb_long(lm_challenge_response,lm_password_hash,serverchallenge);
672 if( !memcmp(ref_nt_challenge_response,nt_challenge_response,24) && !memcmp(ref_lm_challenge_response,lm_challenge_response,24) ) {
676 /* So it's clearly not like this that's put into NTLMSSP doc but after some digging into samba code I'm quite confident
677 * that sessionbasekey should be based md4(nt_password_hash) only in the case of some NT auth
678 * Otherwise it should be lm_password_hash ...*/
679 crypt_md4(md4,nt_password_hash,16);
680 if (flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY) {
681 memcpy(challenges,serverchallenge,8);
682 memcpy(challenges+8,clientchallenge,8);
683 /*md5_hmac(text,text_len,key,key_len,digest);*/
684 md5_hmac(challenges,16,md4,16,sessionbasekey);
687 memcpy(sessionbasekey,md4,16);
696 get_keyexchange_key(keyexchangekey,sessionbasekey,lm_challenge_response,flags);
697 memset(sessionkey, 0, 16);
698 /*printnbyte(nt_challenge_response,24,"NT challenge response","\n");
699 printnbyte(lm_challenge_response,24,"LM challenge response","\n");*/
700 /* now decrypt session key if needed and setup sessionkey for decrypting further communications */
701 if (flags & NTLMSSP_NEGOTIATE_KEY_EXCH)
703 memcpy(sessionkey,encryptedsessionkey,16);
704 crypt_rc4_init(&rc4state,keyexchangekey,16);
705 crypt_rc4(&rc4state,sessionkey,16);
709 memcpy(sessionkey,keyexchangekey,16);
713 get_siging_key(guint8 *sign_key_server,guint8* sign_key_client,const guint8 key[16], int keylen)
715 md5_state_t md5state;
716 md5_state_t md5state2;
717 memset(sign_key_client,0,16);
718 memset(sign_key_server,0,16);
720 md5_append(&md5state,key,keylen);
721 md5_append(&md5state,CLIENT_SIGN_TEXT,strlen(CLIENT_SIGN_TEXT)+1);
722 md5_finish(&md5state,sign_key_client);
723 md5_init(&md5state2);
724 md5_append(&md5state2,key,keylen);
725 md5_append(&md5state2,SERVER_SIGN_TEXT,strlen(SERVER_SIGN_TEXT)+1);
726 md5_finish(&md5state2,sign_key_server);
730 /* We return either a 128 or 64 bit key
733 get_sealing_rc4key(const guint8 exportedsessionkey[16] ,const int flags ,int *keylen ,guint8 *clientsealkey ,guint8 *serversealkey)
735 md5_state_t md5state;
736 md5_state_t md5state2;
737 memset(clientsealkey,0,16);
738 memset(serversealkey,0,16);
739 memcpy(clientsealkey,exportedsessionkey,16);
740 if (flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY)
742 if (flags & NTLMSSP_NEGOTIATE_128)
744 /* The exportedsessionkey has already the good length just update the length*/
749 if (flags & NTLMSSP_NEGOTIATE_56)
751 memset(clientsealkey+7,0,9);
756 memset(clientsealkey+5,0,11);
760 memcpy(serversealkey,clientsealkey,16);
762 md5_append(&md5state,clientsealkey,*keylen);
763 md5_append(&md5state,CLIENT_SEAL_TEXT,strlen(CLIENT_SEAL_TEXT)+1);
764 md5_finish(&md5state,clientsealkey);
765 md5_init(&md5state2);
766 md5_append(&md5state2,serversealkey,*keylen);
767 md5_append(&md5state2,SERVER_SEAL_TEXT,strlen(SERVER_SEAL_TEXT)+1);
768 md5_finish(&md5state2,serversealkey);
772 if (flags & NTLMSSP_NEGOTIATE_128)
774 /* The exportedsessionkey has already the good length just update the length*/
780 if (flags & NTLMSSP_NEGOTIATE_56)
782 memset(clientsealkey+7,0,9);
786 memset(clientsealkey+5,0,11);
787 clientsealkey[5]=0xe5;
788 clientsealkey[6]=0x38;
789 clientsealkey[7]=0xb0;
792 serversealkey = memcpy(serversealkey,clientsealkey,*keylen);
795 /* Create an NTLMSSP version 1 key.
796 * password points to the ANSI password to encrypt, challenge points to
797 * the 8 octet challenge string, key128 will do a 128 bit key if set to 1,
798 * otherwise it will do a 40 bit key. The result is stored in
799 * sspkey (expected to be 16 octets)
801 /* dissect a string - header area contains:
804 four byte offset of string in data area
805 The function returns the offset at the end of the string header,
806 but the 'end' parameter returns the offset of the end of the string itself
807 The 'start' parameter returns the offset of the beginning of the string
810 dissect_ntlmssp_string (tvbuff_t *tvb, int offset,
811 proto_tree *ntlmssp_tree,
812 gboolean unicode_strings,
813 int string_hf, int *start, int *end,
814 const char **stringp)
816 proto_tree *tree = NULL;
817 proto_item *tf = NULL;
818 gint16 string_length = tvb_get_letohs(tvb, offset);
819 gint16 string_maxlen = tvb_get_letohs(tvb, offset+2);
820 gint32 string_offset = tvb_get_letohl(tvb, offset+4);
821 const char *string_text = NULL;
825 *start = (string_offset > offset+8 ? string_offset : offset+8);
826 if (0 == string_length) {
829 proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
836 bc = result_length = string_length;
837 string_text = get_unicode_or_ascii_string(tvb, &string_offset,
838 unicode_strings, &result_length,
841 *stringp = string_text;
844 tf = proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
845 string_offset, result_length, string_text);
846 tree = proto_item_add_subtree(tf, ett_ntlmssp_string);
848 proto_tree_add_uint(tree, hf_ntlmssp_string_len,
849 tvb, offset, 2, string_length);
851 proto_tree_add_uint(tree, hf_ntlmssp_string_maxlen,
852 tvb, offset, 2, string_maxlen);
854 proto_tree_add_uint(tree, hf_ntlmssp_string_offset,
855 tvb, offset, 4, string_offset);
858 *end = string_offset + string_length;
862 /* dissect a generic blob - header area contains:
865 four byte offset of blob in data area
866 The function returns the offset at the end of the blob header,
867 but the 'end' parameter returns the offset of the end of the blob itself
870 dissect_ntlmssp_blob (tvbuff_t *tvb, int offset,
871 proto_tree *ntlmssp_tree,
872 int blob_hf, int *end, ntlmssp_blob *result)
874 proto_item *tf = NULL;
875 proto_tree *tree = NULL;
876 guint16 blob_length = tvb_get_letohs(tvb, offset);
877 guint16 blob_maxlen = tvb_get_letohs(tvb, offset+2);
878 guint32 blob_offset = tvb_get_letohl(tvb, offset+4);
879 if (0 == blob_length) {
880 *end = (blob_offset > ((guint)offset)+8 ? blob_offset : ((guint)offset)+8);
882 proto_tree_add_text(ntlmssp_tree, tvb, offset, 8, "%s: Empty",
883 proto_registrar_get_name(blob_hf));
888 tf = proto_tree_add_item (ntlmssp_tree, blob_hf, tvb,
889 blob_offset, blob_length, FALSE);
890 tree = proto_item_add_subtree(tf, ett_ntlmssp_blob);
892 proto_tree_add_uint(tree, hf_ntlmssp_blob_len,
893 tvb, offset, 2, blob_length);
895 proto_tree_add_uint(tree, hf_ntlmssp_blob_maxlen,
896 tvb, offset, 2, blob_maxlen);
898 proto_tree_add_uint(tree, hf_ntlmssp_blob_offset,
899 tvb, offset, 4, blob_offset);
902 *end = blob_offset + blob_length;
904 if (result != NULL) {
905 result->length = blob_length;
906 memset(result->contents, 0, MAX_BLOB_SIZE);
907 if (blob_length < MAX_BLOB_SIZE)
909 tvb_memcpy(tvb, result->contents, blob_offset, blob_length);
910 if (blob_hf == hf_ntlmssp_auth_lmresponse && !(memcmp(tvb->real_data+blob_offset+8,"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",16)))
912 proto_tree_add_item (ntlmssp_tree,
913 hf_ntlmssp_ntlm_client_challenge,
914 tvb, blob_offset, 8, FALSE);
919 /* If we are dissecting the NTLM response and it is a NTLMv2
920 response call the appropriate dissector. */
922 if (blob_hf == hf_ntlmssp_auth_ntresponse && blob_length > 24)
924 proto_tree_add_item (ntlmssp_tree,
925 hf_ntlmssp_ntlm_client_challenge,
926 tvb, blob_offset+32, 8, FALSE);
927 dissect_ntlmv2_response(tvb, tree, blob_offset, blob_length);
934 dissect_ntlmssp_negotiate_flags (tvbuff_t *tvb, int offset,
935 proto_tree *ntlmssp_tree,
936 guint32 negotiate_flags)
938 proto_tree *negotiate_flags_tree = NULL;
939 proto_item *tf = NULL;
942 tf = proto_tree_add_uint (ntlmssp_tree,
943 hf_ntlmssp_negotiate_flags,
944 tvb, offset, 4, negotiate_flags);
945 negotiate_flags_tree = proto_item_add_subtree (tf, ett_ntlmssp_negotiate_flags);
948 proto_tree_add_boolean (negotiate_flags_tree,
949 hf_ntlmssp_negotiate_flags_80000000,
950 tvb, offset, 4, negotiate_flags);
951 proto_tree_add_boolean (negotiate_flags_tree,
952 hf_ntlmssp_negotiate_flags_40000000,
953 tvb, offset, 4, negotiate_flags);
954 proto_tree_add_boolean (negotiate_flags_tree,
955 hf_ntlmssp_negotiate_flags_20000000,
956 tvb, offset, 4, negotiate_flags);
957 proto_tree_add_boolean (negotiate_flags_tree,
958 hf_ntlmssp_negotiate_flags_10000000,
959 tvb, offset, 4, negotiate_flags);
960 proto_tree_add_boolean (negotiate_flags_tree,
961 hf_ntlmssp_negotiate_flags_8000000,
962 tvb, offset, 4, negotiate_flags);
963 proto_tree_add_boolean (negotiate_flags_tree,
964 hf_ntlmssp_negotiate_flags_4000000,
965 tvb, offset, 4, negotiate_flags);
966 proto_tree_add_boolean (negotiate_flags_tree,
967 hf_ntlmssp_negotiate_flags_2000000,
968 tvb, offset, 4, negotiate_flags);
969 proto_tree_add_boolean (negotiate_flags_tree,
970 hf_ntlmssp_negotiate_flags_1000000,
971 tvb, offset, 4, negotiate_flags);
972 proto_tree_add_boolean (negotiate_flags_tree,
973 hf_ntlmssp_negotiate_flags_800000,
974 tvb, offset, 4, negotiate_flags);
975 proto_tree_add_boolean (negotiate_flags_tree,
976 hf_ntlmssp_negotiate_flags_400000,
977 tvb, offset, 4, negotiate_flags);
978 proto_tree_add_boolean (negotiate_flags_tree,
979 hf_ntlmssp_negotiate_flags_200000,
980 tvb, offset, 4, negotiate_flags);
981 proto_tree_add_boolean (negotiate_flags_tree,
982 hf_ntlmssp_negotiate_flags_100000,
983 tvb, offset, 4, negotiate_flags);
984 proto_tree_add_boolean (negotiate_flags_tree,
985 hf_ntlmssp_negotiate_flags_80000,
986 tvb, offset, 4, negotiate_flags);
987 proto_tree_add_boolean (negotiate_flags_tree,
988 hf_ntlmssp_negotiate_flags_40000,
989 tvb, offset, 4, negotiate_flags);
990 proto_tree_add_boolean (negotiate_flags_tree,
991 hf_ntlmssp_negotiate_flags_20000,
992 tvb, offset, 4, negotiate_flags);
993 proto_tree_add_boolean (negotiate_flags_tree,
994 hf_ntlmssp_negotiate_flags_10000,
995 tvb, offset, 4, negotiate_flags);
996 proto_tree_add_boolean (negotiate_flags_tree,
997 hf_ntlmssp_negotiate_flags_8000,
998 tvb, offset, 4, negotiate_flags);
999 proto_tree_add_boolean (negotiate_flags_tree,
1000 hf_ntlmssp_negotiate_flags_4000,
1001 tvb, offset, 4, negotiate_flags);
1002 proto_tree_add_boolean (negotiate_flags_tree,
1003 hf_ntlmssp_negotiate_flags_2000,
1004 tvb, offset, 4, negotiate_flags);
1005 proto_tree_add_boolean (negotiate_flags_tree,
1006 hf_ntlmssp_negotiate_flags_1000,
1007 tvb, offset, 4, negotiate_flags);
1008 proto_tree_add_boolean (negotiate_flags_tree,
1009 hf_ntlmssp_negotiate_flags_800,
1010 tvb, offset, 4, negotiate_flags);
1011 proto_tree_add_boolean (negotiate_flags_tree,
1012 hf_ntlmssp_negotiate_flags_400,
1013 tvb, offset, 4, negotiate_flags);
1014 proto_tree_add_boolean (negotiate_flags_tree,
1015 hf_ntlmssp_negotiate_flags_200,
1016 tvb, offset, 4, negotiate_flags);
1017 proto_tree_add_boolean (negotiate_flags_tree,
1018 hf_ntlmssp_negotiate_flags_100,
1019 tvb, offset, 4, negotiate_flags);
1020 proto_tree_add_boolean (negotiate_flags_tree,
1021 hf_ntlmssp_negotiate_flags_80,
1022 tvb, offset, 4, negotiate_flags);
1023 proto_tree_add_boolean (negotiate_flags_tree,
1024 hf_ntlmssp_negotiate_flags_40,
1025 tvb, offset, 4, negotiate_flags);
1026 proto_tree_add_boolean (negotiate_flags_tree,
1027 hf_ntlmssp_negotiate_flags_20,
1028 tvb, offset, 4, negotiate_flags);
1029 proto_tree_add_boolean (negotiate_flags_tree,
1030 hf_ntlmssp_negotiate_flags_10,
1031 tvb, offset, 4, negotiate_flags);
1032 proto_tree_add_boolean (negotiate_flags_tree,
1033 hf_ntlmssp_negotiate_flags_08,
1034 tvb, offset, 4, negotiate_flags);
1035 proto_tree_add_boolean (negotiate_flags_tree,
1036 hf_ntlmssp_negotiate_flags_04,
1037 tvb, offset, 4, negotiate_flags);
1038 proto_tree_add_boolean (negotiate_flags_tree,
1039 hf_ntlmssp_negotiate_flags_02,
1040 tvb, offset, 4, negotiate_flags);
1041 proto_tree_add_boolean (negotiate_flags_tree,
1042 hf_ntlmssp_negotiate_flags_01,
1043 tvb, offset, 4, negotiate_flags);
1045 return (offset + 4);
1048 /* Dissect a NTLM response. This is documented at
1049 http://ubiqx.org/cifs/SMB.html#SMB.8, para 2.8.5.3 */
1054 * XXX - the davenport document says that a type of 5 has been seen,
1055 * "apparently containing the 'parent' DNS domain for servers in
1059 #define NTLM_NAME_END 0x0000
1060 #define NTLM_NAME_NB_HOST 0x0001
1061 #define NTLM_NAME_NB_DOMAIN 0x0002
1062 #define NTLM_NAME_DNS_HOST 0x0003
1063 #define NTLM_NAME_DNS_DOMAIN 0x0004
1064 #define NTLM_NAME_CLIENT_TIME 0x0007
1065 #define NTLM_NAME_RESTRICTION 0x0008
1069 static const value_string ntlm_name_types[] = {
1070 { NTLM_NAME_END, "End of list" },
1071 { NTLM_NAME_NB_HOST, "NetBIOS host name" },
1072 { NTLM_NAME_NB_DOMAIN, "NetBIOS domain name" },
1073 { NTLM_NAME_DNS_HOST, "DNS host name" },
1074 { NTLM_NAME_DNS_DOMAIN, "DNS domain name" },
1076 { NTLM_NAME_CLIENT_TIME, "Client Time" },
1077 { NTLM_NAME_RESTRICTION, "Encoding restriction" },
1082 dissect_ntlmv2_response(tvbuff_t *tvb, proto_tree *tree, int offset, int len)
1084 proto_item *ntlmv2_item = NULL;
1085 proto_tree *ntlmv2_tree = NULL;
1086 const guint8 *restriction_bytes;
1087 /* Dissect NTLMv2 bits&pieces */
1090 ntlmv2_item = proto_tree_add_item(
1091 tree, hf_ntlmssp_ntlmv2_response, tvb,
1093 ntlmv2_tree = proto_item_add_subtree(
1094 ntlmv2_item, ett_ntlmssp_ntlmv2_response);
1097 proto_tree_add_item(
1098 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_hmac, tvb,
1103 proto_tree_add_item(
1104 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_header, tvb,
1109 proto_tree_add_item(
1110 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_reserved, tvb,
1115 offset = dissect_nt_64bit_time(
1116 tvb, ntlmv2_tree, offset, hf_ntlmssp_ntlmv2_response_time);
1118 proto_tree_add_item(
1119 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_chal, tvb,
1124 proto_tree_add_item(
1125 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_unknown, tvb,
1130 /* Variable length list of names */
1133 guint16 name_type = tvb_get_letohs(tvb, offset);
1134 guint16 name_len = tvb_get_letohs(tvb, offset + 2);
1135 proto_tree *name_tree = NULL;
1136 proto_item *name_item = NULL;
1140 name_item = proto_tree_add_item(
1141 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_name,
1142 tvb, offset, 0, TRUE);
1143 name_tree = proto_item_add_subtree(
1144 name_item, ett_ntlmssp_ntlmv2_response_name);
1147 /* Dissect name header */
1149 proto_tree_add_item(
1150 name_tree, hf_ntlmssp_ntlmv2_response_name_type, tvb,
1155 proto_tree_add_item(
1156 name_tree, hf_ntlmssp_ntlmv2_response_name_len, tvb,
1166 proto_item_append_text(
1168 val_to_str(name_type, ntlm_name_types,
1171 case NTLM_NAME_CLIENT_TIME:
1172 dissect_nt_64bit_time(
1173 tvb, name_tree, offset,
1174 hf_ntlmssp_ntlmv2_response_client_time);
1175 proto_item_append_text(
1176 name_item, "Client Time");
1178 case NTLM_NAME_RESTRICTION:
1179 proto_item_append_text(
1181 val_to_str(name_type, ntlm_name_types,
1183 restriction_bytes = tvb_get_ptr(tvb, offset,name_len);
1184 proto_tree_add_bytes (name_tree,hf_ntlmssp_ntlmv2_response_restriction,tvb,offset,name_len,restriction_bytes);
1186 case NTLM_NAME_NB_HOST:
1187 case NTLM_NAME_NB_DOMAIN:
1188 case NTLM_NAME_DNS_HOST:
1189 case NTLM_NAME_DNS_DOMAIN:
1191 name = tvb_get_ephemeral_faked_unicode(
1192 tvb, offset, name_len / 2, TRUE);
1193 proto_tree_add_text(
1194 name_tree, tvb, offset, name_len,
1196 proto_item_append_text(
1197 name_item, "%s, %s",
1198 val_to_str(name_type, ntlm_name_types,
1206 proto_item_set_len(name_item, name_len + 4);
1208 if (name_type == 0) /* End of list */
1213 * XXX - Windows puts 4 bytes of additional stuff here.
1214 * Samba's smbclient doesn't.
1215 * Both of them appear to be able to connect to W2K SMB
1217 * Should we display the rest of the response as an
1218 * "extra data" item?
1220 * XXX - we should also check whether we go past the length
1226 /* tapping into ntlmssph not yet implemented */
1228 dissect_ntlmssp_negotiate (tvbuff_t *tvb, int offset, proto_tree *ntlmssp_tree, ntlmssp_header_t *ntlmssph _U_)
1230 guint32 negotiate_flags;
1232 int workstation_end;
1235 /* NTLMSSP Negotiate Flags */
1236 negotiate_flags = tvb_get_letohl (tvb, offset);
1237 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
1241 * XXX - the davenport document says that these might not be
1242 * sent at all, presumably meaning the length of the message
1243 * isn't enough to contain them.
1245 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
1246 hf_ntlmssp_negotiate_domain,
1247 &start, &workstation_end, NULL);
1248 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
1249 hf_ntlmssp_negotiate_workstation,
1250 &start, &domain_end, NULL);
1252 /* XXX - two blobs after this one, sometimes? */
1254 return MAX(workstation_end, domain_end);
1259 dissect_ntlmssp_address_list (tvbuff_t *tvb, int offset,
1260 proto_tree *ntlmssp_tree,
1263 guint16 list_length = tvb_get_letohs(tvb, offset);
1264 guint16 list_maxlen = tvb_get_letohs(tvb, offset+2);
1265 guint32 list_offset = tvb_get_letohl(tvb, offset+4);
1266 guint16 item_type, item_length;
1267 guint32 item_offset;
1268 proto_item *tf = NULL;
1269 proto_tree *tree = NULL;
1270 proto_item *addr_tf = NULL;
1271 proto_tree *addr_tree = NULL;
1273 /* the address list is just a blob */
1274 if (0 == list_length) {
1275 *end = (list_offset > ((guint)offset)+8 ? list_offset : ((guint)offset)+8);
1277 proto_tree_add_text(ntlmssp_tree, tvb, offset, 8,
1278 "Address List: Empty");
1283 tf = proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_address_list, tvb,
1284 list_offset, list_length, FALSE);
1285 tree = proto_item_add_subtree(tf, ett_ntlmssp_address_list);
1287 proto_tree_add_uint(tree, hf_ntlmssp_address_list_len,
1288 tvb, offset, 2, list_length);
1290 proto_tree_add_uint(tree, hf_ntlmssp_address_list_maxlen,
1291 tvb, offset, 2, list_maxlen);
1293 proto_tree_add_uint(tree, hf_ntlmssp_address_list_offset,
1294 tvb, offset, 4, list_offset);
1297 /* Now enumerate through the individual items in the list */
1298 item_offset = list_offset;
1300 while (item_offset < (list_offset + list_length)) {
1301 const char *text=NULL;
1302 guint32 content_offset;
1303 guint16 content_length;
1304 guint32 type_offset;
1308 type_offset = item_offset;
1309 item_type = tvb_get_letohs(tvb, type_offset);
1311 /* Content length */
1312 len_offset = type_offset + 2;
1313 content_length = tvb_get_letohs(tvb, len_offset);
1316 content_offset = len_offset + 2;
1317 item_length = content_length + 4;
1319 /* Strings are always in Unicode regardless of the negotiated
1321 if (content_length > 0) {
1324 int item_offset_int;
1326 item_offset_int = content_offset;
1327 bc = content_length;
1328 text = get_unicode_or_ascii_string(tvb, &item_offset_int,
1329 TRUE, &result_length,
1333 if (!text) text = ""; /* Make sure we don't blow up below */
1336 case NTLM_NAME_NB_HOST:
1337 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_server_nb,
1338 tvb, item_offset, item_length, text);
1340 case NTLM_NAME_NB_DOMAIN:
1341 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_domain_nb,
1342 tvb, item_offset, item_length, text);
1344 case NTLM_NAME_DNS_HOST:
1345 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_server_dns,
1346 tvb, item_offset, item_length, text);
1348 case NTLM_NAME_DNS_DOMAIN:
1349 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_domain_dns,
1350 tvb, item_offset, item_length, text);
1353 addr_tf = proto_tree_add_item(tree, hf_ntlmssp_address_list_terminator,
1354 tvb, item_offset, item_length, TRUE);
1357 addr_tf = proto_tree_add_text(tree, tvb, item_offset, item_length, "Unknown type:0x%04x", item_type);
1360 /* Now show the actual bytes that made up the summary line */
1361 addr_tree = proto_item_add_subtree (addr_tf,
1362 ett_ntlmssp_address_list_item);
1363 proto_tree_add_item (addr_tree, hf_ntlmssp_address_list_item_type,
1364 tvb, type_offset, 2, TRUE);
1365 proto_tree_add_item (addr_tree, hf_ntlmssp_address_list_item_len,
1366 tvb, len_offset, 2, TRUE);
1367 if (content_length > 0) {
1368 proto_tree_add_string(addr_tree, hf_ntlmssp_address_list_item_content,
1369 tvb, content_offset, content_length, text);
1372 item_offset += item_length;
1375 *end = list_offset + list_length;
1379 /* tapping into ntlmssph not yet implemented */
1381 dissect_ntlmssp_challenge (tvbuff_t *tvb, packet_info *pinfo, int offset,
1382 proto_tree *ntlmssp_tree, ntlmssp_header_t *ntlmssph _U_)
1384 guint32 negotiate_flags;
1385 int item_start, item_end;
1386 int data_start, data_end;
1387 guint8 clientkey[16]; /* NTLMSSP cipher key for client */
1388 guint8 serverkey[16]; /* NTLMSSP cipher key for server*/
1389 ntlmssp_info *conv_ntlmssp_info = NULL;
1390 conversation_t *conversation;
1391 gboolean unicode_strings = FALSE;
1392 guint8 challenge[8];
1394 guint8 sspkey[16]; /* NTLMSSP cipher key */
1395 int ssp_key_len; /* Either 8 or 16 (40 bit or 128) */
1397 /* need to find unicode flag */
1398 negotiate_flags = tvb_get_letohl (tvb, offset+8);
1399 if (negotiate_flags & NTLMSSP_NEGOTIATE_UNICODE)
1400 unicode_strings = TRUE;
1404 * XXX - the davenport document calls this the "Target Name",
1405 * presumably because non-domain targets are supported.
1407 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, unicode_strings,
1408 hf_ntlmssp_challenge_domain,
1409 &item_start, &item_end, NULL);
1410 data_start = item_start;
1411 data_end = item_end;
1413 /* NTLMSSP Negotiate Flags */
1414 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
1417 /* NTLMSSP NT Lan Manager Challenge */
1418 proto_tree_add_item (ntlmssp_tree,
1419 hf_ntlmssp_ntlm_server_challenge,
1420 tvb, offset, 8, FALSE);
1423 * Store the flags and the RC4 state information with the conversation,
1424 * as they're needed in order to dissect subsequent messages.
1426 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1427 pinfo->ptype, pinfo->srcport,
1428 pinfo->destport, 0);
1429 if (!conversation) { /* Create one */
1430 conversation = conversation_new(pinfo->fd->num, &pinfo->src, &pinfo->dst, pinfo->ptype,
1431 pinfo->srcport, pinfo->destport, 0);
1433 tvb_memcpy(tvb, tmp, offset, 8);
1434 /* We can face more than one NTLM exchange over the same couple of IP and ports ...*/
1435 conv_ntlmssp_info = conversation_get_proto_data(conversation, proto_ntlmssp);
1436 if (!conv_ntlmssp_info || memcmp(tmp,conv_ntlmssp_info->server_challenge,8) != 0) {
1437 conv_ntlmssp_info = se_alloc(sizeof(ntlmssp_info));
1438 /* Insert the flags into the conversation */
1439 conv_ntlmssp_info->flags = negotiate_flags;
1440 /* Insert the RC4 state information into the conversation */
1441 tvb_memcpy(tvb, challenge, offset, 8);
1442 tvb_memcpy(tvb, conv_ntlmssp_info->server_challenge, offset, 8);
1443 conv_ntlmssp_info->is_auth_ntlm_v2=0;
1444 /* Between the challenge and the user provided password, we can build the
1445 NTLMSSP key and initialize the cipher if we are not in EXTENDED SECURITY
1446 in this case we need the client challenge as well*/
1447 /* BTW this is true just if we are in LM Authentification if not the logic is a bit different.
1448 * Right now it's not very clear what is LM Authentification it __seems__ to be when
1449 * NEGOTIATE NT ONLY is not set and NEGOSIATE EXTENDED SECURITY is not set as well*/
1450 if (!(conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY))
1452 conv_ntlmssp_info->rc4_state_initialized = 0;
1453 create_ntlmssp_v1_key(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);
1454 if( memcmp(sspkey,zeros,16) != 0 ) {
1455 get_sealing_rc4key(sspkey,conv_ntlmssp_info->flags,&ssp_key_len,clientkey,serverkey);
1456 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_client, sspkey, ssp_key_len);
1457 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_server, sspkey, ssp_key_len);
1458 conv_ntlmssp_info->server_dest_port = pinfo->destport;
1459 conv_ntlmssp_info->rc4_state_initialized = 1;
1463 conversation_add_proto_data(conversation, proto_ntlmssp, conv_ntlmssp_info);
1467 /* Reserved (function not completely known) */
1469 * XXX - SSP key? The davenport document says
1471 * The context field is typically populated when Negotiate Local
1472 * Call is set. It contains an SSPI context handle, which allows
1473 * the client to "short-circuit" authentication and effectively
1474 * circumvent responding to the challenge. Physically, the context
1475 * is two long values. This is covered in greater detail later,
1476 * in the "Local Authentication" section.
1478 * It also says that that information may be omitted.
1480 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_reserved,
1481 tvb, offset, 8, FALSE);
1485 * The presence or absence of this field is not obviously correlated
1486 * with any flags in the previous NEGOTIATE message or in this
1487 * message (other than the "Workstation Supplied" and "Domain
1488 * Supplied" flags in the NEGOTIATE message, at least in the capture
1489 * I've seen - but those also correlate with the presence of workstation
1490 * and domain name fields, so it doesn't seem to make sense that they
1491 * actually *indicate* whether the subsequent CHALLENGE has an
1494 if (offset < data_start) {
1495 offset = dissect_ntlmssp_address_list(tvb, offset, ntlmssp_tree, &item_end);
1496 data_end = MAX(data_end, item_end);
1499 return MAX(offset, data_end);
1503 dissect_ntlmssp_auth (tvbuff_t *tvb, packet_info *pinfo, int offset,
1504 proto_tree *ntlmssp_tree, ntlmssp_header_t *ntlmssph)
1506 int item_start, item_end;
1507 int data_start, data_end = 0;
1508 guint32 negotiate_flags;
1509 guint8 sspkey[16]; /* exported session key */
1510 guint8 clientkey[16]; /* NTLMSSP cipher key for client */
1511 guint8 serverkey[16]; /* NTLMSSP cipher key for server*/
1512 guint8 encryptedsessionkey[16];
1513 ntlmssp_blob sessionblob;
1514 gboolean unicode_strings = FALSE;
1515 ntlmssp_info *conv_ntlmssp_info = NULL;
1516 conversation_t *conversation;
1519 * Get flag info from the original negotiate message, if any.
1520 * This is because the flag information is sometimes missing from
1521 * the AUTHENTICATE message, so we can't figure out whether
1522 * strings are Unicode or not by looking at *our* flags.
1523 * XXX it seems it's more from the CHALLENGE message, which is more clever in fact
1524 * because the server can change some flags.
1525 * But according to MS NTLMSSP doc it's not that simple.
1526 * In case of Conection less mode AUTHENTICATE flags should be used because they
1527 * reprensent the choice of the client after having been informed of options of the
1528 * server in the CHALLENGE message.
1529 * In Connection mode then the CHALLENGE flags should (must ?) be used
1531 conv_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1532 if (conv_ntlmssp_info == NULL) {
1534 * There isn't any. Is there any from this conversation? If so,
1535 * it means this is the first time we've dissected this frame, so
1536 * we should give it flag info.
1538 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1539 pinfo->ptype, pinfo->srcport,
1540 pinfo->destport, 0);
1541 if (conversation != NULL) {
1542 conv_ntlmssp_info = conversation_get_proto_data(conversation, proto_ntlmssp);
1543 if (conv_ntlmssp_info != NULL) {
1545 * We have flag info; attach it to the frame.
1547 p_add_proto_data(pinfo->fd, proto_ntlmssp, conv_ntlmssp_info);
1551 if (conv_ntlmssp_info != NULL) {
1552 if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_UNICODE)
1553 unicode_strings = TRUE;
1557 * Sometimes the session key and flags are missing.
1558 * Sometimes the session key is present but the flags are missing.
1559 * XXX Who stay so ? Reading spec I would rather say the opposite: flags are
1560 * always present, session information are always there as well but sometime
1561 * session information could be null (in case of no session)
1562 * Sometimes they're both present.
1564 * This does not correlate with any flags in the previous CHALLENGE
1565 * message, and only correlates with "Negotiate Unicode", "Workstation
1566 * Supplied", and "Domain Supplied" in the NEGOTIATE message - but
1567 * those don't make sense as flags to use to determine this.
1569 * So we check all of the descriptors to figure out where the data
1570 * area begins, and if the session key or the flags would be in the
1571 * middle of the data area, we assume the field in question is
1575 /* Lan Manager response */
1576 data_start = tvb_get_letohl(tvb, offset+4);
1577 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
1578 hf_ntlmssp_auth_lmresponse,
1580 conv_ntlmssp_info == NULL ? NULL :
1581 &conv_ntlmssp_info->lm_response);
1582 data_end = MAX(data_end, item_end);
1585 item_start = tvb_get_letohl(tvb, offset+4);
1586 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
1587 hf_ntlmssp_auth_ntresponse,
1589 conv_ntlmssp_info == NULL ? NULL :
1590 &conv_ntlmssp_info->ntlm_response);
1591 if( conv_ntlmssp_info != NULL && conv_ntlmssp_info->ntlm_response.length > 24 ) {
1592 memcpy(conv_ntlmssp_info->client_challenge,conv_ntlmssp_info->ntlm_response.contents+32,8);
1594 data_start = MIN(data_start, item_start);
1595 data_end = MAX(data_end, item_end);
1596 if( conv_ntlmssp_info != NULL )
1598 if( conv_ntlmssp_info->ntlm_response.length > 24 )
1600 conv_ntlmssp_info->is_auth_ntlm_v2=1;
1604 conv_ntlmssp_info->is_auth_ntlm_v2=0;
1609 item_start = tvb_get_letohl(tvb, offset+4);
1610 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
1612 hf_ntlmssp_auth_domain,
1613 &item_start, &item_end, &(ntlmssph->domain_name));
1614 /*ntlmssph->domain_name_len=item_end-item_start;*/
1615 data_start = MIN(data_start, item_start);
1616 data_end = MAX(data_end, item_end);
1619 item_start = tvb_get_letohl(tvb, offset+4);
1620 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
1622 hf_ntlmssp_auth_username,
1623 &item_start, &item_end, &(ntlmssph->acct_name));
1624 /*ntlmssph->acct_name_len=item_end-item_start;*/
1625 data_start = MIN(data_start, item_start);
1626 data_end = MAX(data_end, item_end);
1628 if (check_col(pinfo->cinfo, COL_INFO))
1629 col_append_fstr(pinfo->cinfo, COL_INFO, ", User: %s\\%s",
1630 ntlmssph->domain_name, ntlmssph->acct_name);
1633 item_start = tvb_get_letohl(tvb, offset+4);
1634 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
1636 hf_ntlmssp_auth_hostname,
1637 &item_start, &item_end, &(ntlmssph->host_name));
1638 data_start = MIN(data_start, item_start);
1639 data_end = MAX(data_end, item_end);
1640 memset(sessionblob.contents, 0, MAX_BLOB_SIZE);
1641 sessionblob.length = 0;
1642 if (offset < data_start) {
1644 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
1645 hf_ntlmssp_auth_sesskey,
1646 &item_end, &sessionblob);
1647 data_end = MAX(data_end, item_end);
1649 if( sessionblob.length != 0 ) {
1650 memcpy(encryptedsessionkey,sessionblob.contents,sessionblob.length);
1651 if (offset < data_start) {
1652 /* NTLMSSP Negotiate Flags */
1653 negotiate_flags = tvb_get_letohl (tvb, offset);
1654 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
1657 /* Try to attach to an existing conversation if not then it's useless to try to do so
1658 * because we are missing important information (ie. server challenge)
1660 if (conv_ntlmssp_info) {
1661 /* If we are in EXTENDED SECURITY then we can now initialize cipher */
1662 if ((conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY))
1664 conv_ntlmssp_info->rc4_state_initialized = 0;
1665 if( conv_ntlmssp_info->is_auth_ntlm_v2 ) {
1666 create_ntlmssp_v2_key(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);
1670 memcpy(conv_ntlmssp_info->client_challenge,conv_ntlmssp_info->lm_response.contents,8);
1671 create_ntlmssp_v1_key(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);
1673 /* ssp is the exported session key */
1674 if( memcmp(sspkey,zeros,16) != 0) {
1675 get_sealing_rc4key(sspkey,conv_ntlmssp_info->flags,&ssp_key_len,clientkey,serverkey);
1676 get_siging_key((guint8*)&conv_ntlmssp_info->sign_key_server,(guint8*)&conv_ntlmssp_info->sign_key_client,sspkey,ssp_key_len);
1677 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_server, serverkey, ssp_key_len);
1678 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_client, clientkey, ssp_key_len);
1679 conv_ntlmssp_info->server_dest_port = pinfo->destport;
1680 conv_ntlmssp_info->rc4_state_initialized = 1;
1685 return MAX(offset, data_end);
1688 get_sign_key(packet_info *pinfo, int cryptpeer)
1690 conversation_t *conversation;
1691 ntlmssp_info *conv_ntlmssp_info;
1693 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1694 pinfo->ptype, pinfo->srcport,
1695 pinfo->destport, 0);
1696 if (conversation == NULL) {
1697 /* We don't have a conversation. In this case, stop processing
1698 because we do not have enough info to decrypt the payload */
1702 /* We have a conversation, check for encryption state */
1703 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1705 if (conv_ntlmssp_info == NULL) {
1706 /* No encryption state tied to the conversation. Therefore, we
1707 cannot decrypt the payload */
1711 /* We have the encryption state in the conversation. So return the
1712 crypt state tied to the requested peer
1714 if (cryptpeer == 1) {
1715 return (guint8*)&conv_ntlmssp_info->sign_key_client;
1717 return (guint8*)&conv_ntlmssp_info->sign_key_server;
1723 * Get the encryption state tied to this conversation. cryptpeer indicates
1724 * whether to retrieve the client key (1) or the server key (0)
1726 static rc4_state_struct *
1727 get_encrypted_state(packet_info *pinfo, int cryptpeer)
1729 conversation_t *conversation;
1730 ntlmssp_info *conv_ntlmssp_info;
1732 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1733 pinfo->ptype, pinfo->srcport,
1734 pinfo->destport, 0);
1735 if (conversation == NULL) {
1736 /* We don't have a conversation. In this case, stop processing
1737 because we do not have enough info to decrypt the payload */
1741 /* We have a conversation, check for encryption state */
1742 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1744 if (conv_ntlmssp_info == NULL) {
1745 /* No encryption state tied to the conversation. Therefore, we
1746 cannot decrypt the payload */
1750 /* We have the encryption state in the conversation. So return the
1751 crypt state tied to the requested peer
1753 if (cryptpeer == 1) {
1754 return &conv_ntlmssp_info->rc4_state_client;
1756 return &conv_ntlmssp_info->rc4_state_server;
1762 decrypt_data_payload(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
1763 packet_info *pinfo, proto_tree *tree _U_,gpointer key);
1765 decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
1766 packet_info *pinfo, proto_tree *tree,gpointer key);
1769 dissect_ntlmssp_encrypted_payload(tvbuff_t *data_tvb,
1770 tvbuff_t *auth_tvb _U_,
1773 dcerpc_auth_info *auth_info _U_)*/
1776 dissect_ntlmssp_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
1778 volatile int offset = 0;
1779 proto_tree *volatile ntlmssp_tree = NULL;
1780 proto_item *tf = NULL;
1782 guint32 encrypted_block_length;
1784 /* the magic ntlm is the identifier of a NTLMSSP packet that's 00 00 00 01
1786 guint32 ntlm_magic_size = 4;
1787 guint32 ntlm_signature_size = 8;
1788 guint32 ntlm_seq_size = 4;
1789 length = tvb_length (tvb);
1790 /* signature + seq + real payload */
1791 encrypted_block_length = length - ntlm_magic_size;
1793 if (encrypted_block_length < (ntlm_signature_size + ntlm_seq_size)) {
1794 /* Don't know why this would happen, but if it does, don't even bother
1795 attempting decryption/dissection */
1796 return offset + length;
1799 /* Setup a new tree for the NTLMSSP payload */
1801 tf = proto_tree_add_item (tree,
1803 tvb, offset, -1, FALSE);
1805 ntlmssp_tree = proto_item_add_subtree (tf,
1810 * Catch the ReportedBoundsError exception; the stuff we've been
1811 * handed doesn't necessarily run to the end of the packet, it's
1812 * an item inside a packet, so if it happens to be malformed (or
1813 * we, or a dissector we call, has a bug), so that an exception
1814 * is thrown, we want to report the error, but return and let
1815 * our caller dissect the rest of the packet.
1817 * If it gets a BoundsError, we can stop, as there's nothing more
1818 * in the packet after our blob to see, so we just re-throw the
1822 /* Version number */
1823 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_vers,
1824 tvb, offset, 4, TRUE);
1827 /* Encrypted body */
1828 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_body,
1829 tvb, offset, ntlm_signature_size + ntlm_seq_size, TRUE);
1830 tvb_memcpy(tvb, key, offset, ntlm_signature_size + ntlm_seq_size);
1831 /* Try to decrypt */
1832 decrypt_data_payload (tvb, offset+(ntlm_signature_size + ntlm_seq_size), encrypted_block_length-(ntlm_signature_size + ntlm_seq_size), pinfo, ntlmssp_tree,key);
1833 decrypt_verifier (tvb, offset, ntlm_signature_size + ntlm_seq_size, pinfo, ntlmssp_tree,key);
1834 /* let's try to hook ourselves here */
1837 } CATCH(BoundsError) {
1839 } CATCH(ReportedBoundsError) {
1840 show_reported_bounds_error(tvb, pinfo, tree);
1846 decrypt_data_payload(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
1847 packet_info *pinfo, proto_tree *tree _U_,gpointer key)
1849 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
1851 conversation_t *conversation;
1852 rc4_state_struct *rc4_state;
1853 rc4_state_struct *rc4_state_peer;
1854 ntlmssp_info *conv_ntlmssp_info = NULL;
1855 ntlmssp_packet_info *packet_ntlmssp_info = NULL;
1856 ntlmssp_packet_info *stored_packet_ntlmssp_info = NULL;
1858 /* Check to see if we already have state for this packet */
1859 packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1860 if (packet_ntlmssp_info == NULL) {
1861 /* We don't have any packet state, so create one */
1862 packet_ntlmssp_info = se_alloc(sizeof(ntlmssp_packet_info));
1863 memset(packet_ntlmssp_info, 0, sizeof(ntlmssp_packet_info));
1864 p_add_proto_data(pinfo->fd, proto_ntlmssp, packet_ntlmssp_info);
1866 if (!packet_ntlmssp_info->payload_decrypted) {
1867 /* Pull the challenge info from the conversation */
1868 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1869 pinfo->ptype, pinfo->srcport,
1870 pinfo->destport, 0);
1871 if (conversation == NULL) {
1872 /* There is no conversation, thus no encryption state */
1876 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1878 if (conv_ntlmssp_info == NULL) {
1879 /* There is no NTLMSSP state tied to the conversation */
1882 if (conv_ntlmssp_info->rc4_state_initialized != 1 ) {
1883 /* The crypto sybsystem is not initialized. This means that either
1884 the conversation did not include a challenge, or that we do not have the right password */
1888 stored_packet_ntlmssp_info = g_hash_table_lookup(hash_packet,key);
1890 if( stored_packet_ntlmssp_info != NULL && stored_packet_ntlmssp_info->payload_decrypted == TRUE)
1892 /* Mat TBD fprintf(stderr,"Found a already decrypted packet\n");*/
1893 memcpy(packet_ntlmssp_info,stored_packet_ntlmssp_info,sizeof(ntlmssp_packet_info));
1894 /* Mat TBD printnbyte(packet_ntlmssp_info->decrypted_payload,encrypted_block_length,"Data: ","\n");*/
1898 /* Get the pair of RC4 state structures. One is used for to decrypt the
1899 payload. The other is used to re-encrypt the payload to represent
1901 if (conv_ntlmssp_info->server_dest_port == pinfo->destport) {
1903 rc4_state = get_encrypted_state(pinfo, 1);
1904 rc4_state_peer = get_encrypted_state(pinfo, 0);
1907 rc4_state = get_encrypted_state(pinfo, 0);
1908 rc4_state_peer = get_encrypted_state(pinfo, 1);
1911 if (rc4_state == NULL ) {
1912 /* There is no encryption state, so we cannot decrypt */
1916 /* Store the decrypted contents in the packet state struct
1917 (of course at this point, they aren't decrypted yet) */
1918 packet_ntlmssp_info->decrypted_payload = tvb_memdup(tvb, offset,
1919 encrypted_block_length);
1920 packet_ntlmssp_info->payload_len = encrypted_block_length;
1921 decrypted_payloads = g_slist_prepend(decrypted_payloads,
1922 packet_ntlmssp_info->decrypted_payload);
1924 g_hash_table_insert(hash_packet,key,packet_ntlmssp_info);
1927 /* Do the decryption of the payload */
1928 crypt_rc4(rc4_state, packet_ntlmssp_info->decrypted_payload,
1929 encrypted_block_length);
1930 /* decrypt the verifier */
1931 /*printnchar(packet_ntlmssp_info->decrypted_payload,encrypted_block_length,"data: ","\n");*/
1932 /* We setup a temporary buffer so we can re-encrypt the payload after
1933 decryption. This is to update the opposite peer's RC4 state
1934 it's usefull when we have only one key for both conversation
1935 in case of KEY_EXCH we have independant key so this is not needed*/
1936 if( !(NTLMSSP_NEGOTIATE_KEY_EXCH & conv_ntlmssp_info->flags)) {
1937 peer_block = ep_alloc(encrypted_block_length);
1938 memcpy(peer_block, packet_ntlmssp_info->decrypted_payload,
1939 encrypted_block_length);
1940 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
1943 packet_ntlmssp_info->payload_decrypted = TRUE;
1947 /* Show the decrypted buffer in a new window */
1948 decr_tvb = tvb_new_real_data(packet_ntlmssp_info->decrypted_payload,
1949 encrypted_block_length,
1950 encrypted_block_length);
1952 tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
1953 pinfo->gssapi_decrypted_tvb = decr_tvb;
1956 dissect_ntlmssp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1958 volatile int offset = 0;
1959 proto_tree *volatile ntlmssp_tree = NULL;
1960 proto_item *tf = NULL;
1961 ntlmssp_header_t *ntlmssph;
1963 ntlmssph=ep_alloc(sizeof(ntlmssp_header_t));
1965 ntlmssph->domain_name=NULL;
1966 ntlmssph->acct_name=NULL;
1967 ntlmssph->host_name=NULL;
1969 /* Setup a new tree for the NTLMSSP payload */
1971 tf = proto_tree_add_item (tree,
1973 tvb, offset, -1, FALSE);
1975 ntlmssp_tree = proto_item_add_subtree (tf,
1980 * Catch the ReportedBoundsError exception; the stuff we've been
1981 * handed doesn't necessarily run to the end of the packet, it's
1982 * an item inside a packet, so if it happens to be malformed (or
1983 * we, or a dissector we call, has a bug), so that an exception
1984 * is thrown, we want to report the error, but return and let
1985 * our caller dissect the rest of the packet.
1987 * If it gets a BoundsError, we can stop, as there's nothing more
1988 * in the packet after our blob to see, so we just re-throw the
1992 /* NTLMSSP constant */
1993 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth,
1994 tvb, offset, 8, FALSE);
1997 /* NTLMSSP Message Type */
1998 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_message_type,
1999 tvb, offset, 4, TRUE);
2000 ntlmssph->type = tvb_get_letohl (tvb, offset);
2003 if (check_col(pinfo->cinfo, COL_INFO))
2004 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
2005 val_to_str(ntlmssph->type,
2006 ntlmssp_message_types,
2007 "Unknown message type"));
2009 /* Call the appropriate dissector based on the Message Type */
2010 switch (ntlmssph->type) {
2012 case NTLMSSP_NEGOTIATE:
2013 offset = dissect_ntlmssp_negotiate (tvb, offset, ntlmssp_tree, ntlmssph);
2016 case NTLMSSP_CHALLENGE:
2017 offset = dissect_ntlmssp_challenge (tvb, pinfo, offset, ntlmssp_tree, ntlmssph);
2021 offset = dissect_ntlmssp_auth (tvb, pinfo, offset, ntlmssp_tree, ntlmssph);
2025 /* Unrecognized message type */
2026 proto_tree_add_text (ntlmssp_tree, tvb, offset, -1,
2027 "Unrecognized NTLMSSP Message");
2030 } CATCH(BoundsError) {
2032 } CATCH(ReportedBoundsError) {
2033 show_reported_bounds_error(tvb, pinfo, tree);
2036 /*tap_queue_packet(ntlmssp_tap, pinfo, ntlmssph);*/
2042 * See page 45 of "DCE/RPC over SMB" by Luke Kenneth Casson Leighton.
2045 decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
2046 packet_info *pinfo, proto_tree *tree,gpointer key)
2048 proto_tree *decr_tree = NULL;
2049 proto_item *tf = NULL;
2050 conversation_t *conversation;
2052 rc4_state_struct *rc4_state;
2053 rc4_state_struct *rc4_state_peer;
2054 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
2057 guint8 calculated_md5[16];
2058 ntlmssp_info *conv_ntlmssp_info = NULL;
2059 ntlmssp_packet_info *packet_ntlmssp_info = NULL;
2060 int decrypted_offset = 0;
2063 ntlmssp_packet_info *stored_packet_ntlmssp_info = NULL;
2064 packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
2065 if (packet_ntlmssp_info == NULL) {
2066 /* We don't have data for this packet */
2069 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
2070 pinfo->ptype, pinfo->srcport,
2071 pinfo->destport, 0);
2072 if (conversation == NULL) {
2073 /* There is no conversation, thus no encryption state */
2076 conv_ntlmssp_info = conversation_get_proto_data(conversation,
2078 if (conv_ntlmssp_info == NULL) {
2079 /* There is no NTLMSSP state tied to the conversation */
2084 stored_packet_ntlmssp_info = g_hash_table_lookup(hash_packet,key);
2086 if( stored_packet_ntlmssp_info != NULL && stored_packet_ntlmssp_info->verifier_decrypted == TRUE) {
2087 /* Mat TBD fprintf(stderr,"Found a already decrypted packet\n");*/
2088 /* In Theory it's aleady the case, and we should be more clever ... like just copying buffers ...*/
2089 packet_ntlmssp_info = stored_packet_ntlmssp_info;
2092 if (!packet_ntlmssp_info->verifier_decrypted) {
2093 if (conv_ntlmssp_info->rc4_state_initialized != 1 ) {
2094 /* The crypto sybsystem is not initialized. This means that either
2095 the conversation did not include a challenge, or we are doing
2096 something other than NTLMSSP v1 */
2099 if (conv_ntlmssp_info->server_dest_port == pinfo->destport) {
2100 /* client talk to server */
2101 rc4_state = get_encrypted_state(pinfo, 1);
2102 sign_key = get_sign_key(pinfo,1);
2103 rc4_state_peer = get_encrypted_state(pinfo, 0);
2105 rc4_state = get_encrypted_state(pinfo, 0);
2106 sign_key = get_sign_key(pinfo,0);
2107 rc4_state_peer = get_encrypted_state(pinfo, 1);
2110 if (rc4_state == NULL || rc4_state_peer == NULL) {
2111 /* There is no encryption state, so we cannot decrypt */
2115 /* Setup the buffer to decrypt to */
2116 tvb_memcpy(tvb, packet_ntlmssp_info->verifier,
2117 offset, encrypted_block_length);
2119 /*if( !(NTLMSSP_NEGOTIATE_KEY_EXCH & packet_ntlmssp_info->flags)) {*/
2120 if( conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY ) {
2121 if( (NTLMSSP_NEGOTIATE_KEY_EXCH & conv_ntlmssp_info->flags)) {
2122 /* The spec says that if we have have a key exchange then we have a the signature that is crypted
2123 * otherwise it's just a hmac_md5(keysign,concat(message,sequence))[0..7]
2125 crypt_rc4(rc4_state, packet_ntlmssp_info->verifier,
2129 * Try to check the HMAC MD5 of the message against those calculated works great with LDAP payload but
2130 * don't with DCE/RPC calls.
2131 * Some analysis need to be done ...
2133 if( sign_key != NULL ) {
2134 check_buf = ep_alloc(packet_ntlmssp_info->payload_len+4);
2135 tvb_memcpy(tvb, &sequence,offset+8,4);
2136 memcpy(check_buf,&sequence,4);
2137 memcpy(check_buf+4,packet_ntlmssp_info->decrypted_payload,packet_ntlmssp_info->payload_len);
2138 md5_hmac(check_buf,(int)(packet_ntlmssp_info->payload_len+4),sign_key,16,calculated_md5);
2140 printnbyte(packet_ntlmssp_info->verifier,8,"HMAC from packet: ","\n");
2141 printnbyte(calculated_md5,8,"HMAC : ","\n");
2146 /* 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 */
2147 /* Do the actual decryption of the verifier */
2148 crypt_rc4(rc4_state, packet_ntlmssp_info->verifier,
2149 encrypted_block_length);
2154 /* We setup a temporary buffer so we can re-encrypt the payload after
2155 decryption. This is to update the opposite peer's RC4 state
2156 This is not needed when we just have EXTENDED SECURITY because the signature is not crypted
2157 and it's also not needed when we have key exchange because server and client have independant keys */
2158 if( !(NTLMSSP_NEGOTIATE_KEY_EXCH & conv_ntlmssp_info->flags) && !(NTLMSSP_NEGOTIATE_EXTENDED_SECURITY & conv_ntlmssp_info->flags)) {
2159 peer_block = ep_alloc(encrypted_block_length);
2160 memcpy(peer_block, packet_ntlmssp_info->verifier,
2161 encrypted_block_length);
2162 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
2165 /* Mark the packet as decrypted so that subsequent attempts to dissect
2166 the packet use the already decrypted payload instead of attempting
2168 packet_ntlmssp_info->verifier_decrypted = TRUE;
2171 /* Show the decrypted buffer in a new window */
2172 decr_tvb = tvb_new_child_real_data(tvb, packet_ntlmssp_info->verifier,
2173 encrypted_block_length,
2174 encrypted_block_length);
2175 add_new_data_source(pinfo, decr_tvb,
2176 "Decrypted NTLMSSP Verifier");
2178 /* Show the decrypted payload in the tree */
2179 tf = proto_tree_add_text(tree, decr_tvb, 0, -1,
2180 "Decrypted Verifier (%d byte%s)",
2181 encrypted_block_length,
2182 plurality(encrypted_block_length, "", "s"));
2183 decr_tree = proto_item_add_subtree (tf, ett_ntlmssp);
2185 if(( conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY )) {
2186 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_hmacmd5,
2187 decr_tvb, decrypted_offset, 8,TRUE);
2188 decrypted_offset += 8;
2192 /* Incrementing sequence number of DCE conversation */
2193 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_sequence,
2194 decr_tvb, decrypted_offset, 4, TRUE);
2195 decrypted_offset += 4;
2199 /* RANDOM PAD usually it's 0 */
2200 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_randompad,
2201 decr_tvb, decrypted_offset, 4, TRUE);
2202 decrypted_offset += 4;
2204 /* CRC32 of the DCE fragment data */
2205 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_crc32,
2206 decr_tvb, decrypted_offset, 4, TRUE);
2207 decrypted_offset += 4;
2209 /* Incrementing sequence number of DCE conversation */
2210 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_sequence,
2211 decr_tvb, decrypted_offset, 4, TRUE);
2212 decrypted_offset += 4;
2216 /* Used when NTLMSSP is done over DCE/RPC because in this case verifier and real payload are not contigious*/
2218 dissect_ntlmssp_payload_only(tvbuff_t *tvb, packet_info *pinfo, _U_ proto_tree *tree)
2220 volatile int offset = 0;
2221 proto_tree *volatile ntlmssp_tree = NULL;
2222 guint32 encrypted_block_length;
2223 /* the magic ntlm is the identifier of a NTLMSSP packet that's 00 00 00 01
2225 encrypted_block_length = tvb_length (tvb);
2226 /* signature + seq + real payload */
2228 /* Setup a new tree for the NTLMSSP payload */
2231 tf = proto_tree_add_item (tree,
2233 tvb, offset, -1, FALSE);
2235 ntlmssp_tree = proto_item_add_subtree (tf,
2240 * Catch the ReportedBoundsError exception; the stuff we've been
2241 * handed doesn't necessarily run to the end of the packet, it's
2242 * an item inside a packet, so if it happens to be malformed (or
2243 * we, or a dissector we call, has a bug), so that an exception
2244 * is thrown, we want to report the error, but return and let
2245 * our caller dissect the rest of the packet.
2247 * If it gets a BoundsError, we can stop, as there's nothing more
2248 * in the packet after our blob to see, so we just re-throw the
2252 /* Version number */
2254 /* Try to decrypt */
2255 decrypt_data_payload (tvb, offset, encrypted_block_length, pinfo, ntlmssp_tree,NULL);
2256 /* let's try to hook ourselves here */
2258 } CATCH(BoundsError) {
2260 } CATCH(ReportedBoundsError) {
2261 show_reported_bounds_error(tvb, pinfo, tree);
2266 /* Used when NTLMSSP is done over DCE/RPC because in this case verifier and real payload are not contigious
2267 * But in fact this function could be merged with wrap_dissect_ntlmssp_verf because it's only used there
2270 dissect_ntlmssp_verf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2272 volatile int offset = 0;
2273 proto_tree *volatile ntlmssp_tree = NULL;
2274 proto_item *tf = NULL;
2275 guint32 verifier_length;
2276 guint32 encrypted_block_length;
2278 verifier_length = tvb_length (tvb);
2279 encrypted_block_length = verifier_length - 4;
2281 if (encrypted_block_length < 12) {
2282 /* Don't know why this would happen, but if it does, don't even bother
2283 attempting decryption/dissection */
2284 return offset + verifier_length;
2287 /* Setup a new tree for the NTLMSSP payload */
2289 tf = proto_tree_add_item (tree,
2291 tvb, offset, -1, FALSE);
2293 ntlmssp_tree = proto_item_add_subtree (tf,
2298 * Catch the ReportedBoundsError exception; the stuff we've been
2299 * handed doesn't necessarily run to the end of the packet, it's
2300 * an item inside a packet, so if it happens to be malformed (or
2301 * we, or a dissector we call, has a bug), so that an exception
2302 * is thrown, we want to report the error, but return and let
2303 * our caller dissect the rest of the packet.
2305 * If it gets a BoundsError, we can stop, as there's nothing more
2306 * in the packet after our blob to see, so we just re-throw the
2310 /* Version number */
2311 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_vers,
2312 tvb, offset, 4, TRUE);
2315 /* Encrypted body */
2316 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_body,
2317 tvb, offset, encrypted_block_length, TRUE);
2319 /* Try to decrypt */
2320 decrypt_verifier (tvb, offset, encrypted_block_length, pinfo, ntlmssp_tree,NULL);
2321 /* let's try to hook ourselves here */
2324 offset += encrypted_block_length;
2325 } CATCH(BoundsError) {
2327 } CATCH(ReportedBoundsError) {
2328 show_reported_bounds_error(tvb, pinfo, tree);
2335 wrap_dissect_ntlmssp_payload_only(tvbuff_t *tvb,tvbuff_t *auth_tvb _U_,
2336 int offset, packet_info *pinfo,dcerpc_auth_info *auth_info _U_)
2340 data_tvb = tvb_new_subset(
2341 tvb, offset, tvb_length_remaining(tvb, offset),
2342 tvb_length_remaining(tvb, offset));
2343 dissect_ntlmssp_payload_only(data_tvb, pinfo, NULL);
2344 return pinfo->gssapi_decrypted_tvb;
2348 dissect_ntlmssp_encrypted_payload(tvbuff_t *data_tvb,
2349 tvbuff_t *auth_tvb _U_,
2352 dcerpc_auth_info *auth_info _U_)
2354 / * gssapi_decrypted_tvb=NULL * /
2355 tvbuff_t *decr_tvb; / * Used to display decrypted buffer * /
2357 conversation_t *conversation;
2358 guint32 encrypted_block_length;
2359 rc4_state_struct *rc4_state;
2360 rc4_state_struct *rc4_state_peer;
2361 ntlmssp_info *conv_ntlmssp_info = NULL;
2362 ntlmssp_packet_info *packet_ntlmssp_info = NULL;
2363 encrypted_block_length = tvb_length_remaining (data_tvb, offset);
2365 fprintf(stderr,"Called dissect_ntlmssp_encrypted_payload\n");
2366 / * Check to see if we already have state for this packet * /
2367 packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
2368 if (packet_ntlmssp_info == NULL) {
2369 / * We don't have any packet state, so create one * /
2370 packet_ntlmssp_info = se_alloc(sizeof(ntlmssp_packet_info));
2371 memset(packet_ntlmssp_info, 0, sizeof(ntlmssp_packet_info));
2372 p_add_proto_data(pinfo->fd, proto_ntlmssp, packet_ntlmssp_info);
2375 if (!packet_ntlmssp_info->payload_decrypted) {
2376 / * Pull the challenge info from the conversation * /
2377 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
2378 pinfo->ptype, pinfo->srcport,
2379 pinfo->destport, 0);
2380 if (conversation == NULL) {
2381 / * There is no conversation, thus no encryption state * /
2385 conv_ntlmssp_info = conversation_get_proto_data(conversation,
2387 if (conv_ntlmssp_info == NULL) {
2388 / * There is no NTLMSSP state tied to the conversation * /
2391 / * Get the pair of RC4 state structures. One is used for to decrypt the
2392 payload. The other is used to re-encrypt the payload to represent
2394 if (conv_ntlmssp_info->server_dest_port == pinfo->destport) {
2395 rc4_state = get_encrypted_state(pinfo, 1);
2396 rc4_state_peer = get_encrypted_state(pinfo, 0);
2398 rc4_state = get_encrypted_state(pinfo, 0);
2399 rc4_state_peer = get_encrypted_state(pinfo, 1);
2402 if (rc4_state == NULL || rc4_state_peer == NULL) {
2403 / * There is no encryption state, so we cannot decrypt * /
2407 / * Store the decrypted contents in the packet state struct
2408 (of course at this point, they aren't decrypted yet) * /
2409 packet_ntlmssp_info->decrypted_payload = tvb_memdup(data_tvb, offset,
2410 encrypted_block_length);
2411 decrypted_payloads = g_slist_prepend(decrypted_payloads,
2412 packet_ntlmssp_info->decrypted_payload);
2414 / * Do the decryption of the payload * /
2415 crypt_rc4(rc4_state, packet_ntlmssp_info->decrypted_payload,
2416 encrypted_block_length);
2418 / * We setup a temporary buffer so we can re-encrypt the payload after
2419 decryption. This is to update the opposite peer's RC4 state * /
2420 peer_block = ep_alloc(encrypted_block_length);
2421 memcpy(peer_block, packet_ntlmssp_info->decrypted_payload,
2422 encrypted_block_length);
2423 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
2425 packet_ntlmssp_info->payload_decrypted = TRUE;
2428 / * Show the decrypted buffer in a new window * /
2429 decr_tvb = tvb_new_child_real_data(data_tvb, packet_ntlmssp_info->decrypted_payload,
2430 encrypted_block_length,
2431 encrypted_block_length);
2433 offset += encrypted_block_length;
2439 free_payload(gpointer decrypted_payload, gpointer user_data _U_)
2441 g_free(decrypted_payload);
2444 guint g_header_hash(gconstpointer pointer) {
2445 guint32 crc = ~calculate_crc32c(pointer,16,CRC32C_PRELOAD);
2446 /* Mat TBD fprintf(stderr,"Val: %u\n",crc);*/
2450 gboolean g_header_equal(gconstpointer pointer1, gconstpointer pointer2) {
2451 if(!memcmp(pointer1,pointer2,16)) {
2460 ntlmssp_init_protocol(void)
2463 * Free the decrypted payloads, and then free the list of decrypted
2466 if (decrypted_payloads != NULL) {
2467 g_slist_foreach(decrypted_payloads, free_payload, NULL);
2468 g_slist_free(decrypted_payloads);
2469 decrypted_payloads = NULL;
2472 if(hash_packet == NULL) {
2473 hash_packet = g_hash_table_new(g_header_hash,g_header_equal);
2481 proto_register_ntlmssp(void)
2484 static hf_register_info hf[] = {
2486 { "NTLMSSP", "ntlmssp", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2488 { "NTLMSSP identifier", "ntlmssp.identifier", FT_STRING, BASE_NONE, NULL, 0x0, "NTLMSSP Identifier", HFILL }},
2489 { &hf_ntlmssp_message_type,
2490 { "NTLM Message Type", "ntlmssp.messagetype", FT_UINT32, BASE_HEX, VALS(ntlmssp_message_types), 0x0, NULL, HFILL }},
2491 { &hf_ntlmssp_negotiate_flags,
2492 { "Flags", "ntlmssp.negotiateflags", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2493 { &hf_ntlmssp_negotiate_flags_01,
2494 { "Negotiate UNICODE", "ntlmssp.negotiateunicode", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_UNICODE, NULL, HFILL }},
2495 { &hf_ntlmssp_negotiate_flags_02,
2496 { "Negotiate OEM", "ntlmssp.negotiateoem", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_OEM, NULL, HFILL }},
2497 { &hf_ntlmssp_negotiate_flags_04,
2498 { "Request Target", "ntlmssp.requesttarget", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_REQUEST_TARGET, NULL, HFILL }},
2499 { &hf_ntlmssp_negotiate_flags_08,
2500 { "Request 0x00000008", "ntlmssp.negotiate00000008", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00000008, NULL, HFILL }},
2501 { &hf_ntlmssp_negotiate_flags_10,
2502 { "Negotiate Sign", "ntlmssp.negotiatesign", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_SIGN, NULL, HFILL }},
2503 { &hf_ntlmssp_negotiate_flags_20,
2504 { "Negotiate Seal", "ntlmssp.negotiateseal", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_SEAL, NULL, HFILL }},
2505 { &hf_ntlmssp_negotiate_flags_40,
2506 { "Negotiate Datagram", "ntlmssp.negotiatedatagram", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_DATAGRAM, NULL, HFILL }},
2507 { &hf_ntlmssp_negotiate_flags_80,
2508 { "Negotiate Lan Manager Key", "ntlmssp.negotiatelmkey", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_LM_KEY, NULL, HFILL }},
2509 { &hf_ntlmssp_negotiate_flags_100,
2510 { "Negotiate 0x00000100", "ntlmssp.negotiate00000100", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00000100, NULL, HFILL }},
2511 { &hf_ntlmssp_negotiate_flags_200,
2512 { "Negotiate NTLM key", "ntlmssp.negotiatentlm", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_NTLM, NULL, HFILL }},
2513 { &hf_ntlmssp_negotiate_flags_400,
2514 { "Negotiate NT Only", "ntlmssp.negotiatentonly", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_NT_ONLY, NULL, HFILL }},
2515 { &hf_ntlmssp_negotiate_flags_800,
2516 { "Negotiate 0x00000800", "ntlmssp.negotiate00000800", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00000800, NULL, HFILL }},
2517 { &hf_ntlmssp_negotiate_flags_1000,
2518 { "Negotiate OEM Domain Supplied", "ntlmssp.negotiateoemdomainsupplied", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED, NULL, HFILL }},
2519 { &hf_ntlmssp_negotiate_flags_2000,
2520 { "Negotiate OEM Workstation Supplied", "ntlmssp.negotiateoemworkstationsupplied", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED, NULL, HFILL }},
2521 { &hf_ntlmssp_negotiate_flags_4000,
2522 { "Negotiate 0x00004000", "ntlmssp.negotiate00004000", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00004000, NULL, HFILL }},
2523 { &hf_ntlmssp_negotiate_flags_8000,
2524 { "Negotiate Always Sign", "ntlmssp.negotiatealwayssign", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_ALWAYS_SIGN, NULL, HFILL }},
2525 { &hf_ntlmssp_negotiate_flags_10000,
2526 { "Target Type Domain", "ntlmssp.targettypedomain", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_TARGET_TYPE_DOMAIN, NULL, HFILL }},
2527 { &hf_ntlmssp_negotiate_flags_20000,
2528 { "Target Type Server", "ntlmssp.targettypeserver", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_TARGET_TYPE_SERVER, NULL, HFILL }},
2529 { &hf_ntlmssp_negotiate_flags_40000,
2530 { "Target Type Share", "ntlmssp.targettypeshare", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_TARGET_TYPE_SHARE, NULL, HFILL }},
2531 { &hf_ntlmssp_negotiate_flags_80000,
2532 { "Negotiate Extended Security", "ntlmssp.negotiatentlm2", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_EXTENDED_SECURITY, "", HFILL }},
2533 { &hf_ntlmssp_negotiate_flags_100000,
2534 { "Negotiate Identify", "ntlmssp.negotiateidentify", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_IDENTIFY, NULL, HFILL }},
2535 { &hf_ntlmssp_negotiate_flags_200000,
2536 { "Negotiate 0x00200000", "ntlmssp.negotiatent00200000", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00200000, NULL, HFILL }},
2537 { &hf_ntlmssp_negotiate_flags_400000,
2538 { "Request Non-NT Session", "ntlmssp.requestnonntsession", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_REQUEST_NON_NT_SESSION, NULL, HFILL }},
2539 { &hf_ntlmssp_negotiate_flags_800000,
2540 { "Negotiate Target Info", "ntlmssp.negotiatetargetinfo", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_TARGET_INFO, NULL, HFILL }},
2541 { &hf_ntlmssp_negotiate_flags_1000000,
2542 { "Negotiate 0x01000000", "ntlmssp.negotiatent01000000", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_01000000, NULL, HFILL }},
2543 { &hf_ntlmssp_negotiate_flags_2000000,
2544 { "Negotiate Version", "ntlmssp.negotiateversion", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_VERSION, NULL, HFILL }},
2545 { &hf_ntlmssp_negotiate_flags_4000000,
2546 { "Negotiate 0x04000000", "ntlmssp.negotiatent04000000", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_04000000, NULL, HFILL }},
2547 { &hf_ntlmssp_negotiate_flags_8000000,
2548 { "Negotiate 0x08000000", "ntlmssp.negotiatent08000000", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_08000000, NULL, HFILL }},
2549 { &hf_ntlmssp_negotiate_flags_10000000,
2550 { "Negotiate 0x10000000", "ntlmssp.negotiatent10000000", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_10000000, NULL, HFILL }},
2551 { &hf_ntlmssp_negotiate_flags_20000000,
2552 { "Negotiate 128", "ntlmssp.negotiate128", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_128, "128-bit encryption is supported", HFILL }},
2553 { &hf_ntlmssp_negotiate_flags_40000000,
2554 { "Negotiate Key Exchange", "ntlmssp.negotiatekeyexch", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_KEY_EXCH, NULL, HFILL }},
2555 { &hf_ntlmssp_negotiate_flags_80000000,
2556 { "Negotiate 56", "ntlmssp.negotiate56", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_56, "56-bit encryption is supported", HFILL }},
2557 { &hf_ntlmssp_negotiate_workstation_strlen,
2558 { "Calling workstation name length", "ntlmssp.negotiate.callingworkstation.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2559 { &hf_ntlmssp_negotiate_workstation_maxlen,
2560 { "Calling workstation name max length", "ntlmssp.negotiate.callingworkstation.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2561 { &hf_ntlmssp_negotiate_workstation_buffer,
2562 { "Calling workstation name buffer", "ntlmssp.negotiate.callingworkstation.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2563 { &hf_ntlmssp_negotiate_workstation,
2564 { "Calling workstation name", "ntlmssp.negotiate.callingworkstation", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2565 { &hf_ntlmssp_negotiate_domain_strlen,
2566 { "Calling workstation domain length", "ntlmssp.negotiate.domain.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2567 { &hf_ntlmssp_negotiate_domain_maxlen,
2568 { "Calling workstation domain max length", "ntlmssp.negotiate.domain.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2569 { &hf_ntlmssp_negotiate_domain_buffer,
2570 { "Calling workstation domain buffer", "ntlmssp.negotiate.domain.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2571 { &hf_ntlmssp_negotiate_domain,
2572 { "Calling workstation domain", "ntlmssp.negotiate.domain", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2573 { &hf_ntlmssp_ntlm_client_challenge,
2574 { "NTLM Client Challenge", "ntlmssp.ntlmclientchallenge", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
2575 { &hf_ntlmssp_ntlm_server_challenge,
2576 { "NTLM Server Challenge", "ntlmssp.ntlmserverchallenge", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
2577 { &hf_ntlmssp_reserved,
2578 { "Reserved", "ntlmssp.reserved", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2579 { &hf_ntlmssp_challenge_domain,
2580 { "Domain", "ntlmssp.challenge.domain", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2581 { &hf_ntlmssp_auth_domain,
2582 { "Domain name", "ntlmssp.auth.domain", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2583 { &hf_ntlmssp_auth_username,
2584 { "User name", "ntlmssp.auth.username", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2585 { &hf_ntlmssp_auth_hostname,
2586 { "Host name", "ntlmssp.auth.hostname", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2587 { &hf_ntlmssp_auth_lmresponse,
2588 { "Lan Manager Response", "ntlmssp.auth.lmresponse", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2589 { &hf_ntlmssp_auth_ntresponse,
2590 { "NTLM Response", "ntlmssp.auth.ntresponse", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2591 { &hf_ntlmssp_auth_sesskey,
2592 { "Session Key", "ntlmssp.auth.sesskey", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2593 { &hf_ntlmssp_string_len,
2594 { "Length", "ntlmssp.string.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2595 { &hf_ntlmssp_string_maxlen,
2596 { "Maxlen", "ntlmssp.string.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2597 { &hf_ntlmssp_string_offset,
2598 { "Offset", "ntlmssp.string.offset", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2599 { &hf_ntlmssp_blob_len,
2600 { "Length", "ntlmssp.blob.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2601 { &hf_ntlmssp_blob_maxlen,
2602 { "Maxlen", "ntlmssp.blob.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2603 { &hf_ntlmssp_blob_offset,
2604 { "Offset", "ntlmssp.blob.offset", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2605 { &hf_ntlmssp_address_list,
2606 { "Address List", "ntlmssp.challenge.addresslist", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
2607 { &hf_ntlmssp_address_list_len,
2608 { "Length", "ntlmssp.challenge.addresslist.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2609 { &hf_ntlmssp_address_list_maxlen,
2610 { "Maxlen", "ntlmssp.challenge.addresslist.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2611 { &hf_ntlmssp_address_list_offset,
2612 { "Offset", "ntlmssp.challenge.addresslist.offset", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2613 { &hf_ntlmssp_address_list_item_type,
2614 { "Target item type", "ntlmssp.targetitemtype", FT_UINT16, BASE_HEX, VALS(ntlm_name_types), 0x0, NULL, HFILL }},
2615 { &hf_ntlmssp_address_list_item_len,
2616 { "Target item Length", "ntlmssp.challenge.addresslist.item.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2617 { &hf_ntlmssp_address_list_item_content,
2618 { "Target item Content", "ntlmssp.challenge.addresslist.item.content", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}},
2619 { &hf_ntlmssp_address_list_server_nb,
2620 { "Server NetBIOS Name", "ntlmssp.challenge.addresslist.servernb", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2621 { &hf_ntlmssp_address_list_domain_nb,
2622 { "Domain NetBIOS Name", "ntlmssp.challenge.addresslist.domainnb", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2623 { &hf_ntlmssp_address_list_server_dns,
2624 { "Server DNS Name", "ntlmssp.challenge.addresslist.serverdns", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2625 { &hf_ntlmssp_address_list_domain_dns,
2626 { "Domain DNS Name", "ntlmssp.challenge.addresslist.domaindns", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2627 { &hf_ntlmssp_address_list_terminator,
2628 { "List Terminator", "ntlmssp.challenge.addresslist.terminator", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2630 { "NTLMSSP Verifier", "ntlmssp.verf", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2631 { &hf_ntlmssp_verf_vers,
2632 { "Version Number", "ntlmssp.verf.vers", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2633 { &hf_ntlmssp_verf_body,
2634 { "Verifier Body", "ntlmssp.verf.body", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2635 { &hf_ntlmssp_decrypted_payload,
2636 { "NTLM Decrypted Payload", "ntlmssp.decrypted_payload", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2637 { &hf_ntlmssp_verf_randompad,
2638 { "Random Pad", "ntlmssp.verf.randompad", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }},
2639 { &hf_ntlmssp_verf_crc32,
2640 { "Verifier CRC32", "ntlmssp.verf.crc32", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2641 { &hf_ntlmssp_verf_hmacmd5,
2642 { "HMAC MD5", "ntlmssp.verf.hmacmd5", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
2643 { &hf_ntlmssp_verf_sequence,
2644 { "Sequence", "ntlmssp.verf.sequence", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
2645 { &hf_ntlmssp_ntlmv2_response,
2646 { "NTLMv2 Response", "ntlmssp.ntlmv2response", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2647 { &hf_ntlmssp_ntlmv2_response_hmac,
2648 { "HMAC", "ntlmssp.ntlmv2response.hmac", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2649 { &hf_ntlmssp_ntlmv2_response_header,
2650 { "Header", "ntlmssp.ntlmv2response.header", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2651 { &hf_ntlmssp_ntlmv2_response_reserved,
2652 { "Reserved", "ntlmssp.ntlmv2response.reserved", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2653 { &hf_ntlmssp_ntlmv2_response_time,
2654 { "Time", "ntlmssp.ntlmv2response.time", FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0, NULL, HFILL }},
2655 { &hf_ntlmssp_ntlmv2_response_chal,
2656 { "Client challenge", "ntlmssp.ntlmv2response.chal", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2657 { &hf_ntlmssp_ntlmv2_response_unknown,
2658 { "Unknown", "ntlmssp.ntlmv2response.unknown", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2659 { &hf_ntlmssp_ntlmv2_response_name,
2660 { "Attribute", "ntlmssp.ntlmv2response.name", FT_STRING, BASE_NONE, NULL, 0x0, "", HFILL }},
2661 { &hf_ntlmssp_ntlmv2_response_name_type,
2662 { "Attribute type", "ntlmssp.ntlmv2response.name.type", FT_UINT32, BASE_DEC, VALS(ntlm_name_types), 0x0, "", HFILL }},
2663 { &hf_ntlmssp_ntlmv2_response_name_len,
2664 { "Value len", "ntlmssp.ntlmv2response.name.len", FT_UINT32, BASE_DEC, NULL, 0x0, "", HFILL }},
2665 { &hf_ntlmssp_ntlmv2_response_restriction,
2666 { "Encoding restrictions", "ntlmssp.ntlmv2response.name.restrictions", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }},
2667 { &hf_ntlmssp_ntlmv2_response_client_time,
2668 { "Client Time", "ntlmssp.ntlmv2response.client_time", FT_ABSOLUTE_TIME, BASE_NONE, NULL, 0, NULL, HFILL }}
2672 static gint *ett[] = {
2674 &ett_ntlmssp_negotiate_flags,
2675 &ett_ntlmssp_string,
2677 &ett_ntlmssp_address_list,
2678 &ett_ntlmssp_address_list_item,
2679 &ett_ntlmssp_ntlmv2_response,
2680 &ett_ntlmssp_ntlmv2_response_name
2682 module_t *ntlmssp_module;
2684 proto_ntlmssp = proto_register_protocol (
2685 "NTLM Secure Service Provider", /* name */
2686 "NTLMSSP", /* short name */
2687 "ntlmssp" /* abbrev */
2689 proto_register_field_array (proto_ntlmssp, hf, array_length (hf));
2690 proto_register_subtree_array (ett, array_length (ett));
2691 register_init_routine(&ntlmssp_init_protocol);
2693 ntlmssp_module = prefs_register_protocol(proto_ntlmssp, NULL);
2695 prefs_register_string_preference(ntlmssp_module, "nt_password",
2697 "NT Password (used to decrypt payloads)",
2700 register_dissector("ntlmssp", dissect_ntlmssp, proto_ntlmssp);
2701 new_register_dissector("ntlmssp_payload", dissect_ntlmssp_payload, proto_ntlmssp);
2702 new_register_dissector("ntlmssp_data_only", dissect_ntlmssp_payload_only, proto_ntlmssp);
2703 new_register_dissector("ntlmssp_verf", dissect_ntlmssp_verf, proto_ntlmssp);
2706 static int wrap_dissect_ntlmssp(tvbuff_t *tvb, int offset, packet_info *pinfo,
2707 proto_tree *tree, guint8 *drep _U_)
2711 auth_tvb = tvb_new_subset(
2712 tvb, offset, tvb_length_remaining(tvb, offset),
2713 tvb_length_remaining(tvb, offset));
2715 dissect_ntlmssp(auth_tvb, pinfo, tree);
2717 return tvb_length_remaining(tvb, offset);
2720 static int wrap_dissect_ntlmssp_verf(tvbuff_t *tvb, int offset, packet_info *pinfo,
2721 proto_tree *tree, guint8 *drep _U_)
2725 auth_tvb = tvb_new_subset(
2726 tvb, offset, tvb_length_remaining(tvb, offset),
2727 tvb_length_remaining(tvb, offset));
2728 return dissect_ntlmssp_verf(auth_tvb, pinfo, tree);
2731 static dcerpc_auth_subdissector_fns ntlmssp_sign_fns = {
2732 wrap_dissect_ntlmssp, /* Bind */
2733 wrap_dissect_ntlmssp, /* Bind ACK */
2734 wrap_dissect_ntlmssp, /* AUTH3 */
2735 wrap_dissect_ntlmssp_verf, /* Request verifier */
2736 wrap_dissect_ntlmssp_verf, /* Response verifier */
2737 NULL, /* Request data */
2738 NULL /* Response data */
2741 static dcerpc_auth_subdissector_fns ntlmssp_seal_fns = {
2742 wrap_dissect_ntlmssp, /* Bind */
2743 wrap_dissect_ntlmssp, /* Bind ACK */
2744 wrap_dissect_ntlmssp, /* AUTH3 */
2745 wrap_dissect_ntlmssp_verf, /* Request verifier */
2746 wrap_dissect_ntlmssp_verf, /* Response verifier */
2747 wrap_dissect_ntlmssp_payload_only, /* Request data */
2748 wrap_dissect_ntlmssp_payload_only /* Response data */
2752 proto_reg_handoff_ntlmssp(void)
2754 dissector_handle_t ntlmssp_handle, ntlmssp_wrap_handle;
2756 /* Register protocol with the GSS-API module */
2758 ntlmssp_handle = find_dissector("ntlmssp");
2759 ntlmssp_wrap_handle = find_dissector("ntlmssp_verf");
2760 gssapi_init_oid("1.3.6.1.4.1.311.2.2.10", proto_ntlmssp, ett_ntlmssp,
2761 ntlmssp_handle, ntlmssp_wrap_handle,
2762 "NTLMSSP - Microsoft NTLM Security Support Provider");
2764 /* Register authenticated pipe dissector */
2767 * XXX - the verifiers here seem to have a version of 1 and a body of all
2770 * XXX - DCE_C_AUTHN_LEVEL_CONNECT is, according to the DCE RPC 1.1
2771 * spec, upgraded to DCE_C_AUTHN_LEVEL_PKT. Should we register
2772 * any other levels here?
2774 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_CONNECT,
2775 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
2778 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT,
2779 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
2782 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
2783 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
2786 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
2787 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
2789 ntlmssp_tap = register_tap("ntlmssp");