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/expert.h>
50 #include <epan/crypt/crypt-rc4.h>
51 #include <epan/crypt/crypt-md4.h>
52 #include <epan/crypt/crypt-md5.h>
53 #include <epan/crypt/crypt-des.h>
54 #include "packet-dcerpc.h"
55 #include "packet-gssapi.h"
56 #include <epan/crc32.h>
58 #include "packet-ntlmssp.h"
60 static int ntlmssp_tap = -1;
64 #define NTLMSSP_NEGOTIATE 1
65 #define NTLMSSP_CHALLENGE 2
66 #define NTLMSSP_AUTH 3
67 #define NTLMSSP_UNKNOWN 4
68 #define CLIENT_SIGN_TEXT "session key to client-to-server signing key magic constant"
69 #define CLIENT_SEAL_TEXT "session key to client-to-server sealing key magic constant"
70 #define SERVER_SIGN_TEXT "session key to server-to-client signing key magic constant"
71 #define SERVER_SEAL_TEXT "session key to server-to-client sealing key magic constant"
73 #define NTLMSSP_KEY_LEN 16
75 static const value_string ntlmssp_message_types[] = {
76 { NTLMSSP_NEGOTIATE, "NTLMSSP_NEGOTIATE" },
77 { NTLMSSP_CHALLENGE, "NTLMSSP_CHALLENGE" },
78 { NTLMSSP_AUTH, "NTLMSSP_AUTH" },
79 { NTLMSSP_UNKNOWN, "NTLMSSP_UNKNOWN" },
83 typedef struct _md4_pass {
84 guint8 md4[NTLMSSP_KEY_LEN];
87 static unsigned char gbl_zeros[24] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
88 static GHashTable* hash_packet = NULL;
91 * NTLMSSP negotiation flags
96 * http://davenport.sourceforge.net/ntlm.html
98 * although that document says that:
100 * 0x00010000 is "Target Type Domain";
101 * 0x00020000 is "Target Type Server"
102 * 0x00040000 is "Target Type Share";
104 * and that 0x00100000, 0x00200000, and 0x00400000 are
105 * "Request Init Response", "Request Accept Response", and
106 * "Request Non-NT Session Key", rather than those values shifted
107 * right one having those interpretations.
109 * UPDATE: Further information obtained from [MS-NLMP]:
110 * NT LAN Manager (NTLM) Authentication Protocol Specification
111 * http://msdn2.microsoft.com/en-us/library/cc236621.aspx
114 #define NTLMSSP_NEGOTIATE_UNICODE 0x00000001
115 #define NTLMSSP_NEGOTIATE_OEM 0x00000002
116 #define NTLMSSP_REQUEST_TARGET 0x00000004
117 #define NTLMSSP_NEGOTIATE_00000008 0x00000008
118 #define NTLMSSP_NEGOTIATE_SIGN 0x00000010
119 #define NTLMSSP_NEGOTIATE_SEAL 0x00000020
120 #define NTLMSSP_NEGOTIATE_DATAGRAM 0x00000040
121 #define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080
122 #define NTLMSSP_NEGOTIATE_00000100 0x00000100
123 #define NTLMSSP_NEGOTIATE_NTLM 0x00000200
124 #define NTLMSSP_NEGOTIATE_NT_ONLY 0x00000400
125 #define NTLMSSP_NEGOTIATE_00000800 0x00000800
126 #define NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED 0x00001000
127 #define NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED 0x00002000
128 #define NTLMSSP_NEGOTIATE_00004000 0x00004000
129 #define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000
130 #define NTLMSSP_TARGET_TYPE_DOMAIN 0x00010000
131 #define NTLMSSP_TARGET_TYPE_SERVER 0x00020000
132 #define NTLMSSP_TARGET_TYPE_SHARE 0x00040000
133 #define NTLMSSP_NEGOTIATE_EXTENDED_SECURITY 0x00080000
134 #define NTLMSSP_NEGOTIATE_IDENTIFY 0x00100000
135 #define NTLMSSP_NEGOTIATE_00200000 0x00200000
136 #define NTLMSSP_REQUEST_NON_NT_SESSION 0x00400000
137 #define NTLMSSP_NEGOTIATE_TARGET_INFO 0x00800000
138 #define NTLMSSP_NEGOTIATE_01000000 0x01000000
139 #define NTLMSSP_NEGOTIATE_VERSION 0x02000000
140 #define NTLMSSP_NEGOTIATE_04000000 0x04000000
141 #define NTLMSSP_NEGOTIATE_08000000 0x08000000
142 #define NTLMSSP_NEGOTIATE_10000000 0x10000000
143 #define NTLMSSP_NEGOTIATE_128 0x20000000
144 #define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000
145 #define NTLMSSP_NEGOTIATE_56 0x80000000
147 static int proto_ntlmssp = -1;
148 static int hf_ntlmssp_auth = -1;
149 static int hf_ntlmssp_message_type = -1;
150 static int hf_ntlmssp_negotiate_flags = -1;
151 static int hf_ntlmssp_negotiate_flags_01 = -1;
152 static int hf_ntlmssp_negotiate_flags_02 = -1;
153 static int hf_ntlmssp_negotiate_flags_04 = -1;
154 static int hf_ntlmssp_negotiate_flags_08 = -1;
155 static int hf_ntlmssp_negotiate_flags_10 = -1;
156 static int hf_ntlmssp_negotiate_flags_20 = -1;
157 static int hf_ntlmssp_negotiate_flags_40 = -1;
158 static int hf_ntlmssp_negotiate_flags_80 = -1;
159 static int hf_ntlmssp_negotiate_flags_100 = -1;
160 static int hf_ntlmssp_negotiate_flags_200 = -1;
161 static int hf_ntlmssp_negotiate_flags_400 = -1;
162 static int hf_ntlmssp_negotiate_flags_800 = -1;
163 static int hf_ntlmssp_negotiate_flags_1000 = -1;
164 static int hf_ntlmssp_negotiate_flags_2000 = -1;
165 static int hf_ntlmssp_negotiate_flags_4000 = -1;
166 static int hf_ntlmssp_negotiate_flags_8000 = -1;
167 static int hf_ntlmssp_negotiate_flags_10000 = -1;
168 static int hf_ntlmssp_negotiate_flags_20000 = -1;
169 static int hf_ntlmssp_negotiate_flags_40000 = -1;
170 static int hf_ntlmssp_negotiate_flags_80000 = -1;
171 static int hf_ntlmssp_negotiate_flags_100000 = -1;
172 static int hf_ntlmssp_negotiate_flags_200000 = -1;
173 static int hf_ntlmssp_negotiate_flags_400000 = -1;
174 static int hf_ntlmssp_negotiate_flags_800000 = -1;
175 static int hf_ntlmssp_negotiate_flags_1000000 = -1;
176 static int hf_ntlmssp_negotiate_flags_2000000 = -1;
177 static int hf_ntlmssp_negotiate_flags_4000000 = -1;
178 static int hf_ntlmssp_negotiate_flags_8000000 = -1;
179 static int hf_ntlmssp_negotiate_flags_10000000 = -1;
180 static int hf_ntlmssp_negotiate_flags_20000000 = -1;
181 static int hf_ntlmssp_negotiate_flags_40000000 = -1;
182 static int hf_ntlmssp_negotiate_flags_80000000 = -1;
183 static int hf_ntlmssp_negotiate_workstation_strlen = -1;
184 static int hf_ntlmssp_negotiate_workstation_maxlen = -1;
185 static int hf_ntlmssp_negotiate_workstation_buffer = -1;
186 static int hf_ntlmssp_negotiate_workstation = -1;
187 static int hf_ntlmssp_negotiate_domain_strlen = -1;
188 static int hf_ntlmssp_negotiate_domain_maxlen = -1;
189 static int hf_ntlmssp_negotiate_domain_buffer = -1;
190 static int hf_ntlmssp_negotiate_domain = -1;
191 static int hf_ntlmssp_ntlm_server_challenge = -1;
192 static int hf_ntlmssp_ntlm_client_challenge = -1;
193 static int hf_ntlmssp_reserved = -1;
194 static int hf_ntlmssp_challenge_domain = -1;
195 static int hf_ntlmssp_auth_username = -1;
196 static int hf_ntlmssp_auth_domain = -1;
197 static int hf_ntlmssp_auth_hostname = -1;
198 static int hf_ntlmssp_auth_lmresponse = -1;
199 static int hf_ntlmssp_auth_ntresponse = -1;
200 static int hf_ntlmssp_auth_sesskey = -1;
201 static int hf_ntlmssp_string_len = -1;
202 static int hf_ntlmssp_string_maxlen = -1;
203 static int hf_ntlmssp_string_offset = -1;
204 static int hf_ntlmssp_blob_len = -1;
205 static int hf_ntlmssp_blob_maxlen = -1;
206 static int hf_ntlmssp_blob_offset = -1;
207 static int hf_ntlmssp_address_list = -1;
208 static int hf_ntlmssp_address_list_len = -1;
209 static int hf_ntlmssp_address_list_maxlen = -1;
210 static int hf_ntlmssp_address_list_offset = -1;
211 static int hf_ntlmssp_address_list_server_nb = -1;
212 static int hf_ntlmssp_address_list_domain_nb = -1;
213 static int hf_ntlmssp_address_list_server_dns = -1;
214 static int hf_ntlmssp_address_list_domain_dns = -1;
215 static int hf_ntlmssp_address_list_forest_dns = -1;
216 static int hf_ntlmssp_address_list_terminator = -1;
217 static int hf_ntlmssp_address_list_item_type = -1;
218 static int hf_ntlmssp_address_list_item_len = -1;
219 static int hf_ntlmssp_address_list_item_content = -1;
220 static int hf_ntlmssp_verf = -1;
221 static int hf_ntlmssp_verf_vers = -1;
222 static int hf_ntlmssp_verf_body = -1;
223 static int hf_ntlmssp_verf_randompad = -1;
224 static int hf_ntlmssp_verf_hmacmd5 = -1;
225 static int hf_ntlmssp_verf_crc32 = -1;
226 static int hf_ntlmssp_verf_sequence = -1;
227 static int hf_ntlmssp_decrypted_payload = -1;
228 static int hf_ntlmssp_ntlmv2_response = -1;
229 static int hf_ntlmssp_ntlmv2_response_hmac = -1;
230 static int hf_ntlmssp_ntlmv2_response_header = -1;
231 static int hf_ntlmssp_ntlmv2_response_reserved = -1;
232 static int hf_ntlmssp_ntlmv2_response_time = -1;
233 static int hf_ntlmssp_ntlmv2_response_chal = -1;
234 static int hf_ntlmssp_ntlmv2_response_unknown = -1;
235 static int hf_ntlmssp_ntlmv2_response_name = -1;
236 static int hf_ntlmssp_ntlmv2_response_name_type = -1;
237 static int hf_ntlmssp_ntlmv2_response_name_len = -1;
238 static int hf_ntlmssp_ntlmv2_response_restriction = -1;
239 static int hf_ntlmssp_ntlmv2_response_client_time = -1;
241 static gint ett_ntlmssp = -1;
242 static gint ett_ntlmssp_negotiate_flags = -1;
243 static gint ett_ntlmssp_string = -1;
244 static gint ett_ntlmssp_blob = -1;
245 static gint ett_ntlmssp_address_list = -1;
246 static gint ett_ntlmssp_address_list_item = -1;
247 static gint ett_ntlmssp_ntlmv2_response = -1;
248 static gint ett_ntlmssp_ntlmv2_response_name = -1;
250 /* Configuration variables */
251 const char *gbl_nt_password = NULL;
253 #define MAX_BLOB_SIZE 256
254 typedef struct _ntlmssp_blob {
256 guint8 contents[MAX_BLOB_SIZE];
259 /* Used in the conversation function */
260 typedef struct _ntlmssp_info {
263 rc4_state_struct rc4_state_client;
264 rc4_state_struct rc4_state_server;
265 guint8 sign_key_client[NTLMSSP_KEY_LEN];
266 guint8 sign_key_server[NTLMSSP_KEY_LEN];
267 guint32 server_dest_port;
268 unsigned char server_challenge[8];
269 unsigned char client_challenge[8];
270 int rc4_state_initialized;
271 ntlmssp_blob ntlm_response;
272 ntlmssp_blob lm_response;
275 /* If this struct exists in the payload_decrypt, then we have already
277 typedef struct _ntlmssp_packet_info {
278 guint8 *decrypted_payload;
280 guint8 verifier[NTLMSSP_KEY_LEN];
281 gboolean payload_decrypted;
282 gboolean verifier_decrypted;
283 } ntlmssp_packet_info;
286 static void printnbyte(const guint8* tab,int nb,const char* txt,const char* txt2)
289 fprintf(stderr,"%s ",txt);
292 fprintf(stderr,"%02hhX ",*(tab+i));
294 fprintf(stderr,"%s",txt2);
297 static void printnchar(const guint8* tab,int nb,char* txt,char* txt2)
300 fprintf(stderr,"%s ",txt);
303 fprintf(stderr,"%c",*(tab+i));
305 fprintf(stderr,"%s",txt2);
309 static void printnbyte(const guint8* tab _U_,int nb _U_, const char* txt _U_,const char* txt2 _U_)
314 * GSlist of decrypted payloads.
316 static GSList *decrypted_payloads;
318 int LEBE_Convert(int value)
323 b=(value&0x0000FF00) >> 8;
324 c=(value&0x00FF0000) >> 16;
325 d=(value&0xFF000000) >> 24;
326 return (a << 24) | (b << 16) | (c << 8) | d;
329 Perform a DES encryption with a 16 bit key and 8bit data item.
330 It's in fact 3 susbsequent call to crypt_des_ecb with a 7 bit key.
331 Missing bits for the key are replaced by 0;
332 Returns output in response, which is expected to be 24 bytes.
334 static int crypt_des_ecb_long(guint8 *response,
338 guint8 pw21[21]; /* 21 bytes place for the needed key */
340 memset(pw21, 0, sizeof(pw21));
341 memcpy(pw21, key, 16);
343 memset(response, 0, 24);
344 /* crypt_des_ecb(data,key)*/
345 crypt_des_ecb(response, data, pw21, 1);
346 crypt_des_ecb(response + 8, data, pw21 + 7, 1);
347 crypt_des_ecb(response + 16, data, pw21 + 14, 1);
352 Generate a challenge response, given an eight byte challenge and
353 either the NT or the Lan Manager password hash (16 bytes).
354 Returns output in response, which is expected to be 24 bytes.
356 static int ntlmssp_generate_challenge_response(guint8 *response,
357 const guint8 *passhash,
358 const guint8 *challenge)
360 guint8 pw21[21]; /* Password hash padded to 21 bytes */
362 memset(pw21, 0x0, sizeof(pw21));
363 memcpy(pw21, passhash, 16);
365 memset(response, 0, 24);
367 crypt_des_ecb(response, challenge, pw21, 1);
368 crypt_des_ecb(response + 8, challenge, pw21 + 7, 1);
369 crypt_des_ecb(response + 16, challenge, pw21 + 14, 1);
375 /* Ultra simple ainsi to unicode converter, will only work for ascii password ...*/
376 static void str_to_unicode(const char *nt_password, char *nt_password_unicode)
378 size_t password_len = 0;
381 password_len = strlen(nt_password);
382 if(nt_password_unicode != NULL)
384 for(i=0;i<(password_len);i++)
386 nt_password_unicode[i*2]=nt_password[i];
387 nt_password_unicode[i*2+1]=0;
389 nt_password_unicode[2*password_len]='\0';
393 /* This function generate the Key Exchange Key
394 * Depending on the flags this key will either be used to crypt the exported session key
395 * or will be used directly as exported session key.
396 * Exported session key is the key that will be used for sealing and signing communication*/
399 get_keyexchange_key(unsigned char keyexchangekey[NTLMSSP_KEY_LEN],const unsigned char sessionbasekey[NTLMSSP_KEY_LEN],const unsigned char lm_challenge_response[24],int flags)
401 guint8 basekey[NTLMSSP_KEY_LEN];
404 memset(keyexchangekey,0,NTLMSSP_KEY_LEN);
405 memset(basekey,0,NTLMSSP_KEY_LEN);
406 /* sessionbasekey is either derived from lm_password_hash or from nt_password_hash depending on the key type negotiated */
407 memcpy(basekey,sessionbasekey,8);
408 memset(basekey,0xBD,8);
409 if(flags&NTLMSSP_NEGOTIATE_LM_KEY)
412 crypt_des_ecb(keyexchangekey,lm_challenge_response,basekey,1);
413 crypt_des_ecb(keyexchangekey+8,lm_challenge_response,basekey+7,1);
417 if(flags&NTLMSSP_REQUEST_NON_NT_SESSION)
419 /*People from samba tends to use the same function in this case than in the previous one but with 0 data
420 * it's not clear that it produce the good result
421 * memcpy(keyexchangekey,lm_hash,8);
422 * Let's trust samba implementation it mights seem weird but they are more often rights than the spec !
425 crypt_des_ecb(keyexchangekey,zeros,basekey,3);
426 crypt_des_ecb(keyexchangekey+8,zeros,basekey+7,1);
430 /* it is stated page 65 of NTLM SSP spec that sessionbasekey should be encrypted with hmac_md5 using the concact of both challenge
431 * when it's NTLM v1 + extended security but it turns out to be wrong !
433 memcpy(keyexchangekey,sessionbasekey,NTLMSSP_KEY_LEN);
437 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
439 get_md4pass_list(md4_pass** p_pass_list,const char* nt_password)
444 unsigned char nt_password_hash[NTLMSSP_KEY_LEN];
445 int password_len = 0;
446 char nt_password_unicode[256];
453 read_keytab_file_from_preferences();
455 for(ek=enc_key_list;ek;ek=ek->next){
456 if( ek->keylength == NTLMSSP_KEY_LEN ) {
460 memset(nt_password_hash,0,NTLMSSP_KEY_LEN);
461 if (nt_password[0] != '\0' && ( strlen(nt_password) < 129 )) {
463 password_len = strlen(nt_password);
464 str_to_unicode(nt_password,nt_password_unicode);
465 crypt_md4(nt_password_hash,nt_password_unicode,password_len*2);
468 /* Unable to calculate the session key without a password or if password is more than 128 char ......*/
472 *p_pass_list = ep_alloc(nb_pass*sizeof(md4_pass));
473 pass_list=*p_pass_list;
475 if( memcmp(nt_password_hash,gbl_zeros,NTLMSSP_KEY_LEN) != 0 ) {
476 memcpy(pass_list[i].md4,nt_password_hash,NTLMSSP_KEY_LEN);
479 for(ek=enc_key_list;ek;ek=ek->next){
480 if( ek->keylength == NTLMSSP_KEY_LEN ) {
481 memcpy(pass_list[i].md4,ek->keyvalue,NTLMSSP_KEY_LEN);
488 /* Create an NTLMSSP version 2
491 create_ntlmssp_v2_key(const char *nt_password _U_, const guint8 *serverchallenge , const guint8 *clientchallenge ,
492 guint8 *sessionkey ,const guint8 *encryptedsessionkey , int flags , ntlmssp_blob ntlm_response, ntlmssp_blob lm_response _U_, ntlmssp_header_t *ntlmssph ) {
493 char domain_name_unicode[256];
494 char user_uppercase[256];
496 /*guint8 md4[NTLMSSP_KEY_LEN];*/
497 unsigned char nt_password_hash[NTLMSSP_KEY_LEN];
498 unsigned char nt_proof[NTLMSSP_KEY_LEN];
499 unsigned char ntowf[NTLMSSP_KEY_LEN];
500 guint8 sessionbasekey[NTLMSSP_KEY_LEN];
501 guint8 keyexchangekey[NTLMSSP_KEY_LEN];
502 guint8 lm_challenge_response[24];
505 rc4_state_struct rc4state;
508 md4_pass *pass_list = NULL;
512 /* We are going to try password encrypted in keytab as well, it's an idean of Stefan Metzmacher <metze@samba.org>
513 * The idea is to be able to test all the key of domain in once and to be able to decode the NTLM dialogs */
515 memset(sessionkey, 0, NTLMSSP_KEY_LEN);
516 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
517 nb_pass = get_md4pass_list(&pass_list,nt_password);
520 memset(user_uppercase,0,256);
521 user_len = strlen(ntlmssph->acct_name);
522 if( user_len < 129 ) {
524 str_to_unicode(ntlmssph->acct_name,buf);
525 for (j = 0; j < (2*user_len); j++) {
526 if( buf[j] != '\0' ) {
527 user_uppercase[j] = toupper(buf[j]);
532 /* Unable to calculate the session not enought space in buffer, note this is unlikely to happen but ......*/
535 domain_len = strlen(ntlmssph->domain_name);
536 if( domain_len < 129 ) {
537 str_to_unicode(ntlmssph->domain_name,domain_name_unicode);
540 /* Unable to calculate the session not enought space in buffer, note this is unlikely to happen but ......*/
543 while (i < nb_pass ) {
544 /*fprintf(stderr,"Turn %d, ",i);*/
545 memcpy(nt_password_hash,pass_list[i].md4,NTLMSSP_KEY_LEN);
546 /*printnbyte(nt_password_hash,NTLMSSP_KEY_LEN,"Current NT password hash: ","\n");*/
548 /* ntowf computation */
550 memcpy(buf,user_uppercase,user_len*2);
551 memcpy(buf+user_len*2,domain_name_unicode,domain_len*2);
552 md5_hmac(buf,domain_len*2+user_len*2,nt_password_hash,NTLMSSP_KEY_LEN,ntowf);
555 memcpy(buf,serverchallenge,8);
556 memcpy(buf+8,clientchallenge,8);
557 md5_hmac(buf,NTLMSSP_KEY_LEN,ntowf,NTLMSSP_KEY_LEN,lm_challenge_response);
558 memcpy(lm_challenge_response+NTLMSSP_KEY_LEN,clientchallenge,8);
559 printnbyte(lm_challenge_response,24,"LM Response: ","\n");
561 /* NT proof = First NTLMSSP_KEY_LEN bytes of NT response */
563 memcpy(buf,serverchallenge,8);
564 memcpy(buf+8,ntlm_response.contents+NTLMSSP_KEY_LEN,ntlm_response.length-NTLMSSP_KEY_LEN);
565 md5_hmac(buf,ntlm_response.length-8,ntowf,NTLMSSP_KEY_LEN,nt_proof);
566 printnbyte(nt_proof,NTLMSSP_KEY_LEN,"NT proof: ","\n");
567 if( !memcmp(nt_proof,ntlm_response.contents,NTLMSSP_KEY_LEN) ) {
578 md5_hmac(nt_proof,NTLMSSP_KEY_LEN,ntowf,NTLMSSP_KEY_LEN,sessionbasekey);
579 get_keyexchange_key(keyexchangekey,sessionbasekey,lm_challenge_response,flags);
580 /* now decrypt session key if needed and setup sessionkey for decrypting further communications */
581 if (flags & NTLMSSP_NEGOTIATE_KEY_EXCH)
583 memcpy(sessionkey,encryptedsessionkey,NTLMSSP_KEY_LEN);
584 crypt_rc4_init(&rc4state,keyexchangekey,NTLMSSP_KEY_LEN);
585 crypt_rc4(&rc4state,sessionkey,NTLMSSP_KEY_LEN);
589 memcpy(sessionkey,keyexchangekey,NTLMSSP_KEY_LEN);
593 /* Create an NTLMSSP version 1 key
594 * That is more complicated logic and methods and user challenge as well.
595 * password points to the ANSI password to encrypt, challenge points to
596 * the 8 octet challenge string
599 create_ntlmssp_v1_key(const char *nt_password, const guint8 *serverchallenge, const guint8 *clientchallenge,
600 guint8 *sessionkey,const guint8 *encryptedsessionkey, int flags, const guint8 *ref_nt_challenge_response,const guint8 *ref_lm_challenge_response)
602 unsigned char lm_password_upper[NTLMSSP_KEY_LEN];
603 unsigned char lm_password_hash[NTLMSSP_KEY_LEN];
604 unsigned char nt_password_hash[NTLMSSP_KEY_LEN];
605 unsigned char challenges_hash[NTLMSSP_KEY_LEN];
606 unsigned char challenges_hash_first8[8];
607 unsigned char challenges[NTLMSSP_KEY_LEN];
608 guint8 md4[NTLMSSP_KEY_LEN];
610 guint8 sessionbasekey[NTLMSSP_KEY_LEN];
611 guint8 keyexchangekey[NTLMSSP_KEY_LEN];
612 guint8 lm_challenge_response[24];
613 guint8 nt_challenge_response[24];
614 rc4_state_struct rc4state;
615 md5_state_t md5state;
616 char nt_password_unicode[256];
620 md4_pass *pass_list = NULL;
621 unsigned char lmhash_key[] =
622 {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
624 memset(sessionkey, 0, NTLMSSP_KEY_LEN);
625 memset(lm_password_upper, 0, sizeof(lm_password_upper));
626 /* lm auth/lm session == (!NTLM_NEGOTIATE_NT_ONLY && NTLMSSP_NEGOTIATE_LM_KEY) || ! (EXTENDED_SECURITY) || ! NTLMSSP_NEGOTIATE_NTLM*/
627 /* Create a Lan Manager hash of the input password */
628 if (nt_password[0] != '\0') {
629 password_len = strlen(nt_password);
630 /*Do not forget to free nt_password_nt*/
631 str_to_unicode(nt_password,nt_password_unicode);
632 crypt_md4(nt_password_hash,nt_password_unicode,password_len*2);
633 /* Truncate password if too long */
634 if (password_len > NTLMSSP_KEY_LEN)
635 password_len = NTLMSSP_KEY_LEN;
636 for (i = 0; i < password_len; i++) {
637 lm_password_upper[i] = toupper(nt_password[i]);
642 /* Unable to calculate the session key without a password ... and we will not use one for a keytab*/
643 if( !(flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY )) {
647 if((flags & NTLMSSP_NEGOTIATE_LM_KEY && !(flags & NTLMSSP_NEGOTIATE_NT_ONLY)) || !(flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY) || !(flags & NTLMSSP_NEGOTIATE_NTLM)) {
648 crypt_des_ecb(lm_password_hash, lmhash_key, lm_password_upper, 1);
649 crypt_des_ecb(lm_password_hash+8, lmhash_key, lm_password_upper+7, 1);
650 ntlmssp_generate_challenge_response(lm_challenge_response,
651 lm_password_hash, serverchallenge);
652 memcpy(sessionbasekey,lm_password_hash,NTLMSSP_KEY_LEN);
656 memset(lm_challenge_response,0,24);
657 if( flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY ) {
658 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
659 nb_pass = get_md4pass_list(&pass_list,nt_password);
662 while (i < nb_pass ) {
663 /*fprintf(stderr,"Turn %d, ",i);*/
664 memcpy(nt_password_hash,pass_list[i].md4,NTLMSSP_KEY_LEN);
665 /*printnbyte(nt_password_hash,NTLMSSP_KEY_LEN,"Current NT password hash: ","\n");*/
667 memcpy(lm_challenge_response,clientchallenge,8);
669 md5_append(&md5state,serverchallenge,8);
670 md5_append(&md5state,clientchallenge,8);
671 md5_finish(&md5state,challenges_hash);
672 memcpy(challenges_hash_first8,challenges_hash,8);
673 crypt_des_ecb_long(nt_challenge_response,nt_password_hash,challenges_hash_first8);
674 if( !memcmp(ref_nt_challenge_response,nt_challenge_response,24) ) {
681 crypt_des_ecb_long(nt_challenge_response,nt_password_hash,serverchallenge);
682 if( flags & NTLMSSP_NEGOTIATE_NT_ONLY ) {
683 memcpy(lm_challenge_response,nt_challenge_response,24);
686 crypt_des_ecb_long(lm_challenge_response,lm_password_hash,serverchallenge);
688 if( !memcmp(ref_nt_challenge_response,nt_challenge_response,24) && !memcmp(ref_lm_challenge_response,lm_challenge_response,24) ) {
692 /* So it's clearly not like this that's put into NTLMSSP doc but after some digging into samba code I'm quite confident
693 * that sessionbasekey should be based md4(nt_password_hash) only in the case of some NT auth
694 * Otherwise it should be lm_password_hash ...*/
695 crypt_md4(md4,nt_password_hash,NTLMSSP_KEY_LEN);
696 if (flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY) {
697 memcpy(challenges,serverchallenge,8);
698 memcpy(challenges+8,clientchallenge,8);
699 /*md5_hmac(text,text_len,key,key_len,digest);*/
700 md5_hmac(challenges,NTLMSSP_KEY_LEN,md4,NTLMSSP_KEY_LEN,sessionbasekey);
703 memcpy(sessionbasekey,md4,NTLMSSP_KEY_LEN);
712 get_keyexchange_key(keyexchangekey,sessionbasekey,lm_challenge_response,flags);
713 memset(sessionkey, 0, NTLMSSP_KEY_LEN);
714 /*printnbyte(nt_challenge_response,24,"NT challenge response","\n");
715 printnbyte(lm_challenge_response,24,"LM challenge response","\n");*/
716 /* now decrypt session key if needed and setup sessionkey for decrypting further communications */
717 if (flags & NTLMSSP_NEGOTIATE_KEY_EXCH)
719 memcpy(sessionkey,encryptedsessionkey,NTLMSSP_KEY_LEN);
720 crypt_rc4_init(&rc4state,keyexchangekey,NTLMSSP_KEY_LEN);
721 crypt_rc4(&rc4state,sessionkey,NTLMSSP_KEY_LEN);
725 memcpy(sessionkey,keyexchangekey,NTLMSSP_KEY_LEN);
729 get_siging_key(guint8 *sign_key_server,guint8* sign_key_client,const guint8 key[NTLMSSP_KEY_LEN], int keylen)
731 md5_state_t md5state;
732 md5_state_t md5state2;
733 memset(sign_key_client,0,NTLMSSP_KEY_LEN);
734 memset(sign_key_server,0,NTLMSSP_KEY_LEN);
736 md5_append(&md5state,key,keylen);
737 md5_append(&md5state,CLIENT_SIGN_TEXT,strlen(CLIENT_SIGN_TEXT)+1);
738 md5_finish(&md5state,sign_key_client);
739 md5_init(&md5state2);
740 md5_append(&md5state2,key,keylen);
741 md5_append(&md5state2,SERVER_SIGN_TEXT,strlen(SERVER_SIGN_TEXT)+1);
742 md5_finish(&md5state2,sign_key_server);
746 /* We return either a 128 or 64 bit key
749 get_sealing_rc4key(const guint8 exportedsessionkey[NTLMSSP_KEY_LEN] ,const int flags ,int *keylen ,guint8 *clientsealkey ,guint8 *serversealkey)
751 md5_state_t md5state;
752 md5_state_t md5state2;
753 memset(clientsealkey,0,NTLMSSP_KEY_LEN);
754 memset(serversealkey,0,NTLMSSP_KEY_LEN);
755 memcpy(clientsealkey,exportedsessionkey,NTLMSSP_KEY_LEN);
756 if (flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY)
758 if (flags & NTLMSSP_NEGOTIATE_128)
760 /* The exportedsessionkey has already the good length just update the length*/
765 if (flags & NTLMSSP_NEGOTIATE_56)
767 memset(clientsealkey+7,0,9);
772 memset(clientsealkey+5,0,11);
776 memcpy(serversealkey,clientsealkey,NTLMSSP_KEY_LEN);
778 md5_append(&md5state,clientsealkey,*keylen);
779 md5_append(&md5state,CLIENT_SEAL_TEXT,strlen(CLIENT_SEAL_TEXT)+1);
780 md5_finish(&md5state,clientsealkey);
781 md5_init(&md5state2);
782 md5_append(&md5state2,serversealkey,*keylen);
783 md5_append(&md5state2,SERVER_SEAL_TEXT,strlen(SERVER_SEAL_TEXT)+1);
784 md5_finish(&md5state2,serversealkey);
788 if (flags & NTLMSSP_NEGOTIATE_128)
790 /* The exportedsessionkey has already the good length just update the length*/
796 if (flags & NTLMSSP_NEGOTIATE_56)
798 memset(clientsealkey+7,0,9);
802 memset(clientsealkey+5,0,11);
803 clientsealkey[5]=0xe5;
804 clientsealkey[6]=0x38;
805 clientsealkey[7]=0xb0;
808 serversealkey = memcpy(serversealkey,clientsealkey,*keylen);
811 /* Create an NTLMSSP version 1 key.
812 * password points to the ANSI password to encrypt, challenge points to
813 * the 8 octet challenge string, key128 will do a 128 bit key if set to 1,
814 * otherwise it will do a 40 bit key. The result is stored in
815 * sspkey (expected to be NTLMSSP_KEY_LEN octets)
817 /* dissect a string - header area contains:
820 four byte offset of string in data area
821 The function returns the offset at the end of the string header,
822 but the 'end' parameter returns the offset of the end of the string itself
823 The 'start' parameter returns the offset of the beginning of the string
826 dissect_ntlmssp_string (tvbuff_t *tvb, int offset,
827 proto_tree *ntlmssp_tree,
828 gboolean unicode_strings,
829 int string_hf, int *start, int *end,
830 const char **stringp)
832 proto_tree *tree = NULL;
833 proto_item *tf = NULL;
834 gint16 string_length = tvb_get_letohs(tvb, offset);
835 gint16 string_maxlen = tvb_get_letohs(tvb, offset+2);
836 gint32 string_offset = tvb_get_letohl(tvb, offset+4);
837 const char *string_text = NULL;
841 *start = (string_offset > offset+8 ? string_offset : offset+8);
842 if (0 == string_length) {
845 proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
852 bc = result_length = string_length;
853 string_text = get_unicode_or_ascii_string(tvb, &string_offset,
854 unicode_strings, &result_length,
857 if (stringp != NULL) {
858 if (!string_text) string_text = ""; /* Make sure we don't blow up later */
860 *stringp = string_text;
864 tf = proto_tree_add_string(ntlmssp_tree, string_hf, tvb,
865 string_offset, result_length, string_text);
866 tree = proto_item_add_subtree(tf, ett_ntlmssp_string);
868 proto_tree_add_uint(tree, hf_ntlmssp_string_len,
869 tvb, offset, 2, string_length);
871 proto_tree_add_uint(tree, hf_ntlmssp_string_maxlen,
872 tvb, offset, 2, string_maxlen);
874 proto_tree_add_uint(tree, hf_ntlmssp_string_offset,
875 tvb, offset, 4, string_offset);
878 *end = string_offset + string_length;
882 /* dissect a generic blob - header area contains:
885 four byte offset of blob in data area
886 The function returns the offset at the end of the blob header,
887 but the 'end' parameter returns the offset of the end of the blob itself
890 dissect_ntlmssp_blob (tvbuff_t *tvb, int offset,
891 proto_tree *ntlmssp_tree,
892 int blob_hf, int *end, ntlmssp_blob *result)
894 proto_item *tf = NULL;
895 proto_tree *tree = NULL;
896 guint16 blob_length = tvb_get_letohs(tvb, offset);
897 guint16 blob_maxlen = tvb_get_letohs(tvb, offset+2);
898 guint32 blob_offset = tvb_get_letohl(tvb, offset+4);
899 if (0 == blob_length) {
900 *end = (blob_offset > ((guint)offset)+8 ? blob_offset : ((guint)offset)+8);
902 proto_tree_add_text(ntlmssp_tree, tvb, offset, 8, "%s: Empty",
903 proto_registrar_get_name(blob_hf));
908 tf = proto_tree_add_item (ntlmssp_tree, blob_hf, tvb,
909 blob_offset, blob_length, FALSE);
910 tree = proto_item_add_subtree(tf, ett_ntlmssp_blob);
912 proto_tree_add_uint(tree, hf_ntlmssp_blob_len,
913 tvb, offset, 2, blob_length);
915 proto_tree_add_uint(tree, hf_ntlmssp_blob_maxlen,
916 tvb, offset, 2, blob_maxlen);
918 proto_tree_add_uint(tree, hf_ntlmssp_blob_offset,
919 tvb, offset, 4, blob_offset);
922 *end = blob_offset + blob_length;
924 if (result != NULL) {
925 result->length = blob_length;
926 memset(result->contents, 0, MAX_BLOB_SIZE);
927 if (blob_length < MAX_BLOB_SIZE)
929 tvb_memcpy(tvb, result->contents, blob_offset, blob_length);
930 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",NTLMSSP_KEY_LEN)))
932 proto_tree_add_item (ntlmssp_tree,
933 hf_ntlmssp_ntlm_client_challenge,
934 tvb, blob_offset, 8, FALSE);
939 /* If we are dissecting the NTLM response and it is a NTLMv2
940 response call the appropriate dissector. */
942 if (blob_hf == hf_ntlmssp_auth_ntresponse && blob_length > 24)
944 proto_tree_add_item (ntlmssp_tree,
945 hf_ntlmssp_ntlm_client_challenge,
946 tvb, blob_offset+32, 8, FALSE);
947 dissect_ntlmv2_response(tvb, tree, blob_offset, blob_length);
954 dissect_ntlmssp_negotiate_flags (tvbuff_t *tvb, int offset,
955 proto_tree *ntlmssp_tree,
956 guint32 negotiate_flags)
958 proto_tree *negotiate_flags_tree = NULL;
959 proto_item *tf = NULL;
962 tf = proto_tree_add_uint (ntlmssp_tree,
963 hf_ntlmssp_negotiate_flags,
964 tvb, offset, 4, negotiate_flags);
965 negotiate_flags_tree = proto_item_add_subtree (tf, ett_ntlmssp_negotiate_flags);
968 proto_tree_add_boolean (negotiate_flags_tree,
969 hf_ntlmssp_negotiate_flags_80000000,
970 tvb, offset, 4, negotiate_flags);
971 proto_tree_add_boolean (negotiate_flags_tree,
972 hf_ntlmssp_negotiate_flags_40000000,
973 tvb, offset, 4, negotiate_flags);
974 proto_tree_add_boolean (negotiate_flags_tree,
975 hf_ntlmssp_negotiate_flags_20000000,
976 tvb, offset, 4, negotiate_flags);
977 proto_tree_add_boolean (negotiate_flags_tree,
978 hf_ntlmssp_negotiate_flags_10000000,
979 tvb, offset, 4, negotiate_flags);
980 proto_tree_add_boolean (negotiate_flags_tree,
981 hf_ntlmssp_negotiate_flags_8000000,
982 tvb, offset, 4, negotiate_flags);
983 proto_tree_add_boolean (negotiate_flags_tree,
984 hf_ntlmssp_negotiate_flags_4000000,
985 tvb, offset, 4, negotiate_flags);
986 proto_tree_add_boolean (negotiate_flags_tree,
987 hf_ntlmssp_negotiate_flags_2000000,
988 tvb, offset, 4, negotiate_flags);
989 proto_tree_add_boolean (negotiate_flags_tree,
990 hf_ntlmssp_negotiate_flags_1000000,
991 tvb, offset, 4, negotiate_flags);
992 proto_tree_add_boolean (negotiate_flags_tree,
993 hf_ntlmssp_negotiate_flags_800000,
994 tvb, offset, 4, negotiate_flags);
995 proto_tree_add_boolean (negotiate_flags_tree,
996 hf_ntlmssp_negotiate_flags_400000,
997 tvb, offset, 4, negotiate_flags);
998 proto_tree_add_boolean (negotiate_flags_tree,
999 hf_ntlmssp_negotiate_flags_200000,
1000 tvb, offset, 4, negotiate_flags);
1001 proto_tree_add_boolean (negotiate_flags_tree,
1002 hf_ntlmssp_negotiate_flags_100000,
1003 tvb, offset, 4, negotiate_flags);
1004 proto_tree_add_boolean (negotiate_flags_tree,
1005 hf_ntlmssp_negotiate_flags_80000,
1006 tvb, offset, 4, negotiate_flags);
1007 proto_tree_add_boolean (negotiate_flags_tree,
1008 hf_ntlmssp_negotiate_flags_40000,
1009 tvb, offset, 4, negotiate_flags);
1010 proto_tree_add_boolean (negotiate_flags_tree,
1011 hf_ntlmssp_negotiate_flags_20000,
1012 tvb, offset, 4, negotiate_flags);
1013 proto_tree_add_boolean (negotiate_flags_tree,
1014 hf_ntlmssp_negotiate_flags_10000,
1015 tvb, offset, 4, negotiate_flags);
1016 proto_tree_add_boolean (negotiate_flags_tree,
1017 hf_ntlmssp_negotiate_flags_8000,
1018 tvb, offset, 4, negotiate_flags);
1019 proto_tree_add_boolean (negotiate_flags_tree,
1020 hf_ntlmssp_negotiate_flags_4000,
1021 tvb, offset, 4, negotiate_flags);
1022 proto_tree_add_boolean (negotiate_flags_tree,
1023 hf_ntlmssp_negotiate_flags_2000,
1024 tvb, offset, 4, negotiate_flags);
1025 proto_tree_add_boolean (negotiate_flags_tree,
1026 hf_ntlmssp_negotiate_flags_1000,
1027 tvb, offset, 4, negotiate_flags);
1028 proto_tree_add_boolean (negotiate_flags_tree,
1029 hf_ntlmssp_negotiate_flags_800,
1030 tvb, offset, 4, negotiate_flags);
1031 proto_tree_add_boolean (negotiate_flags_tree,
1032 hf_ntlmssp_negotiate_flags_400,
1033 tvb, offset, 4, negotiate_flags);
1034 proto_tree_add_boolean (negotiate_flags_tree,
1035 hf_ntlmssp_negotiate_flags_200,
1036 tvb, offset, 4, negotiate_flags);
1037 proto_tree_add_boolean (negotiate_flags_tree,
1038 hf_ntlmssp_negotiate_flags_100,
1039 tvb, offset, 4, negotiate_flags);
1040 proto_tree_add_boolean (negotiate_flags_tree,
1041 hf_ntlmssp_negotiate_flags_80,
1042 tvb, offset, 4, negotiate_flags);
1043 proto_tree_add_boolean (negotiate_flags_tree,
1044 hf_ntlmssp_negotiate_flags_40,
1045 tvb, offset, 4, negotiate_flags);
1046 proto_tree_add_boolean (negotiate_flags_tree,
1047 hf_ntlmssp_negotiate_flags_20,
1048 tvb, offset, 4, negotiate_flags);
1049 proto_tree_add_boolean (negotiate_flags_tree,
1050 hf_ntlmssp_negotiate_flags_10,
1051 tvb, offset, 4, negotiate_flags);
1052 proto_tree_add_boolean (negotiate_flags_tree,
1053 hf_ntlmssp_negotiate_flags_08,
1054 tvb, offset, 4, negotiate_flags);
1055 proto_tree_add_boolean (negotiate_flags_tree,
1056 hf_ntlmssp_negotiate_flags_04,
1057 tvb, offset, 4, negotiate_flags);
1058 proto_tree_add_boolean (negotiate_flags_tree,
1059 hf_ntlmssp_negotiate_flags_02,
1060 tvb, offset, 4, negotiate_flags);
1061 proto_tree_add_boolean (negotiate_flags_tree,
1062 hf_ntlmssp_negotiate_flags_01,
1063 tvb, offset, 4, negotiate_flags);
1065 return (offset + 4);
1068 /* Dissect a NTLM response. This is documented at
1069 http://ubiqx.org/cifs/SMB.html#SMB.8, para 2.8.5.3 */
1074 * XXX - the davenport document says that a type of 5 has been seen,
1075 * "apparently containing the 'parent' DNS domain for servers in
1079 #define NTLM_NAME_END 0x0000
1080 #define NTLM_NAME_NB_HOST 0x0001
1081 #define NTLM_NAME_NB_DOMAIN 0x0002
1082 #define NTLM_NAME_DNS_HOST 0x0003
1083 #define NTLM_NAME_DNS_DOMAIN 0x0004
1084 #define NTLM_NAME_DNS_FOREST 0x0005
1085 #define NTLM_NAME_CLIENT_TIME 0x0007
1086 #define NTLM_NAME_RESTRICTION 0x0008
1090 static const value_string ntlm_name_types[] = {
1091 { NTLM_NAME_END, "End of list" },
1092 { NTLM_NAME_NB_HOST, "NetBIOS host name" },
1093 { NTLM_NAME_NB_DOMAIN, "NetBIOS domain name" },
1094 { NTLM_NAME_DNS_HOST, "DNS host name" },
1095 { NTLM_NAME_DNS_DOMAIN, "DNS domain name" },
1096 { NTLM_NAME_DNS_FOREST, "DNS forest name" },
1098 { NTLM_NAME_CLIENT_TIME, "Client Time" },
1099 { NTLM_NAME_RESTRICTION, "Encoding restriction" },
1104 dissect_ntlmv2_response(tvbuff_t *tvb, proto_tree *tree, int offset, int len)
1106 proto_item *ntlmv2_item = NULL;
1107 proto_tree *ntlmv2_tree = NULL;
1108 const guint8 *restriction_bytes;
1109 /* Dissect NTLMv2 bits&pieces */
1112 ntlmv2_item = proto_tree_add_item(
1113 tree, hf_ntlmssp_ntlmv2_response, tvb,
1115 ntlmv2_tree = proto_item_add_subtree(
1116 ntlmv2_item, ett_ntlmssp_ntlmv2_response);
1119 proto_tree_add_item(
1120 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_hmac, tvb,
1125 proto_tree_add_item(
1126 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_header, tvb,
1131 proto_tree_add_item(
1132 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_reserved, tvb,
1137 offset = dissect_nt_64bit_time(
1138 tvb, ntlmv2_tree, offset, hf_ntlmssp_ntlmv2_response_time);
1140 proto_tree_add_item(
1141 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_chal, tvb,
1146 proto_tree_add_item(
1147 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_unknown, tvb,
1152 /* Variable length list of names */
1155 guint16 name_type = tvb_get_letohs(tvb, offset);
1156 guint16 name_len = tvb_get_letohs(tvb, offset + 2);
1157 proto_tree *name_tree = NULL;
1158 proto_item *name_item = NULL;
1159 const char *name = NULL;
1162 name_item = proto_tree_add_item(
1163 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_name,
1164 tvb, offset, 0, TRUE);
1165 name_tree = proto_item_add_subtree(
1166 name_item, ett_ntlmssp_ntlmv2_response_name);
1169 /* Dissect name header */
1171 proto_tree_add_item(
1172 name_tree, hf_ntlmssp_ntlmv2_response_name_type, tvb,
1177 proto_tree_add_item(
1178 name_tree, hf_ntlmssp_ntlmv2_response_name_len, tvb,
1188 proto_item_append_text(
1190 val_to_str(name_type, ntlm_name_types,
1193 case NTLM_NAME_CLIENT_TIME:
1194 dissect_nt_64bit_time(
1195 tvb, name_tree, offset,
1196 hf_ntlmssp_ntlmv2_response_client_time);
1197 proto_item_append_text(
1198 name_item, "Client Time");
1200 case NTLM_NAME_RESTRICTION:
1201 proto_item_append_text(
1203 val_to_str(name_type, ntlm_name_types,
1205 restriction_bytes = tvb_get_ptr(tvb, offset,name_len);
1206 proto_tree_add_bytes (name_tree,hf_ntlmssp_ntlmv2_response_restriction,tvb,offset,name_len,restriction_bytes);
1208 case NTLM_NAME_NB_HOST:
1209 case NTLM_NAME_NB_DOMAIN:
1210 case NTLM_NAME_DNS_HOST:
1211 case NTLM_NAME_DNS_DOMAIN:
1212 case NTLM_NAME_DNS_FOREST:
1214 name = tvb_get_ephemeral_faked_unicode(
1215 tvb, offset, name_len / 2, TRUE);
1216 proto_tree_add_text(
1217 name_tree, tvb, offset, name_len,
1219 proto_item_append_text(
1220 name_item, "%s, %s",
1221 val_to_str(name_type, ntlm_name_types,
1229 proto_item_set_len(name_item, name_len + 4);
1231 if (name_type == 0) /* End of list */
1236 * XXX - Windows puts 4 bytes of additional stuff here.
1237 * Samba's smbclient doesn't.
1238 * Both of them appear to be able to connect to W2K SMB
1240 * Should we display the rest of the response as an
1241 * "extra data" item?
1243 * XXX - we should also check whether we go past the length
1249 /* tapping into ntlmssph not yet implemented */
1251 dissect_ntlmssp_negotiate (tvbuff_t *tvb, int offset, proto_tree *ntlmssp_tree, ntlmssp_header_t *ntlmssph _U_)
1253 guint32 negotiate_flags;
1255 int workstation_end;
1258 /* NTLMSSP Negotiate Flags */
1259 negotiate_flags = tvb_get_letohl (tvb, offset);
1260 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
1264 * XXX - the davenport document says that these might not be
1265 * sent at all, presumably meaning the length of the message
1266 * isn't enough to contain them.
1268 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
1269 hf_ntlmssp_negotiate_domain,
1270 &start, &workstation_end, NULL);
1271 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE,
1272 hf_ntlmssp_negotiate_workstation,
1273 &start, &domain_end, NULL);
1275 /* XXX - two blobs after this one, sometimes? */
1277 return MAX(workstation_end, domain_end);
1282 dissect_ntlmssp_address_list (tvbuff_t *tvb, int offset,
1283 proto_tree *ntlmssp_tree,
1286 guint16 list_length = tvb_get_letohs(tvb, offset);
1287 guint16 list_maxlen = tvb_get_letohs(tvb, offset+2);
1288 guint32 list_offset = tvb_get_letohl(tvb, offset+4);
1289 guint16 item_type, item_length;
1290 guint32 item_offset;
1291 proto_item *tf = NULL;
1292 proto_tree *tree = NULL;
1293 proto_item *addr_tf = NULL;
1294 proto_tree *addr_tree = NULL;
1296 /* the address list is just a blob */
1297 if (0 == list_length) {
1298 *end = (list_offset > ((guint)offset)+8 ? list_offset : ((guint)offset)+8);
1300 proto_tree_add_text(ntlmssp_tree, tvb, offset, 8,
1301 "Address List: Empty");
1306 tf = proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_address_list, tvb,
1307 list_offset, list_length, FALSE);
1308 tree = proto_item_add_subtree(tf, ett_ntlmssp_address_list);
1310 proto_tree_add_uint(tree, hf_ntlmssp_address_list_len,
1311 tvb, offset, 2, list_length);
1313 proto_tree_add_uint(tree, hf_ntlmssp_address_list_maxlen,
1314 tvb, offset, 2, list_maxlen);
1316 proto_tree_add_uint(tree, hf_ntlmssp_address_list_offset,
1317 tvb, offset, 4, list_offset);
1320 /* Now enumerate through the individual items in the list */
1321 item_offset = list_offset;
1323 while (item_offset < (list_offset + list_length)) {
1324 const char *text=NULL;
1325 guint32 content_offset;
1326 guint16 content_length;
1327 guint32 type_offset;
1331 type_offset = item_offset;
1332 item_type = tvb_get_letohs(tvb, type_offset);
1334 /* Content length */
1335 len_offset = type_offset + 2;
1336 content_length = tvb_get_letohs(tvb, len_offset);
1339 content_offset = len_offset + 2;
1340 item_length = content_length + 4;
1342 /* Strings are always in Unicode regardless of the negotiated
1344 if (content_length > 0) {
1347 int item_offset_int;
1349 item_offset_int = content_offset;
1350 bc = content_length;
1351 text = get_unicode_or_ascii_string(tvb, &item_offset_int,
1352 TRUE, &result_length,
1356 if (!text) text = ""; /* Make sure we don't blow up below */
1359 case NTLM_NAME_NB_HOST:
1360 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_server_nb,
1361 tvb, item_offset, item_length, text);
1363 case NTLM_NAME_NB_DOMAIN:
1364 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_domain_nb,
1365 tvb, item_offset, item_length, text);
1367 case NTLM_NAME_DNS_HOST:
1368 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_server_dns,
1369 tvb, item_offset, item_length, text);
1371 case NTLM_NAME_DNS_DOMAIN:
1372 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_domain_dns,
1373 tvb, item_offset, item_length, text);
1375 case NTLM_NAME_DNS_FOREST:
1376 addr_tf = proto_tree_add_string(tree, hf_ntlmssp_address_list_forest_dns,
1377 tvb, item_offset, item_length, text);
1380 addr_tf = proto_tree_add_item(tree, hf_ntlmssp_address_list_terminator,
1381 tvb, item_offset, item_length, TRUE);
1384 addr_tf = proto_tree_add_text(tree, tvb, item_offset, item_length, "Unknown type:0x%04x", item_type);
1387 /* Now show the actual bytes that made up the summary line */
1388 addr_tree = proto_item_add_subtree (addr_tf,
1389 ett_ntlmssp_address_list_item);
1390 proto_tree_add_item (addr_tree, hf_ntlmssp_address_list_item_type,
1391 tvb, type_offset, 2, TRUE);
1392 proto_tree_add_item (addr_tree, hf_ntlmssp_address_list_item_len,
1393 tvb, len_offset, 2, TRUE);
1394 if (content_length > 0) {
1395 proto_tree_add_string(addr_tree, hf_ntlmssp_address_list_item_content,
1396 tvb, content_offset, content_length, text);
1399 item_offset += item_length;
1402 *end = list_offset + list_length;
1406 /* tapping into ntlmssph not yet implemented */
1408 dissect_ntlmssp_challenge (tvbuff_t *tvb, packet_info *pinfo, int offset,
1409 proto_tree *ntlmssp_tree, ntlmssp_header_t *ntlmssph _U_)
1411 guint32 negotiate_flags;
1412 int item_start, item_end;
1413 int data_start, data_end;
1414 guint8 clientkey[NTLMSSP_KEY_LEN]; /* NTLMSSP cipher key for client */
1415 guint8 serverkey[NTLMSSP_KEY_LEN]; /* NTLMSSP cipher key for server*/
1416 ntlmssp_info *conv_ntlmssp_info = NULL;
1417 conversation_t *conversation;
1418 gboolean unicode_strings = FALSE;
1419 guint8 challenge[8];
1421 guint8 sspkey[NTLMSSP_KEY_LEN]; /* NTLMSSP cipher key */
1422 int ssp_key_len; /* Either 8 or 16 (40 bit or 128) */
1424 /* need to find unicode flag */
1425 negotiate_flags = tvb_get_letohl (tvb, offset+8);
1426 if (negotiate_flags & NTLMSSP_NEGOTIATE_UNICODE)
1427 unicode_strings = TRUE;
1431 * XXX - the davenport document calls this the "Target Name",
1432 * presumably because non-domain targets are supported.
1434 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, unicode_strings,
1435 hf_ntlmssp_challenge_domain,
1436 &item_start, &item_end, NULL);
1437 data_start = item_start;
1438 data_end = item_end;
1440 /* NTLMSSP Negotiate Flags */
1441 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
1444 /* NTLMSSP NT Lan Manager Challenge */
1445 proto_tree_add_item (ntlmssp_tree,
1446 hf_ntlmssp_ntlm_server_challenge,
1447 tvb, offset, 8, FALSE);
1450 * Store the flags and the RC4 state information with the conversation,
1451 * as they're needed in order to dissect subsequent messages.
1453 conversation = find_or_create_conversation(pinfo);
1455 tvb_memcpy(tvb, tmp, offset, 8);
1456 /* We can face more than one NTLM exchange over the same couple of IP and ports ...*/
1457 conv_ntlmssp_info = conversation_get_proto_data(conversation, proto_ntlmssp);
1458 if (!conv_ntlmssp_info || memcmp(tmp,conv_ntlmssp_info->server_challenge,8) != 0) {
1459 conv_ntlmssp_info = se_alloc(sizeof(ntlmssp_info));
1460 /* Insert the flags into the conversation */
1461 conv_ntlmssp_info->flags = negotiate_flags;
1462 /* Insert the RC4 state information into the conversation */
1463 tvb_memcpy(tvb, challenge, offset, 8);
1464 tvb_memcpy(tvb, conv_ntlmssp_info->server_challenge, offset, 8);
1465 conv_ntlmssp_info->is_auth_ntlm_v2=0;
1466 /* Between the challenge and the user provided password, we can build the
1467 NTLMSSP key and initialize the cipher if we are not in EXTENDED SECURITY
1468 in this case we need the client challenge as well*/
1469 /* BTW this is true just if we are in LM Authentification if not the logic is a bit different.
1470 * Right now it's not very clear what is LM Authentification it __seems__ to be when
1471 * NEGOTIATE NT ONLY is not set and NEGOSIATE EXTENDED SECURITY is not set as well*/
1472 if (!(conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY))
1474 conv_ntlmssp_info->rc4_state_initialized = 0;
1475 create_ntlmssp_v1_key(gbl_nt_password, conv_ntlmssp_info->server_challenge,NULL, sspkey,NULL,conv_ntlmssp_info->flags,conv_ntlmssp_info->ntlm_response.contents,conv_ntlmssp_info->lm_response.contents);
1476 if( memcmp(sspkey,gbl_zeros,NTLMSSP_KEY_LEN) != 0 ) {
1477 get_sealing_rc4key(sspkey,conv_ntlmssp_info->flags,&ssp_key_len,clientkey,serverkey);
1478 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_client, sspkey, ssp_key_len);
1479 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_server, sspkey, ssp_key_len);
1480 conv_ntlmssp_info->server_dest_port = pinfo->destport;
1481 conv_ntlmssp_info->rc4_state_initialized = 1;
1485 conversation_add_proto_data(conversation, proto_ntlmssp, conv_ntlmssp_info);
1489 /* Reserved (function not completely known) */
1491 * XXX - SSP key? The davenport document says
1493 * The context field is typically populated when Negotiate Local
1494 * Call is set. It contains an SSPI context handle, which allows
1495 * the client to "short-circuit" authentication and effectively
1496 * circumvent responding to the challenge. Physically, the context
1497 * is two long values. This is covered in greater detail later,
1498 * in the "Local Authentication" section.
1500 * It also says that that information may be omitted.
1502 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_reserved,
1503 tvb, offset, 8, FALSE);
1507 * The presence or absence of this field is not obviously correlated
1508 * with any flags in the previous NEGOTIATE message or in this
1509 * message (other than the "Workstation Supplied" and "Domain
1510 * Supplied" flags in the NEGOTIATE message, at least in the capture
1511 * I've seen - but those also correlate with the presence of workstation
1512 * and domain name fields, so it doesn't seem to make sense that they
1513 * actually *indicate* whether the subsequent CHALLENGE has an
1516 if (offset < data_start) {
1517 offset = dissect_ntlmssp_address_list(tvb, offset, ntlmssp_tree, &item_end);
1518 data_end = MAX(data_end, item_end);
1521 return MAX(offset, data_end);
1525 dissect_ntlmssp_auth (tvbuff_t *tvb, packet_info *pinfo, int offset,
1526 proto_tree *ntlmssp_tree, ntlmssp_header_t *ntlmssph)
1528 int item_start, item_end;
1529 int data_start, data_end = 0;
1530 guint32 negotiate_flags;
1531 guint8 sspkey[NTLMSSP_KEY_LEN]; /* exported session key */
1532 guint8 clientkey[NTLMSSP_KEY_LEN]; /* NTLMSSP cipher key for client */
1533 guint8 serverkey[NTLMSSP_KEY_LEN]; /* NTLMSSP cipher key for server*/
1534 guint8 encryptedsessionkey[NTLMSSP_KEY_LEN];
1535 ntlmssp_blob sessionblob;
1536 gboolean unicode_strings = FALSE;
1537 ntlmssp_info *conv_ntlmssp_info = NULL;
1538 conversation_t *conversation;
1541 * Get flag info from the original negotiate message, if any.
1542 * This is because the flag information is sometimes missing from
1543 * the AUTHENTICATE message, so we can't figure out whether
1544 * strings are Unicode or not by looking at *our* flags.
1545 * XXX it seems it's more from the CHALLENGE message, which is more clever in fact
1546 * because the server can change some flags.
1547 * But according to MS NTLMSSP doc it's not that simple.
1548 * In case of Conection less mode AUTHENTICATE flags should be used because they
1549 * reprensent the choice of the client after having been informed of options of the
1550 * server in the CHALLENGE message.
1551 * In Connection mode then the CHALLENGE flags should (must ?) be used
1553 conv_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1554 if (conv_ntlmssp_info == NULL) {
1556 * There isn't any. Is there any from this conversation? If so,
1557 * it means this is the first time we've dissected this frame, so
1558 * we should give it flag info.
1560 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1561 pinfo->ptype, pinfo->srcport,
1562 pinfo->destport, 0);
1563 if (conversation != NULL) {
1564 conv_ntlmssp_info = conversation_get_proto_data(conversation, proto_ntlmssp);
1565 if (conv_ntlmssp_info != NULL) {
1567 * We have flag info; attach it to the frame.
1569 p_add_proto_data(pinfo->fd, proto_ntlmssp, conv_ntlmssp_info);
1573 if (conv_ntlmssp_info != NULL) {
1574 if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_UNICODE)
1575 unicode_strings = TRUE;
1579 * Sometimes the session key and flags are missing.
1580 * Sometimes the session key is present but the flags are missing.
1581 * XXX Who stay so ? Reading spec I would rather say the opposite: flags are
1582 * always present, session information are always there as well but sometime
1583 * session information could be null (in case of no session)
1584 * Sometimes they're both present.
1586 * This does not correlate with any flags in the previous CHALLENGE
1587 * message, and only correlates with "Negotiate Unicode", "Workstation
1588 * Supplied", and "Domain Supplied" in the NEGOTIATE message - but
1589 * those don't make sense as flags to use to determine this.
1591 * So we check all of the descriptors to figure out where the data
1592 * area begins, and if the session key or the flags would be in the
1593 * middle of the data area, we assume the field in question is
1597 /* Lan Manager response */
1598 data_start = tvb_get_letohl(tvb, offset+4);
1599 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
1600 hf_ntlmssp_auth_lmresponse,
1602 conv_ntlmssp_info == NULL ? NULL :
1603 &conv_ntlmssp_info->lm_response);
1604 data_end = MAX(data_end, item_end);
1607 item_start = tvb_get_letohl(tvb, offset+4);
1608 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
1609 hf_ntlmssp_auth_ntresponse,
1611 conv_ntlmssp_info == NULL ? NULL :
1612 &conv_ntlmssp_info->ntlm_response);
1613 if( conv_ntlmssp_info != NULL && conv_ntlmssp_info->ntlm_response.length > 24 ) {
1614 memcpy(conv_ntlmssp_info->client_challenge,conv_ntlmssp_info->ntlm_response.contents+32,8);
1616 data_start = MIN(data_start, item_start);
1617 data_end = MAX(data_end, item_end);
1618 if( conv_ntlmssp_info != NULL )
1620 if( conv_ntlmssp_info->ntlm_response.length > 24 )
1622 conv_ntlmssp_info->is_auth_ntlm_v2=1;
1626 conv_ntlmssp_info->is_auth_ntlm_v2=0;
1631 item_start = tvb_get_letohl(tvb, offset+4);
1632 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
1634 hf_ntlmssp_auth_domain,
1635 &item_start, &item_end, &(ntlmssph->domain_name));
1636 /*ntlmssph->domain_name_len=item_end-item_start;*/
1637 data_start = MIN(data_start, item_start);
1638 data_end = MAX(data_end, item_end);
1641 item_start = tvb_get_letohl(tvb, offset+4);
1642 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
1644 hf_ntlmssp_auth_username,
1645 &item_start, &item_end, &(ntlmssph->acct_name));
1646 /*ntlmssph->acct_name_len=item_end-item_start;*/
1647 data_start = MIN(data_start, item_start);
1648 data_end = MAX(data_end, item_end);
1650 if (check_col(pinfo->cinfo, COL_INFO))
1651 col_append_fstr(pinfo->cinfo, COL_INFO, ", User: %s\\%s",
1652 ntlmssph->domain_name, ntlmssph->acct_name);
1655 item_start = tvb_get_letohl(tvb, offset+4);
1656 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree,
1658 hf_ntlmssp_auth_hostname,
1659 &item_start, &item_end, &(ntlmssph->host_name));
1660 data_start = MIN(data_start, item_start);
1661 data_end = MAX(data_end, item_end);
1662 memset(sessionblob.contents, 0, MAX_BLOB_SIZE);
1663 sessionblob.length = 0;
1664 if (offset < data_start) {
1666 offset = dissect_ntlmssp_blob(tvb, offset, ntlmssp_tree,
1667 hf_ntlmssp_auth_sesskey,
1668 &item_end, &sessionblob);
1669 data_end = MAX(data_end, item_end);
1671 if ( sessionblob.length > NTLMSSP_KEY_LEN ) {
1672 expert_add_info_format(pinfo, NULL, PI_WARN, PI_UNDECODED, "Session blob length too long: %u", sessionblob.length);
1673 } else if( sessionblob.length != 0 ) {
1674 memcpy(encryptedsessionkey,sessionblob.contents,sessionblob.length);
1675 if (offset < data_start) {
1676 /* NTLMSSP Negotiate Flags */
1677 negotiate_flags = tvb_get_letohl (tvb, offset);
1678 offset = dissect_ntlmssp_negotiate_flags (tvb, offset, ntlmssp_tree,
1681 /* Try to attach to an existing conversation if not then it's useless to try to do so
1682 * because we are missing important information (ie. server challenge)
1684 if (conv_ntlmssp_info) {
1685 /* If we are in EXTENDED SECURITY then we can now initialize cipher */
1686 if ((conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY))
1688 conv_ntlmssp_info->rc4_state_initialized = 0;
1689 if( conv_ntlmssp_info->is_auth_ntlm_v2 ) {
1690 create_ntlmssp_v2_key(gbl_nt_password, conv_ntlmssp_info->server_challenge,conv_ntlmssp_info->client_challenge, sspkey,encryptedsessionkey,conv_ntlmssp_info->flags,conv_ntlmssp_info->ntlm_response,conv_ntlmssp_info->lm_response,ntlmssph);
1694 memcpy(conv_ntlmssp_info->client_challenge,conv_ntlmssp_info->lm_response.contents,8);
1695 create_ntlmssp_v1_key(gbl_nt_password, conv_ntlmssp_info->server_challenge,conv_ntlmssp_info->client_challenge, sspkey,encryptedsessionkey,conv_ntlmssp_info->flags,conv_ntlmssp_info->ntlm_response.contents,conv_ntlmssp_info->lm_response.contents);
1697 /* ssp is the exported session key */
1698 if( memcmp(sspkey,gbl_zeros,NTLMSSP_KEY_LEN) != 0) {
1699 get_sealing_rc4key(sspkey,conv_ntlmssp_info->flags,&ssp_key_len,clientkey,serverkey);
1700 get_siging_key((guint8*)&conv_ntlmssp_info->sign_key_server,(guint8*)&conv_ntlmssp_info->sign_key_client,sspkey,ssp_key_len);
1701 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_server, serverkey, ssp_key_len);
1702 crypt_rc4_init(&conv_ntlmssp_info->rc4_state_client, clientkey, ssp_key_len);
1703 conv_ntlmssp_info->server_dest_port = pinfo->destport;
1704 conv_ntlmssp_info->rc4_state_initialized = 1;
1709 return MAX(offset, data_end);
1712 get_sign_key(packet_info *pinfo, int cryptpeer)
1714 conversation_t *conversation;
1715 ntlmssp_info *conv_ntlmssp_info;
1717 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1718 pinfo->ptype, pinfo->srcport,
1719 pinfo->destport, 0);
1720 if (conversation == NULL) {
1721 /* We don't have a conversation. In this case, stop processing
1722 because we do not have enough info to decrypt the payload */
1726 /* We have a conversation, check for encryption state */
1727 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1729 if (conv_ntlmssp_info == NULL) {
1730 /* No encryption state tied to the conversation. Therefore, we
1731 cannot decrypt the payload */
1735 /* We have the encryption state in the conversation. So return the
1736 crypt state tied to the requested peer
1738 if (cryptpeer == 1) {
1739 return (guint8*)&conv_ntlmssp_info->sign_key_client;
1741 return (guint8*)&conv_ntlmssp_info->sign_key_server;
1747 * Get the encryption state tied to this conversation. cryptpeer indicates
1748 * whether to retrieve the client key (1) or the server key (0)
1750 static rc4_state_struct *
1751 get_encrypted_state(packet_info *pinfo, int cryptpeer)
1753 conversation_t *conversation;
1754 ntlmssp_info *conv_ntlmssp_info;
1756 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1757 pinfo->ptype, pinfo->srcport,
1758 pinfo->destport, 0);
1759 if (conversation == NULL) {
1760 /* We don't have a conversation. In this case, stop processing
1761 because we do not have enough info to decrypt the payload */
1765 /* We have a conversation, check for encryption state */
1766 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1768 if (conv_ntlmssp_info == NULL) {
1769 /* No encryption state tied to the conversation. Therefore, we
1770 cannot decrypt the payload */
1774 /* We have the encryption state in the conversation. So return the
1775 crypt state tied to the requested peer
1777 if (cryptpeer == 1) {
1778 return &conv_ntlmssp_info->rc4_state_client;
1780 return &conv_ntlmssp_info->rc4_state_server;
1786 decrypt_data_payload(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
1787 packet_info *pinfo, proto_tree *tree _U_,gpointer key);
1789 decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
1790 packet_info *pinfo, proto_tree *tree,gpointer key);
1793 dissect_ntlmssp_encrypted_payload(tvbuff_t *data_tvb,
1794 tvbuff_t *auth_tvb _U_,
1797 dcerpc_auth_info *auth_info _U_)*/
1800 dissect_ntlmssp_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree )
1802 volatile int offset = 0;
1803 proto_tree *volatile ntlmssp_tree = NULL;
1804 proto_item *tf = NULL;
1806 guint32 encrypted_block_length;
1807 guint8 key[NTLMSSP_KEY_LEN];
1808 /* the magic ntlm is the identifier of a NTLMSSP packet that's 00 00 00 01
1810 guint32 ntlm_magic_size = 4;
1811 guint32 ntlm_signature_size = 8;
1812 guint32 ntlm_seq_size = 4;
1813 length = tvb_length (tvb);
1814 /* signature + seq + real payload */
1815 encrypted_block_length = length - ntlm_magic_size;
1817 if (encrypted_block_length < (ntlm_signature_size + ntlm_seq_size)) {
1818 /* Don't know why this would happen, but if it does, don't even bother
1819 attempting decryption/dissection */
1820 return offset + length;
1823 /* Setup a new tree for the NTLMSSP payload */
1825 tf = proto_tree_add_item (tree,
1827 tvb, offset, -1, FALSE);
1829 ntlmssp_tree = proto_item_add_subtree (tf,
1834 * Catch the ReportedBoundsError exception; the stuff we've been
1835 * handed doesn't necessarily run to the end of the packet, it's
1836 * an item inside a packet, so if it happens to be malformed (or
1837 * we, or a dissector we call, has a bug), so that an exception
1838 * is thrown, we want to report the error, but return and let
1839 * our caller dissect the rest of the packet.
1841 * If it gets a BoundsError, we can stop, as there's nothing more
1842 * in the packet after our blob to see, so we just re-throw the
1846 /* Version number */
1847 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_vers,
1848 tvb, offset, 4, TRUE);
1851 /* Encrypted body */
1852 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_body,
1853 tvb, offset, ntlm_signature_size + ntlm_seq_size, TRUE);
1854 tvb_memcpy(tvb, key, offset, ntlm_signature_size + ntlm_seq_size);
1855 /* Try to decrypt */
1856 decrypt_data_payload (tvb, offset+(ntlm_signature_size + ntlm_seq_size), encrypted_block_length-(ntlm_signature_size + ntlm_seq_size), pinfo, ntlmssp_tree,key);
1857 decrypt_verifier (tvb, offset, ntlm_signature_size + ntlm_seq_size, pinfo, ntlmssp_tree,key);
1858 /* let's try to hook ourselves here */
1861 } CATCH(BoundsError) {
1863 } CATCH(ReportedBoundsError) {
1864 show_reported_bounds_error(tvb, pinfo, tree);
1870 decrypt_data_payload(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
1871 packet_info *pinfo, proto_tree *tree _U_,gpointer key)
1873 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
1875 conversation_t *conversation;
1876 rc4_state_struct *rc4_state;
1877 rc4_state_struct *rc4_state_peer;
1878 ntlmssp_info *conv_ntlmssp_info = NULL;
1879 ntlmssp_packet_info *packet_ntlmssp_info = NULL;
1880 ntlmssp_packet_info *stored_packet_ntlmssp_info = NULL;
1882 /* Check to see if we already have state for this packet */
1883 packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
1884 if (packet_ntlmssp_info == NULL) {
1885 /* We don't have any packet state, so create one */
1886 packet_ntlmssp_info = se_alloc0(sizeof(ntlmssp_packet_info));
1887 p_add_proto_data(pinfo->fd, proto_ntlmssp, packet_ntlmssp_info);
1889 if (!packet_ntlmssp_info->payload_decrypted) {
1890 /* Pull the challenge info from the conversation */
1891 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
1892 pinfo->ptype, pinfo->srcport,
1893 pinfo->destport, 0);
1894 if (conversation == NULL) {
1895 /* There is no conversation, thus no encryption state */
1899 conv_ntlmssp_info = conversation_get_proto_data(conversation,
1901 if (conv_ntlmssp_info == NULL) {
1902 /* There is no NTLMSSP state tied to the conversation */
1905 if (conv_ntlmssp_info->rc4_state_initialized != 1 ) {
1906 /* The crypto sybsystem is not initialized. This means that either
1907 the conversation did not include a challenge, or that we do not have the right password */
1911 stored_packet_ntlmssp_info = g_hash_table_lookup(hash_packet,key);
1913 if( stored_packet_ntlmssp_info != NULL && stored_packet_ntlmssp_info->payload_decrypted == TRUE)
1915 /* Mat TBD (stderr,"Found a already decrypted packet\n");*/
1916 memcpy(packet_ntlmssp_info,stored_packet_ntlmssp_info,sizeof(ntlmssp_packet_info));
1917 /* Mat TBD printnbyte(packet_ntlmssp_info->decrypted_payload,encrypted_block_length,"Data: ","\n");*/
1921 /* Get the pair of RC4 state structures. One is used for to decrypt the
1922 payload. The other is used to re-encrypt the payload to represent
1924 if (conv_ntlmssp_info->server_dest_port == pinfo->destport) {
1926 rc4_state = get_encrypted_state(pinfo, 1);
1927 rc4_state_peer = get_encrypted_state(pinfo, 0);
1930 rc4_state = get_encrypted_state(pinfo, 0);
1931 rc4_state_peer = get_encrypted_state(pinfo, 1);
1934 if (rc4_state == NULL ) {
1935 /* There is no encryption state, so we cannot decrypt */
1939 /* Store the decrypted contents in the packet state struct
1940 (of course at this point, they aren't decrypted yet) */
1941 packet_ntlmssp_info->decrypted_payload = tvb_memdup(tvb, offset,
1942 encrypted_block_length);
1943 packet_ntlmssp_info->payload_len = encrypted_block_length;
1944 decrypted_payloads = g_slist_prepend(decrypted_payloads,
1945 packet_ntlmssp_info->decrypted_payload);
1947 g_hash_table_insert(hash_packet,key,packet_ntlmssp_info);
1950 /* Do the decryption of the payload */
1951 crypt_rc4(rc4_state, packet_ntlmssp_info->decrypted_payload,
1952 encrypted_block_length);
1953 /* decrypt the verifier */
1954 /*printnchar(packet_ntlmssp_info->decrypted_payload,encrypted_block_length,"data: ","\n");*/
1955 /* We setup a temporary buffer so we can re-encrypt the payload after
1956 decryption. This is to update the opposite peer's RC4 state
1957 it's usefull when we have only one key for both conversation
1958 in case of KEY_EXCH we have independant key so this is not needed*/
1959 if( !(NTLMSSP_NEGOTIATE_KEY_EXCH & conv_ntlmssp_info->flags)) {
1960 peer_block = ep_memdup(packet_ntlmssp_info->decrypted_payload, encrypted_block_length);
1961 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
1964 packet_ntlmssp_info->payload_decrypted = TRUE;
1968 /* Show the decrypted buffer in a new window */
1969 decr_tvb = tvb_new_real_data(packet_ntlmssp_info->decrypted_payload,
1970 encrypted_block_length,
1971 encrypted_block_length);
1973 tvb_set_child_real_data_tvbuff(tvb, decr_tvb);
1974 pinfo->gssapi_decrypted_tvb = decr_tvb;
1977 dissect_ntlmssp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1979 volatile int offset = 0;
1980 proto_tree *volatile ntlmssp_tree = NULL;
1981 proto_item *tf = NULL;
1982 ntlmssp_header_t *ntlmssph;
1984 ntlmssph=ep_alloc(sizeof(ntlmssp_header_t));
1986 ntlmssph->domain_name=NULL;
1987 ntlmssph->acct_name=NULL;
1988 ntlmssph->host_name=NULL;
1990 /* Setup a new tree for the NTLMSSP payload */
1992 tf = proto_tree_add_item (tree,
1994 tvb, offset, -1, FALSE);
1996 ntlmssp_tree = proto_item_add_subtree (tf,
2001 * Catch the ReportedBoundsError exception; the stuff we've been
2002 * handed doesn't necessarily run to the end of the packet, it's
2003 * an item inside a packet, so if it happens to be malformed (or
2004 * we, or a dissector we call, has a bug), so that an exception
2005 * is thrown, we want to report the error, but return and let
2006 * our caller dissect the rest of the packet.
2008 * If it gets a BoundsError, we can stop, as there's nothing more
2009 * in the packet after our blob to see, so we just re-throw the
2013 /* NTLMSSP constant */
2014 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth,
2015 tvb, offset, 8, FALSE);
2018 /* NTLMSSP Message Type */
2019 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_message_type,
2020 tvb, offset, 4, TRUE);
2021 ntlmssph->type = tvb_get_letohl (tvb, offset);
2024 if (check_col(pinfo->cinfo, COL_INFO))
2025 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
2026 val_to_str(ntlmssph->type,
2027 ntlmssp_message_types,
2028 "Unknown message type"));
2030 /* Call the appropriate dissector based on the Message Type */
2031 switch (ntlmssph->type) {
2033 case NTLMSSP_NEGOTIATE:
2034 offset = dissect_ntlmssp_negotiate (tvb, offset, ntlmssp_tree, ntlmssph);
2037 case NTLMSSP_CHALLENGE:
2038 offset = dissect_ntlmssp_challenge (tvb, pinfo, offset, ntlmssp_tree, ntlmssph);
2042 offset = dissect_ntlmssp_auth (tvb, pinfo, offset, ntlmssp_tree, ntlmssph);
2046 /* Unrecognized message type */
2047 proto_tree_add_text (ntlmssp_tree, tvb, offset, -1,
2048 "Unrecognized NTLMSSP Message");
2051 } CATCH(BoundsError) {
2053 } CATCH(ReportedBoundsError) {
2054 show_reported_bounds_error(tvb, pinfo, tree);
2057 /*tap_queue_packet(ntlmssp_tap, pinfo, ntlmssph);*/
2063 * See page 45 of "DCE/RPC over SMB" by Luke Kenneth Casson Leighton.
2066 decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length,
2067 packet_info *pinfo, proto_tree *tree,gpointer key)
2069 proto_tree *decr_tree = NULL;
2070 proto_item *tf = NULL;
2071 conversation_t *conversation;
2073 rc4_state_struct *rc4_state;
2074 rc4_state_struct *rc4_state_peer;
2075 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */
2078 guint8 calculated_md5[NTLMSSP_KEY_LEN];
2079 ntlmssp_info *conv_ntlmssp_info = NULL;
2080 ntlmssp_packet_info *packet_ntlmssp_info = NULL;
2081 int decrypted_offset = 0;
2084 ntlmssp_packet_info *stored_packet_ntlmssp_info = NULL;
2085 packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
2086 if (packet_ntlmssp_info == NULL) {
2087 /* We don't have data for this packet */
2090 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
2091 pinfo->ptype, pinfo->srcport,
2092 pinfo->destport, 0);
2093 if (conversation == NULL) {
2094 /* There is no conversation, thus no encryption state */
2097 conv_ntlmssp_info = conversation_get_proto_data(conversation,
2099 if (conv_ntlmssp_info == NULL) {
2100 /* There is no NTLMSSP state tied to the conversation */
2105 stored_packet_ntlmssp_info = g_hash_table_lookup(hash_packet,key);
2107 if( stored_packet_ntlmssp_info != NULL && stored_packet_ntlmssp_info->verifier_decrypted == TRUE) {
2108 /* Mat TBD fprintf(stderr,"Found a already decrypted packet\n");*/
2109 /* In Theory it's aleady the case, and we should be more clever ... like just copying buffers ...*/
2110 packet_ntlmssp_info = stored_packet_ntlmssp_info;
2113 if (!packet_ntlmssp_info->verifier_decrypted) {
2114 if (conv_ntlmssp_info->rc4_state_initialized != 1 ) {
2115 /* The crypto sybsystem is not initialized. This means that either
2116 the conversation did not include a challenge, or we are doing
2117 something other than NTLMSSP v1 */
2120 if (conv_ntlmssp_info->server_dest_port == pinfo->destport) {
2121 /* client talk to server */
2122 rc4_state = get_encrypted_state(pinfo, 1);
2123 sign_key = get_sign_key(pinfo,1);
2124 rc4_state_peer = get_encrypted_state(pinfo, 0);
2126 rc4_state = get_encrypted_state(pinfo, 0);
2127 sign_key = get_sign_key(pinfo,0);
2128 rc4_state_peer = get_encrypted_state(pinfo, 1);
2131 if (rc4_state == NULL || rc4_state_peer == NULL) {
2132 /* There is no encryption state, so we cannot decrypt */
2136 /* Setup the buffer to decrypt to */
2137 tvb_memcpy(tvb, packet_ntlmssp_info->verifier,
2138 offset, encrypted_block_length);
2140 /*if( !(NTLMSSP_NEGOTIATE_KEY_EXCH & packet_ntlmssp_info->flags)) {*/
2141 if( conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY ) {
2142 if( (NTLMSSP_NEGOTIATE_KEY_EXCH & conv_ntlmssp_info->flags)) {
2143 /* The spec says that if we have have a key exchange then we have a the signature that is crypted
2144 * otherwise it's just a hmac_md5(keysign,concat(message,sequence))[0..7]
2146 crypt_rc4(rc4_state, packet_ntlmssp_info->verifier,
2150 * Try to check the HMAC MD5 of the message against those calculated works great with LDAP payload but
2151 * don't with DCE/RPC calls.
2152 * Some analysis need to be done ...
2154 if( sign_key != NULL ) {
2155 check_buf = ep_alloc(packet_ntlmssp_info->payload_len+4);
2156 tvb_memcpy(tvb, &sequence,offset+8,4);
2157 memcpy(check_buf,&sequence,4);
2158 memcpy(check_buf+4,packet_ntlmssp_info->decrypted_payload,packet_ntlmssp_info->payload_len);
2159 md5_hmac(check_buf,(int)(packet_ntlmssp_info->payload_len+4),sign_key,NTLMSSP_KEY_LEN,calculated_md5);
2161 printnbyte(packet_ntlmssp_info->verifier,8,"HMAC from packet: ","\n");
2162 printnbyte(calculated_md5,8,"HMAC : ","\n");
2167 /* 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 */
2168 /* Do the actual decryption of the verifier */
2169 crypt_rc4(rc4_state, packet_ntlmssp_info->verifier,
2170 encrypted_block_length);
2175 /* We setup a temporary buffer so we can re-encrypt the payload after
2176 decryption. This is to update the opposite peer's RC4 state
2177 This is not needed when we just have EXTENDED SECURITY because the signature is not crypted
2178 and it's also not needed when we have key exchange because server and client have independant keys */
2179 if( !(NTLMSSP_NEGOTIATE_KEY_EXCH & conv_ntlmssp_info->flags) && !(NTLMSSP_NEGOTIATE_EXTENDED_SECURITY & conv_ntlmssp_info->flags)) {
2180 peer_block = ep_memdup(packet_ntlmssp_info->verifier, encrypted_block_length);
2181 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
2184 /* Mark the packet as decrypted so that subsequent attempts to dissect
2185 the packet use the already decrypted payload instead of attempting
2187 packet_ntlmssp_info->verifier_decrypted = TRUE;
2190 /* Show the decrypted buffer in a new window */
2191 decr_tvb = tvb_new_child_real_data(tvb, packet_ntlmssp_info->verifier,
2192 encrypted_block_length,
2193 encrypted_block_length);
2194 add_new_data_source(pinfo, decr_tvb,
2195 "Decrypted NTLMSSP Verifier");
2197 /* Show the decrypted payload in the tree */
2198 tf = proto_tree_add_text(tree, decr_tvb, 0, -1,
2199 "Decrypted Verifier (%d byte%s)",
2200 encrypted_block_length,
2201 plurality(encrypted_block_length, "", "s"));
2202 decr_tree = proto_item_add_subtree (tf, ett_ntlmssp);
2204 if(( conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY )) {
2205 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_hmacmd5,
2206 decr_tvb, decrypted_offset, 8,TRUE);
2207 decrypted_offset += 8;
2211 /* Incrementing sequence number of DCE conversation */
2212 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_sequence,
2213 decr_tvb, decrypted_offset, 4, TRUE);
2214 decrypted_offset += 4;
2218 /* RANDOM PAD usually it's 0 */
2219 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_randompad,
2220 decr_tvb, decrypted_offset, 4, TRUE);
2221 decrypted_offset += 4;
2223 /* CRC32 of the DCE fragment data */
2224 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_crc32,
2225 decr_tvb, decrypted_offset, 4, TRUE);
2226 decrypted_offset += 4;
2228 /* Incrementing sequence number of DCE conversation */
2229 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_sequence,
2230 decr_tvb, decrypted_offset, 4, TRUE);
2231 decrypted_offset += 4;
2235 /* Used when NTLMSSP is done over DCE/RPC because in this case verifier and real payload are not contigious*/
2237 dissect_ntlmssp_payload_only(tvbuff_t *tvb, packet_info *pinfo, _U_ proto_tree *tree)
2239 volatile int offset = 0;
2240 proto_tree *volatile ntlmssp_tree = NULL;
2241 guint32 encrypted_block_length;
2242 /* the magic ntlm is the identifier of a NTLMSSP packet that's 00 00 00 01
2244 encrypted_block_length = tvb_length (tvb);
2245 /* signature + seq + real payload */
2247 /* Setup a new tree for the NTLMSSP payload */
2250 tf = proto_tree_add_item (tree,
2252 tvb, offset, -1, FALSE);
2254 ntlmssp_tree = proto_item_add_subtree (tf,
2259 * Catch the ReportedBoundsError exception; the stuff we've been
2260 * handed doesn't necessarily run to the end of the packet, it's
2261 * an item inside a packet, so if it happens to be malformed (or
2262 * we, or a dissector we call, has a bug), so that an exception
2263 * is thrown, we want to report the error, but return and let
2264 * our caller dissect the rest of the packet.
2266 * If it gets a BoundsError, we can stop, as there's nothing more
2267 * in the packet after our blob to see, so we just re-throw the
2271 /* Version number */
2273 /* Try to decrypt */
2274 decrypt_data_payload (tvb, offset, encrypted_block_length, pinfo, ntlmssp_tree,NULL);
2275 /* let's try to hook ourselves here */
2277 } CATCH(BoundsError) {
2279 } CATCH(ReportedBoundsError) {
2280 show_reported_bounds_error(tvb, pinfo, tree);
2285 /* Used when NTLMSSP is done over DCE/RPC because in this case verifier and real payload are not contigious
2286 * But in fact this function could be merged with wrap_dissect_ntlmssp_verf because it's only used there
2289 dissect_ntlmssp_verf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2291 volatile int offset = 0;
2292 proto_tree *volatile ntlmssp_tree = NULL;
2293 proto_item *tf = NULL;
2294 guint32 verifier_length;
2295 guint32 encrypted_block_length;
2297 verifier_length = tvb_length (tvb);
2298 encrypted_block_length = verifier_length - 4;
2300 if (encrypted_block_length < 12) {
2301 /* Don't know why this would happen, but if it does, don't even bother
2302 attempting decryption/dissection */
2303 return offset + verifier_length;
2306 /* Setup a new tree for the NTLMSSP payload */
2308 tf = proto_tree_add_item (tree,
2310 tvb, offset, -1, FALSE);
2312 ntlmssp_tree = proto_item_add_subtree (tf,
2317 * Catch the ReportedBoundsError exception; the stuff we've been
2318 * handed doesn't necessarily run to the end of the packet, it's
2319 * an item inside a packet, so if it happens to be malformed (or
2320 * we, or a dissector we call, has a bug), so that an exception
2321 * is thrown, we want to report the error, but return and let
2322 * our caller dissect the rest of the packet.
2324 * If it gets a BoundsError, we can stop, as there's nothing more
2325 * in the packet after our blob to see, so we just re-throw the
2329 /* Version number */
2330 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_vers,
2331 tvb, offset, 4, TRUE);
2334 /* Encrypted body */
2335 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_body,
2336 tvb, offset, encrypted_block_length, TRUE);
2338 /* Try to decrypt */
2339 decrypt_verifier (tvb, offset, encrypted_block_length, pinfo, ntlmssp_tree,NULL);
2340 /* let's try to hook ourselves here */
2343 offset += encrypted_block_length;
2344 } CATCH(BoundsError) {
2346 } CATCH(ReportedBoundsError) {
2347 show_reported_bounds_error(tvb, pinfo, tree);
2354 wrap_dissect_ntlmssp_payload_only(tvbuff_t *tvb,tvbuff_t *auth_tvb _U_,
2355 int offset, packet_info *pinfo,dcerpc_auth_info *auth_info _U_)
2359 data_tvb = tvb_new_subset(
2360 tvb, offset, tvb_length_remaining(tvb, offset),
2361 tvb_length_remaining(tvb, offset));
2362 dissect_ntlmssp_payload_only(data_tvb, pinfo, NULL);
2363 return pinfo->gssapi_decrypted_tvb;
2367 dissect_ntlmssp_encrypted_payload(tvbuff_t *data_tvb,
2368 tvbuff_t *auth_tvb _U_,
2371 dcerpc_auth_info *auth_info _U_)
2373 / * gssapi_decrypted_tvb=NULL * /
2374 tvbuff_t *decr_tvb; / * Used to display decrypted buffer * /
2376 conversation_t *conversation;
2377 guint32 encrypted_block_length;
2378 rc4_state_struct *rc4_state;
2379 rc4_state_struct *rc4_state_peer;
2380 ntlmssp_info *conv_ntlmssp_info = NULL;
2381 ntlmssp_packet_info *packet_ntlmssp_info = NULL;
2382 encrypted_block_length = tvb_length_remaining (data_tvb, offset);
2384 fprintf(stderr,"Called dissect_ntlmssp_encrypted_payload\n");
2385 / * Check to see if we already have state for this packet * /
2386 packet_ntlmssp_info = p_get_proto_data(pinfo->fd, proto_ntlmssp);
2387 if (packet_ntlmssp_info == NULL) {
2388 / * We don't have any packet state, so create one * /
2389 packet_ntlmssp_info = se_alloc0(sizeof(ntlmssp_packet_info));
2390 p_add_proto_data(pinfo->fd, proto_ntlmssp, packet_ntlmssp_info);
2393 if (!packet_ntlmssp_info->payload_decrypted) {
2394 / * Pull the challenge info from the conversation * /
2395 conversation = find_conversation(pinfo->fd->num, &pinfo->src, &pinfo->dst,
2396 pinfo->ptype, pinfo->srcport,
2397 pinfo->destport, 0);
2398 if (conversation == NULL) {
2399 / * There is no conversation, thus no encryption state * /
2403 conv_ntlmssp_info = conversation_get_proto_data(conversation,
2405 if (conv_ntlmssp_info == NULL) {
2406 / * There is no NTLMSSP state tied to the conversation * /
2409 / * Get the pair of RC4 state structures. One is used for to decrypt the
2410 payload. The other is used to re-encrypt the payload to represent
2412 if (conv_ntlmssp_info->server_dest_port == pinfo->destport) {
2413 rc4_state = get_encrypted_state(pinfo, 1);
2414 rc4_state_peer = get_encrypted_state(pinfo, 0);
2416 rc4_state = get_encrypted_state(pinfo, 0);
2417 rc4_state_peer = get_encrypted_state(pinfo, 1);
2420 if (rc4_state == NULL || rc4_state_peer == NULL) {
2421 / * There is no encryption state, so we cannot decrypt * /
2425 / * Store the decrypted contents in the packet state struct
2426 (of course at this point, they aren't decrypted yet) * /
2427 packet_ntlmssp_info->decrypted_payload = tvb_memdup(data_tvb, offset,
2428 encrypted_block_length);
2429 decrypted_payloads = g_slist_prepend(decrypted_payloads,
2430 packet_ntlmssp_info->decrypted_payload);
2432 / * Do the decryption of the payload * /
2433 crypt_rc4(rc4_state, packet_ntlmssp_info->decrypted_payload,
2434 encrypted_block_length);
2436 / * We setup a temporary buffer so we can re-encrypt the payload after
2437 decryption. This is to update the opposite peer's RC4 state * /
2438 peer_block = ep_memdup(packet_ntlmssp_info->decrypted_payload, encrypted_block_length);
2439 crypt_rc4(rc4_state_peer, peer_block, encrypted_block_length);
2441 packet_ntlmssp_info->payload_decrypted = TRUE;
2444 / * Show the decrypted buffer in a new window * /
2445 decr_tvb = tvb_new_child_real_data(data_tvb, packet_ntlmssp_info->decrypted_payload,
2446 encrypted_block_length,
2447 encrypted_block_length);
2449 offset += encrypted_block_length;
2455 free_payload(gpointer decrypted_payload, gpointer user_data _U_)
2457 g_free(decrypted_payload);
2460 guint g_header_hash(gconstpointer pointer) {
2461 guint32 crc = ~crc32c_calculate(pointer,NTLMSSP_KEY_LEN,CRC32C_PRELOAD);
2462 /* Mat TBD fprintf(stderr,"Val: %u\n",crc);*/
2466 gboolean g_header_equal(gconstpointer pointer1, gconstpointer pointer2) {
2467 if(!memcmp(pointer1,pointer2,16)) {
2476 ntlmssp_init_protocol(void)
2479 * Free the decrypted payloads, and then free the list of decrypted
2482 if (decrypted_payloads != NULL) {
2483 g_slist_foreach(decrypted_payloads, free_payload, NULL);
2484 g_slist_free(decrypted_payloads);
2485 decrypted_payloads = NULL;
2488 if(hash_packet == NULL) {
2489 hash_packet = g_hash_table_new(g_header_hash,g_header_equal);
2497 proto_register_ntlmssp(void)
2500 static hf_register_info hf[] = {
2502 { "NTLMSSP identifier", "ntlmssp.identifier", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2503 { &hf_ntlmssp_message_type,
2504 { "NTLM Message Type", "ntlmssp.messagetype", FT_UINT32, BASE_HEX, VALS(ntlmssp_message_types), 0x0, NULL, HFILL }},
2505 { &hf_ntlmssp_negotiate_flags,
2506 { "Flags", "ntlmssp.negotiateflags", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2507 { &hf_ntlmssp_negotiate_flags_01,
2508 { "Negotiate UNICODE", "ntlmssp.negotiateunicode", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_UNICODE, NULL, HFILL }},
2509 { &hf_ntlmssp_negotiate_flags_02,
2510 { "Negotiate OEM", "ntlmssp.negotiateoem", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_OEM, NULL, HFILL }},
2511 { &hf_ntlmssp_negotiate_flags_04,
2512 { "Request Target", "ntlmssp.requesttarget", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_REQUEST_TARGET, NULL, HFILL }},
2513 { &hf_ntlmssp_negotiate_flags_08,
2514 { "Request 0x00000008", "ntlmssp.negotiate00000008", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00000008, NULL, HFILL }},
2515 { &hf_ntlmssp_negotiate_flags_10,
2516 { "Negotiate Sign", "ntlmssp.negotiatesign", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_SIGN, NULL, HFILL }},
2517 { &hf_ntlmssp_negotiate_flags_20,
2518 { "Negotiate Seal", "ntlmssp.negotiateseal", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_SEAL, NULL, HFILL }},
2519 { &hf_ntlmssp_negotiate_flags_40,
2520 { "Negotiate Datagram", "ntlmssp.negotiatedatagram", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_DATAGRAM, NULL, HFILL }},
2521 { &hf_ntlmssp_negotiate_flags_80,
2522 { "Negotiate Lan Manager Key", "ntlmssp.negotiatelmkey", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_LM_KEY, NULL, HFILL }},
2523 { &hf_ntlmssp_negotiate_flags_100,
2524 { "Negotiate 0x00000100", "ntlmssp.negotiate00000100", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00000100, NULL, HFILL }},
2525 { &hf_ntlmssp_negotiate_flags_200,
2526 { "Negotiate NTLM key", "ntlmssp.negotiatentlm", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_NTLM, NULL, HFILL }},
2527 { &hf_ntlmssp_negotiate_flags_400,
2528 { "Negotiate NT Only", "ntlmssp.negotiatentonly", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_NT_ONLY, NULL, HFILL }},
2529 { &hf_ntlmssp_negotiate_flags_800,
2530 { "Negotiate 0x00000800", "ntlmssp.negotiate00000800", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00000800, NULL, HFILL }},
2531 { &hf_ntlmssp_negotiate_flags_1000,
2532 { "Negotiate OEM Domain Supplied", "ntlmssp.negotiateoemdomainsupplied", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED, NULL, HFILL }},
2533 { &hf_ntlmssp_negotiate_flags_2000,
2534 { "Negotiate OEM Workstation Supplied", "ntlmssp.negotiateoemworkstationsupplied", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED, NULL, HFILL }},
2535 { &hf_ntlmssp_negotiate_flags_4000,
2536 { "Negotiate 0x00004000", "ntlmssp.negotiate00004000", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00004000, NULL, HFILL }},
2537 { &hf_ntlmssp_negotiate_flags_8000,
2538 { "Negotiate Always Sign", "ntlmssp.negotiatealwayssign", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_ALWAYS_SIGN, NULL, HFILL }},
2539 { &hf_ntlmssp_negotiate_flags_10000,
2540 { "Target Type Domain", "ntlmssp.targettypedomain", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_TARGET_TYPE_DOMAIN, NULL, HFILL }},
2541 { &hf_ntlmssp_negotiate_flags_20000,
2542 { "Target Type Server", "ntlmssp.targettypeserver", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_TARGET_TYPE_SERVER, NULL, HFILL }},
2543 { &hf_ntlmssp_negotiate_flags_40000,
2544 { "Target Type Share", "ntlmssp.targettypeshare", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_TARGET_TYPE_SHARE, NULL, HFILL }},
2545 { &hf_ntlmssp_negotiate_flags_80000,
2546 { "Negotiate Extended Security", "ntlmssp.negotiatentlm2", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_EXTENDED_SECURITY, NULL, HFILL }},
2547 { &hf_ntlmssp_negotiate_flags_100000,
2548 { "Negotiate Identify", "ntlmssp.negotiateidentify", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_IDENTIFY, NULL, HFILL }},
2549 { &hf_ntlmssp_negotiate_flags_200000,
2550 { "Negotiate 0x00200000", "ntlmssp.negotiatent00200000", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00200000, NULL, HFILL }},
2551 { &hf_ntlmssp_negotiate_flags_400000,
2552 { "Request Non-NT Session", "ntlmssp.requestnonntsession", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_REQUEST_NON_NT_SESSION, NULL, HFILL }},
2553 { &hf_ntlmssp_negotiate_flags_800000,
2554 { "Negotiate Target Info", "ntlmssp.negotiatetargetinfo", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_TARGET_INFO, NULL, HFILL }},
2555 { &hf_ntlmssp_negotiate_flags_1000000,
2556 { "Negotiate 0x01000000", "ntlmssp.negotiatent01000000", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_01000000, NULL, HFILL }},
2557 { &hf_ntlmssp_negotiate_flags_2000000,
2558 { "Negotiate Version", "ntlmssp.negotiateversion", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_VERSION, NULL, HFILL }},
2559 { &hf_ntlmssp_negotiate_flags_4000000,
2560 { "Negotiate 0x04000000", "ntlmssp.negotiatent04000000", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_04000000, NULL, HFILL }},
2561 { &hf_ntlmssp_negotiate_flags_8000000,
2562 { "Negotiate 0x08000000", "ntlmssp.negotiatent08000000", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_08000000, NULL, HFILL }},
2563 { &hf_ntlmssp_negotiate_flags_10000000,
2564 { "Negotiate 0x10000000", "ntlmssp.negotiatent10000000", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_10000000, NULL, HFILL }},
2565 { &hf_ntlmssp_negotiate_flags_20000000,
2566 { "Negotiate 128", "ntlmssp.negotiate128", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_128, "128-bit encryption is supported", HFILL }},
2567 { &hf_ntlmssp_negotiate_flags_40000000,
2568 { "Negotiate Key Exchange", "ntlmssp.negotiatekeyexch", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_KEY_EXCH, NULL, HFILL }},
2569 { &hf_ntlmssp_negotiate_flags_80000000,
2570 { "Negotiate 56", "ntlmssp.negotiate56", FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_56, "56-bit encryption is supported", HFILL }},
2571 { &hf_ntlmssp_negotiate_workstation_strlen,
2572 { "Calling workstation name length", "ntlmssp.negotiate.callingworkstation.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2573 { &hf_ntlmssp_negotiate_workstation_maxlen,
2574 { "Calling workstation name max length", "ntlmssp.negotiate.callingworkstation.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2575 { &hf_ntlmssp_negotiate_workstation_buffer,
2576 { "Calling workstation name buffer", "ntlmssp.negotiate.callingworkstation.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2577 { &hf_ntlmssp_negotiate_workstation,
2578 { "Calling workstation name", "ntlmssp.negotiate.callingworkstation", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2579 { &hf_ntlmssp_negotiate_domain_strlen,
2580 { "Calling workstation domain length", "ntlmssp.negotiate.domain.strlen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2581 { &hf_ntlmssp_negotiate_domain_maxlen,
2582 { "Calling workstation domain max length", "ntlmssp.negotiate.domain.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2583 { &hf_ntlmssp_negotiate_domain_buffer,
2584 { "Calling workstation domain buffer", "ntlmssp.negotiate.domain.buffer", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2585 { &hf_ntlmssp_negotiate_domain,
2586 { "Calling workstation domain", "ntlmssp.negotiate.domain", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2587 { &hf_ntlmssp_ntlm_client_challenge,
2588 { "NTLM Client Challenge", "ntlmssp.ntlmclientchallenge", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2589 { &hf_ntlmssp_ntlm_server_challenge,
2590 { "NTLM Server Challenge", "ntlmssp.ntlmserverchallenge", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2591 { &hf_ntlmssp_reserved,
2592 { "Reserved", "ntlmssp.reserved", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2593 { &hf_ntlmssp_challenge_domain,
2594 { "Domain", "ntlmssp.challenge.domain", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2595 { &hf_ntlmssp_auth_domain,
2596 { "Domain name", "ntlmssp.auth.domain", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2597 { &hf_ntlmssp_auth_username,
2598 { "User name", "ntlmssp.auth.username", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2599 { &hf_ntlmssp_auth_hostname,
2600 { "Host name", "ntlmssp.auth.hostname", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2601 { &hf_ntlmssp_auth_lmresponse,
2602 { "Lan Manager Response", "ntlmssp.auth.lmresponse", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2603 { &hf_ntlmssp_auth_ntresponse,
2604 { "NTLM Response", "ntlmssp.auth.ntresponse", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2605 { &hf_ntlmssp_auth_sesskey,
2606 { "Session Key", "ntlmssp.auth.sesskey", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2607 { &hf_ntlmssp_string_len,
2608 { "Length", "ntlmssp.string.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2609 { &hf_ntlmssp_string_maxlen,
2610 { "Maxlen", "ntlmssp.string.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2611 { &hf_ntlmssp_string_offset,
2612 { "Offset", "ntlmssp.string.offset", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2613 { &hf_ntlmssp_blob_len,
2614 { "Length", "ntlmssp.blob.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2615 { &hf_ntlmssp_blob_maxlen,
2616 { "Maxlen", "ntlmssp.blob.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2617 { &hf_ntlmssp_blob_offset,
2618 { "Offset", "ntlmssp.blob.offset", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2619 { &hf_ntlmssp_address_list,
2620 { "Address List", "ntlmssp.challenge.addresslist", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
2621 { &hf_ntlmssp_address_list_len,
2622 { "Length", "ntlmssp.challenge.addresslist.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2623 { &hf_ntlmssp_address_list_maxlen,
2624 { "Maxlen", "ntlmssp.challenge.addresslist.maxlen", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2625 { &hf_ntlmssp_address_list_offset,
2626 { "Offset", "ntlmssp.challenge.addresslist.offset", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2627 { &hf_ntlmssp_address_list_item_type,
2628 { "Target item type", "ntlmssp.targetitemtype", FT_UINT16, BASE_HEX, VALS(ntlm_name_types), 0x0, NULL, HFILL }},
2629 { &hf_ntlmssp_address_list_item_len,
2630 { "Target item Length", "ntlmssp.challenge.addresslist.item.length", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
2631 { &hf_ntlmssp_address_list_item_content,
2632 { "Target item Content", "ntlmssp.challenge.addresslist.item.content", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}},
2633 { &hf_ntlmssp_address_list_server_nb,
2634 { "Server NetBIOS Name", "ntlmssp.challenge.addresslist.servernb", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2635 { &hf_ntlmssp_address_list_domain_nb,
2636 { "Domain NetBIOS Name", "ntlmssp.challenge.addresslist.domainnb", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2637 { &hf_ntlmssp_address_list_server_dns,
2638 { "Server DNS Name", "ntlmssp.challenge.addresslist.serverdns", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2639 { &hf_ntlmssp_address_list_domain_dns,
2640 { "Domain DNS Name", "ntlmssp.challenge.addresslist.domaindns", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2641 { &hf_ntlmssp_address_list_forest_dns,
2642 { "Forest DNS Name", "ntlmssp.challenge.addresslist.forestdns", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2643 { &hf_ntlmssp_address_list_terminator,
2644 { "List Terminator", "ntlmssp.challenge.addresslist.terminator", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2646 { "NTLMSSP Verifier", "ntlmssp.verf", FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2647 { &hf_ntlmssp_verf_vers,
2648 { "Version Number", "ntlmssp.verf.vers", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2649 { &hf_ntlmssp_verf_body,
2650 { "Verifier Body", "ntlmssp.verf.body", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2651 { &hf_ntlmssp_decrypted_payload,
2652 { "NTLM Decrypted Payload", "ntlmssp.decrypted_payload", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2653 { &hf_ntlmssp_verf_randompad,
2654 { "Random Pad", "ntlmssp.verf.randompad", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2655 { &hf_ntlmssp_verf_crc32,
2656 { "Verifier CRC32", "ntlmssp.verf.crc32", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2657 { &hf_ntlmssp_verf_hmacmd5,
2658 { "HMAC MD5", "ntlmssp.verf.hmacmd5", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2659 { &hf_ntlmssp_verf_sequence,
2660 { "Sequence", "ntlmssp.verf.sequence", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2661 { &hf_ntlmssp_ntlmv2_response,
2662 { "NTLMv2 Response", "ntlmssp.ntlmv2response", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2663 { &hf_ntlmssp_ntlmv2_response_hmac,
2664 { "HMAC", "ntlmssp.ntlmv2response.hmac", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2665 { &hf_ntlmssp_ntlmv2_response_header,
2666 { "Header", "ntlmssp.ntlmv2response.header", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2667 { &hf_ntlmssp_ntlmv2_response_reserved,
2668 { "Reserved", "ntlmssp.ntlmv2response.reserved", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2669 { &hf_ntlmssp_ntlmv2_response_time,
2670 { "Time", "ntlmssp.ntlmv2response.time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0, NULL, HFILL }},
2671 { &hf_ntlmssp_ntlmv2_response_chal,
2672 { "Client challenge", "ntlmssp.ntlmv2response.chal", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2673 { &hf_ntlmssp_ntlmv2_response_unknown,
2674 { "Unknown", "ntlmssp.ntlmv2response.unknown", FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
2675 { &hf_ntlmssp_ntlmv2_response_name,
2676 { "Attribute", "ntlmssp.ntlmv2response.name", FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2677 { &hf_ntlmssp_ntlmv2_response_name_type,
2678 { "Attribute type", "ntlmssp.ntlmv2response.name.type", FT_UINT32, BASE_DEC, VALS(ntlm_name_types), 0x0, NULL, HFILL }},
2679 { &hf_ntlmssp_ntlmv2_response_name_len,
2680 { "Value len", "ntlmssp.ntlmv2response.name.len", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
2681 { &hf_ntlmssp_ntlmv2_response_restriction,
2682 { "Encoding restrictions", "ntlmssp.ntlmv2response.name.restrictions", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
2683 { &hf_ntlmssp_ntlmv2_response_client_time,
2684 { "Client Time", "ntlmssp.ntlmv2response.client_time", FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0, NULL, HFILL }}
2688 static gint *ett[] = {
2690 &ett_ntlmssp_negotiate_flags,
2691 &ett_ntlmssp_string,
2693 &ett_ntlmssp_address_list,
2694 &ett_ntlmssp_address_list_item,
2695 &ett_ntlmssp_ntlmv2_response,
2696 &ett_ntlmssp_ntlmv2_response_name
2698 module_t *ntlmssp_module;
2700 proto_ntlmssp = proto_register_protocol (
2701 "NTLM Secure Service Provider", /* name */
2702 "NTLMSSP", /* short name */
2703 "ntlmssp" /* abbrev */
2705 proto_register_field_array (proto_ntlmssp, hf, array_length (hf));
2706 proto_register_subtree_array (ett, array_length (ett));
2707 register_init_routine(&ntlmssp_init_protocol);
2709 ntlmssp_module = prefs_register_protocol(proto_ntlmssp, NULL);
2711 prefs_register_string_preference(ntlmssp_module, "nt_password",
2713 "NT Password (used to decrypt payloads)",
2716 register_dissector("ntlmssp", dissect_ntlmssp, proto_ntlmssp);
2717 new_register_dissector("ntlmssp_payload", dissect_ntlmssp_payload, proto_ntlmssp);
2718 new_register_dissector("ntlmssp_data_only", dissect_ntlmssp_payload_only, proto_ntlmssp);
2719 new_register_dissector("ntlmssp_verf", dissect_ntlmssp_verf, proto_ntlmssp);
2722 static int wrap_dissect_ntlmssp(tvbuff_t *tvb, int offset, packet_info *pinfo,
2723 proto_tree *tree, guint8 *drep _U_)
2727 auth_tvb = tvb_new_subset(
2728 tvb, offset, tvb_length_remaining(tvb, offset),
2729 tvb_length_remaining(tvb, offset));
2731 dissect_ntlmssp(auth_tvb, pinfo, tree);
2733 return tvb_length_remaining(tvb, offset);
2736 static int wrap_dissect_ntlmssp_verf(tvbuff_t *tvb, int offset, packet_info *pinfo,
2737 proto_tree *tree, guint8 *drep _U_)
2741 auth_tvb = tvb_new_subset(
2742 tvb, offset, tvb_length_remaining(tvb, offset),
2743 tvb_length_remaining(tvb, offset));
2744 return dissect_ntlmssp_verf(auth_tvb, pinfo, tree);
2747 static dcerpc_auth_subdissector_fns ntlmssp_sign_fns = {
2748 wrap_dissect_ntlmssp, /* Bind */
2749 wrap_dissect_ntlmssp, /* Bind ACK */
2750 wrap_dissect_ntlmssp, /* AUTH3 */
2751 wrap_dissect_ntlmssp_verf, /* Request verifier */
2752 wrap_dissect_ntlmssp_verf, /* Response verifier */
2753 NULL, /* Request data */
2754 NULL /* Response data */
2757 static dcerpc_auth_subdissector_fns ntlmssp_seal_fns = {
2758 wrap_dissect_ntlmssp, /* Bind */
2759 wrap_dissect_ntlmssp, /* Bind ACK */
2760 wrap_dissect_ntlmssp, /* AUTH3 */
2761 wrap_dissect_ntlmssp_verf, /* Request verifier */
2762 wrap_dissect_ntlmssp_verf, /* Response verifier */
2763 wrap_dissect_ntlmssp_payload_only, /* Request data */
2764 wrap_dissect_ntlmssp_payload_only /* Response data */
2768 proto_reg_handoff_ntlmssp(void)
2770 dissector_handle_t ntlmssp_handle, ntlmssp_wrap_handle;
2772 /* Register protocol with the GSS-API module */
2774 ntlmssp_handle = find_dissector("ntlmssp");
2775 ntlmssp_wrap_handle = find_dissector("ntlmssp_verf");
2776 gssapi_init_oid("1.3.6.1.4.1.311.2.2.10", proto_ntlmssp, ett_ntlmssp,
2777 ntlmssp_handle, ntlmssp_wrap_handle,
2778 "NTLMSSP - Microsoft NTLM Security Support Provider");
2780 /* Register authenticated pipe dissector */
2783 * XXX - the verifiers here seem to have a version of 1 and a body of all
2786 * XXX - DCE_C_AUTHN_LEVEL_CONNECT is, according to the DCE RPC 1.1
2787 * spec, upgraded to DCE_C_AUTHN_LEVEL_PKT. Should we register
2788 * any other levels here?
2790 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_CONNECT,
2791 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
2794 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT,
2795 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
2798 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY,
2799 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
2802 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY,
2803 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP,
2805 ntlmssp_tap = register_tap("ntlmssp");
2809 * Editor modelines - http://www.wireshark.org/tools/modelines.html
2814 * indent-tabs-mode: nil
2817 * vi: set shiftwidth=2 tabstop=8 expandtab
2818 * :indentSize=2:tabSize=8:noTabs=true: