2 * Add-on for better NTLM v1/v2 handling
3 * Copyright 2009, 2012 Matthieu Patou <mat@matws.net>
4 * Routines for NTLM Secure Service Provider
5 * Devin Heitmueller <dheitmueller@netilla.com>
6 * Copyright 2003, Tim Potter <tpot@samba.org>
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1998 Gerald Combs
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version 2
17 * of the License, or (at your option) any later version.
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
28 /* Just set me to activate debug #define DEBUG_NTLMSSP */
38 #include <wsutil/rc4.h>
39 #include <wsutil/md4.h>
40 #include <wsutil/md5.h>
41 #include <wsutil/des.h>
42 #include <wsutil/crc32.h>
44 #include <epan/packet.h>
45 #include <epan/exceptions.h>
46 #include <epan/asn1.h>
47 #include <epan/prefs.h>
48 #include <epan/wmem/wmem.h>
50 #include <epan/expert.h>
51 #include <epan/show_exception.h>
53 #include "packet-windows-common.h"
54 #include "packet-smb-common.h"
55 #include "packet-kerberos.h"
56 #include "packet-dcerpc.h"
57 #include "packet-gssapi.h"
59 #include "packet-ntlmssp.h"
61 static int ntlmssp_tap
= -1;
63 #define CLIENT_SIGN_TEXT "session key to client-to-server signing key magic constant"
64 #define CLIENT_SEAL_TEXT "session key to client-to-server sealing key magic constant"
65 #define SERVER_SIGN_TEXT "session key to server-to-client signing key magic constant"
66 #define SERVER_SEAL_TEXT "session key to server-to-client sealing key magic constant"
68 static const value_string ntlmssp_message_types
[] = {
69 { NTLMSSP_NEGOTIATE
, "NTLMSSP_NEGOTIATE" },
70 { NTLMSSP_CHALLENGE
, "NTLMSSP_CHALLENGE" },
71 { NTLMSSP_AUTH
, "NTLMSSP_AUTH" },
72 { NTLMSSP_UNKNOWN
, "NTLMSSP_UNKNOWN" },
76 typedef struct _md4_pass
{
77 guint8 md4
[NTLMSSP_KEY_LEN
];
80 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";
81 static GHashTable
* hash_packet
= NULL
;
84 * NTLMSSP negotiation flags
89 * http://davenport.sourceforge.net/ntlm.html
91 * although that document says that:
93 * 0x00010000 is "Target Type Domain";
94 * 0x00020000 is "Target Type Server"
95 * 0x00040000 is "Target Type Share";
97 * and that 0x00100000, 0x00200000, and 0x00400000 are
98 * "Request Init Response", "Request Accept Response", and
99 * "Request Non-NT Session Key", rather than those values shifted
100 * right one having those interpretations.
102 * UPDATE: Further information obtained from [MS-NLMP] 2.2.2.5:
103 * NT LAN Manager (NTLM) Authentication Protocol Specification
104 * http://msdn2.microsoft.com/en-us/library/cc236621.aspx
107 #define NTLMSSP_NEGOTIATE_UNICODE 0x00000001
108 #define NTLMSSP_NEGOTIATE_OEM 0x00000002
109 #define NTLMSSP_REQUEST_TARGET 0x00000004
110 #define NTLMSSP_NEGOTIATE_00000008 0x00000008
111 #define NTLMSSP_NEGOTIATE_SIGN 0x00000010
112 #define NTLMSSP_NEGOTIATE_SEAL 0x00000020
113 #define NTLMSSP_NEGOTIATE_DATAGRAM 0x00000040
114 #define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080
115 #define NTLMSSP_NEGOTIATE_00000100 0x00000100
116 #define NTLMSSP_NEGOTIATE_NTLM 0x00000200
117 #define NTLMSSP_NEGOTIATE_NT_ONLY 0x00000400
118 #define NTLMSSP_NEGOTIATE_ANONYMOUS 0x00000800
119 #define NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED 0x00001000
120 #define NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED 0x00002000
121 #define NTLMSSP_NEGOTIATE_00004000 0x00004000
122 #define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000
123 #define NTLMSSP_TARGET_TYPE_DOMAIN 0x00010000
124 #define NTLMSSP_TARGET_TYPE_SERVER 0x00020000
125 #define NTLMSSP_TARGET_TYPE_SHARE 0x00040000
126 #define NTLMSSP_NEGOTIATE_EXTENDED_SECURITY 0x00080000
127 #define NTLMSSP_NEGOTIATE_IDENTIFY 0x00100000
128 #define NTLMSSP_NEGOTIATE_00200000 0x00200000
129 #define NTLMSSP_REQUEST_NON_NT_SESSION 0x00400000
130 #define NTLMSSP_NEGOTIATE_TARGET_INFO 0x00800000
131 #define NTLMSSP_NEGOTIATE_01000000 0x01000000
132 #define NTLMSSP_NEGOTIATE_VERSION 0x02000000
133 #define NTLMSSP_NEGOTIATE_04000000 0x04000000
134 #define NTLMSSP_NEGOTIATE_08000000 0x08000000
135 #define NTLMSSP_NEGOTIATE_10000000 0x10000000
136 #define NTLMSSP_NEGOTIATE_128 0x20000000
137 #define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000
138 #define NTLMSSP_NEGOTIATE_56 0x80000000
140 static int proto_ntlmssp
= -1;
141 static int hf_ntlmssp_auth
= -1;
142 static int hf_ntlmssp_message_type
= -1;
143 static int hf_ntlmssp_negotiate_flags
= -1;
144 static int hf_ntlmssp_negotiate_flags_01
= -1;
145 static int hf_ntlmssp_negotiate_flags_02
= -1;
146 static int hf_ntlmssp_negotiate_flags_04
= -1;
147 static int hf_ntlmssp_negotiate_flags_08
= -1;
148 static int hf_ntlmssp_negotiate_flags_10
= -1;
149 static int hf_ntlmssp_negotiate_flags_20
= -1;
150 static int hf_ntlmssp_negotiate_flags_40
= -1;
151 static int hf_ntlmssp_negotiate_flags_80
= -1;
152 static int hf_ntlmssp_negotiate_flags_100
= -1;
153 static int hf_ntlmssp_negotiate_flags_200
= -1;
154 static int hf_ntlmssp_negotiate_flags_400
= -1;
155 static int hf_ntlmssp_negotiate_flags_800
= -1;
156 static int hf_ntlmssp_negotiate_flags_1000
= -1;
157 static int hf_ntlmssp_negotiate_flags_2000
= -1;
158 static int hf_ntlmssp_negotiate_flags_4000
= -1;
159 static int hf_ntlmssp_negotiate_flags_8000
= -1;
160 static int hf_ntlmssp_negotiate_flags_10000
= -1;
161 static int hf_ntlmssp_negotiate_flags_20000
= -1;
162 static int hf_ntlmssp_negotiate_flags_40000
= -1;
163 static int hf_ntlmssp_negotiate_flags_80000
= -1;
164 static int hf_ntlmssp_negotiate_flags_100000
= -1;
165 static int hf_ntlmssp_negotiate_flags_200000
= -1;
166 static int hf_ntlmssp_negotiate_flags_400000
= -1;
167 static int hf_ntlmssp_negotiate_flags_800000
= -1;
168 static int hf_ntlmssp_negotiate_flags_1000000
= -1;
169 static int hf_ntlmssp_negotiate_flags_2000000
= -1;
170 static int hf_ntlmssp_negotiate_flags_4000000
= -1;
171 static int hf_ntlmssp_negotiate_flags_8000000
= -1;
172 static int hf_ntlmssp_negotiate_flags_10000000
= -1;
173 static int hf_ntlmssp_negotiate_flags_20000000
= -1;
174 static int hf_ntlmssp_negotiate_flags_40000000
= -1;
175 static int hf_ntlmssp_negotiate_flags_80000000
= -1;
176 /* static int hf_ntlmssp_negotiate_workstation_strlen = -1; */
177 /* static int hf_ntlmssp_negotiate_workstation_maxlen = -1; */
178 /* static int hf_ntlmssp_negotiate_workstation_buffer = -1; */
179 static int hf_ntlmssp_negotiate_workstation
= -1;
180 /* static int hf_ntlmssp_negotiate_domain_strlen = -1; */
181 /* static int hf_ntlmssp_negotiate_domain_maxlen = -1; */
182 /* static int hf_ntlmssp_negotiate_domain_buffer = -1; */
183 static int hf_ntlmssp_negotiate_domain
= -1;
184 static int hf_ntlmssp_ntlm_server_challenge
= -1;
185 static int hf_ntlmssp_ntlm_client_challenge
= -1;
186 static int hf_ntlmssp_reserved
= -1;
187 static int hf_ntlmssp_challenge_target_name
= -1;
188 static int hf_ntlmssp_auth_username
= -1;
189 static int hf_ntlmssp_auth_domain
= -1;
190 static int hf_ntlmssp_auth_hostname
= -1;
191 static int hf_ntlmssp_auth_lmresponse
= -1;
192 static int hf_ntlmssp_auth_ntresponse
= -1;
193 static int hf_ntlmssp_auth_sesskey
= -1;
194 static int hf_ntlmssp_string_len
= -1;
195 static int hf_ntlmssp_string_maxlen
= -1;
196 static int hf_ntlmssp_string_offset
= -1;
197 static int hf_ntlmssp_blob_len
= -1;
198 static int hf_ntlmssp_blob_maxlen
= -1;
199 static int hf_ntlmssp_blob_offset
= -1;
200 static int hf_ntlmssp_version
= -1;
201 static int hf_ntlmssp_version_major
= -1;
202 static int hf_ntlmssp_version_minor
= -1;
203 static int hf_ntlmssp_version_build_number
= -1;
204 static int hf_ntlmssp_version_ntlm_current_revision
= -1;
206 static int hf_ntlmssp_challenge_target_info
= -1;
207 static int hf_ntlmssp_challenge_target_info_len
= -1;
208 static int hf_ntlmssp_challenge_target_info_maxlen
= -1;
209 static int hf_ntlmssp_challenge_target_info_offset
= -1;
211 static int hf_ntlmssp_challenge_target_info_item_type
= -1;
212 static int hf_ntlmssp_challenge_target_info_item_len
= -1;
214 static int hf_ntlmssp_challenge_target_info_end
= -1;
215 static int hf_ntlmssp_challenge_target_info_nb_computer_name
= -1;
216 static int hf_ntlmssp_challenge_target_info_nb_domain_name
= -1;
217 static int hf_ntlmssp_challenge_target_info_dns_computer_name
= -1;
218 static int hf_ntlmssp_challenge_target_info_dns_domain_name
= -1;
219 static int hf_ntlmssp_challenge_target_info_dns_tree_name
= -1;
220 static int hf_ntlmssp_challenge_target_info_flags
= -1;
221 static int hf_ntlmssp_challenge_target_info_timestamp
= -1;
222 static int hf_ntlmssp_challenge_target_info_restrictions
= -1;
223 static int hf_ntlmssp_challenge_target_info_target_name
=-1;
224 static int hf_ntlmssp_challenge_target_info_channel_bindings
=-1;
226 static int hf_ntlmssp_ntlmv2_response_item_type
= -1;
227 static int hf_ntlmssp_ntlmv2_response_item_len
= -1;
229 static int hf_ntlmssp_ntlmv2_response_end
= -1;
230 static int hf_ntlmssp_ntlmv2_response_nb_computer_name
= -1;
231 static int hf_ntlmssp_ntlmv2_response_nb_domain_name
= -1;
232 static int hf_ntlmssp_ntlmv2_response_dns_computer_name
= -1;
233 static int hf_ntlmssp_ntlmv2_response_dns_domain_name
= -1;
234 static int hf_ntlmssp_ntlmv2_response_dns_tree_name
= -1;
235 static int hf_ntlmssp_ntlmv2_response_flags
= -1;
236 static int hf_ntlmssp_ntlmv2_response_timestamp
= -1;
237 static int hf_ntlmssp_ntlmv2_response_restrictions
= -1;
238 static int hf_ntlmssp_ntlmv2_response_target_name
=-1;
239 static int hf_ntlmssp_ntlmv2_response_channel_bindings
=-1;
241 static int hf_ntlmssp_message_integrity_code
= -1;
242 static int hf_ntlmssp_verf
= -1;
243 static int hf_ntlmssp_verf_vers
= -1;
244 static int hf_ntlmssp_verf_body
= -1;
245 static int hf_ntlmssp_verf_randompad
= -1;
246 static int hf_ntlmssp_verf_hmacmd5
= -1;
247 static int hf_ntlmssp_verf_crc32
= -1;
248 static int hf_ntlmssp_verf_sequence
= -1;
249 /* static int hf_ntlmssp_decrypted_payload = -1; */
251 static int hf_ntlmssp_ntlmv2_response
= -1;
252 static int hf_ntlmssp_ntlmv2_response_ntproofstr
= -1;
253 static int hf_ntlmssp_ntlmv2_response_rversion
= -1;
254 static int hf_ntlmssp_ntlmv2_response_hirversion
= -1;
255 static int hf_ntlmssp_ntlmv2_response_z
= -1;
256 static int hf_ntlmssp_ntlmv2_response_pad
= -1;
257 static int hf_ntlmssp_ntlmv2_response_time
= -1;
258 static int hf_ntlmssp_ntlmv2_response_chal
= -1;
260 static gint ett_ntlmssp
= -1;
261 static gint ett_ntlmssp_negotiate_flags
= -1;
262 static gint ett_ntlmssp_string
= -1;
263 static gint ett_ntlmssp_blob
= -1;
264 static gint ett_ntlmssp_version
= -1;
265 static gint ett_ntlmssp_challenge_target_info
= -1;
266 static gint ett_ntlmssp_challenge_target_info_item
= -1;
267 static gint ett_ntlmssp_ntlmv2_response
= -1;
268 static gint ett_ntlmssp_ntlmv2_response_item
= -1;
270 static expert_field ei_ntlmssp_v2_key_too_long
= EI_INIT
;
271 static expert_field ei_ntlmssp_blob_len_too_long
= EI_INIT
;
272 static expert_field ei_ntlmssp_target_info_attr
= EI_INIT
;
274 /* Configuration variables */
275 const char *gbl_nt_password
= NULL
;
277 #define MAX_BLOB_SIZE 10240
278 typedef struct _ntlmssp_blob
{
283 #define NTLMSSP_CONV_INFO_KEY 0
284 /* Used in the conversation function */
285 typedef struct _ntlmssp_info
{
288 rc4_state_struct rc4_state_client
;
289 rc4_state_struct rc4_state_server
;
290 guint8 sign_key_client
[NTLMSSP_KEY_LEN
];
291 guint8 sign_key_server
[NTLMSSP_KEY_LEN
];
292 guint32 server_dest_port
;
293 unsigned char server_challenge
[8];
294 unsigned char client_challenge
[8];
295 int rc4_state_initialized
;
296 ntlmssp_blob ntlm_response
;
297 ntlmssp_blob lm_response
;
300 #define NTLMSSP_PACKET_INFO_KEY 1
301 /* If this struct exists in the payload_decrypt, then we have already
303 typedef struct _ntlmssp_packet_info
{
304 guint8
*decrypted_payload
;
306 guint8 verifier
[NTLMSSP_KEY_LEN
];
307 gboolean payload_decrypted
;
308 gboolean verifier_decrypted
;
309 } ntlmssp_packet_info
;
312 static void printnbyte(const guint8
* tab
, int nb
, const char* txt
, const char* txt2
)
315 fprintf(stderr
, "%s ", txt
);
318 fprintf(stderr
, "%02X ", *(tab
+i
));
320 fprintf(stderr
, "%s", txt2
);
323 static void printnchar(const guint8
* tab
, int nb
, char* txt
, char* txt2
)
326 fprintf(stderr
, "%s ", txt
);
329 fprintf(stderr
, "%c", *(tab
+i
));
331 fprintf(stderr
, "%s", txt2
);
335 static void printnbyte(const guint8
* tab _U_
, int nb _U_
, const char* txt _U_
, const char* txt2 _U_
)
341 * GSlist of decrypted payloads.
343 static GSList
*decrypted_payloads
;
347 LEBE_Convert(int value
)
351 a
= value
&0x000000FF;
352 b
= (value
&0x0000FF00) >> 8;
353 c
= (value
&0x00FF0000) >> 16;
354 d
= (value
&0xFF000000) >> 24;
355 return (a
<< 24) | (b
<< 16) | (c
<< 8) | d
;
360 Perform a DES encryption with a 16 bit key and 8bit data item.
361 It's in fact 3 susbsequent call to crypt_des_ecb with a 7 bit key.
362 Missing bits for the key are replaced by 0;
363 Returns output in response, which is expected to be 24 bytes.
366 crypt_des_ecb_long(guint8
*response
,
370 guint8 pw21
[21]; /* 21 bytes place for the needed key */
372 memset(pw21
, 0, sizeof(pw21
));
373 memcpy(pw21
, key
, 16);
375 memset(response
, 0, 24);
376 /* crypt_des_ecb(data, key)*/
377 crypt_des_ecb(response
, data
, pw21
, 1);
378 crypt_des_ecb(response
+ 8, data
, pw21
+ 7, 1);
379 crypt_des_ecb(response
+ 16, data
, pw21
+ 14, 1);
385 Generate a challenge response, given an eight byte challenge and
386 either the NT or the Lan Manager password hash (16 bytes).
387 Returns output in response, which is expected to be 24 bytes.
390 ntlmssp_generate_challenge_response(guint8
*response
,
391 const guint8
*passhash
,
392 const guint8
*challenge
)
394 guint8 pw21
[21]; /* Password hash padded to 21 bytes */
396 memset(pw21
, 0x0, sizeof(pw21
));
397 memcpy(pw21
, passhash
, 16);
399 memset(response
, 0, 24);
401 crypt_des_ecb(response
, challenge
, pw21
, 1);
402 crypt_des_ecb(response
+ 8, challenge
, pw21
+ 7, 1);
403 crypt_des_ecb(response
+ 16, challenge
, pw21
+ 14, 1);
409 /* Ultra simple ainsi to unicode converter, will only work for ascii password ...*/
411 str_to_unicode(const char *nt_password
, char *nt_password_unicode
)
416 password_len
= strlen(nt_password
);
417 if (nt_password_unicode
!= NULL
) {
418 for (i
=0; i
<(password_len
); i
++) {
419 nt_password_unicode
[i
*2]=nt_password
[i
];
420 nt_password_unicode
[i
*2+1]=0;
422 nt_password_unicode
[2*password_len
]='\0';
426 /* This function generate the Key Exchange Key
427 * Depending on the flags this key will either be used to crypt the exported session key
428 * or will be used directly as exported session key.
429 * Exported session key is the key that will be used for sealing and signing communication*/
432 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
)
434 guint8 basekey
[NTLMSSP_KEY_LEN
];
437 memset(keyexchangekey
, 0, NTLMSSP_KEY_LEN
);
438 memset(basekey
, 0, NTLMSSP_KEY_LEN
);
439 /* sessionbasekey is either derived from lm_password_hash or from nt_password_hash depending on the key type negotiated */
440 memcpy(basekey
, sessionbasekey
, 8);
441 memset(basekey
, 0xBD, 8);
442 if (flags
&NTLMSSP_NEGOTIATE_LM_KEY
) {
444 crypt_des_ecb(keyexchangekey
, lm_challenge_response
, basekey
, 1);
445 crypt_des_ecb(keyexchangekey
+8, lm_challenge_response
, basekey
+7, 1);
448 if (flags
&NTLMSSP_REQUEST_NON_NT_SESSION
) {
449 /*People from samba tends to use the same function in this case than in the previous one but with 0 data
450 * it's not clear that it produce the good result
451 * memcpy(keyexchangekey, lm_hash, 8);
452 * Let's trust samba implementation it mights seem weird but they are more often rights than the spec !
454 memset(zeros
, 0, 24);
455 crypt_des_ecb(keyexchangekey
, zeros
, basekey
, 3);
456 crypt_des_ecb(keyexchangekey
+8, zeros
, basekey
+7, 1);
459 /* it is stated page 65 of NTLM SSP spec that sessionbasekey should be encrypted with hmac_md5 using the concact of both challenge
460 * when it's NTLM v1 + extended security but it turns out to be wrong !
462 memcpy(keyexchangekey
, sessionbasekey
, NTLMSSP_KEY_LEN
);
467 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
469 get_md4pass_list(md4_pass
** p_pass_list
, const char* nt_password
)
474 unsigned char nt_password_hash
[NTLMSSP_KEY_LEN
];
475 char nt_password_unicode
[256];
483 read_keytab_file_from_preferences();
485 for (ek
=enc_key_list
; ek
; ek
=ek
->next
) {
486 if (ek
->keylength
== NTLMSSP_KEY_LEN
) {
490 memset(nt_password_unicode
, 0, sizeof(nt_password_unicode
));
491 memset(nt_password_hash
, 0, NTLMSSP_KEY_LEN
);
492 if ((nt_password
[0] != '\0') && (strlen(nt_password
) < 129)) {
495 password_len
= (int)strlen(nt_password
);
496 str_to_unicode(nt_password
, nt_password_unicode
);
497 crypt_md4(nt_password_hash
, nt_password_unicode
, password_len
*2);
500 /* Unable to calculate the session key without a password or if password is more than 128 char ......*/
504 *p_pass_list
= (md4_pass
*)wmem_alloc(wmem_packet_scope(), nb_pass
*sizeof(md4_pass
));
505 pass_list
= *p_pass_list
;
507 if (memcmp(nt_password_hash
, gbl_zeros
, NTLMSSP_KEY_LEN
) != 0) {
508 memcpy(pass_list
[i
].md4
, nt_password_hash
, NTLMSSP_KEY_LEN
);
511 for (ek
=enc_key_list
; ek
; ek
=ek
->next
) {
512 if (ek
->keylength
== NTLMSSP_KEY_LEN
) {
513 memcpy(pass_list
[i
].md4
, ek
->keyvalue
, NTLMSSP_KEY_LEN
);
521 /* Create an NTLMSSP version 2 key
524 create_ntlmssp_v2_key(const char *nt_password _U_
, const guint8
*serverchallenge
, const guint8
*clientchallenge
,
525 guint8
*sessionkey
, const guint8
*encryptedsessionkey
, int flags
,
526 const ntlmssp_blob
*ntlm_response
, const ntlmssp_blob
*lm_response _U_
, ntlmssp_header_t
*ntlmssph
)
528 char domain_name_unicode
[256];
529 char user_uppercase
[256];
531 /*guint8 md4[NTLMSSP_KEY_LEN];*/
532 unsigned char nt_password_hash
[NTLMSSP_KEY_LEN
];
533 unsigned char nt_proof
[NTLMSSP_KEY_LEN
];
534 unsigned char ntowf
[NTLMSSP_KEY_LEN
];
535 guint8 sessionbasekey
[NTLMSSP_KEY_LEN
];
536 guint8 keyexchangekey
[NTLMSSP_KEY_LEN
];
537 guint8 lm_challenge_response
[24];
540 rc4_state_struct rc4state
;
543 md4_pass
*pass_list
= NULL
;
545 gboolean found
= FALSE
;
547 /* We are going to try password encrypted in keytab as well, it's an idean of Stefan Metzmacher <metze@samba.org>
548 * The idea is to be able to test all the key of domain in once and to be able to decode the NTLM dialogs */
550 memset(sessionkey
, 0, NTLMSSP_KEY_LEN
);
551 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
552 nb_pass
= get_md4pass_list(&pass_list
, nt_password
);
555 memset(user_uppercase
, 0, 256);
556 user_len
= strlen(ntlmssph
->acct_name
);
557 if (user_len
< 129) {
559 str_to_unicode(ntlmssph
->acct_name
, buf
);
560 for (j
= 0; j
< (2*user_len
); j
++) {
561 if (buf
[j
] != '\0') {
562 user_uppercase
[j
] = toupper(buf
[j
]);
567 /* Unable to calculate the session not enought space in buffer, note this is unlikely to happen but ......*/
570 domain_len
= strlen(ntlmssph
->domain_name
);
571 if (domain_len
< 129) {
572 str_to_unicode(ntlmssph
->domain_name
, domain_name_unicode
);
575 /* Unable to calculate the session not enought space in buffer, note this is unlikely to happen but ......*/
578 while (i
< nb_pass
) {
580 fprintf(stderr
, "Turn %d, ", i
);
582 memcpy(nt_password_hash
, pass_list
[i
].md4
, NTLMSSP_KEY_LEN
);
583 printnbyte(nt_password_hash
, NTLMSSP_KEY_LEN
, "Current NT password hash: ", "\n");
585 /* ntowf computation */
587 memcpy(buf
, user_uppercase
, user_len
*2);
588 memcpy(buf
+user_len
*2, domain_name_unicode
, domain_len
*2);
589 md5_hmac(buf
, domain_len
*2+user_len
*2, nt_password_hash
, NTLMSSP_KEY_LEN
, ntowf
);
590 printnbyte(ntowf
, NTLMSSP_KEY_LEN
, "NTOWF: ", "\n");
594 memcpy(buf
, serverchallenge
, 8);
595 memcpy(buf
+8, clientchallenge
, 8);
596 md5_hmac(buf
, NTLMSSP_KEY_LEN
, ntowf
, NTLMSSP_KEY_LEN
, lm_challenge_response
);
597 memcpy(lm_challenge_response
+NTLMSSP_KEY_LEN
, clientchallenge
, 8);
598 printnbyte(lm_challenge_response
, 24, "LM Response: ", "\n");
600 /* NT proof = First NTLMSSP_KEY_LEN bytes of NT response */
602 memcpy(buf
, serverchallenge
, 8);
603 memcpy(buf
+8, ntlm_response
->contents
+NTLMSSP_KEY_LEN
, ntlm_response
->length
-NTLMSSP_KEY_LEN
);
604 md5_hmac(buf
, ntlm_response
->length
-8, ntowf
, NTLMSSP_KEY_LEN
, nt_proof
);
605 printnbyte(nt_proof
, NTLMSSP_KEY_LEN
, "NT proof: ", "\n");
606 if (!memcmp(nt_proof
, ntlm_response
->contents
, NTLMSSP_KEY_LEN
)) {
615 md5_hmac(nt_proof
, NTLMSSP_KEY_LEN
, ntowf
, NTLMSSP_KEY_LEN
, sessionbasekey
);
616 get_keyexchange_key(keyexchangekey
, sessionbasekey
, lm_challenge_response
, flags
);
617 /* now decrypt session key if needed and setup sessionkey for decrypting further communications */
618 if (flags
& NTLMSSP_NEGOTIATE_KEY_EXCH
)
620 memcpy(sessionkey
, encryptedsessionkey
, NTLMSSP_KEY_LEN
);
621 crypt_rc4_init(&rc4state
, keyexchangekey
, NTLMSSP_KEY_LEN
);
622 crypt_rc4(&rc4state
, sessionkey
, NTLMSSP_KEY_LEN
);
626 memcpy(sessionkey
, keyexchangekey
, NTLMSSP_KEY_LEN
);
629 memcpy(ntlmssph
->session_key
, sessionkey
, NTLMSSP_KEY_LEN
);
632 /* Create an NTLMSSP version 1 key
633 * That is more complicated logic and methods and user challenge as well.
634 * password points to the ANSI password to encrypt, challenge points to
635 * the 8 octet challenge string
638 create_ntlmssp_v1_key(const char *nt_password
, const guint8
*serverchallenge
, const guint8
*clientchallenge
,
639 guint8
*sessionkey
, const guint8
*encryptedsessionkey
, int flags
,
640 const guint8
*ref_nt_challenge_response
, const guint8
*ref_lm_challenge_response
,
641 ntlmssp_header_t
*ntlmssph
)
643 unsigned char lm_password_upper
[NTLMSSP_KEY_LEN
];
644 unsigned char lm_password_hash
[NTLMSSP_KEY_LEN
];
645 unsigned char nt_password_hash
[NTLMSSP_KEY_LEN
];
646 unsigned char challenges_hash
[NTLMSSP_KEY_LEN
];
647 unsigned char challenges_hash_first8
[8];
648 unsigned char challenges
[NTLMSSP_KEY_LEN
];
649 guint8 md4
[NTLMSSP_KEY_LEN
];
651 guint8 sessionbasekey
[NTLMSSP_KEY_LEN
];
652 guint8 keyexchangekey
[NTLMSSP_KEY_LEN
];
653 guint8 lm_challenge_response
[24];
654 guint8 nt_challenge_response
[24];
655 rc4_state_struct rc4state
;
656 md5_state_t md5state
;
657 char nt_password_unicode
[256];
660 gboolean found
= FALSE
;
661 md4_pass
*pass_list
= NULL
;
663 static const unsigned char lmhash_key
[] =
664 {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
666 memset(sessionkey
, 0, NTLMSSP_KEY_LEN
);
667 memset(lm_password_upper
, 0, sizeof(lm_password_upper
));
668 /* lm auth/lm session == (!NTLM_NEGOTIATE_NT_ONLY && NTLMSSP_NEGOTIATE_LM_KEY) || ! (EXTENDED_SECURITY) || ! NTLMSSP_NEGOTIATE_NTLM*/
669 /* Create a Lan Manager hash of the input password */
670 if (nt_password
[0] != '\0') {
671 password_len
= strlen(nt_password
);
672 /*Do not forget to free nt_password_nt*/
673 str_to_unicode(nt_password
, nt_password_unicode
);
674 crypt_md4(nt_password_hash
, nt_password_unicode
, password_len
*2);
675 /* Truncate password if too long */
676 if (password_len
> NTLMSSP_KEY_LEN
)
677 password_len
= NTLMSSP_KEY_LEN
;
678 for (i
= 0; i
< password_len
; i
++) {
679 lm_password_upper
[i
] = toupper(nt_password
[i
]);
684 /* Unable to calculate the session key without a password ... and we will not use one for a keytab*/
685 if (!(flags
& NTLMSSP_NEGOTIATE_EXTENDED_SECURITY
)) {
689 if ((flags
& NTLMSSP_NEGOTIATE_LM_KEY
&& !(flags
& NTLMSSP_NEGOTIATE_NT_ONLY
)) || !(flags
& NTLMSSP_NEGOTIATE_EXTENDED_SECURITY
) || !(flags
& NTLMSSP_NEGOTIATE_NTLM
)) {
690 crypt_des_ecb(lm_password_hash
, lmhash_key
, lm_password_upper
, 1);
691 crypt_des_ecb(lm_password_hash
+8, lmhash_key
, lm_password_upper
+7, 1);
692 ntlmssp_generate_challenge_response(lm_challenge_response
,
693 lm_password_hash
, serverchallenge
);
694 memcpy(sessionbasekey
, lm_password_hash
, NTLMSSP_KEY_LEN
);
698 memset(lm_challenge_response
, 0, 24);
699 if (flags
& NTLMSSP_NEGOTIATE_EXTENDED_SECURITY
) {
700 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)
701 nb_pass
= get_md4pass_list(&pass_list
, nt_password
);
704 while (i
< nb_pass
) {
705 /*fprintf(stderr, "Turn %d, ", i);*/
706 memcpy(nt_password_hash
, pass_list
[i
].md4
, NTLMSSP_KEY_LEN
);
707 /*printnbyte(nt_password_hash, NTLMSSP_KEY_LEN, "Current NT password hash: ", "\n");*/
709 memcpy(lm_challenge_response
, clientchallenge
, 8);
711 md5_append(&md5state
, serverchallenge
, 8);
712 md5_append(&md5state
, clientchallenge
, 8);
713 md5_finish(&md5state
, challenges_hash
);
714 memcpy(challenges_hash_first8
, challenges_hash
, 8);
715 crypt_des_ecb_long(nt_challenge_response
, nt_password_hash
, challenges_hash_first8
);
716 if (ref_nt_challenge_response
&& !memcmp(ref_nt_challenge_response
, nt_challenge_response
, 24)) {
723 crypt_des_ecb_long(nt_challenge_response
, nt_password_hash
, serverchallenge
);
724 if (flags
& NTLMSSP_NEGOTIATE_NT_ONLY
) {
725 memcpy(lm_challenge_response
, nt_challenge_response
, 24);
728 crypt_des_ecb_long(lm_challenge_response
, lm_password_hash
, serverchallenge
);
730 if (ref_nt_challenge_response
&&
731 !memcmp(ref_nt_challenge_response
, nt_challenge_response
, 24) &&
732 ref_lm_challenge_response
&&
733 !memcmp(ref_lm_challenge_response
, lm_challenge_response
, 24))
738 /* So it's clearly not like this that's put into NTLMSSP doc but after some digging into samba code I'm quite confident
739 * that sessionbasekey should be based md4(nt_password_hash) only in the case of some NT auth
740 * Otherwise it should be lm_password_hash ...*/
741 crypt_md4(md4
, nt_password_hash
, NTLMSSP_KEY_LEN
);
742 if (flags
& NTLMSSP_NEGOTIATE_EXTENDED_SECURITY
) {
743 memcpy(challenges
, serverchallenge
, 8);
744 memcpy(challenges
+8, clientchallenge
, 8);
745 /*md5_hmac(text, text_len, key, key_len, digest);*/
746 md5_hmac(challenges
, NTLMSSP_KEY_LEN
, md4
, NTLMSSP_KEY_LEN
, sessionbasekey
);
749 memcpy(sessionbasekey
, md4
, NTLMSSP_KEY_LEN
);
757 get_keyexchange_key(keyexchangekey
, sessionbasekey
, lm_challenge_response
, flags
);
758 memset(sessionkey
, 0, NTLMSSP_KEY_LEN
);
759 /*printnbyte(nt_challenge_response, 24, "NT challenge response", "\n");
760 printnbyte(lm_challenge_response, 24, "LM challenge response", "\n");*/
761 /* now decrypt session key if needed and setup sessionkey for decrypting further communications */
762 if (flags
& NTLMSSP_NEGOTIATE_KEY_EXCH
)
764 memcpy(sessionkey
, encryptedsessionkey
, NTLMSSP_KEY_LEN
);
765 crypt_rc4_init(&rc4state
, keyexchangekey
, NTLMSSP_KEY_LEN
);
766 crypt_rc4(&rc4state
, sessionkey
, NTLMSSP_KEY_LEN
);
770 memcpy(sessionkey
, keyexchangekey
, NTLMSSP_KEY_LEN
);
772 memcpy(ntlmssph
->session_key
, sessionkey
, NTLMSSP_KEY_LEN
);
776 get_siging_key(guint8
*sign_key_server
, guint8
* sign_key_client
, const guint8 key
[NTLMSSP_KEY_LEN
], int keylen
)
778 md5_state_t md5state
;
779 md5_state_t md5state2
;
781 memset(sign_key_client
, 0, NTLMSSP_KEY_LEN
);
782 memset(sign_key_server
, 0, NTLMSSP_KEY_LEN
);
784 md5_append(&md5state
, key
, keylen
);
785 md5_append(&md5state
, CLIENT_SIGN_TEXT
, strlen(CLIENT_SIGN_TEXT
)+1);
786 md5_finish(&md5state
, sign_key_client
);
787 md5_init(&md5state2
);
788 md5_append(&md5state2
, key
, keylen
);
789 md5_append(&md5state2
, SERVER_SIGN_TEXT
, strlen(SERVER_SIGN_TEXT
)+1);
790 md5_finish(&md5state2
, sign_key_server
);
794 /* We return either a 128 or 64 bit key
797 get_sealing_rc4key(const guint8 exportedsessionkey
[NTLMSSP_KEY_LEN
] , const int flags
, int *keylen
,
798 guint8
*clientsealkey
, guint8
*serversealkey
)
800 md5_state_t md5state
;
801 md5_state_t md5state2
;
803 memset(clientsealkey
, 0, NTLMSSP_KEY_LEN
);
804 memset(serversealkey
, 0, NTLMSSP_KEY_LEN
);
805 memcpy(clientsealkey
, exportedsessionkey
, NTLMSSP_KEY_LEN
);
806 if (flags
& NTLMSSP_NEGOTIATE_EXTENDED_SECURITY
)
808 if (flags
& NTLMSSP_NEGOTIATE_128
)
810 /* The exportedsessionkey has already the good length just update the length*/
815 if (flags
& NTLMSSP_NEGOTIATE_56
)
817 memset(clientsealkey
+7, 0, 9);
822 memset(clientsealkey
+5, 0, 11);
826 memcpy(serversealkey
, clientsealkey
, NTLMSSP_KEY_LEN
);
828 md5_append(&md5state
, clientsealkey
,*keylen
);
829 md5_append(&md5state
, CLIENT_SEAL_TEXT
, strlen(CLIENT_SEAL_TEXT
)+1);
830 md5_finish(&md5state
, clientsealkey
);
831 md5_init(&md5state2
);
832 md5_append(&md5state2
, serversealkey
,*keylen
);
833 md5_append(&md5state2
, SERVER_SEAL_TEXT
, strlen(SERVER_SEAL_TEXT
)+1);
834 md5_finish(&md5state2
, serversealkey
);
838 if (flags
& NTLMSSP_NEGOTIATE_128
)
840 /* The exportedsessionkey has already the good length just update the length*/
846 if (flags
& NTLMSSP_NEGOTIATE_56
)
848 memset(clientsealkey
+7, 0, 9);
852 memset(clientsealkey
+5, 0, 11);
853 clientsealkey
[5]=0xe5;
854 clientsealkey
[6]=0x38;
855 clientsealkey
[7]=0xb0;
858 memcpy(serversealkey
, clientsealkey
,*keylen
);
861 /* Create an NTLMSSP version 1 key.
862 * password points to the ANSI password to encrypt, challenge points to
863 * the 8 octet challenge string, key128 will do a 128 bit key if set to 1,
864 * otherwise it will do a 40 bit key. The result is stored in
865 * sspkey (expected to be NTLMSSP_KEY_LEN octets)
867 /* dissect a string - header area contains:
870 four byte offset of string in data area
871 The function returns the offset at the end of the string header,
872 but the 'end' parameter returns the offset of the end of the string itself
873 The 'start' parameter returns the offset of the beginning of the string
874 If there's no string, just use the offset of the end of the tvb as start/end.
877 dissect_ntlmssp_string (tvbuff_t
*tvb
, int offset
,
878 proto_tree
*ntlmssp_tree
,
879 gboolean unicode_strings
,
880 int string_hf
, int *start
, int *end
,
881 const char **stringp
)
883 proto_tree
*tree
= NULL
;
884 proto_item
*tf
= NULL
;
885 gint16 string_length
= tvb_get_letohs(tvb
, offset
);
886 gint16 string_maxlen
= tvb_get_letohs(tvb
, offset
+2);
887 gint32 string_offset
= tvb_get_letohl(tvb
, offset
+4);
888 const char *string_text
= NULL
;
892 *start
= (string_offset
> offset
+8 ? string_offset
: (signed)tvb_reported_length(tvb
));
893 if (0 == string_length
) {
896 proto_tree_add_string(ntlmssp_tree
, string_hf
, tvb
,
903 bc
= result_length
= string_length
;
904 string_text
= get_unicode_or_ascii_string(tvb
, &string_offset
,
905 unicode_strings
, &result_length
,
908 if (stringp
!= NULL
) {
909 if (!string_text
) string_text
= ""; /* Make sure we don't blow up later */
911 *stringp
= string_text
;
915 tf
= proto_tree_add_string(ntlmssp_tree
, string_hf
, tvb
,
916 string_offset
, result_length
, string_text
);
917 tree
= proto_item_add_subtree(tf
, ett_ntlmssp_string
);
919 proto_tree_add_uint(tree
, hf_ntlmssp_string_len
,
920 tvb
, offset
, 2, string_length
);
922 proto_tree_add_uint(tree
, hf_ntlmssp_string_maxlen
,
923 tvb
, offset
, 2, string_maxlen
);
925 proto_tree_add_uint(tree
, hf_ntlmssp_string_offset
,
926 tvb
, offset
, 4, string_offset
);
929 *end
= string_offset
+ string_length
;
933 /* dissect a generic blob - header area contains:
936 four byte offset of blob in data area
937 The function returns the offset at the end of the blob header,
938 but the 'end' parameter returns the offset of the end of the blob itself
941 dissect_ntlmssp_blob (tvbuff_t
*tvb
, packet_info
*pinfo
,
942 proto_tree
*ntlmssp_tree
, int offset
,
943 int blob_hf
, int *end
, ntlmssp_blob
*result
)
945 proto_item
*tf
= NULL
;
946 proto_tree
*tree
= NULL
;
947 guint16 blob_length
= tvb_get_letohs(tvb
, offset
);
948 guint16 blob_maxlen
= tvb_get_letohs(tvb
, offset
+2);
949 guint32 blob_offset
= tvb_get_letohl(tvb
, offset
+4);
951 if (0 == blob_length
) {
952 *end
= (blob_offset
> ((guint
)offset
)+8 ? blob_offset
: ((guint
)offset
)+8);
954 proto_tree_add_text(ntlmssp_tree
, tvb
, offset
, 8, "%s: Empty",
955 proto_registrar_get_name(blob_hf
));
957 result
->contents
= NULL
;
962 tf
= proto_tree_add_item (ntlmssp_tree
, blob_hf
, tvb
,
963 blob_offset
, blob_length
, ENC_NA
);
964 tree
= proto_item_add_subtree(tf
, ett_ntlmssp_blob
);
966 proto_tree_add_uint(tree
, hf_ntlmssp_blob_len
,
967 tvb
, offset
, 2, blob_length
);
969 proto_tree_add_uint(tree
, hf_ntlmssp_blob_maxlen
,
970 tvb
, offset
, 2, blob_maxlen
);
972 proto_tree_add_uint(tree
, hf_ntlmssp_blob_offset
,
973 tvb
, offset
, 4, blob_offset
);
976 *end
= blob_offset
+ blob_length
;
978 if (result
!= NULL
) {
979 result
->length
= blob_length
;
980 if (blob_length
< MAX_BLOB_SIZE
)
982 result
->contents
= (guint8
*)wmem_alloc(wmem_file_scope(), blob_length
);
983 tvb_memcpy(tvb
, result
->contents
, blob_offset
, blob_length
);
984 if (blob_hf
== hf_ntlmssp_auth_lmresponse
&&
985 !(tvb_memeql(tvb
, blob_offset
+8, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", NTLMSSP_KEY_LEN
)))
987 proto_tree_add_item (ntlmssp_tree
,
988 hf_ntlmssp_ntlm_client_challenge
,
989 tvb
, blob_offset
, 8, ENC_NA
);
993 result
->contents
= NULL
;
994 expert_add_info_format(pinfo
, tf
, &ei_ntlmssp_v2_key_too_long
,
995 "NTLM v2 key is %d bytes long, too big for our %d buffer", blob_length
, MAX_BLOB_SIZE
);
999 /* If we are dissecting the NTLM response and it is a NTLMv2
1000 response call the appropriate dissector. */
1002 if (blob_hf
== hf_ntlmssp_auth_ntresponse
&& blob_length
> 24)
1004 proto_tree_add_item (ntlmssp_tree
,
1005 hf_ntlmssp_ntlm_client_challenge
,
1006 tvb
, blob_offset
+32, 8, ENC_NA
);
1007 dissect_ntlmv2_response(tvb
, pinfo
, tree
, blob_offset
, blob_length
);
1014 dissect_ntlmssp_negotiate_flags (tvbuff_t
*tvb
, int offset
,
1015 proto_tree
*ntlmssp_tree
,
1016 guint32 negotiate_flags
)
1018 proto_tree
*negotiate_flags_tree
= NULL
;
1019 proto_item
*tf
= NULL
;
1022 tf
= proto_tree_add_uint (ntlmssp_tree
,
1023 hf_ntlmssp_negotiate_flags
,
1024 tvb
, offset
, 4, negotiate_flags
);
1025 negotiate_flags_tree
= proto_item_add_subtree (tf
, ett_ntlmssp_negotiate_flags
);
1028 proto_tree_add_boolean (negotiate_flags_tree
,
1029 hf_ntlmssp_negotiate_flags_80000000
,
1030 tvb
, offset
, 4, negotiate_flags
);
1031 proto_tree_add_boolean (negotiate_flags_tree
,
1032 hf_ntlmssp_negotiate_flags_40000000
,
1033 tvb
, offset
, 4, negotiate_flags
);
1034 proto_tree_add_boolean (negotiate_flags_tree
,
1035 hf_ntlmssp_negotiate_flags_20000000
,
1036 tvb
, offset
, 4, negotiate_flags
);
1037 proto_tree_add_boolean (negotiate_flags_tree
,
1038 hf_ntlmssp_negotiate_flags_10000000
,
1039 tvb
, offset
, 4, negotiate_flags
);
1040 proto_tree_add_boolean (negotiate_flags_tree
,
1041 hf_ntlmssp_negotiate_flags_8000000
,
1042 tvb
, offset
, 4, negotiate_flags
);
1043 proto_tree_add_boolean (negotiate_flags_tree
,
1044 hf_ntlmssp_negotiate_flags_4000000
,
1045 tvb
, offset
, 4, negotiate_flags
);
1046 proto_tree_add_boolean (negotiate_flags_tree
,
1047 hf_ntlmssp_negotiate_flags_2000000
,
1048 tvb
, offset
, 4, negotiate_flags
);
1049 proto_tree_add_boolean (negotiate_flags_tree
,
1050 hf_ntlmssp_negotiate_flags_1000000
,
1051 tvb
, offset
, 4, negotiate_flags
);
1052 proto_tree_add_boolean (negotiate_flags_tree
,
1053 hf_ntlmssp_negotiate_flags_800000
,
1054 tvb
, offset
, 4, negotiate_flags
);
1055 proto_tree_add_boolean (negotiate_flags_tree
,
1056 hf_ntlmssp_negotiate_flags_400000
,
1057 tvb
, offset
, 4, negotiate_flags
);
1058 proto_tree_add_boolean (negotiate_flags_tree
,
1059 hf_ntlmssp_negotiate_flags_200000
,
1060 tvb
, offset
, 4, negotiate_flags
);
1061 proto_tree_add_boolean (negotiate_flags_tree
,
1062 hf_ntlmssp_negotiate_flags_100000
,
1063 tvb
, offset
, 4, negotiate_flags
);
1064 proto_tree_add_boolean (negotiate_flags_tree
,
1065 hf_ntlmssp_negotiate_flags_80000
,
1066 tvb
, offset
, 4, negotiate_flags
);
1067 proto_tree_add_boolean (negotiate_flags_tree
,
1068 hf_ntlmssp_negotiate_flags_40000
,
1069 tvb
, offset
, 4, negotiate_flags
);
1070 proto_tree_add_boolean (negotiate_flags_tree
,
1071 hf_ntlmssp_negotiate_flags_20000
,
1072 tvb
, offset
, 4, negotiate_flags
);
1073 proto_tree_add_boolean (negotiate_flags_tree
,
1074 hf_ntlmssp_negotiate_flags_10000
,
1075 tvb
, offset
, 4, negotiate_flags
);
1076 proto_tree_add_boolean (negotiate_flags_tree
,
1077 hf_ntlmssp_negotiate_flags_8000
,
1078 tvb
, offset
, 4, negotiate_flags
);
1079 proto_tree_add_boolean (negotiate_flags_tree
,
1080 hf_ntlmssp_negotiate_flags_4000
,
1081 tvb
, offset
, 4, negotiate_flags
);
1082 proto_tree_add_boolean (negotiate_flags_tree
,
1083 hf_ntlmssp_negotiate_flags_2000
,
1084 tvb
, offset
, 4, negotiate_flags
);
1085 proto_tree_add_boolean (negotiate_flags_tree
,
1086 hf_ntlmssp_negotiate_flags_1000
,
1087 tvb
, offset
, 4, negotiate_flags
);
1088 proto_tree_add_boolean (negotiate_flags_tree
,
1089 hf_ntlmssp_negotiate_flags_800
,
1090 tvb
, offset
, 4, negotiate_flags
);
1091 proto_tree_add_boolean (negotiate_flags_tree
,
1092 hf_ntlmssp_negotiate_flags_400
,
1093 tvb
, offset
, 4, negotiate_flags
);
1094 proto_tree_add_boolean (negotiate_flags_tree
,
1095 hf_ntlmssp_negotiate_flags_200
,
1096 tvb
, offset
, 4, negotiate_flags
);
1097 proto_tree_add_boolean (negotiate_flags_tree
,
1098 hf_ntlmssp_negotiate_flags_100
,
1099 tvb
, offset
, 4, negotiate_flags
);
1100 proto_tree_add_boolean (negotiate_flags_tree
,
1101 hf_ntlmssp_negotiate_flags_80
,
1102 tvb
, offset
, 4, negotiate_flags
);
1103 proto_tree_add_boolean (negotiate_flags_tree
,
1104 hf_ntlmssp_negotiate_flags_40
,
1105 tvb
, offset
, 4, negotiate_flags
);
1106 proto_tree_add_boolean (negotiate_flags_tree
,
1107 hf_ntlmssp_negotiate_flags_20
,
1108 tvb
, offset
, 4, negotiate_flags
);
1109 proto_tree_add_boolean (negotiate_flags_tree
,
1110 hf_ntlmssp_negotiate_flags_10
,
1111 tvb
, offset
, 4, negotiate_flags
);
1112 proto_tree_add_boolean (negotiate_flags_tree
,
1113 hf_ntlmssp_negotiate_flags_08
,
1114 tvb
, offset
, 4, negotiate_flags
);
1115 proto_tree_add_boolean (negotiate_flags_tree
,
1116 hf_ntlmssp_negotiate_flags_04
,
1117 tvb
, offset
, 4, negotiate_flags
);
1118 proto_tree_add_boolean (negotiate_flags_tree
,
1119 hf_ntlmssp_negotiate_flags_02
,
1120 tvb
, offset
, 4, negotiate_flags
);
1121 proto_tree_add_boolean (negotiate_flags_tree
,
1122 hf_ntlmssp_negotiate_flags_01
,
1123 tvb
, offset
, 4, negotiate_flags
);
1125 return (offset
+ 4);
1128 /* Dissect "version" */
1131 0 Major Version Number 1 byte
1132 1 Minor Version Number 1 byte
1133 2 Build Number short(LE)
1134 3 (Reserved) 3 bytes
1135 4 NTLM Current Revision 1 byte
1139 dissect_ntlmssp_version(tvbuff_t
*tvb
, int offset
,
1140 proto_tree
*ntlmssp_tree
)
1144 proto_tree
*version_tree
;
1145 tf
= proto_tree_add_none_format(ntlmssp_tree
, hf_ntlmssp_version
, tvb
, offset
, 8,
1146 "Version %u.%u (Build %u); NTLM Current Revision %u",
1147 tvb_get_guint8(tvb
, offset
),
1148 tvb_get_guint8(tvb
, offset
+1),
1149 tvb_get_letohs(tvb
, offset
+2),
1150 tvb_get_guint8(tvb
, offset
+7));
1151 version_tree
= proto_item_add_subtree (tf
, ett_ntlmssp_version
);
1152 proto_tree_add_item(version_tree
, hf_ntlmssp_version_major
, tvb
, offset
, 1, ENC_NA
);
1153 proto_tree_add_item(version_tree
, hf_ntlmssp_version_minor
, tvb
, offset
+1, 1, ENC_NA
);
1154 proto_tree_add_item(version_tree
, hf_ntlmssp_version_build_number
, tvb
, offset
+2, 2, ENC_LITTLE_ENDIAN
);
1155 proto_tree_add_item(version_tree
, hf_ntlmssp_version_ntlm_current_revision
, tvb
, offset
+7, 1, ENC_NA
);
1160 /* Dissect a NTLM response. This is documented at
1161 http://ubiqx.org/cifs/SMB.html#SMB.8, para 2.8.5.3 */
1163 /* Attribute types */
1165 * XXX - the davenport document says that a type of 5 has been seen,
1166 * "apparently containing the 'parent' DNS domain for servers in
1168 * XXX: MS-NLMP info is newer than Davenport info;
1169 * The attribute type list and the attribute names below are
1170 * based upon MS-NLMP.
1173 #define NTLM_TARGET_INFO_END 0x0000
1174 #define NTLM_TARGET_INFO_NB_COMPUTER_NAME 0x0001
1175 #define NTLM_TARGET_INFO_NB_DOMAIN_NAME 0x0002
1176 #define NTLM_TARGET_INFO_DNS_COMPUTER_NAME 0x0003
1177 #define NTLM_TARGET_INFO_DNS_DOMAIN_NAME 0x0004
1178 #define NTLM_TARGET_INFO_DNS_TREE_NAME 0x0005
1179 #define NTLM_TARGET_INFO_FLAGS 0x0006
1180 #define NTLM_TARGET_INFO_TIMESTAMP 0x0007
1181 #define NTLM_TARGET_INFO_RESTRICTIONS 0x0008
1182 #define NTLM_TARGET_INFO_TARGET_NAME 0x0009
1183 #define NTLM_TARGET_INFO_CHANNEL_BINDINGS 0x000A
1185 static const value_string ntlm_name_types
[] = {
1186 { NTLM_TARGET_INFO_END
, "End of list" },
1187 { NTLM_TARGET_INFO_NB_COMPUTER_NAME
, "NetBIOS computer name" },
1188 { NTLM_TARGET_INFO_NB_DOMAIN_NAME
, "NetBIOS domain name" },
1189 { NTLM_TARGET_INFO_DNS_COMPUTER_NAME
, "DNS computer name" },
1190 { NTLM_TARGET_INFO_DNS_DOMAIN_NAME
, "DNS domain name" },
1191 { NTLM_TARGET_INFO_DNS_TREE_NAME
, "DNS tree name" },
1192 { NTLM_TARGET_INFO_FLAGS
, "Flags" },
1193 { NTLM_TARGET_INFO_TIMESTAMP
, "Timestamp" },
1194 { NTLM_TARGET_INFO_RESTRICTIONS
, "Restrictions" },
1195 { NTLM_TARGET_INFO_TARGET_NAME
, "Target Name"},
1196 { NTLM_TARGET_INFO_CHANNEL_BINDINGS
, "Channel Bindings"},
1200 /* The following *must* match the order of the list of attribute types */
1201 /* Assumption: values in the list are a sequence starting with 0 and */
1202 /* with no gaps allowing a direct access of the array by attribute type */
1203 static int *ntlmssp_hf_challenge_target_info_hf_ptr_array
[] = {
1204 &hf_ntlmssp_challenge_target_info_end
,
1205 &hf_ntlmssp_challenge_target_info_nb_computer_name
,
1206 &hf_ntlmssp_challenge_target_info_nb_domain_name
,
1207 &hf_ntlmssp_challenge_target_info_dns_computer_name
,
1208 &hf_ntlmssp_challenge_target_info_dns_domain_name
,
1209 &hf_ntlmssp_challenge_target_info_dns_tree_name
,
1210 &hf_ntlmssp_challenge_target_info_flags
,
1211 &hf_ntlmssp_challenge_target_info_timestamp
,
1212 &hf_ntlmssp_challenge_target_info_restrictions
,
1213 &hf_ntlmssp_challenge_target_info_target_name
,
1214 &hf_ntlmssp_challenge_target_info_channel_bindings
1217 static int *ntlmssp_hf_ntlmv2_response_hf_ptr_array
[] = {
1218 &hf_ntlmssp_ntlmv2_response_end
,
1219 &hf_ntlmssp_ntlmv2_response_nb_computer_name
,
1220 &hf_ntlmssp_ntlmv2_response_nb_domain_name
,
1221 &hf_ntlmssp_ntlmv2_response_dns_computer_name
,
1222 &hf_ntlmssp_ntlmv2_response_dns_domain_name
,
1223 &hf_ntlmssp_ntlmv2_response_dns_tree_name
,
1224 &hf_ntlmssp_ntlmv2_response_flags
,
1225 &hf_ntlmssp_ntlmv2_response_timestamp
,
1226 &hf_ntlmssp_ntlmv2_response_restrictions
,
1227 &hf_ntlmssp_ntlmv2_response_target_name
,
1228 &hf_ntlmssp_ntlmv2_response_channel_bindings
1231 typedef struct _tif
{
1234 int *hf_item_length
;
1235 int **hf_attr_array_p
;
1238 static tif_t ntlmssp_challenge_target_info_tif
= {
1239 &ett_ntlmssp_challenge_target_info_item
,
1240 &hf_ntlmssp_challenge_target_info_item_type
,
1241 &hf_ntlmssp_challenge_target_info_item_len
,
1242 ntlmssp_hf_challenge_target_info_hf_ptr_array
1245 static tif_t ntlmssp_ntlmv2_response_tif
= {
1246 &ett_ntlmssp_ntlmv2_response_item
,
1247 &hf_ntlmssp_ntlmv2_response_item_type
,
1248 &hf_ntlmssp_ntlmv2_response_item_len
,
1249 ntlmssp_hf_ntlmv2_response_hf_ptr_array
1252 /** See [MS-NLMP] 2.2.2.1 */
1254 dissect_ntlmssp_target_info_list(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
1255 guint32 target_info_offset
, guint16 target_info_length
,
1258 guint32 item_offset
;
1259 guint16 item_type
= ~0;
1260 guint16 item_length
;
1262 /* Now enumerate through the individual items in the list */
1263 item_offset
= target_info_offset
;
1265 while (item_offset
< (target_info_offset
+ target_info_length
) && (item_type
!= NTLM_TARGET_INFO_END
)) {
1266 proto_item
*target_info_tf
;
1267 proto_tree
*target_info_tree
;
1268 guint32 content_offset
;
1269 guint16 content_length
;
1270 guint32 type_offset
;
1272 const gchar
*text
= NULL
;
1274 int **hf_array_p
= tif_p
->hf_attr_array_p
;
1277 type_offset
= item_offset
;
1278 item_type
= tvb_get_letohs(tvb
, type_offset
);
1280 /* Content length */
1281 len_offset
= type_offset
+ 2;
1282 content_length
= tvb_get_letohs(tvb
, len_offset
);
1285 content_offset
= len_offset
+ 2;
1286 item_length
= content_length
+ 4;
1288 target_info_tf
= proto_tree_add_text(tree
, tvb
, item_offset
, item_length
, "Attribute: %s",
1289 val_to_str(item_type
, ntlm_name_types
, "Unknown (%d)"));
1291 target_info_tree
= proto_item_add_subtree (target_info_tf
, *tif_p
->ett
);
1292 proto_tree_add_item (target_info_tree
, *tif_p
->hf_item_type
, tvb
, type_offset
, 2, ENC_LITTLE_ENDIAN
);
1293 proto_tree_add_item (target_info_tree
, *tif_p
->hf_item_length
, tvb
, len_offset
, 2, ENC_LITTLE_ENDIAN
);
1295 if (content_length
> 0) {
1296 switch (item_type
) {
1297 case NTLM_TARGET_INFO_NB_COMPUTER_NAME
:
1298 case NTLM_TARGET_INFO_NB_DOMAIN_NAME
:
1299 case NTLM_TARGET_INFO_DNS_COMPUTER_NAME
:
1300 case NTLM_TARGET_INFO_DNS_DOMAIN_NAME
:
1301 case NTLM_TARGET_INFO_DNS_TREE_NAME
:
1302 case NTLM_TARGET_INFO_TARGET_NAME
:
1303 text
= tvb_get_unicode_string(wmem_packet_scope(), tvb
, content_offset
, content_length
, ENC_LITTLE_ENDIAN
);
1304 proto_tree_add_string(target_info_tree
, *hf_array_p
[item_type
], tvb
, content_offset
, content_length
, text
);
1305 proto_item_append_text(target_info_tf
, ": %s", text
);
1308 case NTLM_TARGET_INFO_FLAGS
:
1309 proto_tree_add_item(target_info_tree
, *hf_array_p
[item_type
], tvb
, content_offset
, content_length
, ENC_LITTLE_ENDIAN
);
1312 case NTLM_TARGET_INFO_TIMESTAMP
:
1313 dissect_nt_64bit_time(tvb
, target_info_tree
, content_offset
, *hf_array_p
[item_type
]);
1316 case NTLM_TARGET_INFO_RESTRICTIONS
:
1317 case NTLM_TARGET_INFO_CHANNEL_BINDINGS
:
1318 proto_tree_add_item(target_info_tree
, *hf_array_p
[item_type
], tvb
, content_offset
, content_length
, ENC_NA
);
1322 proto_tree_add_expert(target_info_tree
, pinfo
, &ei_ntlmssp_target_info_attr
,
1323 tvb
, content_offset
, content_length
);
1328 item_offset
+= item_length
;
1334 /** See [MS-NLMP] 3.3.2 */
1336 dissect_ntlmv2_response(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, int offset
, int len
)
1338 proto_item
*ntlmv2_item
= NULL
;
1339 proto_tree
*ntlmv2_tree
= NULL
;
1340 const int orig_offset
= offset
;
1343 ntlmv2_item
= proto_tree_add_item(
1344 tree
, hf_ntlmssp_ntlmv2_response
, tvb
,
1345 offset
, len
, ENC_NA
);
1346 ntlmv2_tree
= proto_item_add_subtree(
1347 ntlmv2_item
, ett_ntlmssp_ntlmv2_response
);
1350 proto_tree_add_item(
1351 ntlmv2_tree
, hf_ntlmssp_ntlmv2_response_ntproofstr
, tvb
,
1352 offset
, 16, ENC_NA
);
1355 proto_tree_add_item(ntlmv2_tree
, hf_ntlmssp_ntlmv2_response_rversion
, tvb
, offset
, 1, ENC_NA
);
1358 proto_tree_add_item(ntlmv2_tree
, hf_ntlmssp_ntlmv2_response_hirversion
, tvb
, offset
, 1, ENC_NA
);
1361 proto_tree_add_item(ntlmv2_tree
, hf_ntlmssp_ntlmv2_response_z
, tvb
, offset
, 6, ENC_NA
);
1364 offset
= dissect_nt_64bit_time(
1365 tvb
, ntlmv2_tree
, offset
, hf_ntlmssp_ntlmv2_response_time
);
1366 proto_tree_add_item(
1367 ntlmv2_tree
, hf_ntlmssp_ntlmv2_response_chal
, tvb
,
1371 proto_tree_add_item(ntlmv2_tree
, hf_ntlmssp_ntlmv2_response_z
, tvb
, offset
, 4, ENC_NA
);
1374 offset
= dissect_ntlmssp_target_info_list(tvb
, pinfo
, ntlmv2_tree
, offset
, len
- (offset
- orig_offset
), &ntlmssp_ntlmv2_response_tif
);
1376 if ((offset
- orig_offset
) < len
) {
1377 proto_tree_add_item(ntlmv2_tree
, hf_ntlmssp_ntlmv2_response_z
, tvb
, offset
, 4, ENC_NA
);
1381 if ((offset
- orig_offset
) < len
) {
1382 proto_tree_add_item(ntlmv2_tree
, hf_ntlmssp_ntlmv2_response_pad
, tvb
, offset
, len
- (offset
- orig_offset
), ENC_NA
);
1388 /* tapping into ntlmssph not yet implemented */
1390 dissect_ntlmssp_negotiate (tvbuff_t
*tvb
, int offset
, proto_tree
*ntlmssp_tree
, ntlmssp_header_t
*ntlmssph _U_
)
1392 guint32 negotiate_flags
;
1398 /* NTLMSSP Negotiate Flags */
1399 negotiate_flags
= tvb_get_letohl (tvb
, offset
);
1400 offset
= dissect_ntlmssp_negotiate_flags (tvb
, offset
, ntlmssp_tree
,
1404 * XXX - the davenport document says that these might not be
1405 * sent at all, presumably meaning the length of the message
1406 * isn't enough to contain them.
1408 offset
= dissect_ntlmssp_string(tvb
, offset
, ntlmssp_tree
, FALSE
,
1409 hf_ntlmssp_negotiate_domain
,
1410 &data_start
, &data_end
, NULL
);
1412 offset
= dissect_ntlmssp_string(tvb
, offset
, ntlmssp_tree
, FALSE
,
1413 hf_ntlmssp_negotiate_workstation
,
1414 &item_start
, &item_end
, NULL
);
1415 data_start
= MIN(data_start
, item_start
);
1416 data_end
= MAX(data_end
, item_end
);
1418 /* If there are more bytes before the data block dissect a version field
1419 if NTLMSSP_NEGOTIATE_VERSION is set in the flags (see MS-NLMP) */
1420 if (offset
< data_start
) {
1421 if (negotiate_flags
& NTLMSSP_NEGOTIATE_VERSION
)
1422 dissect_ntlmssp_version(tvb
, offset
, ntlmssp_tree
);
1429 dissect_ntlmssp_challenge_target_info_blob (packet_info
*pinfo
, tvbuff_t
*tvb
, int offset
,
1430 proto_tree
*ntlmssp_tree
,
1433 guint16 challenge_target_info_length
= tvb_get_letohs(tvb
, offset
);
1434 guint16 challenge_target_info_maxlen
= tvb_get_letohs(tvb
, offset
+2);
1435 guint32 challenge_target_info_offset
= tvb_get_letohl(tvb
, offset
+4);
1436 proto_item
*tf
= NULL
;
1437 proto_tree
*challenge_target_info_tree
= NULL
;
1439 /* the target info list is just a blob */
1440 if (0 == challenge_target_info_length
) {
1441 *end
= (challenge_target_info_offset
> ((guint
)offset
)+8 ? challenge_target_info_offset
: ((guint
)offset
)+8);
1443 proto_tree_add_text(ntlmssp_tree
, tvb
, offset
, 8,
1444 "Target Info List: Empty");
1449 tf
= proto_tree_add_item (ntlmssp_tree
, hf_ntlmssp_challenge_target_info
, tvb
,
1450 challenge_target_info_offset
, challenge_target_info_length
, ENC_NA
);
1451 challenge_target_info_tree
= proto_item_add_subtree(tf
, ett_ntlmssp_challenge_target_info
);
1453 proto_tree_add_uint(challenge_target_info_tree
, hf_ntlmssp_challenge_target_info_len
,
1454 tvb
, offset
, 2, challenge_target_info_length
);
1456 proto_tree_add_uint(challenge_target_info_tree
, hf_ntlmssp_challenge_target_info_maxlen
,
1457 tvb
, offset
, 2, challenge_target_info_maxlen
);
1459 proto_tree_add_uint(challenge_target_info_tree
, hf_ntlmssp_challenge_target_info_offset
,
1460 tvb
, offset
, 4, challenge_target_info_offset
);
1463 dissect_ntlmssp_target_info_list(tvb
, pinfo
, challenge_target_info_tree
,
1464 challenge_target_info_offset
, challenge_target_info_length
,
1465 &ntlmssp_challenge_target_info_tif
);
1467 *end
= challenge_target_info_offset
+ challenge_target_info_length
;
1471 /* tapping into ntlmssph not yet implemented */
1473 dissect_ntlmssp_challenge (tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
,
1474 proto_tree
*ntlmssp_tree
, ntlmssp_header_t
*ntlmssph _U_
)
1476 guint32 negotiate_flags
;
1477 int item_start
, item_end
;
1478 int data_start
, data_end
; /* MIN and MAX seen */
1479 guint8 clientkey
[NTLMSSP_KEY_LEN
]; /* NTLMSSP cipher key for client */
1480 guint8 serverkey
[NTLMSSP_KEY_LEN
]; /* NTLMSSP cipher key for server*/
1481 ntlmssp_info
*conv_ntlmssp_info
= NULL
;
1482 conversation_t
*conversation
;
1483 gboolean unicode_strings
= FALSE
;
1485 guint8 sspkey
[NTLMSSP_KEY_LEN
]; /* NTLMSSP cipher key */
1486 int ssp_key_len
; /* Either 8 or 16 (40 bit or 128) */
1488 /* need to find unicode flag */
1489 negotiate_flags
= tvb_get_letohl (tvb
, offset
+8);
1490 if (negotiate_flags
& NTLMSSP_NEGOTIATE_UNICODE
)
1491 unicode_strings
= TRUE
;
1495 * XXX - the davenport document (and MS-NLMP) calls this "Target Name",
1496 * presumably because non-domain targets are supported.
1497 * XXX - Original name "domain" changed to "target_name" to match MS-NLMP
1499 offset
= dissect_ntlmssp_string(tvb
, offset
, ntlmssp_tree
, unicode_strings
,
1500 hf_ntlmssp_challenge_target_name
,
1501 &item_start
, &item_end
, NULL
);
1502 data_start
= item_start
;
1503 data_end
= item_end
;
1505 /* NTLMSSP Negotiate Flags */
1506 offset
= dissect_ntlmssp_negotiate_flags (tvb
, offset
, ntlmssp_tree
,
1509 /* NTLMSSP NT Lan Manager Challenge */
1510 proto_tree_add_item (ntlmssp_tree
,
1511 hf_ntlmssp_ntlm_server_challenge
,
1512 tvb
, offset
, 8, ENC_NA
);
1515 * Store the flags and the RC4 state information with the conversation,
1516 * as they're needed in order to dissect subsequent messages.
1518 conversation
= find_or_create_conversation(pinfo
);
1520 tvb_memcpy(tvb
, tmp
, offset
, 8); /* challenge */
1521 /* We can face more than one NTLM exchange over the same couple of IP and ports ...*/
1522 conv_ntlmssp_info
= (ntlmssp_info
*)conversation_get_proto_data(conversation
, proto_ntlmssp
);
1523 /* XXX: The following code is (re)executed every time a particular frame is dissected
1524 * (in whatever order). Thus it seems to me that "multiple exchanges" might not be
1525 * handled well depending on the order that frames are visited after the initial dissection.
1527 if (!conv_ntlmssp_info
|| memcmp(tmp
, conv_ntlmssp_info
->server_challenge
, 8) != 0) {
1528 conv_ntlmssp_info
= wmem_new0(wmem_file_scope(), ntlmssp_info
);
1529 /* Insert the flags into the conversation */
1530 conv_ntlmssp_info
->flags
= negotiate_flags
;
1531 /* Insert the RC4 state information into the conversation */
1532 tvb_memcpy(tvb
, conv_ntlmssp_info
->server_challenge
, offset
, 8);
1533 conv_ntlmssp_info
->is_auth_ntlm_v2
= 0;
1534 /* Between the challenge and the user provided password, we can build the
1535 NTLMSSP key and initialize the cipher if we are not in EXTENDED SECURITY
1536 in this case we need the client challenge as well*/
1537 /* BTW this is true just if we are in LM Authentification if not the logic is a bit different.
1538 * Right now it's not very clear what is LM Authentification it __seems__ to be when
1539 * NEGOTIATE NT ONLY is not set and NEGOSIATE EXTENDED SECURITY is not set as well*/
1540 if (!(conv_ntlmssp_info
->flags
& NTLMSSP_NEGOTIATE_EXTENDED_SECURITY
))
1542 conv_ntlmssp_info
->rc4_state_initialized
= 0;
1543 /* XXX - Make sure there is 24 bytes for the key */
1544 conv_ntlmssp_info
->ntlm_response
.contents
= (guint8
*)wmem_alloc0(wmem_file_scope(), 24);
1545 conv_ntlmssp_info
->lm_response
.contents
= (guint8
*)wmem_alloc0(wmem_file_scope(), 24);
1547 create_ntlmssp_v1_key(gbl_nt_password
, conv_ntlmssp_info
->server_challenge
, NULL
, sspkey
, NULL
, conv_ntlmssp_info
->flags
, conv_ntlmssp_info
->ntlm_response
.contents
, conv_ntlmssp_info
->lm_response
.contents
, ntlmssph
);
1548 if (memcmp(sspkey
, gbl_zeros
, NTLMSSP_KEY_LEN
) != 0) {
1549 get_sealing_rc4key(sspkey
, conv_ntlmssp_info
->flags
, &ssp_key_len
, clientkey
, serverkey
);
1550 crypt_rc4_init(&conv_ntlmssp_info
->rc4_state_client
, sspkey
, ssp_key_len
);
1551 crypt_rc4_init(&conv_ntlmssp_info
->rc4_state_server
, sspkey
, ssp_key_len
);
1552 conv_ntlmssp_info
->server_dest_port
= pinfo
->destport
;
1553 conv_ntlmssp_info
->rc4_state_initialized
= 1;
1557 conversation_add_proto_data(conversation
, proto_ntlmssp
, conv_ntlmssp_info
);
1561 /* If no more bytes (ie: no "reserved", ...) before start of data block, then return */
1562 /* XXX: According to Davenport "This form is seen in older Win9x-based systems" */
1563 /* Also: I've seen a capture with an HTTP CONNECT proxy-authentication */
1564 /* message wherein the challenge from the proxy has this form. */
1565 if (offset
>= data_start
) {
1569 /* Reserved (function not completely known) */
1571 * XXX - SSP key? The davenport document says
1573 * The context field is typically populated when Negotiate Local
1574 * Call is set. It contains an SSPI context handle, which allows
1575 * the client to "short-circuit" authentication and effectively
1576 * circumvent responding to the challenge. Physically, the context
1577 * is two long values. This is covered in greater detail later,
1578 * in the "Local Authentication" section.
1580 * It also says that that information may be omitted.
1582 proto_tree_add_item (ntlmssp_tree
, hf_ntlmssp_reserved
,
1583 tvb
, offset
, 8, ENC_NA
);
1587 * The presence or absence of this field is not obviously correlated
1588 * with any flags in the previous NEGOTIATE message or in this
1589 * message (other than the "Workstation Supplied" and "Domain
1590 * Supplied" flags in the NEGOTIATE message, at least in the capture
1591 * I've seen - but those also correlate with the presence of workstation
1592 * and domain name fields, so it doesn't seem to make sense that they
1593 * actually *indicate* whether the subsequent CHALLENGE has an
1596 if (offset
< data_start
) {
1597 offset
= dissect_ntlmssp_challenge_target_info_blob(pinfo
, tvb
, offset
, ntlmssp_tree
, &item_end
);
1598 /* XXX: This code assumes that the address list in the data block */
1599 /* is always after the target name. Is this OK ? */
1600 data_end
= MAX(data_end
, item_end
);
1603 /* If there are more bytes before the data block dissect a version field
1604 if NTLMSSP_NEGOTIATE_VERSION is set in the flags (see MS-NLMP) */
1605 if (offset
< data_start
) {
1606 if (negotiate_flags
& NTLMSSP_NEGOTIATE_VERSION
)
1607 offset
= dissect_ntlmssp_version(tvb
, offset
, ntlmssp_tree
);
1610 return MAX(offset
, data_end
);
1614 dissect_ntlmssp_auth (tvbuff_t
*tvb
, packet_info
*pinfo
, int offset
,
1615 proto_tree
*ntlmssp_tree
, ntlmssp_header_t
*ntlmssph
)
1617 int item_start
, item_end
;
1618 int data_start
, data_end
= 0;
1619 guint32 negotiate_flags
;
1620 guint8 sspkey
[NTLMSSP_KEY_LEN
]; /* exported session key */
1621 guint8 clientkey
[NTLMSSP_KEY_LEN
]; /* NTLMSSP cipher key for client */
1622 guint8 serverkey
[NTLMSSP_KEY_LEN
]; /* NTLMSSP cipher key for server*/
1623 guint8 encryptedsessionkey
[NTLMSSP_KEY_LEN
];
1624 ntlmssp_blob sessionblob
;
1625 gboolean unicode_strings
= FALSE
;
1626 ntlmssp_info
*conv_ntlmssp_info
;
1627 conversation_t
*conversation
;
1631 * Get flag info from the original negotiate message, if any.
1632 * This is because the flag information is sometimes missing from
1633 * the AUTHENTICATE message, so we can't figure out whether
1634 * strings are Unicode or not by looking at *our* flags.
1635 * XXX it seems it's more from the CHALLENGE message, which is more clever in fact
1636 * because the server can change some flags.
1637 * But according to MS NTLMSSP doc it's not that simple.
1638 * In case of Conection less mode AUTHENTICATE flags should be used because they
1639 * reprensent the choice of the client after having been informed of options of the
1640 * server in the CHALLENGE message.
1641 * In Connection mode then the CHALLENGE flags should (must ?) be used
1642 * XXX: MS-NLMP says the flag field in the AUTHENTICATE message "contains the set of bit
1643 * flags (section 2.2.2.5) negotiated in the previous messages."
1644 * I read that to mean that the flags for in connection-mode AUTHENTICATE also represent
1645 * the choice of the client (for the flags which are negotiated).
1646 * XXX: In the absence of CHALLENGE flags, as a last resort we'll use the flags
1647 * (if available) from this AUTHENTICATE message.
1648 * I've seen a capture which does an HTTP CONNECT which:
1649 * - has the NEGOTIATE & CHALLENGE messages in one TCP connection;
1650 * - has the AUTHENTICATE message in a second TCP connection;
1651 * (The authentication aparently succeeded).
1653 conv_ntlmssp_info
= (ntlmssp_info
*)p_get_proto_data(pinfo
->fd
, proto_ntlmssp
, NTLMSSP_CONV_INFO_KEY
);
1654 if (conv_ntlmssp_info
== NULL
) {
1656 * There isn't any. Is there any from this conversation? If so,
1657 * it means this is the first time we've dissected this frame, so
1658 * we should give it flag info.
1660 /* XXX: Create conv_ntlmssp_info & etc if no previous CHALLENGE seen */
1661 /* so we'll have a place to store flags. */
1662 /* This is a bit brute-force but looks like it will be OK. */
1663 conversation
= find_or_create_conversation(pinfo
);
1664 conv_ntlmssp_info
= (ntlmssp_info
*)conversation_get_proto_data(conversation
, proto_ntlmssp
);
1665 if (conv_ntlmssp_info
== NULL
) {
1666 conv_ntlmssp_info
= wmem_new0(wmem_file_scope(), ntlmssp_info
);
1667 conversation_add_proto_data(conversation
, proto_ntlmssp
, conv_ntlmssp_info
);
1669 /* XXX: The *conv_ntlmssp_info struct attached to the frame is the
1670 same as the one attached to the conversation. That is: *both* point to
1671 the exact same struct in memory. Is this what is indended ? */
1672 p_add_proto_data(pinfo
->fd
, proto_ntlmssp
, NTLMSSP_CONV_INFO_KEY
, conv_ntlmssp_info
);
1675 if (conv_ntlmssp_info
!= NULL
) {
1676 if (conv_ntlmssp_info
->flags
& NTLMSSP_NEGOTIATE_UNICODE
)
1677 unicode_strings
= TRUE
;
1681 * Sometimes the session key and flags are missing.
1682 * Sometimes the session key is present but the flags are missing.
1683 * XXX Who stay so ? Reading spec I would rather say the opposite: flags are
1684 * always present, session information are always there as well but sometime
1685 * session information could be null (in case of no session)
1686 * Sometimes they're both present.
1688 * This does not correlate with any flags in the previous CHALLENGE
1689 * message, and only correlates with "Negotiate Unicode", "Workstation
1690 * Supplied", and "Domain Supplied" in the NEGOTIATE message - but
1691 * those don't make sense as flags to use to determine this.
1693 * So we check all of the descriptors to figure out where the data
1694 * area begins, and if the session key or the flags would be in the
1695 * middle of the data area, we assume the field in question is
1698 * XXX - Reading Davenport and MS-NLMP: as I see it the possibilities are:
1699 * a. No session-key; no flags; no version ("Win9x")
1700 * b. Session-key & flags.
1701 * c. Session-key, flags & version.
1702 * In cases b and c the session key may be "null".
1706 /* Lan Manager response */
1707 data_start
= tvb_get_letohl(tvb
, offset
+4);
1708 offset
= dissect_ntlmssp_blob(tvb
, pinfo
, ntlmssp_tree
, offset
,
1709 hf_ntlmssp_auth_lmresponse
,
1711 conv_ntlmssp_info
== NULL
? NULL
:
1712 &conv_ntlmssp_info
->lm_response
);
1713 data_end
= MAX(data_end
, item_end
);
1716 item_start
= tvb_get_letohl(tvb
, offset
+4);
1717 offset
= dissect_ntlmssp_blob(tvb
, pinfo
, ntlmssp_tree
, offset
,
1718 hf_ntlmssp_auth_ntresponse
,
1720 conv_ntlmssp_info
== NULL
? NULL
:
1721 &conv_ntlmssp_info
->ntlm_response
);
1722 if (conv_ntlmssp_info
!= NULL
&& conv_ntlmssp_info
->ntlm_response
.length
> 24) {
1723 memcpy(conv_ntlmssp_info
->client_challenge
, conv_ntlmssp_info
->ntlm_response
.contents
+32, 8);
1725 data_start
= MIN(data_start
, item_start
);
1726 data_end
= MAX(data_end
, item_end
);
1727 if (conv_ntlmssp_info
!= NULL
)
1729 if (conv_ntlmssp_info
->ntlm_response
.length
> 24)
1731 conv_ntlmssp_info
->is_auth_ntlm_v2
= 1;
1735 conv_ntlmssp_info
->is_auth_ntlm_v2
= 0;
1740 item_start
= tvb_get_letohl(tvb
, offset
+4);
1741 offset
= dissect_ntlmssp_string(tvb
, offset
, ntlmssp_tree
,
1743 hf_ntlmssp_auth_domain
,
1744 &item_start
, &item_end
, &(ntlmssph
->domain_name
));
1745 /*ntlmssph->domain_name_len = item_end-item_start;*/
1746 data_start
= MIN(data_start
, item_start
);
1747 data_end
= MAX(data_end
, item_end
);
1750 item_start
= tvb_get_letohl(tvb
, offset
+4);
1751 offset
= dissect_ntlmssp_string(tvb
, offset
, ntlmssp_tree
,
1753 hf_ntlmssp_auth_username
,
1754 &item_start
, &item_end
, &(ntlmssph
->acct_name
));
1755 /*ntlmssph->acct_name_len = item_end-item_start;*/
1756 data_start
= MIN(data_start
, item_start
);
1757 data_end
= MAX(data_end
, item_end
);
1759 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ", ", "User: %s\\%s",
1760 ntlmssph
->domain_name
, ntlmssph
->acct_name
);
1763 item_start
= tvb_get_letohl(tvb
, offset
+4);
1764 offset
= dissect_ntlmssp_string(tvb
, offset
, ntlmssp_tree
,
1766 hf_ntlmssp_auth_hostname
,
1767 &item_start
, &item_end
, &(ntlmssph
->host_name
));
1768 data_start
= MIN(data_start
, item_start
);
1769 data_end
= MAX(data_end
, item_end
);
1771 sessionblob
.length
= 0;
1772 if (offset
< data_start
) {
1774 offset
= dissect_ntlmssp_blob(tvb
, pinfo
, ntlmssp_tree
, offset
,
1775 hf_ntlmssp_auth_sesskey
,
1776 &item_end
, &sessionblob
);
1777 data_end
= MAX(data_end
, item_end
);
1780 if (offset
< data_start
) {
1781 /* NTLMSSP Negotiate Flags */
1782 negotiate_flags
= tvb_get_letohl (tvb
, offset
);
1783 offset
= dissect_ntlmssp_negotiate_flags (tvb
, offset
, ntlmssp_tree
,
1785 /* If no previous flags seen (ie: no previous CHALLENGE) use flags
1786 from the AUTHENTICATE message).
1787 Assumption: (flags == 0) means flags not previously seen */
1788 if ((conv_ntlmssp_info
!= NULL
) && (conv_ntlmssp_info
->flags
== 0)) {
1789 conv_ntlmssp_info
->flags
= negotiate_flags
;
1792 negotiate_flags
= 0;
1794 /* If there are more bytes before the data block dissect a version field
1795 if NTLMSSP_NEGOTIATE_VERSION is set in the flags (see MS-NLMP) */
1796 if (offset
< data_start
) {
1797 if (negotiate_flags
& NTLMSSP_NEGOTIATE_VERSION
)
1798 offset
= dissect_ntlmssp_version(tvb
, offset
, ntlmssp_tree
);
1801 /* If there are still more bytes before the data block dissect an MIC (message integrity_code) field */
1803 if (offset
< data_start
) {
1804 proto_tree_add_item(ntlmssp_tree
, hf_ntlmssp_message_integrity_code
, tvb
, offset
, 16, ENC_NA
);
1808 if (sessionblob
.length
> NTLMSSP_KEY_LEN
) {
1809 expert_add_info_format(pinfo
, NULL
, &ei_ntlmssp_blob_len_too_long
, "Session blob length too long: %u", sessionblob
.length
);
1810 } else if (sessionblob
.length
!= 0) {
1811 memcpy(encryptedsessionkey
, sessionblob
.contents
, sessionblob
.length
);
1812 /* Try to attach to an existing conversation if not then it's useless to try to do so
1813 * because we are missing important information (ie. server challenge)
1815 if (conv_ntlmssp_info
) {
1816 /* If we are in EXTENDED SECURITY then we can now initialize cipher */
1817 if ((conv_ntlmssp_info
->flags
& NTLMSSP_NEGOTIATE_EXTENDED_SECURITY
))
1819 conv_ntlmssp_info
->rc4_state_initialized
= 0;
1820 if (conv_ntlmssp_info
->is_auth_ntlm_v2
) {
1821 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
);
1825 if (conv_ntlmssp_info
->lm_response
.contents
== NULL
|| conv_ntlmssp_info
->lm_response
.length
< 8) {
1826 memset(conv_ntlmssp_info
->client_challenge
, 0, 8);
1828 memcpy(conv_ntlmssp_info
->client_challenge
, conv_ntlmssp_info
->lm_response
.contents
, 8);
1830 create_ntlmssp_v1_key(gbl_nt_password
, conv_ntlmssp_info
->server_challenge
, conv_ntlmssp_info
->client_challenge
, sspkey
, encryptedsessionkey
, conv_ntlmssp_info
->flags
, conv_ntlmssp_info
->ntlm_response
.contents
, conv_ntlmssp_info
->lm_response
.contents
, ntlmssph
);
1832 /* ssp is the exported session key */
1833 if (memcmp(sspkey
, gbl_zeros
, NTLMSSP_KEY_LEN
) != 0) {
1834 get_sealing_rc4key(sspkey
, conv_ntlmssp_info
->flags
, &ssp_key_len
, clientkey
, serverkey
);
1835 get_siging_key((guint8
*)&conv_ntlmssp_info
->sign_key_server
, (guint8
*)&conv_ntlmssp_info
->sign_key_client
, sspkey
, ssp_key_len
);
1836 crypt_rc4_init(&conv_ntlmssp_info
->rc4_state_server
, serverkey
, ssp_key_len
);
1837 crypt_rc4_init(&conv_ntlmssp_info
->rc4_state_client
, clientkey
, ssp_key_len
);
1838 conv_ntlmssp_info
->server_dest_port
= pinfo
->destport
;
1839 conv_ntlmssp_info
->rc4_state_initialized
= 1;
1844 return MAX(offset
, data_end
);
1848 get_sign_key(packet_info
*pinfo
, int cryptpeer
)
1850 conversation_t
*conversation
;
1851 ntlmssp_info
*conv_ntlmssp_info
;
1853 conversation
= find_conversation(pinfo
->fd
->num
, &pinfo
->src
, &pinfo
->dst
,
1854 pinfo
->ptype
, pinfo
->srcport
,
1855 pinfo
->destport
, 0);
1856 if (conversation
== NULL
) {
1857 /* We don't have a conversation. In this case, stop processing
1858 because we do not have enough info to decrypt the payload */
1862 /* We have a conversation, check for encryption state */
1863 conv_ntlmssp_info
= (ntlmssp_info
*)conversation_get_proto_data(conversation
,
1865 if (conv_ntlmssp_info
== NULL
) {
1866 /* No encryption state tied to the conversation. Therefore, we
1867 cannot decrypt the payload */
1871 /* We have the encryption state in the conversation. So return the
1872 crypt state tied to the requested peer
1874 if (cryptpeer
== 1) {
1875 return (guint8
*)&conv_ntlmssp_info
->sign_key_client
;
1877 return (guint8
*)&conv_ntlmssp_info
->sign_key_server
;
1884 * Get the encryption state tied to this conversation. cryptpeer indicates
1885 * whether to retrieve the client key (1) or the server key (0)
1887 static rc4_state_struct
*
1888 get_encrypted_state(packet_info
*pinfo
, int cryptpeer
)
1890 conversation_t
*conversation
;
1891 ntlmssp_info
*conv_ntlmssp_info
;
1893 conversation
= find_conversation(pinfo
->fd
->num
, &pinfo
->src
, &pinfo
->dst
,
1894 pinfo
->ptype
, pinfo
->srcport
,
1895 pinfo
->destport
, 0);
1896 if (conversation
== NULL
) {
1897 /* We don't have a conversation. In this case, stop processing
1898 because we do not have enough info to decrypt the payload */
1902 /* We have a conversation, check for encryption state */
1903 conv_ntlmssp_info
= (ntlmssp_info
*)conversation_get_proto_data(conversation
,
1905 if (conv_ntlmssp_info
== NULL
) {
1906 /* No encryption state tied to the conversation. Therefore, we
1907 cannot decrypt the payload */
1911 /* We have the encryption state in the conversation. So return the
1912 crypt state tied to the requested peer
1914 if (cryptpeer
== 1) {
1915 return &conv_ntlmssp_info
->rc4_state_client
;
1917 return &conv_ntlmssp_info
->rc4_state_server
;
1924 decrypt_data_payload(tvbuff_t
*tvb
, int offset
, guint32 encrypted_block_length
,
1925 packet_info
*pinfo
, proto_tree
*tree _U_
, gpointer key
);
1927 decrypt_verifier(tvbuff_t
*tvb
, int offset
, guint32 encrypted_block_length
,
1928 packet_info
*pinfo
, proto_tree
*tree
, gpointer key
);
1932 dissect_ntlmssp_encrypted_payload(tvbuff_t
*data_tvb
,
1933 tvbuff_t
*auth_tvb _U_
,
1936 dcerpc_auth_info
*auth_info _U_
)
1940 dissect_ntlmssp_payload(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
1942 volatile int offset
= 0;
1943 proto_tree
*volatile ntlmssp_tree
= NULL
;
1944 proto_item
*tf
= NULL
;
1946 guint32 encrypted_block_length
;
1947 guint8 key
[NTLMSSP_KEY_LEN
];
1948 /* the magic ntlm is the identifier of a NTLMSSP packet that's 00 00 00 01 */
1949 guint32 ntlm_magic_size
= 4;
1950 guint32 ntlm_signature_size
= 8;
1951 guint32 ntlm_seq_size
= 4;
1954 length
= tvb_length (tvb
);
1955 /* signature + seq + real payload */
1956 encrypted_block_length
= length
- ntlm_magic_size
;
1958 if (encrypted_block_length
< (ntlm_signature_size
+ ntlm_seq_size
)) {
1959 /* Don't know why this would happen, but if it does, don't even bother
1960 attempting decryption/dissection */
1961 return offset
+ length
;
1964 /* Setup a new tree for the NTLMSSP payload */
1966 tf
= proto_tree_add_item (tree
,
1968 tvb
, offset
, -1, ENC_NA
);
1970 ntlmssp_tree
= proto_item_add_subtree (tf
,
1975 * Catch the ReportedBoundsError exception; the stuff we've been
1976 * handed doesn't necessarily run to the end of the packet, it's
1977 * an item inside a packet, so if it happens to be malformed (or
1978 * we, or a dissector we call, has a bug), so that an exception
1979 * is thrown, we want to report the error, but return and let
1980 * our caller dissect the rest of the packet.
1982 * If it gets a BoundsError, we can stop, as there's nothing more
1983 * in the packet after our blob to see, so we just re-throw the
1986 pd_save
= pinfo
->private_data
;
1988 /* Version number */
1989 proto_tree_add_item (ntlmssp_tree
, hf_ntlmssp_verf_vers
,
1990 tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
1993 /* Encrypted body */
1994 proto_tree_add_item (ntlmssp_tree
, hf_ntlmssp_verf_body
,
1995 tvb
, offset
, ntlm_signature_size
+ ntlm_seq_size
, ENC_NA
);
1996 memset(key
, 0, sizeof(key
));
1997 tvb_memcpy(tvb
, key
, offset
, ntlm_signature_size
+ ntlm_seq_size
);
1998 /* Try to decrypt */
1999 decrypt_data_payload (tvb
, offset
+(ntlm_signature_size
+ ntlm_seq_size
), encrypted_block_length
-(ntlm_signature_size
+ ntlm_seq_size
), pinfo
, ntlmssp_tree
, key
);
2000 decrypt_verifier (tvb
, offset
, ntlm_signature_size
+ ntlm_seq_size
, pinfo
, ntlmssp_tree
, key
);
2001 /* let's try to hook ourselves here */
2004 } CATCH_NONFATAL_ERRORS
{
2005 /* Restore the private_data structure in case one of the
2006 * called dissectors modified it (and, due to the exception,
2007 * was unable to restore it).
2009 pinfo
->private_data
= pd_save
;
2010 show_exception(tvb
, pinfo
, tree
, EXCEPT_CODE
, GET_MESSAGE
);
2017 decrypt_data_payload(tvbuff_t
*tvb
, int offset
, guint32 encrypted_block_length
,
2018 packet_info
*pinfo
, proto_tree
*tree _U_
, gpointer key
)
2020 tvbuff_t
*decr_tvb
; /* Used to display decrypted buffer */
2021 ntlmssp_packet_info
*packet_ntlmssp_info
;
2022 ntlmssp_packet_info
*stored_packet_ntlmssp_info
= NULL
;
2024 /* Check to see if we already have state for this packet */
2025 packet_ntlmssp_info
= (ntlmssp_packet_info
*)p_get_proto_data(pinfo
->fd
, proto_ntlmssp
, NTLMSSP_PACKET_INFO_KEY
);
2026 if (packet_ntlmssp_info
== NULL
) {
2027 /* We don't have any packet state, so create one */
2028 packet_ntlmssp_info
= wmem_new0(wmem_file_scope(), ntlmssp_packet_info
);
2029 p_add_proto_data(pinfo
->fd
, proto_ntlmssp
, NTLMSSP_PACKET_INFO_KEY
, packet_ntlmssp_info
);
2031 if (!packet_ntlmssp_info
->payload_decrypted
) {
2032 conversation_t
*conversation
;
2033 ntlmssp_info
*conv_ntlmssp_info
;
2035 /* Pull the challenge info from the conversation */
2036 conversation
= find_conversation(pinfo
->fd
->num
, &pinfo
->src
, &pinfo
->dst
,
2037 pinfo
->ptype
, pinfo
->srcport
,
2038 pinfo
->destport
, 0);
2039 if (conversation
== NULL
) {
2040 /* There is no conversation, thus no encryption state */
2044 conv_ntlmssp_info
= (ntlmssp_info
*)conversation_get_proto_data(conversation
,
2046 if (conv_ntlmssp_info
== NULL
) {
2047 /* There is no NTLMSSP state tied to the conversation */
2050 if (conv_ntlmssp_info
->rc4_state_initialized
!= 1) {
2051 /* The crypto sybsystem is not initialized. This means that either
2052 the conversation did not include a challenge, or that we do not have the right password */
2056 stored_packet_ntlmssp_info
= (ntlmssp_packet_info
*)g_hash_table_lookup(hash_packet
, key
);
2058 if (stored_packet_ntlmssp_info
!= NULL
&& stored_packet_ntlmssp_info
->payload_decrypted
== TRUE
) {
2059 /* Mat TBD (stderr, "Found a already decrypted packet\n");*/
2060 memcpy(packet_ntlmssp_info
, stored_packet_ntlmssp_info
, sizeof(ntlmssp_packet_info
));
2061 /* Mat TBD printnbyte(packet_ntlmssp_info->decrypted_payload, encrypted_block_length, "Data: ", "\n");*/
2064 rc4_state_struct
*rc4_state
;
2065 rc4_state_struct
*rc4_state_peer
;
2067 /* Get the pair of RC4 state structures. One is used for to decrypt the
2068 payload. The other is used to re-encrypt the payload to represent
2070 if (conv_ntlmssp_info
->server_dest_port
== pinfo
->destport
) {
2072 rc4_state
= get_encrypted_state(pinfo
, 1);
2073 rc4_state_peer
= get_encrypted_state(pinfo
, 0);
2076 rc4_state
= get_encrypted_state(pinfo
, 0);
2077 rc4_state_peer
= get_encrypted_state(pinfo
, 1);
2080 if (rc4_state
== NULL
) {
2081 /* There is no encryption state, so we cannot decrypt */
2085 /* Store the decrypted contents in the packet state struct
2086 (of course at this point, they aren't decrypted yet) */
2087 packet_ntlmssp_info
->decrypted_payload
= (guint8
*)tvb_memdup(NULL
, tvb
, offset
,
2088 encrypted_block_length
);
2089 packet_ntlmssp_info
->payload_len
= encrypted_block_length
;
2090 decrypted_payloads
= g_slist_prepend(decrypted_payloads
,
2091 packet_ntlmssp_info
->decrypted_payload
);
2093 g_hash_table_insert(hash_packet
, key
, packet_ntlmssp_info
);
2096 /* Do the decryption of the payload */
2097 crypt_rc4(rc4_state
, packet_ntlmssp_info
->decrypted_payload
,
2098 encrypted_block_length
);
2099 /* decrypt the verifier */
2100 /*printnchar(packet_ntlmssp_info->decrypted_payload, encrypted_block_length, "data: ", "\n");*/
2101 /* We setup a temporary buffer so we can re-encrypt the payload after
2102 decryption. This is to update the opposite peer's RC4 state
2103 it's useful when we have only one key for both conversation
2104 in case of KEY_EXCH we have independent key so this is not needed*/
2105 if (!(NTLMSSP_NEGOTIATE_KEY_EXCH
& conv_ntlmssp_info
->flags
)) {
2107 peer_block
= (guint8
*)wmem_memdup(wmem_packet_scope(), packet_ntlmssp_info
->decrypted_payload
, encrypted_block_length
);
2108 crypt_rc4(rc4_state_peer
, peer_block
, encrypted_block_length
);
2111 packet_ntlmssp_info
->payload_decrypted
= TRUE
;
2115 /* Show the decrypted buffer in a new window */
2116 decr_tvb
= tvb_new_child_real_data(tvb
, packet_ntlmssp_info
->decrypted_payload
,
2117 encrypted_block_length
,
2118 encrypted_block_length
);
2120 add_new_data_source(pinfo
, decr_tvb
,
2122 pinfo
->gssapi_decrypted_tvb
= decr_tvb
;
2126 dissect_ntlmssp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
2128 volatile int offset
= 0;
2129 proto_tree
*volatile ntlmssp_tree
= NULL
;
2130 proto_item
*tf
= NULL
;
2131 ntlmssp_header_t
*ntlmssph
;
2134 ntlmssph
= wmem_new(wmem_packet_scope(), ntlmssp_header_t
);
2136 ntlmssph
->domain_name
= NULL
;
2137 ntlmssph
->acct_name
= NULL
;
2138 ntlmssph
->host_name
= NULL
;
2139 memset(ntlmssph
->session_key
, 0, NTLMSSP_KEY_LEN
);
2141 /* Setup a new tree for the NTLMSSP payload */
2143 tf
= proto_tree_add_item (tree
,
2145 tvb
, offset
, -1, ENC_NA
);
2147 ntlmssp_tree
= proto_item_add_subtree (tf
,
2152 * Catch the ReportedBoundsError exception; the stuff we've been
2153 * handed doesn't necessarily run to the end of the packet, it's
2154 * an item inside a packet, so if it happens to be malformed (or
2155 * we, or a dissector we call, has a bug), so that an exception
2156 * is thrown, we want to report the error, but return and let
2157 * our caller dissect the rest of the packet.
2159 * If it gets a BoundsError, we can stop, as there's nothing more
2160 * in the packet after our blob to see, so we just re-throw the
2163 pd_save
= pinfo
->private_data
;
2165 /* NTLMSSP constant */
2166 proto_tree_add_item (ntlmssp_tree
, hf_ntlmssp_auth
,
2167 tvb
, offset
, 8, ENC_ASCII
|ENC_NA
);
2170 /* NTLMSSP Message Type */
2171 proto_tree_add_item (ntlmssp_tree
, hf_ntlmssp_message_type
,
2172 tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2173 ntlmssph
->type
= tvb_get_letohl (tvb
, offset
);
2176 col_append_sep_fstr(pinfo
->cinfo
, COL_INFO
, ", ", "%s",
2177 val_to_str_const(ntlmssph
->type
,
2178 ntlmssp_message_types
,
2179 "Unknown NTLMSSP message type"));
2181 /* Call the appropriate dissector based on the Message Type */
2182 switch (ntlmssph
->type
) {
2184 case NTLMSSP_NEGOTIATE
:
2185 dissect_ntlmssp_negotiate (tvb
, offset
, ntlmssp_tree
, ntlmssph
);
2188 case NTLMSSP_CHALLENGE
:
2189 dissect_ntlmssp_challenge (tvb
, pinfo
, offset
, ntlmssp_tree
, ntlmssph
);
2193 dissect_ntlmssp_auth (tvb
, pinfo
, offset
, ntlmssp_tree
, ntlmssph
);
2197 /* Unrecognized message type */
2198 proto_tree_add_text (ntlmssp_tree
, tvb
, offset
, -1,
2199 "Unrecognized NTLMSSP Message");
2202 } CATCH_NONFATAL_ERRORS
{
2203 /* Restore the private_data structure in case one of the
2204 * called dissectors modified it (and, due to the exception,
2205 * was unable to restore it).
2207 pinfo
->private_data
= pd_save
;
2208 show_exception(tvb
, pinfo
, tree
, EXCEPT_CODE
, GET_MESSAGE
);
2211 tap_queue_packet(ntlmssp_tap
, pinfo
, ntlmssph
);
2215 dissect_ntlmssp_heur(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*parent_tree
, void *data _U_
)
2217 if (tvb_memeql(tvb
, 0, "NTLMSSP", 8) == 0) {
2218 dissect_ntlmssp(tvb
, pinfo
, parent_tree
);
2227 * See page 45 of "DCE/RPC over SMB" by Luke Kenneth Casson Leighton.
2230 decrypt_verifier(tvbuff_t
*tvb
, int offset
, guint32 encrypted_block_length
,
2231 packet_info
*pinfo
, proto_tree
*tree
, gpointer key
)
2233 proto_tree
*decr_tree
;
2235 conversation_t
*conversation
;
2237 rc4_state_struct
*rc4_state
;
2238 rc4_state_struct
*rc4_state_peer
;
2239 tvbuff_t
*decr_tvb
; /* Used to display decrypted buffer */
2242 guint8 calculated_md5
[NTLMSSP_KEY_LEN
];
2243 ntlmssp_info
*conv_ntlmssp_info
;
2244 ntlmssp_packet_info
*packet_ntlmssp_info
;
2245 int decrypted_offset
= 0;
2247 ntlmssp_packet_info
*stored_packet_ntlmssp_info
= NULL
;
2249 packet_ntlmssp_info
= (ntlmssp_packet_info
*)p_get_proto_data(pinfo
->fd
, proto_ntlmssp
, NTLMSSP_PACKET_INFO_KEY
);
2250 if (packet_ntlmssp_info
== NULL
) {
2251 /* We don't have data for this packet */
2254 conversation
= find_conversation(pinfo
->fd
->num
, &pinfo
->src
, &pinfo
->dst
,
2255 pinfo
->ptype
, pinfo
->srcport
,
2256 pinfo
->destport
, 0);
2257 if (conversation
== NULL
) {
2258 /* There is no conversation, thus no encryption state */
2261 conv_ntlmssp_info
= (ntlmssp_info
*)conversation_get_proto_data(conversation
,
2263 if (conv_ntlmssp_info
== NULL
) {
2264 /* There is no NTLMSSP state tied to the conversation */
2269 stored_packet_ntlmssp_info
= (ntlmssp_packet_info
*)g_hash_table_lookup(hash_packet
, key
);
2271 if (stored_packet_ntlmssp_info
!= NULL
&& stored_packet_ntlmssp_info
->verifier_decrypted
== TRUE
) {
2272 /* Mat TBD fprintf(stderr, "Found a already decrypted packet\n");*/
2273 /* In Theory it's aleady the case, and we should be more clever ... like just copying buffers ...*/
2274 packet_ntlmssp_info
= stored_packet_ntlmssp_info
;
2277 if (!packet_ntlmssp_info
->verifier_decrypted
) {
2278 if (conv_ntlmssp_info
->rc4_state_initialized
!= 1) {
2279 /* The crypto sybsystem is not initialized. This means that either
2280 the conversation did not include a challenge, or we are doing
2281 something other than NTLMSSP v1 */
2284 if (conv_ntlmssp_info
->server_dest_port
== pinfo
->destport
) {
2285 /* client talk to server */
2286 rc4_state
= get_encrypted_state(pinfo
, 1);
2287 sign_key
= get_sign_key(pinfo
, 1);
2288 rc4_state_peer
= get_encrypted_state(pinfo
, 0);
2290 rc4_state
= get_encrypted_state(pinfo
, 0);
2291 sign_key
= get_sign_key(pinfo
, 0);
2292 rc4_state_peer
= get_encrypted_state(pinfo
, 1);
2295 if (rc4_state
== NULL
|| rc4_state_peer
== NULL
) {
2296 /* There is no encryption state, so we cannot decrypt */
2300 /* Setup the buffer to decrypt to */
2301 tvb_memcpy(tvb
, packet_ntlmssp_info
->verifier
,
2302 offset
, MIN(encrypted_block_length
, sizeof(packet_ntlmssp_info
->verifier
)));
2304 /*if (!(NTLMSSP_NEGOTIATE_KEY_EXCH & packet_ntlmssp_info->flags)) {*/
2305 if (conv_ntlmssp_info
->flags
& NTLMSSP_NEGOTIATE_EXTENDED_SECURITY
) {
2306 if ((NTLMSSP_NEGOTIATE_KEY_EXCH
& conv_ntlmssp_info
->flags
)) {
2307 /* The spec says that if we have have a key exchange then we have a the signature that is crypted
2308 * otherwise it's just a hmac_md5(keysign, concat(message, sequence))[0..7]
2310 crypt_rc4(rc4_state
, packet_ntlmssp_info
->verifier
, 8);
2313 * Try to check the HMAC MD5 of the message against those calculated works great with LDAP payload but
2314 * don't with DCE/RPC calls.
2315 * Some analysis need to be done ...
2317 if (sign_key
!= NULL
) {
2318 check_buf
= (guint8
*)wmem_alloc(wmem_packet_scope(), packet_ntlmssp_info
->payload_len
+4);
2319 tvb_memcpy(tvb
, &sequence
, offset
+8, 4);
2320 memcpy(check_buf
, &sequence
, 4);
2321 memcpy(check_buf
+4, packet_ntlmssp_info
->decrypted_payload
, packet_ntlmssp_info
->payload_len
);
2322 md5_hmac(check_buf
, (int)(packet_ntlmssp_info
->payload_len
+4), sign_key
, NTLMSSP_KEY_LEN
, calculated_md5
);
2324 printnbyte(packet_ntlmssp_info->verifier, 8, "HMAC from packet: ", "\n");
2325 printnbyte(calculated_md5, 8, "HMAC : ", "\n");
2330 /* 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 */
2331 /* Do the actual decryption of the verifier */
2332 crypt_rc4(rc4_state
, packet_ntlmssp_info
->verifier
,
2333 encrypted_block_length
);
2338 /* We setup a temporary buffer so we can re-encrypt the payload after
2339 decryption. This is to update the opposite peer's RC4 state
2340 This is not needed when we just have EXTENDED SECURITY because the signature is not crypted
2341 and it's also not needed when we have key exchange because server and client have independent keys */
2342 if (!(NTLMSSP_NEGOTIATE_KEY_EXCH
& conv_ntlmssp_info
->flags
) && !(NTLMSSP_NEGOTIATE_EXTENDED_SECURITY
& conv_ntlmssp_info
->flags
)) {
2343 peer_block
= (guint8
*)wmem_memdup(wmem_packet_scope(), packet_ntlmssp_info
->verifier
, encrypted_block_length
);
2344 crypt_rc4(rc4_state_peer
, peer_block
, encrypted_block_length
);
2347 /* Mark the packet as decrypted so that subsequent attempts to dissect
2348 the packet use the already decrypted payload instead of attempting
2350 packet_ntlmssp_info
->verifier_decrypted
= TRUE
;
2353 /* Show the decrypted buffer in a new window */
2354 decr_tvb
= tvb_new_child_real_data(tvb
, packet_ntlmssp_info
->verifier
,
2355 encrypted_block_length
,
2356 encrypted_block_length
);
2357 add_new_data_source(pinfo
, decr_tvb
,
2358 "Decrypted NTLMSSP Verifier");
2360 /* Show the decrypted payload in the tree */
2361 tf
= proto_tree_add_text(tree
, decr_tvb
, 0, -1,
2362 "Decrypted Verifier (%d byte%s)",
2363 encrypted_block_length
,
2364 plurality(encrypted_block_length
, "", "s"));
2365 decr_tree
= proto_item_add_subtree (tf
, ett_ntlmssp
);
2367 if (( conv_ntlmssp_info
->flags
& NTLMSSP_NEGOTIATE_EXTENDED_SECURITY
)) {
2368 proto_tree_add_item (decr_tree
, hf_ntlmssp_verf_hmacmd5
,
2369 decr_tvb
, decrypted_offset
, 8, ENC_NA
);
2370 decrypted_offset
+= 8;
2372 /* Incrementing sequence number of DCE conversation */
2373 proto_tree_add_item (decr_tree
, hf_ntlmssp_verf_sequence
,
2374 decr_tvb
, decrypted_offset
, 4, ENC_NA
);
2377 /* RANDOM PAD usually it's 0 */
2378 proto_tree_add_item (decr_tree
, hf_ntlmssp_verf_randompad
,
2379 decr_tvb
, decrypted_offset
, 4, ENC_LITTLE_ENDIAN
);
2380 decrypted_offset
+= 4;
2382 /* CRC32 of the DCE fragment data */
2383 proto_tree_add_item (decr_tree
, hf_ntlmssp_verf_crc32
,
2384 decr_tvb
, decrypted_offset
, 4, ENC_LITTLE_ENDIAN
);
2385 decrypted_offset
+= 4;
2387 /* Incrementing sequence number of DCE conversation */
2388 proto_tree_add_item (decr_tree
, hf_ntlmssp_verf_sequence
,
2389 decr_tvb
, decrypted_offset
, 4, ENC_NA
);
2393 /* Used when NTLMSSP is done over DCE/RPC because in this case verifier and real payload are not contigious*/
2395 dissect_ntlmssp_payload_only(tvbuff_t
*tvb
, packet_info
*pinfo
, _U_ proto_tree
*tree
, void *data _U_
)
2397 volatile int offset
= 0;
2398 proto_tree
*volatile ntlmssp_tree
= NULL
;
2399 guint32 encrypted_block_length
;
2402 /* the magic ntlm is the identifier of a NTLMSSP packet that's 00 00 00 01
2404 encrypted_block_length
= tvb_length (tvb
);
2405 /* signature + seq + real payload */
2407 /* Setup a new tree for the NTLMSSP payload */
2410 tf
= proto_tree_add_item (tree
,
2412 tvb
, offset
, -1, ENC_NA
);
2414 ntlmssp_tree
= proto_item_add_subtree (tf
,
2419 * Catch the ReportedBoundsError exception; the stuff we've been
2420 * handed doesn't necessarily run to the end of the packet, it's
2421 * an item inside a packet, so if it happens to be malformed (or
2422 * we, or a dissector we call, has a bug), so that an exception
2423 * is thrown, we want to report the error, but return and let
2424 * our caller dissect the rest of the packet.
2426 * If it gets a BoundsError, we can stop, as there's nothing more
2427 * in the packet after our blob to see, so we just re-throw the
2430 pd_save
= pinfo
->private_data
;
2432 /* Version number */
2434 /* Try to decrypt */
2435 decrypt_data_payload (tvb
, offset
, encrypted_block_length
, pinfo
, ntlmssp_tree
, NULL
);
2436 /* let's try to hook ourselves here */
2438 } CATCH_NONFATAL_ERRORS
{
2439 /* Restore the private_data structure in case one of the
2440 * called dissectors modified it (and, due to the exception,
2441 * was unable to restore it).
2443 pinfo
->private_data
= pd_save
;
2444 show_exception(tvb
, pinfo
, tree
, EXCEPT_CODE
, GET_MESSAGE
);
2450 /* Used when NTLMSSP is done over DCE/RPC because in this case verifier and real payload are not contigious
2451 * But in fact this function could be merged with wrap_dissect_ntlmssp_verf because it's only used there
2454 dissect_ntlmssp_verf(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
2456 volatile int offset
= 0;
2457 proto_tree
*volatile ntlmssp_tree
= NULL
;
2458 proto_item
*tf
= NULL
;
2459 guint32 verifier_length
;
2460 guint32 encrypted_block_length
;
2463 verifier_length
= tvb_length (tvb
);
2464 encrypted_block_length
= verifier_length
- 4;
2466 if (encrypted_block_length
< 12) {
2467 /* Don't know why this would happen, but if it does, don't even bother
2468 attempting decryption/dissection */
2469 return offset
+ verifier_length
;
2472 /* Setup a new tree for the NTLMSSP payload */
2474 tf
= proto_tree_add_item (tree
,
2476 tvb
, offset
, -1, ENC_NA
);
2478 ntlmssp_tree
= proto_item_add_subtree (tf
,
2483 * Catch the ReportedBoundsError exception; the stuff we've been
2484 * handed doesn't necessarily run to the end of the packet, it's
2485 * an item inside a packet, so if it happens to be malformed (or
2486 * we, or a dissector we call, has a bug), so that an exception
2487 * is thrown, we want to report the error, but return and let
2488 * our caller dissect the rest of the packet.
2490 * If it gets a BoundsError, we can stop, as there's nothing more
2491 * in the packet after our blob to see, so we just re-throw the
2494 pd_save
= pinfo
->private_data
;
2496 /* Version number */
2497 proto_tree_add_item (ntlmssp_tree
, hf_ntlmssp_verf_vers
,
2498 tvb
, offset
, 4, ENC_LITTLE_ENDIAN
);
2501 /* Encrypted body */
2502 proto_tree_add_item (ntlmssp_tree
, hf_ntlmssp_verf_body
,
2503 tvb
, offset
, encrypted_block_length
, ENC_NA
);
2505 /* Try to decrypt */
2506 decrypt_verifier (tvb
, offset
, encrypted_block_length
, pinfo
, ntlmssp_tree
, NULL
);
2507 /* let's try to hook ourselves here */
2510 offset
+= encrypted_block_length
;
2511 } CATCH_NONFATAL_ERRORS
{
2512 /* Restore the private_data structure in case one of the
2513 * called dissectors modified it (and, due to the exception,
2514 * was unable to restore it).
2516 pinfo
->private_data
= pd_save
;
2517 show_exception(tvb
, pinfo
, tree
, EXCEPT_CODE
, GET_MESSAGE
);
2524 wrap_dissect_ntlmssp_payload_only(tvbuff_t
*tvb
, tvbuff_t
*auth_tvb _U_
,
2525 int offset
, packet_info
*pinfo
, dcerpc_auth_info
*auth_info _U_
)
2529 data_tvb
= tvb_new_subset_remaining(tvb
, offset
);
2530 dissect_ntlmssp_payload_only(data_tvb
, pinfo
, NULL
, NULL
);
2531 return pinfo
->gssapi_decrypted_tvb
;
2536 dissect_ntlmssp_encrypted_payload(tvbuff_t
*data_tvb
,
2537 tvbuff_t
*auth_tvb _U_
,
2540 dcerpc_auth_info
*auth_info _U_
)
2542 /* gssapi_decrypted_tvb = NULL */
2543 tvbuff_t
*decr_tvb
; /* Used to display decrypted buffer */
2545 conversation_t
*conversation
;
2546 guint32 encrypted_block_length
;
2547 rc4_state_struct
*rc4_state
;
2548 rc4_state_struct
*rc4_state_peer
;
2549 ntlmssp_info
*conv_ntlmssp_info
= NULL
;
2550 ntlmssp_packet_info
*packet_ntlmssp_info
;
2552 encrypted_block_length
= tvb_length_remaining (data_tvb
, offset
);
2554 fprintf(stderr
, "Called dissect_ntlmssp_encrypted_payload\n");
2555 /* Check to see if we already have state for this packet */
2556 packet_ntlmssp_info
= p_get_proto_data(pinfo
->fd
, proto_ntlmssp
, NTLMSSP_PACKET_INFO_KEY
);
2557 if (packet_ntlmssp_info
== NULL
) {
2558 /* We don't have any packet state, so create one */
2559 packet_ntlmssp_info
= wmem_new0(wmem_file_scope(), ntlmssp_packet_info
);
2560 p_add_proto_data(pinfo
->fd
, proto_ntlmssp
, NTLMSSP_PACKET_INFO_KEY
, packet_ntlmssp_info
);
2563 if (!packet_ntlmssp_info
->payload_decrypted
) {
2564 /* Pull the challenge info from the conversation */
2565 conversation
= find_conversation(pinfo
->fd
->num
, &pinfo
->src
, &pinfo
->dst
,
2566 pinfo
->ptype
, pinfo
->srcport
,
2567 pinfo
->destport
, 0);
2568 if (conversation
== NULL
) {
2569 /* There is no conversation, thus no encryption state */
2573 conv_ntlmssp_info
= conversation_get_proto_data(conversation
,
2575 if (conv_ntlmssp_info
== NULL
) {
2576 /* There is no NTLMSSP state tied to the conversation */
2579 /* Get the pair of RC4 state structures. One is used for to decrypt the
2580 payload. The other is used to re-encrypt the payload to represent
2582 if (conv_ntlmssp_info
->server_dest_port
== pinfo
->destport
) {
2583 rc4_state
= get_encrypted_state(pinfo
, 1);
2584 rc4_state_peer
= get_encrypted_state(pinfo
, 0);
2586 rc4_state
= get_encrypted_state(pinfo
, 0);
2587 rc4_state_peer
= get_encrypted_state(pinfo
, 1);
2590 if (rc4_state
== NULL
|| rc4_state_peer
== NULL
) {
2591 /* There is no encryption state, so we cannot decrypt */
2595 /* Store the decrypted contents in the packet state struct
2596 (of course at this point, they aren't decrypted yet) */
2597 packet_ntlmssp_info
->decrypted_payload
= tvb_memdup(NULL
, data_tvb
, offset
,
2598 encrypted_block_length
);
2599 decrypted_payloads
= g_slist_prepend(decrypted_payloads
,
2600 packet_ntlmssp_info
->decrypted_payload
);
2602 /* Do the decryption of the payload */
2603 crypt_rc4(rc4_state
, packet_ntlmssp_info
->decrypted_payload
,
2604 encrypted_block_length
);
2606 /* We setup a temporary buffer so we can re-encrypt the payload after
2607 decryption. This is to update the opposite peer's RC4 state */
2608 peer_block
= wmem_memdup(wmem_packet_scope(), packet_ntlmssp_info
->decrypted_payload
, encrypted_block_length
);
2609 crypt_rc4(rc4_state_peer
, peer_block
, encrypted_block_length
);
2611 packet_ntlmssp_info
->payload_decrypted
= TRUE
;
2614 /* Show the decrypted buffer in a new window */
2615 decr_tvb
= tvb_new_child_real_data(data_tvb
, packet_ntlmssp_info
->decrypted_payload
,
2616 encrypted_block_length
,
2617 encrypted_block_length
);
2619 offset
+= encrypted_block_length
;
2626 free_payload(gpointer decrypted_payload
, gpointer user_data _U_
)
2628 g_free(decrypted_payload
);
2632 header_hash(gconstpointer pointer
)
2634 guint32 crc
= ~crc32c_calculate(pointer
, NTLMSSP_KEY_LEN
, CRC32C_PRELOAD
);
2635 /* Mat TBD fprintf(stderr, "Val: %u\n", crc);*/
2640 header_equal(gconstpointer pointer1
, gconstpointer pointer2
)
2642 if (!memcmp(pointer1
, pointer2
, 16)) {
2651 ntlmssp_init_protocol(void)
2654 * Free the decrypted payloads, and then free the list of decrypted
2657 if (decrypted_payloads
!= NULL
) {
2658 g_slist_foreach(decrypted_payloads
, free_payload
, NULL
);
2659 g_slist_free(decrypted_payloads
);
2660 decrypted_payloads
= NULL
;
2663 if (hash_packet
!= NULL
) {
2664 g_hash_table_remove_all(hash_packet
);
2666 hash_packet
= g_hash_table_new(header_hash
, header_equal
);
2673 wrap_dissect_ntlmssp(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
,
2674 proto_tree
*tree
, dcerpc_info
*di _U_
, guint8
*drep _U_
)
2678 auth_tvb
= tvb_new_subset_remaining(tvb
, offset
);
2680 dissect_ntlmssp(auth_tvb
, pinfo
, tree
);
2682 return tvb_length_remaining(tvb
, offset
);
2686 wrap_dissect_ntlmssp_verf(tvbuff_t
*tvb
, int offset
, packet_info
*pinfo
,
2687 proto_tree
*tree
, dcerpc_info
*di _U_
, guint8
*drep _U_
)
2691 auth_tvb
= tvb_new_subset_remaining(tvb
, offset
);
2692 return dissect_ntlmssp_verf(auth_tvb
, pinfo
, tree
, NULL
);
2695 static dcerpc_auth_subdissector_fns ntlmssp_sign_fns
= {
2696 wrap_dissect_ntlmssp
, /* Bind */
2697 wrap_dissect_ntlmssp
, /* Bind ACK */
2698 wrap_dissect_ntlmssp
, /* AUTH3 */
2699 wrap_dissect_ntlmssp_verf
, /* Request verifier */
2700 wrap_dissect_ntlmssp_verf
, /* Response verifier */
2701 NULL
, /* Request data */
2702 NULL
/* Response data */
2705 static dcerpc_auth_subdissector_fns ntlmssp_seal_fns
= {
2706 wrap_dissect_ntlmssp
, /* Bind */
2707 wrap_dissect_ntlmssp
, /* Bind ACK */
2708 wrap_dissect_ntlmssp
, /* AUTH3 */
2709 wrap_dissect_ntlmssp_verf
, /* Request verifier */
2710 wrap_dissect_ntlmssp_verf
, /* Response verifier */
2711 wrap_dissect_ntlmssp_payload_only
, /* Request data */
2712 wrap_dissect_ntlmssp_payload_only
/* Response data */
2716 proto_register_ntlmssp(void)
2719 static hf_register_info hf
[] = {
2721 { "NTLMSSP identifier", "ntlmssp.identifier",
2722 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2725 { &hf_ntlmssp_message_type
,
2726 { "NTLM Message Type", "ntlmssp.messagetype",
2727 FT_UINT32
, BASE_HEX
, VALS(ntlmssp_message_types
), 0x0,
2730 { &hf_ntlmssp_negotiate_flags
,
2731 { "Negotiate Flags", "ntlmssp.negotiateflags",
2732 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
2735 { &hf_ntlmssp_negotiate_flags_01
,
2736 { "Negotiate UNICODE", "ntlmssp.negotiateunicode",
2737 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_NEGOTIATE_UNICODE
,
2740 { &hf_ntlmssp_negotiate_flags_02
,
2741 { "Negotiate OEM", "ntlmssp.negotiateoem",
2742 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_NEGOTIATE_OEM
,
2745 { &hf_ntlmssp_negotiate_flags_04
,
2746 { "Request Target", "ntlmssp.requesttarget",
2747 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_REQUEST_TARGET
,
2750 { &hf_ntlmssp_negotiate_flags_08
,
2751 { "Request 0x00000008", "ntlmssp.negotiate00000008",
2752 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_NEGOTIATE_00000008
,
2755 { &hf_ntlmssp_negotiate_flags_10
,
2756 { "Negotiate Sign", "ntlmssp.negotiatesign",
2757 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_NEGOTIATE_SIGN
,
2760 { &hf_ntlmssp_negotiate_flags_20
,
2761 { "Negotiate Seal", "ntlmssp.negotiateseal",
2762 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_NEGOTIATE_SEAL
,
2765 { &hf_ntlmssp_negotiate_flags_40
,
2766 { "Negotiate Datagram", "ntlmssp.negotiatedatagram",
2767 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_NEGOTIATE_DATAGRAM
,
2770 { &hf_ntlmssp_negotiate_flags_80
,
2771 { "Negotiate Lan Manager Key", "ntlmssp.negotiatelmkey",
2772 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_NEGOTIATE_LM_KEY
,
2775 { &hf_ntlmssp_negotiate_flags_100
,
2776 { "Negotiate 0x00000100", "ntlmssp.negotiate00000100",
2777 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_NEGOTIATE_00000100
,
2780 { &hf_ntlmssp_negotiate_flags_200
,
2781 { "Negotiate NTLM key", "ntlmssp.negotiatentlm",
2782 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_NEGOTIATE_NTLM
,
2785 { &hf_ntlmssp_negotiate_flags_400
,
2786 { "Negotiate NT Only", "ntlmssp.negotiatentonly",
2787 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_NEGOTIATE_NT_ONLY
,
2790 { &hf_ntlmssp_negotiate_flags_800
,
2791 { "Negotiate Anonymous", "ntlmssp.negotiateanonymous",
2792 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_NEGOTIATE_ANONYMOUS
,
2795 { &hf_ntlmssp_negotiate_flags_1000
,
2796 { "Negotiate OEM Domain Supplied", "ntlmssp.negotiateoemdomainsupplied",
2797 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED
,
2800 { &hf_ntlmssp_negotiate_flags_2000
,
2801 { "Negotiate OEM Workstation Supplied", "ntlmssp.negotiateoemworkstationsupplied",
2802 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED
,
2805 { &hf_ntlmssp_negotiate_flags_4000
,
2806 { "Negotiate 0x00004000", "ntlmssp.negotiate00004000",
2807 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_NEGOTIATE_00004000
,
2810 { &hf_ntlmssp_negotiate_flags_8000
,
2811 { "Negotiate Always Sign", "ntlmssp.negotiatealwayssign",
2812 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_NEGOTIATE_ALWAYS_SIGN
,
2815 { &hf_ntlmssp_negotiate_flags_10000
,
2816 { "Target Type Domain", "ntlmssp.targettypedomain",
2817 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_TARGET_TYPE_DOMAIN
,
2820 { &hf_ntlmssp_negotiate_flags_20000
,
2821 { "Target Type Server", "ntlmssp.targettypeserver",
2822 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_TARGET_TYPE_SERVER
,
2825 { &hf_ntlmssp_negotiate_flags_40000
,
2826 { "Target Type Share", "ntlmssp.targettypeshare",
2827 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_TARGET_TYPE_SHARE
,
2831 /* Negotiate Flags */
2832 { &hf_ntlmssp_negotiate_flags_80000
,
2833 { "Negotiate Extended Security", "ntlmssp.negotiatentlm2",
2834 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_NEGOTIATE_EXTENDED_SECURITY
,
2837 { &hf_ntlmssp_negotiate_flags_100000
,
2838 { "Negotiate Identify", "ntlmssp.negotiateidentify",
2839 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_NEGOTIATE_IDENTIFY
,
2842 { &hf_ntlmssp_negotiate_flags_200000
,
2843 { "Negotiate 0x00200000", "ntlmssp.negotiatent00200000",
2844 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_NEGOTIATE_00200000
,
2847 { &hf_ntlmssp_negotiate_flags_400000
,
2848 { "Request Non-NT Session", "ntlmssp.requestnonntsession",
2849 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_REQUEST_NON_NT_SESSION
,
2852 { &hf_ntlmssp_negotiate_flags_800000
,
2853 { "Negotiate Target Info", "ntlmssp.negotiatetargetinfo",
2854 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_NEGOTIATE_TARGET_INFO
,
2857 { &hf_ntlmssp_negotiate_flags_1000000
,
2858 { "Negotiate 0x01000000", "ntlmssp.negotiatent01000000",
2859 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_NEGOTIATE_01000000
,
2862 { &hf_ntlmssp_negotiate_flags_2000000
,
2863 { "Negotiate Version", "ntlmssp.negotiateversion",
2864 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_NEGOTIATE_VERSION
,
2867 { &hf_ntlmssp_negotiate_flags_4000000
,
2868 { "Negotiate 0x04000000", "ntlmssp.negotiatent04000000",
2869 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_NEGOTIATE_04000000
,
2872 { &hf_ntlmssp_negotiate_flags_8000000
,
2873 { "Negotiate 0x08000000", "ntlmssp.negotiatent08000000",
2874 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_NEGOTIATE_08000000
,
2877 { &hf_ntlmssp_negotiate_flags_10000000
,
2878 { "Negotiate 0x10000000", "ntlmssp.negotiatent10000000",
2879 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_NEGOTIATE_10000000
,
2882 { &hf_ntlmssp_negotiate_flags_20000000
,
2883 { "Negotiate 128", "ntlmssp.negotiate128",
2884 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_NEGOTIATE_128
,
2885 "128-bit encryption is supported", HFILL
}
2887 { &hf_ntlmssp_negotiate_flags_40000000
,
2888 { "Negotiate Key Exchange", "ntlmssp.negotiatekeyexch",
2889 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_NEGOTIATE_KEY_EXCH
,
2892 { &hf_ntlmssp_negotiate_flags_80000000
,
2893 { "Negotiate 56", "ntlmssp.negotiate56",
2894 FT_BOOLEAN
, 32, TFS (&tfs_set_notset
), NTLMSSP_NEGOTIATE_56
,
2895 "56-bit encryption is supported", HFILL
}
2898 { &hf_ntlmssp_negotiate_workstation_strlen
,
2899 { "Calling workstation name length", "ntlmssp.negotiate.callingworkstation.strlen",
2900 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2905 { &hf_ntlmssp_negotiate_workstation_maxlen
,
2906 { "Calling workstation name max length", "ntlmssp.negotiate.callingworkstation.maxlen",
2907 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2912 { &hf_ntlmssp_negotiate_workstation_buffer
,
2913 { "Calling workstation name buffer", "ntlmssp.negotiate.callingworkstation.buffer",
2914 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
2918 { &hf_ntlmssp_negotiate_workstation
,
2919 { "Calling workstation name", "ntlmssp.negotiate.callingworkstation",
2920 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2924 { &hf_ntlmssp_negotiate_domain_strlen
,
2925 { "Calling workstation domain length", "ntlmssp.negotiate.domain.strlen",
2926 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2931 { &hf_ntlmssp_negotiate_domain_maxlen
,
2932 { "Calling workstation domain max length", "ntlmssp.negotiate.domain.maxlen",
2933 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
2938 { &hf_ntlmssp_negotiate_domain_buffer
,
2939 { "Calling workstation domain buffer", "ntlmssp.negotiate.domain.buffer",
2940 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
2944 { &hf_ntlmssp_negotiate_domain
,
2945 { "Calling workstation domain", "ntlmssp.negotiate.domain",
2946 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2949 { &hf_ntlmssp_ntlm_client_challenge
,
2950 { "NTLM Client Challenge", "ntlmssp.ntlmclientchallenge",
2951 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2954 { &hf_ntlmssp_ntlm_server_challenge
,
2955 { "NTLM Server Challenge", "ntlmssp.ntlmserverchallenge",
2956 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2959 { &hf_ntlmssp_reserved
,
2960 { "Reserved", "ntlmssp.reserved",
2961 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2965 { &hf_ntlmssp_challenge_target_name
,
2966 { "Target Name", "ntlmssp.challenge.target_name",
2967 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2970 { &hf_ntlmssp_auth_domain
,
2971 { "Domain name", "ntlmssp.auth.domain",
2972 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2975 { &hf_ntlmssp_auth_username
,
2976 { "User name", "ntlmssp.auth.username",
2977 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2980 { &hf_ntlmssp_auth_hostname
,
2981 { "Host name", "ntlmssp.auth.hostname",
2982 FT_STRING
, BASE_NONE
, NULL
, 0x0,
2985 { &hf_ntlmssp_auth_lmresponse
,
2986 { "Lan Manager Response", "ntlmssp.auth.lmresponse",
2987 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2990 { &hf_ntlmssp_auth_ntresponse
,
2991 { "NTLM Response", "ntlmssp.auth.ntresponse",
2992 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
2995 { &hf_ntlmssp_auth_sesskey
,
2996 { "Session Key", "ntlmssp.auth.sesskey",
2997 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3000 { &hf_ntlmssp_string_len
,
3001 { "Length", "ntlmssp.string.length",
3002 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3005 { &hf_ntlmssp_string_maxlen
,
3006 { "Maxlen", "ntlmssp.string.maxlen",
3007 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3010 { &hf_ntlmssp_string_offset
,
3011 { "Offset", "ntlmssp.string.offset",
3012 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3015 { &hf_ntlmssp_blob_len
,
3016 { "Length", "ntlmssp.blob.length",
3017 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3020 { &hf_ntlmssp_blob_maxlen
,
3021 { "Maxlen", "ntlmssp.blob.maxlen",
3022 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3025 { &hf_ntlmssp_blob_offset
,
3026 { "Offset", "ntlmssp.blob.offset",
3027 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3030 { &hf_ntlmssp_version
,
3031 { "Version", "ntlmssp.version",
3032 FT_NONE
, BASE_NONE
, NULL
, 0x0,
3035 { &hf_ntlmssp_version_major
,
3036 { "Major Version", "ntlmssp.version.major",
3037 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3040 { &hf_ntlmssp_version_minor
,
3041 { "Minor Version", "ntlmssp.version.minor",
3042 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3045 { &hf_ntlmssp_version_build_number
,
3046 { "Build Number", "ntlmssp.version.build_number",
3047 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3050 { &hf_ntlmssp_version_ntlm_current_revision
,
3051 { "NTLM Current Revision", "ntlmssp.version.ntlm_current_revision",
3052 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3057 { &hf_ntlmssp_challenge_target_info
,
3058 { "Target Info", "ntlmssp.challenge.target_info",
3059 FT_NONE
, BASE_NONE
, NULL
, 0x0,
3062 { &hf_ntlmssp_challenge_target_info_len
,
3063 { "Length", "ntlmssp.challenge.target_info.length",
3064 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3067 { &hf_ntlmssp_challenge_target_info_maxlen
,
3068 { "Maxlen", "ntlmssp.challenge.target_info.maxlen",
3069 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3072 { &hf_ntlmssp_challenge_target_info_offset
,
3073 { "Offset", "ntlmssp.challenge.target_info.offset",
3074 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3078 { &hf_ntlmssp_challenge_target_info_item_type
,
3079 { "Target Info Item Type", "ntlmssp.challenge.target_info.item.type",
3080 FT_UINT16
, BASE_HEX
, VALS(ntlm_name_types
), 0x0,
3083 { &hf_ntlmssp_challenge_target_info_item_len
,
3084 { "Target Info Item Length", "ntlmssp.challenge.target_info.item.length",
3085 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3089 { &hf_ntlmssp_challenge_target_info_end
,
3090 { "List End", "ntlmssp.challenge.target_info.end",
3091 FT_NONE
, BASE_NONE
, NULL
, 0x0,
3094 { &hf_ntlmssp_challenge_target_info_nb_computer_name
,
3095 { "NetBIOS Computer Name", "ntlmssp.challenge.target_info.nb_computer_name",
3096 FT_STRING
, BASE_NONE
, NULL
, 0x0,
3097 "Server NetBIOS Computer Name", HFILL
}
3099 { &hf_ntlmssp_challenge_target_info_nb_domain_name
,
3100 { "NetBIOS Domain Name", "ntlmssp.challenge.target_info.nb_domain_name",
3101 FT_STRING
, BASE_NONE
, NULL
, 0x0,
3102 "Server NetBIOS Domain Name", HFILL
}
3104 { &hf_ntlmssp_challenge_target_info_dns_computer_name
,
3105 { "DNS Computer Name", "ntlmssp.challenge.target_info.dns_computer_name",
3106 FT_STRING
, BASE_NONE
, NULL
, 0x0,
3109 { &hf_ntlmssp_challenge_target_info_dns_domain_name
,
3110 { "DNS Domain Name", "ntlmssp.challenge.target_info.dns_domain_name",
3111 FT_STRING
, BASE_NONE
, NULL
, 0x0,
3114 { &hf_ntlmssp_challenge_target_info_dns_tree_name
,
3115 { "DNS Tree Name", "ntlmssp.challenge.target_info.dns_tree_name",
3116 FT_STRING
, BASE_NONE
, NULL
, 0x0,
3119 { &hf_ntlmssp_challenge_target_info_flags
,
3120 { "Flags", "ntlmssp.challenge.target_info.flags",
3121 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3124 { &hf_ntlmssp_challenge_target_info_timestamp
,
3125 { "Timestamp", "ntlmssp.challenge.target_info.timestamp",
3126 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0,
3129 { &hf_ntlmssp_challenge_target_info_restrictions
,
3130 { "Restrictions", "ntlmssp.challenge.target_info.restrictions",
3131 FT_BYTES
, BASE_NONE
, NULL
, 0,
3134 { &hf_ntlmssp_challenge_target_info_target_name
,
3135 { "Target Name", "ntlmssp.challenge.target_info.target_name",
3136 FT_STRING
, BASE_NONE
, NULL
, 0x0,
3139 { &hf_ntlmssp_challenge_target_info_channel_bindings
,
3140 { "Channel Bindings", "ntlmssp.challenge.target_info.channel_bindings",
3141 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3145 { &hf_ntlmssp_ntlmv2_response_item_type
,
3146 { "NTLMV2 Response Item Type", "ntlmssp.ntlmv2_response.item.type",
3147 FT_UINT16
, BASE_HEX
, VALS(ntlm_name_types
), 0x0,
3150 { &hf_ntlmssp_ntlmv2_response_item_len
,
3151 { "NTLMV2 Response Item Length", "ntlmssp.ntlmv2_response.item.length",
3152 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
3156 { &hf_ntlmssp_ntlmv2_response_end
,
3157 { "List End", "ntlmssp.ntlmv2_response.end",
3158 FT_NONE
, BASE_NONE
, NULL
, 0x0,
3161 { &hf_ntlmssp_ntlmv2_response_nb_computer_name
,
3162 { "NetBIOS Computer Name", "ntlmssp.ntlmv2_response.nb_computer_name",
3163 FT_STRING
, BASE_NONE
, NULL
, 0x0,
3164 "Server NetBIOS Computer Name", HFILL
}
3166 { &hf_ntlmssp_ntlmv2_response_nb_domain_name
,
3167 { "NetBIOS Domain Name", "ntlmssp.ntlmv2_response.nb_domain_name",
3168 FT_STRING
, BASE_NONE
, NULL
, 0x0,
3169 "Server NetBIOS Domain Name", HFILL
}
3171 { &hf_ntlmssp_ntlmv2_response_dns_computer_name
,
3172 { "DNS Computer Name", "ntlmssp.ntlmv2_response.dns_computer_name",
3173 FT_STRING
, BASE_NONE
, NULL
, 0x0,
3176 { &hf_ntlmssp_ntlmv2_response_dns_domain_name
,
3177 { "DNS Domain Name", "ntlmssp.ntlmv2_response.dns_domain_name",
3178 FT_STRING
, BASE_NONE
, NULL
, 0x0,
3181 { &hf_ntlmssp_ntlmv2_response_dns_tree_name
,
3182 { "DNS Tree Name", "ntlmssp.ntlmv2_response.dns_tree_name",
3183 FT_STRING
, BASE_NONE
, NULL
, 0x0,
3186 { &hf_ntlmssp_ntlmv2_response_flags
,
3187 { "Flags", "ntlmssp.ntlmv2_response.flags",
3188 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3191 { &hf_ntlmssp_ntlmv2_response_timestamp
,
3192 { "Timestamp", "ntlmssp.ntlmv2_response.timestamp",
3193 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_LOCAL
, NULL
, 0,
3196 { &hf_ntlmssp_ntlmv2_response_restrictions
,
3197 { "Restrictions", "ntlmssp.ntlmv2_response.restrictions",
3198 FT_BYTES
, BASE_NONE
, NULL
, 0,
3201 { &hf_ntlmssp_ntlmv2_response_target_name
,
3202 { "Target Name", "ntlmssp.ntlmv2_response.target_name",
3203 FT_STRING
, BASE_NONE
, NULL
, 0x0,
3206 { &hf_ntlmssp_ntlmv2_response_channel_bindings
,
3207 { "Channel Bindings", "ntlmssp.ntlmv2_response.channel_bindings",
3208 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3212 { &hf_ntlmssp_message_integrity_code
,
3213 { "MIC", "ntlmssp.authenticate.mic",
3214 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3215 "Message Integrity Code", HFILL
}
3218 { "NTLMSSP Verifier", "ntlmssp.verf",
3219 FT_NONE
, BASE_NONE
, NULL
, 0x0,
3222 { &hf_ntlmssp_verf_vers
,
3223 { "Version Number", "ntlmssp.verf.vers",
3224 FT_UINT32
, BASE_DEC
, NULL
, 0x0,
3227 { &hf_ntlmssp_verf_body
,
3228 { "Verifier Body", "ntlmssp.verf.body",
3229 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3233 { &hf_ntlmssp_decrypted_payload
,
3234 { "NTLM Decrypted Payload", "ntlmssp.decrypted_payload",
3235 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3239 { &hf_ntlmssp_verf_randompad
,
3240 { "Random Pad", "ntlmssp.verf.randompad",
3241 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3244 { &hf_ntlmssp_verf_crc32
,
3245 { "Verifier CRC32", "ntlmssp.verf.crc32",
3246 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
3249 { &hf_ntlmssp_verf_hmacmd5
,
3250 { "HMAC MD5", "ntlmssp.verf.hmacmd5",
3251 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3254 { &hf_ntlmssp_verf_sequence
,
3255 { "Sequence", "ntlmssp.verf.sequence",
3256 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3260 { &hf_ntlmssp_ntlmv2_response
,
3261 { "NTLMv2 Response", "ntlmssp.ntlmv2_response",
3262 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3265 { &hf_ntlmssp_ntlmv2_response_ntproofstr
,
3266 { "NTProofStr", "ntlmssp.ntlmv2_response.ntproofstr",
3267 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3268 "The HMAC-MD5 of the challenge", HFILL
}
3270 { &hf_ntlmssp_ntlmv2_response_rversion
,
3271 { "Response Version", "ntlmssp.ntlmv2_response.rversion",
3272 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3273 "The 1-byte response version, currently set to 1", HFILL
}
3275 { &hf_ntlmssp_ntlmv2_response_hirversion
,
3276 { "Hi Response Version", "ntlmssp.ntlmv2_response.hirversion",
3277 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
3278 "The 1-byte highest response version understood by the client, currently set to 1", HFILL
}
3280 { &hf_ntlmssp_ntlmv2_response_z
,
3281 { "Z", "ntlmssp.ntlmv2_response.z",
3282 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3283 "byte array of zero bytes", HFILL
}
3285 { &hf_ntlmssp_ntlmv2_response_pad
,
3286 { "padding", "ntlmssp.ntlmv2_response.pad",
3287 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3290 { &hf_ntlmssp_ntlmv2_response_time
,
3291 { "Time", "ntlmssp.ntlmv2_response.time",
3292 FT_ABSOLUTE_TIME
, ABSOLUTE_TIME_UTC
, NULL
, 0,
3293 "The 8-byte little-endian time in UTC", HFILL
}
3295 { &hf_ntlmssp_ntlmv2_response_chal
,
3296 { "Client Challenge", "ntlmssp.ntlmv2_response.chal",
3297 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
3298 "The 8-byte challenge message generated by the client", HFILL
}
3303 static gint
*ett
[] = {
3305 &ett_ntlmssp_negotiate_flags
,
3306 &ett_ntlmssp_string
,
3308 &ett_ntlmssp_version
,
3309 &ett_ntlmssp_challenge_target_info
,
3310 &ett_ntlmssp_challenge_target_info_item
,
3311 &ett_ntlmssp_ntlmv2_response
,
3312 &ett_ntlmssp_ntlmv2_response_item
,
3314 static ei_register_info ei
[] = {
3315 { &ei_ntlmssp_v2_key_too_long
, { "ntlmssp.v2_key_too_long", PI_UNDECODED
, PI_WARN
, "NTLM v2 key is too long", EXPFILL
}},
3316 { &ei_ntlmssp_blob_len_too_long
, { "ntlmssp.blob.length.too_long", PI_UNDECODED
, PI_WARN
, "Session blob length too long", EXPFILL
}},
3317 { &ei_ntlmssp_target_info_attr
, { "ntlmssp.target_info_attr.unknown", PI_UNDECODED
, PI_WARN
, "unknown NTLMSSP Target Info Attribute", EXPFILL
}},
3319 module_t
*ntlmssp_module
;
3320 expert_module_t
* expert_ntlmssp
;
3322 proto_ntlmssp
= proto_register_protocol (
3323 "NTLM Secure Service Provider", /* name */
3324 "NTLMSSP", /* short name */
3325 "ntlmssp" /* abbrev */
3327 proto_register_field_array (proto_ntlmssp
, hf
, array_length (hf
));
3328 proto_register_subtree_array (ett
, array_length (ett
));
3329 expert_ntlmssp
= expert_register_protocol(proto_ntlmssp
);
3330 expert_register_field_array(expert_ntlmssp
, ei
, array_length(ei
));
3331 register_init_routine(&ntlmssp_init_protocol
);
3333 ntlmssp_module
= prefs_register_protocol(proto_ntlmssp
, NULL
);
3335 prefs_register_string_preference(ntlmssp_module
, "nt_password",
3337 "NT Password (used to decrypt payloads)",
3340 register_dissector("ntlmssp", dissect_ntlmssp
, proto_ntlmssp
);
3341 new_register_dissector("ntlmssp_payload", dissect_ntlmssp_payload
, proto_ntlmssp
);
3342 new_register_dissector("ntlmssp_data_only", dissect_ntlmssp_payload_only
, proto_ntlmssp
);
3343 new_register_dissector("ntlmssp_verf", dissect_ntlmssp_verf
, proto_ntlmssp
);
3347 proto_reg_handoff_ntlmssp(void)
3349 dissector_handle_t ntlmssp_handle
, ntlmssp_wrap_handle
;
3351 /* Register protocol with the GSS-API module */
3353 ntlmssp_handle
= find_dissector("ntlmssp");
3354 ntlmssp_wrap_handle
= find_dissector("ntlmssp_verf");
3355 gssapi_init_oid("1.3.6.1.4.1.311.2.2.10", proto_ntlmssp
, ett_ntlmssp
,
3356 ntlmssp_handle
, ntlmssp_wrap_handle
,
3357 "NTLMSSP - Microsoft NTLM Security Support Provider");
3359 /* Register authenticated pipe dissector */
3362 * XXX - the verifiers here seem to have a version of 1 and a body of all
3365 * XXX - DCE_C_AUTHN_LEVEL_CONNECT is, according to the DCE RPC 1.1
3366 * spec, upgraded to DCE_C_AUTHN_LEVEL_PKT. Should we register
3367 * any other levels here?
3369 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_CONNECT
,
3370 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP
,
3373 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT
,
3374 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP
,
3377 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY
,
3378 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP
,
3381 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY
,
3382 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP
,
3384 ntlmssp_tap
= register_tap("ntlmssp");
3386 heur_dissector_add("credssp", dissect_ntlmssp_heur
, proto_ntlmssp
);
3391 * Editor modelines - http://www.wireshark.org/tools/modelines.html
3396 * indent-tabs-mode: nil
3399 * vi: set shiftwidth=2 tabstop=8 expandtab:
3400 * :indentSize=2:tabSize=8:noTabs=true: