1 /* packet-ntlmssp.c 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> 7 * 8 * Wireshark - Network traffic analyzer 9 * By Gerald Combs <gerald@wireshark.org> 10 * Copyright 1998 Gerald Combs 11 * 12 * SPDX-License-Identifier: GPL-2.0-or-later 13 */ 14 /* Just set me to activate debug #define DEBUG_NTLMSSP */ 15 #include "config.h" 16 #ifdef DEBUG_NTLMSSP 17 #include <stdio.h> 18 #endif 19 #include <string.h> 20 21 #include <epan/packet.h> 22 #include <epan/exceptions.h> 23 #include <epan/asn1.h> 24 #include <epan/prefs.h> 25 #include <epan/tap.h> 26 #include <epan/expert.h> 27 #include <epan/show_exception.h> 28 #include <epan/proto_data.h> 29 30 #include <wsutil/wsgcrypt.h> 31 #include <wsutil/crc32.h> 32 #include <wsutil/str_util.h> 33 34 #include "packet-windows-common.h" 35 #include "packet-kerberos.h" 36 #include "packet-dcerpc.h" 37 #include "packet-gssapi.h" 38 39 #include "read_keytab_file.h" 40 41 #include "packet-ntlmssp.h" 42 43 /* 44 * See 45 * 46 * https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/ 47 * 48 * for Microsoft's MS-NLMP, NT LAN Manager (NTLM) Authentication Protocol 49 * Specification. 50 * 51 * See also 52 * 53 * http://davenport.sourceforge.net/ntlm.html 54 * 55 * which indicates that, in practice, some fields specified by MS-NLMP 56 * may be absent; this has been seen in some captures. 57 */ 58 59 void proto_register_ntlmssp(void); 60 void proto_reg_handoff_ntlmssp(void); 61 62 static int ntlmssp_tap = -1; 63 64 #define CLIENT_SIGN_TEXT "session key to client-to-server signing key magic constant" 65 #define CLIENT_SEAL_TEXT "session key to client-to-server sealing key magic constant" 66 #define SERVER_SIGN_TEXT "session key to server-to-client signing key magic constant" 67 #define SERVER_SEAL_TEXT "session key to server-to-client sealing key magic constant" 68 69 static const value_string ntlmssp_message_types[] = { 70 { NTLMSSP_NEGOTIATE, "NTLMSSP_NEGOTIATE" }, 71 { NTLMSSP_CHALLENGE, "NTLMSSP_CHALLENGE" }, 72 { NTLMSSP_AUTH, "NTLMSSP_AUTH" }, 73 { NTLMSSP_UNKNOWN, "NTLMSSP_UNKNOWN" }, 74 { 0, NULL } 75 }; 76 77 #define NTLMSSP_EK_IS_NT4HASH(ek) \ 78 (ek->fd_num == -1 && ek->keytype == 23 && ek->keylength == NTLMSSP_KEY_LEN) 79 80 static const unsigned char gbl_zeros[24] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; 81 static GHashTable* hash_packet = NULL; 82 83 /* 84 * NTLMSSP negotiation flags 85 * Taken from Samba 86 * 87 * See also the davenport.sourceforge.net document cited above, 88 * although that document says that: 89 * 90 * 0x00010000 is "Target Type Domain"; 91 * 0x00020000 is "Target Type Server" 92 * 0x00040000 is "Target Type Share"; 93 * 94 * and that 0x00100000, 0x00200000, and 0x00400000 are 95 * "Request Init Response", "Request Accept Response", and 96 * "Request Non-NT Session Key", rather than those values shifted 97 * right one having those interpretations. 98 * 99 * UPDATE: Further information obtained from [MS-NLMP] 2.2.2.5 100 */ 101 #define NTLMSSP_NEGOTIATE_UNICODE 0x00000001 102 #define NTLMSSP_NEGOTIATE_OEM 0x00000002 103 #define NTLMSSP_REQUEST_TARGET 0x00000004 104 #define NTLMSSP_NEGOTIATE_00000008 0x00000008 105 #define NTLMSSP_NEGOTIATE_SIGN 0x00000010 106 #define NTLMSSP_NEGOTIATE_SEAL 0x00000020 107 #define NTLMSSP_NEGOTIATE_DATAGRAM 0x00000040 108 #define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080 109 #define NTLMSSP_NEGOTIATE_00000100 0x00000100 110 #define NTLMSSP_NEGOTIATE_NTLM 0x00000200 111 #define NTLMSSP_NEGOTIATE_NT_ONLY 0x00000400 112 #define NTLMSSP_NEGOTIATE_ANONYMOUS 0x00000800 113 #define NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED 0x00001000 114 #define NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED 0x00002000 115 #define NTLMSSP_NEGOTIATE_00004000 0x00004000 116 #define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000 117 #define NTLMSSP_TARGET_TYPE_DOMAIN 0x00010000 118 #define NTLMSSP_TARGET_TYPE_SERVER 0x00020000 119 #define NTLMSSP_TARGET_TYPE_SHARE 0x00040000 120 #define NTLMSSP_NEGOTIATE_EXTENDED_SECURITY 0x00080000 121 #define NTLMSSP_NEGOTIATE_IDENTIFY 0x00100000 122 #define NTLMSSP_NEGOTIATE_00200000 0x00200000 123 #define NTLMSSP_REQUEST_NON_NT_SESSION 0x00400000 124 #define NTLMSSP_NEGOTIATE_TARGET_INFO 0x00800000 125 #define NTLMSSP_NEGOTIATE_01000000 0x01000000 126 #define NTLMSSP_NEGOTIATE_VERSION 0x02000000 127 #define NTLMSSP_NEGOTIATE_04000000 0x04000000 128 #define NTLMSSP_NEGOTIATE_08000000 0x08000000 129 #define NTLMSSP_NEGOTIATE_10000000 0x10000000 130 #define NTLMSSP_NEGOTIATE_128 0x20000000 131 #define NTLMSSP_NEGOTIATE_KEY_EXCH 0x40000000 132 #define NTLMSSP_NEGOTIATE_56 0x80000000 133 134 static int proto_ntlmssp = -1; 135 static int hf_ntlmssp_auth = -1; 136 static int hf_ntlmssp_message_type = -1; 137 static int hf_ntlmssp_negotiate_flags = -1; 138 static int hf_ntlmssp_negotiate_flags_01 = -1; 139 static int hf_ntlmssp_negotiate_flags_02 = -1; 140 static int hf_ntlmssp_negotiate_flags_04 = -1; 141 static int hf_ntlmssp_negotiate_flags_08 = -1; 142 static int hf_ntlmssp_negotiate_flags_10 = -1; 143 static int hf_ntlmssp_negotiate_flags_20 = -1; 144 static int hf_ntlmssp_negotiate_flags_40 = -1; 145 static int hf_ntlmssp_negotiate_flags_80 = -1; 146 static int hf_ntlmssp_negotiate_flags_100 = -1; 147 static int hf_ntlmssp_negotiate_flags_200 = -1; 148 static int hf_ntlmssp_negotiate_flags_400 = -1; 149 static int hf_ntlmssp_negotiate_flags_800 = -1; 150 static int hf_ntlmssp_negotiate_flags_1000 = -1; 151 static int hf_ntlmssp_negotiate_flags_2000 = -1; 152 static int hf_ntlmssp_negotiate_flags_4000 = -1; 153 static int hf_ntlmssp_negotiate_flags_8000 = -1; 154 static int hf_ntlmssp_negotiate_flags_10000 = -1; 155 static int hf_ntlmssp_negotiate_flags_20000 = -1; 156 static int hf_ntlmssp_negotiate_flags_40000 = -1; 157 static int hf_ntlmssp_negotiate_flags_80000 = -1; 158 static int hf_ntlmssp_negotiate_flags_100000 = -1; 159 static int hf_ntlmssp_negotiate_flags_200000 = -1; 160 static int hf_ntlmssp_negotiate_flags_400000 = -1; 161 static int hf_ntlmssp_negotiate_flags_800000 = -1; 162 static int hf_ntlmssp_negotiate_flags_1000000 = -1; 163 static int hf_ntlmssp_negotiate_flags_2000000 = -1; 164 static int hf_ntlmssp_negotiate_flags_4000000 = -1; 165 static int hf_ntlmssp_negotiate_flags_8000000 = -1; 166 static int hf_ntlmssp_negotiate_flags_10000000 = -1; 167 static int hf_ntlmssp_negotiate_flags_20000000 = -1; 168 static int hf_ntlmssp_negotiate_flags_40000000 = -1; 169 static int hf_ntlmssp_negotiate_flags_80000000 = -1; 170 /* static int hf_ntlmssp_negotiate_workstation_strlen = -1; */ 171 /* static int hf_ntlmssp_negotiate_workstation_maxlen = -1; */ 172 /* static int hf_ntlmssp_negotiate_workstation_buffer = -1; */ 173 static int hf_ntlmssp_negotiate_workstation = -1; 174 /* static int hf_ntlmssp_negotiate_domain_strlen = -1; */ 175 /* static int hf_ntlmssp_negotiate_domain_maxlen = -1; */ 176 /* static int hf_ntlmssp_negotiate_domain_buffer = -1; */ 177 static int hf_ntlmssp_negotiate_domain = -1; 178 static int hf_ntlmssp_ntlm_server_challenge = -1; 179 static int hf_ntlmssp_ntlm_client_challenge = -1; 180 static int hf_ntlmssp_reserved = -1; 181 static int hf_ntlmssp_challenge_target_name = -1; 182 static int hf_ntlmssp_auth_username = -1; 183 static int hf_ntlmssp_auth_domain = -1; 184 static int hf_ntlmssp_auth_hostname = -1; 185 static int hf_ntlmssp_auth_lmresponse = -1; 186 static int hf_ntlmssp_auth_ntresponse = -1; 187 static int hf_ntlmssp_auth_sesskey = -1; 188 static int hf_ntlmssp_string_len = -1; 189 static int hf_ntlmssp_string_maxlen = -1; 190 static int hf_ntlmssp_string_offset = -1; 191 static int hf_ntlmssp_blob_len = -1; 192 static int hf_ntlmssp_blob_maxlen = -1; 193 static int hf_ntlmssp_blob_offset = -1; 194 static int hf_ntlmssp_version = -1; 195 static int hf_ntlmssp_version_major = -1; 196 static int hf_ntlmssp_version_minor = -1; 197 static int hf_ntlmssp_version_build_number = -1; 198 static int hf_ntlmssp_version_ntlm_current_revision = -1; 199 200 static int hf_ntlmssp_challenge_target_info = -1; 201 static int hf_ntlmssp_challenge_target_info_len = -1; 202 static int hf_ntlmssp_challenge_target_info_maxlen = -1; 203 static int hf_ntlmssp_challenge_target_info_offset = -1; 204 205 static int hf_ntlmssp_challenge_target_info_item_type = -1; 206 static int hf_ntlmssp_challenge_target_info_item_len = -1; 207 208 static int hf_ntlmssp_challenge_target_info_end = -1; 209 static int hf_ntlmssp_challenge_target_info_nb_computer_name = -1; 210 static int hf_ntlmssp_challenge_target_info_nb_domain_name = -1; 211 static int hf_ntlmssp_challenge_target_info_dns_computer_name = -1; 212 static int hf_ntlmssp_challenge_target_info_dns_domain_name = -1; 213 static int hf_ntlmssp_challenge_target_info_dns_tree_name = -1; 214 static int hf_ntlmssp_challenge_target_info_flags = -1; 215 static int hf_ntlmssp_challenge_target_info_timestamp = -1; 216 static int hf_ntlmssp_challenge_target_info_restrictions = -1; 217 static int hf_ntlmssp_challenge_target_info_target_name =-1; 218 static int hf_ntlmssp_challenge_target_info_channel_bindings =-1; 219 220 static int hf_ntlmssp_ntlmv2_response_item_type = -1; 221 static int hf_ntlmssp_ntlmv2_response_item_len = -1; 222 223 static int hf_ntlmssp_ntlmv2_response_end = -1; 224 static int hf_ntlmssp_ntlmv2_response_nb_computer_name = -1; 225 static int hf_ntlmssp_ntlmv2_response_nb_domain_name = -1; 226 static int hf_ntlmssp_ntlmv2_response_dns_computer_name = -1; 227 static int hf_ntlmssp_ntlmv2_response_dns_domain_name = -1; 228 static int hf_ntlmssp_ntlmv2_response_dns_tree_name = -1; 229 static int hf_ntlmssp_ntlmv2_response_flags = -1; 230 static int hf_ntlmssp_ntlmv2_response_timestamp = -1; 231 static int hf_ntlmssp_ntlmv2_response_restrictions = -1; 232 static int hf_ntlmssp_ntlmv2_response_target_name =-1; 233 static int hf_ntlmssp_ntlmv2_response_channel_bindings =-1; 234 235 static int hf_ntlmssp_message_integrity_code = -1; 236 static int hf_ntlmssp_verf = -1; 237 static int hf_ntlmssp_verf_vers = -1; 238 static int hf_ntlmssp_verf_body = -1; 239 static int hf_ntlmssp_verf_randompad = -1; 240 static int hf_ntlmssp_verf_hmacmd5 = -1; 241 static int hf_ntlmssp_verf_crc32 = -1; 242 static int hf_ntlmssp_verf_sequence = -1; 243 /* static int hf_ntlmssp_decrypted_payload = -1; */ 244 245 static int hf_ntlmssp_ntlmv2_response = -1; 246 static int hf_ntlmssp_ntlmv2_response_ntproofstr = -1; 247 static int hf_ntlmssp_ntlmv2_response_rversion = -1; 248 static int hf_ntlmssp_ntlmv2_response_hirversion = -1; 249 static int hf_ntlmssp_ntlmv2_response_z = -1; 250 static int hf_ntlmssp_ntlmv2_response_pad = -1; 251 static int hf_ntlmssp_ntlmv2_response_time = -1; 252 static int hf_ntlmssp_ntlmv2_response_chal = -1; 253 254 static int hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL = -1; 255 static int hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_Version = -1; 256 static int hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_Flags = -1; 257 static int hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_LM_PRESENT = -1; 258 static int hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_NT_PRESENT = -1; 259 static int hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_REMOVED = -1; 260 static int hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_CREDKEY_PRESENT = -1; 261 static int hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_SHA_PRESENT = -1; 262 static int hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_CredentialKey = -1; 263 static int hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_CredentialKeyType = -1; 264 static int hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_EncryptedCredsSize = -1; 265 static int hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_EncryptedCreds = -1; 266 267 static gint ett_ntlmssp = -1; 268 static gint ett_ntlmssp_negotiate_flags = -1; 269 static gint ett_ntlmssp_string = -1; 270 static gint ett_ntlmssp_blob = -1; 271 static gint ett_ntlmssp_version = -1; 272 static gint ett_ntlmssp_challenge_target_info = -1; 273 static gint ett_ntlmssp_challenge_target_info_item = -1; 274 static gint ett_ntlmssp_ntlmv2_response = -1; 275 static gint ett_ntlmssp_ntlmv2_response_item = -1; 276 static gint ett_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL = -1; 277 278 static expert_field ei_ntlmssp_v2_key_too_long = EI_INIT; 279 static expert_field ei_ntlmssp_blob_len_too_long = EI_INIT; 280 static expert_field ei_ntlmssp_target_info_attr = EI_INIT; 281 static expert_field ei_ntlmssp_message_type = EI_INIT; 282 static expert_field ei_ntlmssp_auth_nthash = EI_INIT; 283 static expert_field ei_ntlmssp_sessionbasekey = EI_INIT; 284 static expert_field ei_ntlmssp_sessionkey = EI_INIT; 285 286 static dissector_handle_t ntlmssp_handle, ntlmssp_wrap_handle; 287 288 /* Configuration variables */ 289 static const char *ntlmssp_option_nt_password = NULL; 290 291 #define NTLMSSP_CONV_INFO_KEY 0 292 /* Used in the conversation function */ 293 typedef struct _ntlmssp_info { 294 guint32 flags; 295 gboolean saw_challenge; 296 gcry_cipher_hd_t rc4_handle_client; 297 gcry_cipher_hd_t rc4_handle_server; 298 guint8 sign_key_client[NTLMSSP_KEY_LEN]; 299 guint8 sign_key_server[NTLMSSP_KEY_LEN]; 300 guint32 server_dest_port; 301 unsigned char server_challenge[8]; 302 gboolean rc4_state_initialized; 303 ntlmssp_blob ntlm_response; 304 ntlmssp_blob lm_response; 305 } ntlmssp_info; 306 307 #define NTLMSSP_PACKET_INFO_KEY 1 308 /* If this struct exists in the payload_decrypt, then we have already 309 decrypted it once */ 310 typedef struct _ntlmssp_packet_info { 311 guint8 *decrypted_payload; 312 guint8 payload_len; 313 guint8 verifier[NTLMSSP_KEY_LEN]; 314 gboolean payload_decrypted; 315 gboolean verifier_decrypted; 316 } ntlmssp_packet_info; 317 318 #ifdef DEBUG_NTLMSSP 319 static void printnbyte(const guint8* tab, int nb, const char* txt, const char* txt2) 320 { 321 int i; 322 fprintf(stderr, "%s ", txt); 323 for (i=0; i<nb; i++) 324 { 325 fprintf(stderr, "%02X ", *(tab+i)); 326 } 327 fprintf(stderr, "%s", txt2); 328 } 329 #if 0 330 static void printnchar(const guint8* tab, int nb, char* txt, char* txt2) 331 { 332 int i; 333 fprintf(stderr, "%s ", txt); 334 for (i=0; i<nb; i++) 335 { 336 fprintf(stderr, "%c", *(tab+i)); 337 } 338 fprintf(stderr, "%s", txt2); 339 } 340 #endif 341 #else 342 static void printnbyte(const guint8* tab _U_, int nb _U_, const char* txt _U_, const char* txt2 _U_) 343 { 344 } 345 #endif 346 347 /* 348 * GSlist of decrypted payloads. 349 */ 350 static GSList *decrypted_payloads; 351 352 #if 0 353 static int 354 LEBE_Convert(int value) 355 { 356 char a, b, c, d; 357 /* Get each byte */ 358 a = value&0x000000FF; 359 b = (value&0x0000FF00) >> 8; 360 c = (value&0x00FF0000) >> 16; 361 d = (value&0xFF000000) >> 24; 362 return (a << 24) | (b << 16) | (c << 8) | d; 363 } 364 #endif 365 366 static gboolean 367 ntlmssp_sessions_destroy_cb(wmem_allocator_t *allocator _U_, wmem_cb_event_t event _U_, void *user_data _U_) 368 { 369 ntlmssp_info * conv_ntlmssp_info = (ntlmssp_info *) user_data; 370 gcry_cipher_close(conv_ntlmssp_info->rc4_handle_client); 371 gcry_cipher_close(conv_ntlmssp_info->rc4_handle_server); 372 /* unregister this callback */ 373 return FALSE; 374 } 375 376 /* 377 Perform a DES encryption with a 16-byte key and 8-byte data item. 378 It's in fact 3 susbsequent call to crypt_des_ecb with a 7-byte key. 379 Missing bytes for the key are replaced by 0; 380 Returns output in response, which is expected to be 24 bytes. 381 */ 382 static int 383 crypt_des_ecb_long(guint8 *response, 384 const guint8 *key, 385 const guint8 *data) 386 { 387 guint8 pw21[21] = { 0 }; /* 21 bytes place for the needed key */ 388 389 memcpy(pw21, key, 16); 390 391 memset(response, 0, 24); 392 crypt_des_ecb(response, data, pw21); 393 crypt_des_ecb(response + 8, data, pw21 + 7); 394 crypt_des_ecb(response + 16, data, pw21 + 14); 395 396 return 1; 397 } 398 399 /* 400 Generate a challenge response, given an eight byte challenge and 401 either the NT or the Lan Manager password hash (16 bytes). 402 Returns output in response, which is expected to be 24 bytes. 403 */ 404 static int 405 ntlmssp_generate_challenge_response(guint8 *response, 406 const guint8 *passhash, 407 const guint8 *challenge) 408 { 409 guint8 pw21[21]; /* Password hash padded to 21 bytes */ 410 411 memset(pw21, 0x0, sizeof(pw21)); 412 memcpy(pw21, passhash, 16); 413 414 memset(response, 0, 24); 415 416 crypt_des_ecb(response, challenge, pw21); 417 crypt_des_ecb(response + 8, challenge, pw21 + 7); 418 crypt_des_ecb(response + 16, challenge, pw21 + 14); 419 420 return 1; 421 } 422 423 424 /* Ultra simple ainsi to unicode converter, will only work for ascii password ...*/ 425 static void 426 str_to_unicode(const char *nt_password, char *nt_password_unicode) 427 { 428 size_t password_len; 429 size_t i; 430 431 password_len = strlen(nt_password); 432 if (nt_password_unicode != NULL) { 433 for (i=0; i<(password_len); i++) { 434 nt_password_unicode[i*2]=nt_password[i]; 435 nt_password_unicode[i*2+1]=0; 436 } 437 nt_password_unicode[2*password_len]='\0'; 438 } 439 } 440 441 /* This function generate the Key Exchange Key 442 * Depending on the flags this key will either be used to crypt the exported session key 443 * or will be used directly as exported session key. 444 * Exported session key is the key that will be used for sealing and signing communication*/ 445 446 static void 447 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) 448 { 449 guint8 basekey[NTLMSSP_KEY_LEN]; 450 guint8 zeros[24] = { 0 }; 451 452 memset(keyexchangekey, 0, NTLMSSP_KEY_LEN); 453 memset(basekey, 0, NTLMSSP_KEY_LEN); 454 /* sessionbasekey is either derived from lm_password_hash or from nt_password_hash depending on the key type negotiated */ 455 memcpy(basekey, sessionbasekey, 8); 456 memset(basekey, 0xBD, 8); 457 if (flags&NTLMSSP_NEGOTIATE_LM_KEY) { 458 /*data, key*/ 459 crypt_des_ecb(keyexchangekey, lm_challenge_response, basekey); 460 crypt_des_ecb(keyexchangekey+8, lm_challenge_response, basekey+7); 461 } 462 else { 463 if (flags&NTLMSSP_REQUEST_NON_NT_SESSION) { 464 /*People from samba tends to use the same function in this case than in the previous one but with 0 data 465 * it's not clear that it produce the good result 466 * memcpy(keyexchangekey, lm_hash, 8); 467 * Let's trust samba implementation it mights seem weird but they are more often rights than the spec ! 468 */ 469 crypt_des_ecb(keyexchangekey, zeros, basekey); 470 crypt_des_ecb(keyexchangekey+8, zeros, basekey+7); 471 } 472 else { 473 /* it is stated page 65 of NTLM SSP spec that sessionbasekey should be encrypted with hmac_md5 using the concact of both challenge 474 * when it's NTLM v1 + extended security but it turns out to be wrong ! 475 */ 476 memcpy(keyexchangekey, sessionbasekey, NTLMSSP_KEY_LEN); 477 } 478 } 479 } 480 481 guint32 482 get_md4pass_list(wmem_allocator_t *pool 483 #if !defined(HAVE_HEIMDAL_KERBEROS) && !defined(HAVE_MIT_KERBEROS) 484 _U_ 485 #endif 486 , md4_pass** p_pass_list) 487 { 488 #if defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS) 489 guint32 nb_pass = 0; 490 enc_key_t *ek; 491 const char* nt_password = ntlmssp_option_nt_password; 492 unsigned char nt_password_hash[NTLMSSP_KEY_LEN]; 493 char nt_password_unicode[256]; 494 md4_pass* pass_list; 495 int i; 496 497 *p_pass_list = NULL; 498 read_keytab_file_from_preferences(); 499 500 for (ek=enc_key_list; ek; ek=ek->next) { 501 if (NTLMSSP_EK_IS_NT4HASH(ek)) { 502 nb_pass++; 503 } 504 } 505 memset(nt_password_unicode, 0, sizeof(nt_password_unicode)); 506 memset(nt_password_hash, 0, NTLMSSP_KEY_LEN); 507 /* Compute the NT hash of the provided password, even if empty */ 508 if (strlen(nt_password) < 129) { 509 int password_len; 510 nb_pass++; 511 password_len = (int)strlen(nt_password); 512 str_to_unicode(nt_password, nt_password_unicode); 513 gcry_md_hash_buffer(GCRY_MD_MD4, nt_password_hash, nt_password_unicode, password_len*2); 514 } 515 if (nb_pass == 0) { 516 /* Unable to calculate the session key without a valid password (128 chars or less) ......*/ 517 return 0; 518 } 519 i = 0; 520 *p_pass_list = (md4_pass *)wmem_alloc0(pool, nb_pass*sizeof(md4_pass)); 521 pass_list = *p_pass_list; 522 523 if (memcmp(nt_password_hash, gbl_zeros, NTLMSSP_KEY_LEN) != 0) { 524 memcpy(pass_list[i].md4, nt_password_hash, NTLMSSP_KEY_LEN); 525 g_snprintf(pass_list[i].key_origin, NTLMSSP_MAX_ORIG_LEN, 526 "<Global NT Password>"); 527 i = 1; 528 } 529 for (ek=enc_key_list; ek; ek=ek->next) { 530 if (NTLMSSP_EK_IS_NT4HASH(ek)) { 531 memcpy(pass_list[i].md4, ek->keyvalue, NTLMSSP_KEY_LEN); 532 memcpy(pass_list[i].key_origin, ek->key_origin, 533 MIN(sizeof(pass_list[i].key_origin),sizeof(ek->key_origin))); 534 i++; 535 } 536 } 537 return nb_pass; 538 #else /* !(defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)) */ 539 *p_pass_list = NULL; 540 return 0; 541 #endif /* !(defined(HAVE_HEIMDAL_KERBEROS) || defined(HAVE_MIT_KERBEROS)) */ 542 } 543 544 /* Create an NTLMSSP version 2 key 545 */ 546 static void 547 create_ntlmssp_v2_key(const guint8 *serverchallenge, const guint8 *clientchallenge, 548 guint8 *sessionkey , const guint8 *encryptedsessionkey , int flags , 549 const ntlmssp_blob *ntlm_response, const ntlmssp_blob *lm_response _U_, ntlmssp_header_t *ntlmssph, 550 packet_info *pinfo, proto_tree *ntlmssp_tree) 551 { 552 /* static const would be nicer, but -Werror=vla does not like it */ 553 #define DOMAIN_NAME_BUF_SIZE 512 554 #define USER_BUF_SIZE 256 555 #define BUF_SIZE (DOMAIN_NAME_BUF_SIZE + USER_BUF_SIZE) 556 char domain_name_unicode[DOMAIN_NAME_BUF_SIZE]; 557 char user_uppercase[USER_BUF_SIZE]; 558 char buf[BUF_SIZE]; 559 /*guint8 md4[NTLMSSP_KEY_LEN];*/ 560 unsigned char nt_password_hash[NTLMSSP_KEY_LEN]; 561 unsigned char nt_proof[NTLMSSP_KEY_LEN]; 562 unsigned char ntowf[NTLMSSP_KEY_LEN]; 563 guint8 sessionbasekey[NTLMSSP_KEY_LEN]; 564 guint8 keyexchangekey[NTLMSSP_KEY_LEN]; 565 guint8 lm_challenge_response[24]; 566 guint32 i; 567 guint32 j; 568 gcry_cipher_hd_t rc4_handle; 569 size_t user_len; 570 size_t domain_len; 571 md4_pass *pass_list = NULL; 572 const md4_pass *used_md4 = NULL; 573 guint32 nb_pass = 0; 574 gboolean found = FALSE; 575 576 /* We are going to try password encrypted in keytab as well, it's an idea of Stefan Metzmacher <metze@samba.org> 577 * The idea is to be able to test all the key of domain in once and to be able to decode the NTLM dialogs */ 578 579 memset(sessionkey, 0, NTLMSSP_KEY_LEN); 580 nb_pass = get_md4pass_list(pinfo->pool, &pass_list); 581 i = 0; 582 memset(user_uppercase, 0, USER_BUF_SIZE); 583 user_len = strlen(ntlmssph->acct_name); 584 if (user_len < USER_BUF_SIZE / 2) { 585 memset(buf, 0, BUF_SIZE); 586 str_to_unicode(ntlmssph->acct_name, buf); 587 for (j = 0; j < (2*user_len); j++) { 588 if (buf[j] != '\0') { 589 user_uppercase[j] = g_ascii_toupper(buf[j]); 590 } 591 } 592 } 593 else { 594 /* Unable to calculate the session not enough space in buffer, note this is unlikely to happen but ......*/ 595 return; 596 } 597 domain_len = strlen(ntlmssph->domain_name); 598 if (domain_len < DOMAIN_NAME_BUF_SIZE / 2) { 599 str_to_unicode(ntlmssph->domain_name, domain_name_unicode); 600 } 601 else { 602 /* Unable to calculate the session not enough space in buffer, note this is unlikely to happen but ......*/ 603 return; 604 } 605 while (i < nb_pass) { 606 #ifdef DEBUG_NTLMSSP 607 fprintf(stderr, "Turn %d, ", i); 608 #endif 609 used_md4 = &pass_list[i]; 610 memcpy(nt_password_hash, pass_list[i].md4, NTLMSSP_KEY_LEN); 611 printnbyte(nt_password_hash, NTLMSSP_KEY_LEN, "Current NT password hash: ", "\n"); 612 i++; 613 /* ntowf computation */ 614 memset(buf, 0, BUF_SIZE); 615 memcpy(buf, user_uppercase, user_len*2); 616 memcpy(buf+user_len*2, domain_name_unicode, domain_len*2); 617 if (ws_hmac_buffer(GCRY_MD_MD5, ntowf, buf, domain_len*2+user_len*2, nt_password_hash, NTLMSSP_KEY_LEN)) { 618 return; 619 } 620 printnbyte(ntowf, NTLMSSP_KEY_LEN, "NTOWF: ", "\n"); 621 622 /* LM response */ 623 memset(buf, 0, BUF_SIZE); 624 memcpy(buf, serverchallenge, 8); 625 memcpy(buf+8, clientchallenge, 8); 626 if (ws_hmac_buffer(GCRY_MD_MD5, lm_challenge_response, buf, NTLMSSP_KEY_LEN, ntowf, NTLMSSP_KEY_LEN)) { 627 return; 628 } 629 memcpy(lm_challenge_response+NTLMSSP_KEY_LEN, clientchallenge, 8); 630 printnbyte(lm_challenge_response, 24, "LM Response: ", "\n"); 631 632 /* NT proof = First NTLMSSP_KEY_LEN bytes of NT response */ 633 memset(buf, 0, BUF_SIZE); 634 memcpy(buf, serverchallenge, 8); 635 memcpy(buf+8, ntlm_response->contents+NTLMSSP_KEY_LEN, MIN(BUF_SIZE - 8, ntlm_response->length-NTLMSSP_KEY_LEN)); 636 if (ws_hmac_buffer(GCRY_MD_MD5, nt_proof, buf, ntlm_response->length-8, ntowf, NTLMSSP_KEY_LEN)) { 637 return; 638 } 639 printnbyte(nt_proof, NTLMSSP_KEY_LEN, "NT proof: ", "\n"); 640 if (!memcmp(nt_proof, ntlm_response->contents, NTLMSSP_KEY_LEN)) { 641 found = TRUE; 642 break; 643 } 644 } 645 if (!found) { 646 return; 647 } 648 649 if (ws_hmac_buffer(GCRY_MD_MD5, sessionbasekey, nt_proof, NTLMSSP_KEY_LEN, ntowf, NTLMSSP_KEY_LEN)) { 650 return; 651 } 652 653 get_keyexchange_key(keyexchangekey, sessionbasekey, lm_challenge_response, flags); 654 /* now decrypt session key if needed and setup sessionkey for decrypting further communications */ 655 if (flags & NTLMSSP_NEGOTIATE_KEY_EXCH) 656 { 657 memcpy(sessionkey, encryptedsessionkey, NTLMSSP_KEY_LEN); 658 if (!gcry_cipher_open(&rc4_handle, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)) { 659 if (!gcry_cipher_setkey(rc4_handle, keyexchangekey, NTLMSSP_KEY_LEN)) { 660 gcry_cipher_decrypt(rc4_handle, sessionkey, NTLMSSP_KEY_LEN, NULL, 0); 661 } 662 gcry_cipher_close(rc4_handle); 663 } 664 } 665 else 666 { 667 memcpy(sessionkey, keyexchangekey, NTLMSSP_KEY_LEN); 668 } 669 670 memcpy(ntlmssph->session_key, sessionkey, NTLMSSP_KEY_LEN); 671 672 if (used_md4 == NULL) { 673 return; 674 } 675 expert_add_info_format(pinfo, proto_tree_get_parent(ntlmssp_tree), 676 &ei_ntlmssp_auth_nthash, 677 "NTLMv2 authenticated using %s (%02x%02x%02x%02x...)", 678 used_md4->key_origin, 679 used_md4->md4[0] & 0xFF, used_md4->md4[1] & 0xFF, 680 used_md4->md4[2] & 0xFF, used_md4->md4[3] & 0xFF); 681 expert_add_info_format(pinfo, proto_tree_get_parent(ntlmssp_tree), 682 &ei_ntlmssp_sessionbasekey, 683 "NTLMv2 BaseSessionKey (" 684 "%02x%02x%02x%02x" 685 "%02x%02x%02x%02x" 686 "%02x%02x%02x%02x" 687 "%02x%02x%02x%02x" 688 ")", 689 sessionbasekey[0] & 0xFF, sessionbasekey[1] & 0xFF, 690 sessionbasekey[2] & 0xFF, sessionbasekey[3] & 0xFF, 691 sessionbasekey[4] & 0xFF, sessionbasekey[5] & 0xFF, 692 sessionbasekey[6] & 0xFF, sessionbasekey[7] & 0xFF, 693 sessionbasekey[8] & 0xFF, sessionbasekey[9] & 0xFF, 694 sessionbasekey[10] & 0xFF, sessionbasekey[11] & 0xFF, 695 sessionbasekey[12] & 0xFF, sessionbasekey[13] & 0xFF, 696 sessionbasekey[14] & 0xFF, sessionbasekey[15] & 0xFF); 697 if (memcmp(sessionbasekey, sessionkey, NTLMSSP_KEY_LEN) == 0) { 698 return; 699 } 700 expert_add_info_format(pinfo, proto_tree_get_parent(ntlmssp_tree), 701 &ei_ntlmssp_sessionkey, 702 "NTLMSSP SessionKey (" 703 "%02x%02x%02x%02x" 704 "%02x%02x%02x%02x" 705 "%02x%02x%02x%02x" 706 "%02x%02x%02x%02x" 707 ")", 708 sessionkey[0] & 0xFF, sessionkey[1] & 0xFF, 709 sessionkey[2] & 0xFF, sessionkey[3] & 0xFF, 710 sessionkey[4] & 0xFF, sessionkey[5] & 0xFF, 711 sessionkey[6] & 0xFF, sessionkey[7] & 0xFF, 712 sessionkey[8] & 0xFF, sessionkey[9] & 0xFF, 713 sessionkey[10] & 0xFF, sessionkey[11] & 0xFF, 714 sessionkey[12] & 0xFF, sessionkey[13] & 0xFF, 715 sessionkey[14] & 0xFF, sessionkey[15] & 0xFF); 716 } 717 718 /* Create an NTLMSSP version 1 key 719 * That is more complicated logic and methods and user challenge as well. 720 * password points to the ANSI password to encrypt, challenge points to 721 * the 8 octet challenge string 722 */ 723 static void 724 create_ntlmssp_v1_key(const guint8 *serverchallenge, const guint8 *clientchallenge, 725 guint8 *sessionkey, const guint8 *encryptedsessionkey, int flags, 726 const guint8 *ref_nt_challenge_response, const guint8 *ref_lm_challenge_response, 727 ntlmssp_header_t *ntlmssph, 728 packet_info *pinfo, proto_tree *ntlmssp_tree) 729 { 730 const char *nt_password = ntlmssp_option_nt_password; 731 unsigned char lm_password_upper[NTLMSSP_KEY_LEN]; 732 unsigned char lm_password_hash[NTLMSSP_KEY_LEN]; 733 unsigned char nt_password_hash[NTLMSSP_KEY_LEN]; 734 unsigned char challenges_hash_first8[8]; 735 unsigned char challenges[NTLMSSP_KEY_LEN]; 736 guint8 md4[NTLMSSP_KEY_LEN]; 737 guint8 nb_pass = 0; 738 guint8 sessionbasekey[NTLMSSP_KEY_LEN]; 739 guint8 keyexchangekey[NTLMSSP_KEY_LEN]; 740 guint8 lm_challenge_response[24]; 741 guint8 nt_challenge_response[24]; 742 gcry_cipher_hd_t rc4_handle; 743 gcry_md_hd_t md5_handle; 744 char nt_password_unicode[256]; 745 size_t password_len; 746 unsigned int i; 747 gboolean found = FALSE; 748 md4_pass *pass_list = NULL; 749 const md4_pass *used_md4 = NULL; 750 751 static const unsigned char lmhash_key[] = 752 {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25}; 753 754 memset(sessionkey, 0, NTLMSSP_KEY_LEN); 755 memset(lm_password_upper, 0, sizeof(lm_password_upper)); 756 /* lm auth/lm session == (!NTLM_NEGOTIATE_NT_ONLY && NTLMSSP_NEGOTIATE_LM_KEY) || ! (EXTENDED_SECURITY) || ! NTLMSSP_NEGOTIATE_NTLM*/ 757 /* Create a Lan Manager hash of the input password, even if empty */ 758 password_len = strlen(nt_password); 759 /*Do not forget to free nt_password_nt*/ 760 str_to_unicode(nt_password, nt_password_unicode); 761 gcry_md_hash_buffer(GCRY_MD_MD4, nt_password_hash, nt_password_unicode, password_len*2); 762 /* Truncate password if too long */ 763 if (password_len > NTLMSSP_KEY_LEN) 764 password_len = NTLMSSP_KEY_LEN; 765 for (i = 0; i < password_len; i++) { 766 lm_password_upper[i] = g_ascii_toupper(nt_password[i]); 767 } 768 769 if ((flags & NTLMSSP_NEGOTIATE_LM_KEY && !(flags & NTLMSSP_NEGOTIATE_NT_ONLY)) || !(flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY) || !(flags & NTLMSSP_NEGOTIATE_NTLM)) { 770 crypt_des_ecb(lm_password_hash, lmhash_key, lm_password_upper); 771 crypt_des_ecb(lm_password_hash+8, lmhash_key, lm_password_upper+7); 772 ntlmssp_generate_challenge_response(lm_challenge_response, 773 lm_password_hash, serverchallenge); 774 memcpy(sessionbasekey, lm_password_hash, NTLMSSP_KEY_LEN); 775 } 776 else { 777 778 memset(lm_challenge_response, 0, 24); 779 if (flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY) { 780 nb_pass = get_md4pass_list(pinfo->pool, &pass_list); 781 i = 0; 782 while (i < nb_pass) { 783 /*fprintf(stderr, "Turn %d, ", i);*/ 784 used_md4 = &pass_list[i]; 785 memcpy(nt_password_hash, pass_list[i].md4, NTLMSSP_KEY_LEN); 786 /*printnbyte(nt_password_hash, NTLMSSP_KEY_LEN, "Current NT password hash: ", "\n");*/ 787 i++; 788 if(clientchallenge){ 789 memcpy(lm_challenge_response, clientchallenge, 8); 790 } 791 if (gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) { 792 break; 793 } 794 gcry_md_write(md5_handle, serverchallenge, 8); 795 gcry_md_write(md5_handle, clientchallenge, 8); 796 memcpy(challenges_hash_first8, gcry_md_read(md5_handle, 0), 8); 797 gcry_md_close(md5_handle); 798 crypt_des_ecb_long(nt_challenge_response, nt_password_hash, challenges_hash_first8); 799 if (ref_nt_challenge_response && !memcmp(ref_nt_challenge_response, nt_challenge_response, 24)) { 800 found = TRUE; 801 break; 802 } 803 } 804 } 805 else { 806 crypt_des_ecb_long(nt_challenge_response, nt_password_hash, serverchallenge); 807 if (flags & NTLMSSP_NEGOTIATE_NT_ONLY) { 808 memcpy(lm_challenge_response, nt_challenge_response, 24); 809 } 810 else { 811 crypt_des_ecb_long(lm_challenge_response, lm_password_hash, serverchallenge); 812 } 813 if (ref_nt_challenge_response && 814 !memcmp(ref_nt_challenge_response, nt_challenge_response, 24) && 815 ref_lm_challenge_response && 816 !memcmp(ref_lm_challenge_response, lm_challenge_response, 24)) 817 { 818 found = TRUE; 819 } 820 } 821 /* So it's clearly not like this that's put into NTLMSSP doc but after some digging into samba code I'm quite confident 822 * that sessionbasekey should be based md4(nt_password_hash) only in the case of some NT auth 823 * Otherwise it should be lm_password_hash ...*/ 824 gcry_md_hash_buffer(GCRY_MD_MD4, md4, nt_password_hash, NTLMSSP_KEY_LEN); 825 if (flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY) { 826 memcpy(challenges, serverchallenge, 8); 827 if(clientchallenge){ 828 memcpy(challenges+8, clientchallenge, 8); 829 } 830 if (ws_hmac_buffer(GCRY_MD_MD5, sessionbasekey, challenges, NTLMSSP_KEY_LEN, md4, NTLMSSP_KEY_LEN)) { 831 return; 832 } 833 } 834 else { 835 memcpy(sessionbasekey, md4, NTLMSSP_KEY_LEN); 836 } 837 } 838 839 if (!found) { 840 return; 841 } 842 843 get_keyexchange_key(keyexchangekey, sessionbasekey, lm_challenge_response, flags); 844 memset(sessionkey, 0, NTLMSSP_KEY_LEN); 845 /*printnbyte(nt_challenge_response, 24, "NT challenge response", "\n"); 846 printnbyte(lm_challenge_response, 24, "LM challenge response", "\n");*/ 847 /* now decrypt session key if needed and setup sessionkey for decrypting further communications */ 848 if (flags & NTLMSSP_NEGOTIATE_KEY_EXCH) 849 { 850 if(encryptedsessionkey){ 851 memcpy(sessionkey, encryptedsessionkey, NTLMSSP_KEY_LEN); 852 } 853 if (!gcry_cipher_open(&rc4_handle, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)) { 854 if (!gcry_cipher_setkey(rc4_handle, keyexchangekey, NTLMSSP_KEY_LEN)) { 855 gcry_cipher_decrypt(rc4_handle, sessionkey, NTLMSSP_KEY_LEN, NULL, 0); 856 } 857 gcry_cipher_close(rc4_handle); 858 } 859 } 860 else 861 { 862 memcpy(sessionkey, keyexchangekey, NTLMSSP_KEY_LEN); 863 } 864 memcpy(ntlmssph->session_key, sessionkey, NTLMSSP_KEY_LEN); 865 866 if (used_md4 == NULL) { 867 return; 868 } 869 expert_add_info_format(pinfo, proto_tree_get_parent(ntlmssp_tree), 870 &ei_ntlmssp_auth_nthash, 871 "NTLMv1 authenticated using %s (%02x%02x%02x%02x...)", 872 used_md4->key_origin, 873 used_md4->md4[0] & 0xFF, used_md4->md4[1] & 0xFF, 874 used_md4->md4[2] & 0xFF, used_md4->md4[3] & 0xFF); 875 expert_add_info_format(pinfo, proto_tree_get_parent(ntlmssp_tree), 876 &ei_ntlmssp_sessionbasekey, 877 "NTLMv1 BaseSessionKey (" 878 "%02x%02x%02x%02x" 879 "%02x%02x%02x%02x" 880 "%02x%02x%02x%02x" 881 "%02x%02x%02x%02x" 882 ")", 883 sessionbasekey[0] & 0xFF, sessionbasekey[1] & 0xFF, 884 sessionbasekey[2] & 0xFF, sessionbasekey[3] & 0xFF, 885 sessionbasekey[4] & 0xFF, sessionbasekey[5] & 0xFF, 886 sessionbasekey[6] & 0xFF, sessionbasekey[7] & 0xFF, 887 sessionbasekey[8] & 0xFF, sessionbasekey[9] & 0xFF, 888 sessionbasekey[10] & 0xFF, sessionbasekey[11] & 0xFF, 889 sessionbasekey[12] & 0xFF, sessionbasekey[13] & 0xFF, 890 sessionbasekey[14] & 0xFF, sessionbasekey[15] & 0xFF); 891 if (memcmp(sessionbasekey, sessionkey, NTLMSSP_KEY_LEN) == 0) { 892 return; 893 } 894 expert_add_info_format(pinfo, proto_tree_get_parent(ntlmssp_tree), 895 &ei_ntlmssp_sessionkey, 896 "NTLMSSP SessionKey (" 897 "%02x%02x%02x%02x" 898 "%02x%02x%02x%02x" 899 "%02x%02x%02x%02x" 900 "%02x%02x%02x%02x" 901 ")", 902 sessionkey[0] & 0xFF, sessionkey[1] & 0xFF, 903 sessionkey[2] & 0xFF, sessionkey[3] & 0xFF, 904 sessionkey[4] & 0xFF, sessionkey[5] & 0xFF, 905 sessionkey[6] & 0xFF, sessionkey[7] & 0xFF, 906 sessionkey[8] & 0xFF, sessionkey[9] & 0xFF, 907 sessionkey[10] & 0xFF, sessionkey[11] & 0xFF, 908 sessionkey[12] & 0xFF, sessionkey[13] & 0xFF, 909 sessionkey[14] & 0xFF, sessionkey[15] & 0xFF); 910 } 911 912 void 913 ntlmssp_create_session_key(packet_info *pinfo, 914 proto_tree *tree, 915 ntlmssp_header_t *ntlmssph, 916 int flags, 917 const guint8 *server_challenge, 918 const guint8 *encryptedsessionkey, 919 const ntlmssp_blob *ntlm_response, 920 const ntlmssp_blob *lm_response) 921 { 922 guint8 client_challenge[8] = {0, }; 923 guint8 sessionkey[NTLMSSP_KEY_LEN] = {0, }; 924 925 if (ntlm_response->length > 24) 926 { 927 /* 928 * [MS-NLMP] 2.2.2.8 NTLM2 V2 Response: NTLMv2_RESPONSE has 929 * the 2.2.2.7 "NTLM v2: NTLMv2_CLIENT_CHALLENGE" at offset 16. 930 * Within that ChallengeFromClient is at offset 16, that means 931 * it's at offset 32 in total. 932 * 933 * Note that value is only used for the LM_response of NTLMv2. 934 */ 935 if (ntlm_response->length >= 40) { 936 memcpy(client_challenge, 937 ntlm_response->contents+32, 8); 938 } 939 create_ntlmssp_v2_key(server_challenge, 940 client_challenge, 941 sessionkey, 942 encryptedsessionkey, 943 flags, 944 ntlm_response, 945 lm_response, 946 ntlmssph, 947 pinfo, 948 tree); 949 } 950 else if (ntlm_response->length == 24 && lm_response->length == 24) 951 { 952 memcpy(client_challenge, lm_response->contents, 8); 953 954 create_ntlmssp_v1_key(server_challenge, 955 client_challenge, 956 sessionkey, 957 encryptedsessionkey, 958 flags, 959 ntlm_response->contents, 960 lm_response->contents, 961 ntlmssph, 962 pinfo, 963 tree); 964 } 965 } 966 967 static void 968 get_siging_key(guint8 *sign_key_server, guint8* sign_key_client, const guint8 key[NTLMSSP_KEY_LEN], int keylen) 969 { 970 gcry_md_hd_t md5_handle; 971 972 memset(sign_key_client, 0, NTLMSSP_KEY_LEN); 973 memset(sign_key_server, 0, NTLMSSP_KEY_LEN); 974 if (gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) { 975 return; 976 } 977 gcry_md_write(md5_handle, key, keylen); 978 gcry_md_write(md5_handle, CLIENT_SIGN_TEXT, strlen(CLIENT_SIGN_TEXT)+1); 979 memcpy(sign_key_client, gcry_md_read(md5_handle, 0), NTLMSSP_KEY_LEN); 980 gcry_md_reset(md5_handle); 981 gcry_md_write(md5_handle, key, keylen); 982 gcry_md_write(md5_handle, SERVER_SIGN_TEXT, strlen(SERVER_SIGN_TEXT)+1); 983 memcpy(sign_key_server, gcry_md_read(md5_handle, 0), NTLMSSP_KEY_LEN); 984 gcry_md_close(md5_handle); 985 } 986 987 /* We return either a 128 or 64 bit key 988 */ 989 static void 990 get_sealing_rc4key(const guint8 exportedsessionkey[NTLMSSP_KEY_LEN] , const int flags , int *keylen , 991 guint8 *clientsealkey , guint8 *serversealkey) 992 { 993 gcry_md_hd_t md5_handle; 994 995 memset(clientsealkey, 0, NTLMSSP_KEY_LEN); 996 memset(serversealkey, 0, NTLMSSP_KEY_LEN); 997 memcpy(clientsealkey, exportedsessionkey, NTLMSSP_KEY_LEN); 998 if (flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY) 999 { 1000 if (flags & NTLMSSP_NEGOTIATE_128) 1001 { 1002 /* The exportedsessionkey has already the good length just update the length*/ 1003 *keylen = 16; 1004 } 1005 else 1006 { 1007 if (flags & NTLMSSP_NEGOTIATE_56) 1008 { 1009 memset(clientsealkey+7, 0, 9); 1010 *keylen = 7; 1011 } 1012 else 1013 { 1014 memset(clientsealkey+5, 0, 11); 1015 *keylen = 5; 1016 } 1017 } 1018 memcpy(serversealkey, clientsealkey, NTLMSSP_KEY_LEN); 1019 if (gcry_md_open(&md5_handle, GCRY_MD_MD5, 0)) { 1020 return; 1021 } 1022 gcry_md_write(md5_handle, clientsealkey, *keylen); 1023 gcry_md_write(md5_handle, CLIENT_SEAL_TEXT, strlen(CLIENT_SEAL_TEXT)+1); 1024 memcpy(clientsealkey, gcry_md_read(md5_handle, 0), NTLMSSP_KEY_LEN); 1025 gcry_md_reset(md5_handle); 1026 gcry_md_write(md5_handle, serversealkey, *keylen); 1027 gcry_md_write(md5_handle, SERVER_SEAL_TEXT, strlen(SERVER_SEAL_TEXT)+1); 1028 memcpy(serversealkey, gcry_md_read(md5_handle, 0), NTLMSSP_KEY_LEN); 1029 gcry_md_close(md5_handle); 1030 } 1031 else 1032 { 1033 if (flags & NTLMSSP_NEGOTIATE_128) 1034 { 1035 /* The exportedsessionkey has already the good length just update the length*/ 1036 *keylen = 16; 1037 } 1038 else 1039 { 1040 *keylen = 8; 1041 if (flags & NTLMSSP_NEGOTIATE_56) 1042 { 1043 memset(clientsealkey+7, 0, 9); 1044 } 1045 else 1046 { 1047 memset(clientsealkey+5, 0, 11); 1048 clientsealkey[5]=0xe5; 1049 clientsealkey[6]=0x38; 1050 clientsealkey[7]=0xb0; 1051 } 1052 } 1053 memcpy(serversealkey, clientsealkey,*keylen); 1054 } 1055 } 1056 /* Create an NTLMSSP version 1 key. 1057 * password points to the ANSI password to encrypt, challenge points to 1058 * the 8 octet challenge string, key128 will do a 128 bit key if set to 1, 1059 * otherwise it will do a 40 bit key. The result is stored in 1060 * sspkey (expected to be NTLMSSP_KEY_LEN octets) 1061 */ 1062 /* dissect a string - header area contains: 1063 two byte len 1064 two byte maxlen 1065 four byte offset of string in data area 1066 The function returns the offset at the end of the string header, 1067 but the 'end' parameter returns the offset of the end of the string itself 1068 The 'start' parameter returns the offset of the beginning of the string 1069 If there's no string, just use the offset of the end of the tvb as start/end. 1070 */ 1071 static int 1072 dissect_ntlmssp_string (tvbuff_t *tvb, int offset, 1073 proto_tree *ntlmssp_tree, 1074 gboolean unicode_strings, 1075 int string_hf, int *start, int *end, 1076 const guint8 **stringp) 1077 { 1078 proto_tree *tree = NULL; 1079 proto_item *tf = NULL; 1080 gint16 string_length = tvb_get_letohs(tvb, offset); 1081 gint16 string_maxlen = tvb_get_letohs(tvb, offset+2); 1082 gint32 string_offset = tvb_get_letohl(tvb, offset+4); 1083 1084 *start = (string_offset > offset+8 ? string_offset : (signed)tvb_reported_length(tvb)); 1085 if (0 == string_length) { 1086 *end = *start; 1087 if (ntlmssp_tree) 1088 proto_tree_add_string(ntlmssp_tree, string_hf, tvb, 1089 offset, 8, "NULL"); 1090 if (stringp != NULL) 1091 *stringp = ""; 1092 return offset+8; 1093 } 1094 1095 if (unicode_strings) { 1096 /* UTF-16 string; must be 2-byte aligned */ 1097 if ((string_offset & 1) != 0) 1098 string_offset++; 1099 } 1100 tf = proto_tree_add_item_ret_string(ntlmssp_tree, string_hf, tvb, 1101 string_offset, string_length, 1102 unicode_strings ? ENC_UTF_16|ENC_LITTLE_ENDIAN : ENC_ASCII|ENC_NA, 1103 wmem_packet_scope(), stringp); 1104 tree = proto_item_add_subtree(tf, ett_ntlmssp_string); 1105 proto_tree_add_uint(tree, hf_ntlmssp_string_len, 1106 tvb, offset, 2, string_length); 1107 offset += 2; 1108 proto_tree_add_uint(tree, hf_ntlmssp_string_maxlen, 1109 tvb, offset, 2, string_maxlen); 1110 offset += 2; 1111 proto_tree_add_uint(tree, hf_ntlmssp_string_offset, 1112 tvb, offset, 4, string_offset); 1113 offset += 4; 1114 1115 *end = string_offset + string_length; 1116 return offset; 1117 } 1118 1119 /* dissect a generic blob - header area contains: 1120 two byte len 1121 two byte maxlen 1122 four byte offset of blob in data area 1123 The function returns the offset at the end of the blob header, 1124 but the 'end' parameter returns the offset of the end of the blob itself 1125 */ 1126 static int 1127 dissect_ntlmssp_blob (tvbuff_t *tvb, packet_info *pinfo, 1128 proto_tree *ntlmssp_tree, int offset, 1129 int blob_hf, int *end, ntlmssp_blob *result) 1130 { 1131 proto_item *tf = NULL; 1132 proto_tree *tree = NULL; 1133 guint16 blob_length = tvb_get_letohs(tvb, offset); 1134 guint16 blob_maxlen = tvb_get_letohs(tvb, offset+2); 1135 guint32 blob_offset = tvb_get_letohl(tvb, offset+4); 1136 1137 if (0 == blob_length) { 1138 *end = (blob_offset > ((guint)offset)+8 ? blob_offset : ((guint)offset)+8); 1139 proto_tree_add_bytes_format_value(ntlmssp_tree, blob_hf, tvb, offset, 8, NULL, "Empty"); 1140 result->length = 0; 1141 result->contents = NULL; 1142 return offset+8; 1143 } 1144 1145 if (ntlmssp_tree) { 1146 tf = proto_tree_add_item (ntlmssp_tree, blob_hf, tvb, 1147 blob_offset, blob_length, ENC_NA); 1148 tree = proto_item_add_subtree(tf, ett_ntlmssp_blob); 1149 } 1150 proto_tree_add_uint(tree, hf_ntlmssp_blob_len, 1151 tvb, offset, 2, blob_length); 1152 offset += 2; 1153 proto_tree_add_uint(tree, hf_ntlmssp_blob_maxlen, 1154 tvb, offset, 2, blob_maxlen); 1155 offset += 2; 1156 proto_tree_add_uint(tree, hf_ntlmssp_blob_offset, 1157 tvb, offset, 4, blob_offset); 1158 offset += 4; 1159 1160 *end = blob_offset + blob_length; 1161 1162 if (blob_length < NTLMSSP_BLOB_MAX_SIZE) { 1163 result->length = blob_length; 1164 result->contents = (guint8 *)tvb_memdup(wmem_file_scope(), tvb, blob_offset, blob_length); 1165 } else { 1166 expert_add_info_format(pinfo, tf, &ei_ntlmssp_v2_key_too_long, 1167 "NTLM v2 key is %d bytes long, too big for our %d buffer", blob_length, NTLMSSP_BLOB_MAX_SIZE); 1168 result->length = 0; 1169 result->contents = NULL; 1170 } 1171 1172 /* 1173 * XXX - for LmChallengeResponse (hf_ntlmssp_auth_lmresponse), should 1174 * we have a field for both Response (2.2.2.3 "LM_RESPONSE" and 1175 * 2.2.2.4 "LMv2_RESPONSE" in [MS-NLMP]) in addition to ClientChallenge 1176 * (only in 2.2.2.4 "LMv2_RESPONSE")? 1177 * 1178 * XXX - should we also dissect the fields of an NtChallengeResponse 1179 * (hf_ntlmssp_auth_ntresponse)? 1180 * 1181 * XXX - should we warn if the blob is too *small*? 1182 */ 1183 if (blob_hf == hf_ntlmssp_auth_lmresponse) { 1184 /* 1185 * LMChallengeResponse. It's either 2.2.2.3 "LM_RESPONSE" or 1186 * 2.2.2.4 "LMv2_RESPONSE", in [MS-NLMP]. 1187 * 1188 * XXX - should we have a field for Response as well as 1189 * ClientChallenge? 1190 */ 1191 if (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) == 0) { 1192 /* 1193 * LMv2_RESPONSE. 1194 * 1195 * XXX - according to 2.2.2.4 "LMv2_RESPONSE", the ClientChallenge 1196 * is at an offset of 16 from the beginning of the blob; it's not 1197 * at the beginning of the blob. 1198 */ 1199 proto_tree_add_item (ntlmssp_tree, 1200 hf_ntlmssp_ntlm_client_challenge, 1201 tvb, blob_offset, 8, ENC_NA); 1202 } 1203 } else if (blob_hf == hf_ntlmssp_auth_ntresponse) { 1204 /* 1205 * NTChallengeResponse. It's either 2.2.2.6 "NTLM v1 Response: 1206 * NTLM_RESPONSE" or 2.2.2.8 "NTLM v2 Response: NTLMv2_RESPONSE" 1207 * in [MS-NLMP]. 1208 */ 1209 if (blob_length > 24) { 1210 /* 1211 * > 24 bytes, so it's "NTLM v2 Response: NTLMv2_RESPONSE". 1212 * An NTLMv2_RESPONSE has 16 bytes of Response followed 1213 * by an NTLMv2_CLIENT_CHALLENGE; an NTLMv2_CLIENT_CHALLENGE 1214 * is at least 32 bytes, so an NTLMv2_RESPONSE is at least 1215 * 48 bytes long. 1216 */ 1217 dissect_ntlmv2_response(tvb, pinfo, tree, blob_offset, blob_length); 1218 } 1219 } 1220 1221 return offset; 1222 } 1223 1224 static int * const ntlmssp_negotiate_flags[] = { 1225 &hf_ntlmssp_negotiate_flags_80000000, 1226 &hf_ntlmssp_negotiate_flags_40000000, 1227 &hf_ntlmssp_negotiate_flags_20000000, 1228 &hf_ntlmssp_negotiate_flags_10000000, 1229 &hf_ntlmssp_negotiate_flags_8000000, 1230 &hf_ntlmssp_negotiate_flags_4000000, 1231 &hf_ntlmssp_negotiate_flags_2000000, 1232 &hf_ntlmssp_negotiate_flags_1000000, 1233 &hf_ntlmssp_negotiate_flags_800000, 1234 &hf_ntlmssp_negotiate_flags_400000, 1235 &hf_ntlmssp_negotiate_flags_200000, 1236 &hf_ntlmssp_negotiate_flags_100000, 1237 &hf_ntlmssp_negotiate_flags_80000, 1238 &hf_ntlmssp_negotiate_flags_40000, 1239 &hf_ntlmssp_negotiate_flags_20000, 1240 &hf_ntlmssp_negotiate_flags_10000, 1241 &hf_ntlmssp_negotiate_flags_8000, 1242 &hf_ntlmssp_negotiate_flags_4000, 1243 &hf_ntlmssp_negotiate_flags_2000, 1244 &hf_ntlmssp_negotiate_flags_1000, 1245 &hf_ntlmssp_negotiate_flags_800, 1246 &hf_ntlmssp_negotiate_flags_400, 1247 &hf_ntlmssp_negotiate_flags_200, 1248 &hf_ntlmssp_negotiate_flags_100, 1249 &hf_ntlmssp_negotiate_flags_80, 1250 &hf_ntlmssp_negotiate_flags_40, 1251 &hf_ntlmssp_negotiate_flags_20, 1252 &hf_ntlmssp_negotiate_flags_10, 1253 &hf_ntlmssp_negotiate_flags_08, 1254 &hf_ntlmssp_negotiate_flags_04, 1255 &hf_ntlmssp_negotiate_flags_02, 1256 &hf_ntlmssp_negotiate_flags_01, 1257 NULL 1258 }; 1259 1260 /* Dissect "version" */ 1261 1262 /* From MS-NLMP: 1263 0 Major Version Number 1 byte 1264 1 Minor Version Number 1 byte 1265 2 Build Number short(LE) 1266 3 (Reserved) 3 bytes 1267 4 NTLM Current Revision 1 byte 1268 */ 1269 1270 static int 1271 dissect_ntlmssp_version(tvbuff_t *tvb, int offset, 1272 proto_tree *ntlmssp_tree) 1273 { 1274 if (ntlmssp_tree) { 1275 proto_item *tf; 1276 proto_tree *version_tree; 1277 tf = proto_tree_add_none_format(ntlmssp_tree, hf_ntlmssp_version, tvb, offset, 8, 1278 "Version %u.%u (Build %u); NTLM Current Revision %u", 1279 tvb_get_guint8(tvb, offset), 1280 tvb_get_guint8(tvb, offset+1), 1281 tvb_get_letohs(tvb, offset+2), 1282 tvb_get_guint8(tvb, offset+7)); 1283 version_tree = proto_item_add_subtree (tf, ett_ntlmssp_version); 1284 proto_tree_add_item(version_tree, hf_ntlmssp_version_major , tvb, offset , 1, ENC_LITTLE_ENDIAN); 1285 proto_tree_add_item(version_tree, hf_ntlmssp_version_minor , tvb, offset+1, 1, ENC_LITTLE_ENDIAN); 1286 proto_tree_add_item(version_tree, hf_ntlmssp_version_build_number , tvb, offset+2, 2, ENC_LITTLE_ENDIAN); 1287 proto_tree_add_item(version_tree, hf_ntlmssp_version_ntlm_current_revision, tvb, offset+7, 1, ENC_LITTLE_ENDIAN); 1288 } 1289 return offset+8; 1290 } 1291 1292 /* Dissect a NTLM response. This is documented at 1293 http://ubiqx.org/cifs/SMB.html#SMB.8, para 2.8.5.3 */ 1294 1295 /* Attribute types */ 1296 /* 1297 * XXX - the davenport.sourceforge.net document cited above says that a 1298 * type of 5 has been seen, "apparently containing the 'parent' DNS 1299 * domain for servers in subdomains". 1300 * XXX: MS-NLMP info is newer than Davenport info; 1301 * The attribute type list and the attribute names below are 1302 * based upon MS-NLMP. 1303 */ 1304 1305 #define NTLM_TARGET_INFO_END 0x0000 1306 #define NTLM_TARGET_INFO_NB_COMPUTER_NAME 0x0001 1307 #define NTLM_TARGET_INFO_NB_DOMAIN_NAME 0x0002 1308 #define NTLM_TARGET_INFO_DNS_COMPUTER_NAME 0x0003 1309 #define NTLM_TARGET_INFO_DNS_DOMAIN_NAME 0x0004 1310 #define NTLM_TARGET_INFO_DNS_TREE_NAME 0x0005 1311 #define NTLM_TARGET_INFO_FLAGS 0x0006 1312 #define NTLM_TARGET_INFO_TIMESTAMP 0x0007 1313 #define NTLM_TARGET_INFO_RESTRICTIONS 0x0008 1314 #define NTLM_TARGET_INFO_TARGET_NAME 0x0009 1315 #define NTLM_TARGET_INFO_CHANNEL_BINDINGS 0x000A 1316 1317 static const value_string ntlm_name_types[] = { 1318 { NTLM_TARGET_INFO_END, "End of list" }, 1319 { NTLM_TARGET_INFO_NB_COMPUTER_NAME, "NetBIOS computer name" }, 1320 { NTLM_TARGET_INFO_NB_DOMAIN_NAME, "NetBIOS domain name" }, 1321 { NTLM_TARGET_INFO_DNS_COMPUTER_NAME, "DNS computer name" }, 1322 { NTLM_TARGET_INFO_DNS_DOMAIN_NAME, "DNS domain name" }, 1323 { NTLM_TARGET_INFO_DNS_TREE_NAME, "DNS tree name" }, 1324 { NTLM_TARGET_INFO_FLAGS, "Flags" }, 1325 { NTLM_TARGET_INFO_TIMESTAMP, "Timestamp" }, 1326 { NTLM_TARGET_INFO_RESTRICTIONS, "Restrictions" }, 1327 { NTLM_TARGET_INFO_TARGET_NAME, "Target Name"}, 1328 { NTLM_TARGET_INFO_CHANNEL_BINDINGS, "Channel Bindings"}, 1329 { 0, NULL } 1330 }; 1331 static value_string_ext ntlm_name_types_ext = VALUE_STRING_EXT_INIT(ntlm_name_types); 1332 1333 /* The following *must* match the order of the list of attribute types */ 1334 /* Assumption: values in the list are a sequence starting with 0 and */ 1335 /* with no gaps allowing a direct access of the array by attribute type */ 1336 static int *ntlmssp_hf_challenge_target_info_hf_ptr_array[] = { 1337 &hf_ntlmssp_challenge_target_info_end, 1338 &hf_ntlmssp_challenge_target_info_nb_computer_name, 1339 &hf_ntlmssp_challenge_target_info_nb_domain_name, 1340 &hf_ntlmssp_challenge_target_info_dns_computer_name, 1341 &hf_ntlmssp_challenge_target_info_dns_domain_name, 1342 &hf_ntlmssp_challenge_target_info_dns_tree_name, 1343 &hf_ntlmssp_challenge_target_info_flags, 1344 &hf_ntlmssp_challenge_target_info_timestamp, 1345 &hf_ntlmssp_challenge_target_info_restrictions, 1346 &hf_ntlmssp_challenge_target_info_target_name, 1347 &hf_ntlmssp_challenge_target_info_channel_bindings 1348 }; 1349 1350 static int *ntlmssp_hf_ntlmv2_response_hf_ptr_array[] = { 1351 &hf_ntlmssp_ntlmv2_response_end, 1352 &hf_ntlmssp_ntlmv2_response_nb_computer_name, 1353 &hf_ntlmssp_ntlmv2_response_nb_domain_name, 1354 &hf_ntlmssp_ntlmv2_response_dns_computer_name, 1355 &hf_ntlmssp_ntlmv2_response_dns_domain_name, 1356 &hf_ntlmssp_ntlmv2_response_dns_tree_name, 1357 &hf_ntlmssp_ntlmv2_response_flags, 1358 &hf_ntlmssp_ntlmv2_response_timestamp, 1359 &hf_ntlmssp_ntlmv2_response_restrictions, 1360 &hf_ntlmssp_ntlmv2_response_target_name, 1361 &hf_ntlmssp_ntlmv2_response_channel_bindings 1362 }; 1363 1364 typedef struct _tif { 1365 gint *ett; 1366 int *hf_item_type; 1367 int *hf_item_length; 1368 int **hf_attr_array_p; 1369 } tif_t; 1370 1371 static tif_t ntlmssp_challenge_target_info_tif = { 1372 &ett_ntlmssp_challenge_target_info_item, 1373 &hf_ntlmssp_challenge_target_info_item_type, 1374 &hf_ntlmssp_challenge_target_info_item_len, 1375 ntlmssp_hf_challenge_target_info_hf_ptr_array 1376 }; 1377 1378 static tif_t ntlmssp_ntlmv2_response_tif = { 1379 &ett_ntlmssp_ntlmv2_response_item, 1380 &hf_ntlmssp_ntlmv2_response_item_type, 1381 &hf_ntlmssp_ntlmv2_response_item_len, 1382 ntlmssp_hf_ntlmv2_response_hf_ptr_array 1383 }; 1384 1385 /** See [MS-NLMP] 2.2.2.1 */ 1386 static int 1387 dissect_ntlmssp_target_info_list(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, 1388 guint32 target_info_offset, guint16 target_info_length, 1389 tif_t *tif_p) 1390 { 1391 guint32 item_offset; 1392 guint16 item_type = ~0; 1393 guint16 item_length; 1394 1395 /* Now enumerate through the individual items in the list */ 1396 item_offset = target_info_offset; 1397 1398 while (item_offset < (target_info_offset + target_info_length) && (item_type != NTLM_TARGET_INFO_END)) { 1399 proto_item *target_info_tf; 1400 proto_tree *target_info_tree; 1401 guint32 content_offset; 1402 guint16 content_length; 1403 guint32 type_offset; 1404 guint32 len_offset; 1405 const guint8 *text = NULL; 1406 1407 int **hf_array_p = tif_p->hf_attr_array_p; 1408 1409 /* Content type */ 1410 type_offset = item_offset; 1411 item_type = tvb_get_letohs(tvb, type_offset); 1412 1413 /* Content length */ 1414 len_offset = type_offset + 2; 1415 content_length = tvb_get_letohs(tvb, len_offset); 1416 1417 /* Content value */ 1418 content_offset = len_offset + 2; 1419 item_length = content_length + 4; 1420 1421 target_info_tree = proto_tree_add_subtree_format(tree, tvb, item_offset, item_length, *tif_p->ett, &target_info_tf, 1422 "Attribute: %s", val_to_str_ext(item_type, &ntlm_name_types_ext, "Unknown (%d)")); 1423 1424 proto_tree_add_item (target_info_tree, *tif_p->hf_item_type, tvb, type_offset, 2, ENC_LITTLE_ENDIAN); 1425 proto_tree_add_item (target_info_tree, *tif_p->hf_item_length, tvb, len_offset, 2, ENC_LITTLE_ENDIAN); 1426 1427 if (content_length > 0) { 1428 switch (item_type) { 1429 case NTLM_TARGET_INFO_NB_COMPUTER_NAME: 1430 case NTLM_TARGET_INFO_NB_DOMAIN_NAME: 1431 case NTLM_TARGET_INFO_DNS_COMPUTER_NAME: 1432 case NTLM_TARGET_INFO_DNS_DOMAIN_NAME: 1433 case NTLM_TARGET_INFO_DNS_TREE_NAME: 1434 case NTLM_TARGET_INFO_TARGET_NAME: 1435 proto_tree_add_item_ret_string(target_info_tree, *hf_array_p[item_type], tvb, content_offset, content_length, ENC_UTF_16|ENC_LITTLE_ENDIAN, wmem_packet_scope(), &text); 1436 proto_item_append_text(target_info_tf, ": %s", text); 1437 break; 1438 1439 case NTLM_TARGET_INFO_FLAGS: 1440 proto_tree_add_item(target_info_tree, *hf_array_p[item_type], tvb, content_offset, content_length, ENC_LITTLE_ENDIAN); 1441 break; 1442 1443 case NTLM_TARGET_INFO_TIMESTAMP: 1444 dissect_nt_64bit_time(tvb, target_info_tree, content_offset, *hf_array_p[item_type]); 1445 break; 1446 1447 case NTLM_TARGET_INFO_RESTRICTIONS: 1448 case NTLM_TARGET_INFO_CHANNEL_BINDINGS: 1449 proto_tree_add_item(target_info_tree, *hf_array_p[item_type], tvb, content_offset, content_length, ENC_NA); 1450 break; 1451 1452 default: 1453 proto_tree_add_expert(target_info_tree, pinfo, &ei_ntlmssp_target_info_attr, 1454 tvb, content_offset, content_length); 1455 break; 1456 } 1457 } 1458 1459 item_offset += item_length; 1460 } 1461 1462 return item_offset; 1463 } 1464 1465 /** See [MS-NLMP] 3.3.2 */ 1466 int 1467 dissect_ntlmv2_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, int len) 1468 { 1469 proto_item *ntlmv2_item = NULL; 1470 proto_tree *ntlmv2_tree = NULL; 1471 const int orig_offset = offset; 1472 1473 /* XXX - make sure we don't go past len? */ 1474 if (tree) { 1475 ntlmv2_item = proto_tree_add_item( 1476 tree, hf_ntlmssp_ntlmv2_response, tvb, 1477 offset, len, ENC_NA); 1478 ntlmv2_tree = proto_item_add_subtree( 1479 ntlmv2_item, ett_ntlmssp_ntlmv2_response); 1480 } 1481 1482 proto_tree_add_item( 1483 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_ntproofstr, tvb, 1484 offset, 16, ENC_NA); 1485 offset += 16; 1486 1487 proto_tree_add_item(ntlmv2_tree, hf_ntlmssp_ntlmv2_response_rversion, tvb, offset, 1, ENC_LITTLE_ENDIAN); 1488 offset += 1; 1489 1490 proto_tree_add_item(ntlmv2_tree, hf_ntlmssp_ntlmv2_response_hirversion, tvb, offset, 1, ENC_LITTLE_ENDIAN); 1491 offset += 1; 1492 1493 proto_tree_add_item(ntlmv2_tree, hf_ntlmssp_ntlmv2_response_z, tvb, offset, 6, ENC_NA); 1494 offset += 6; 1495 1496 offset = dissect_nt_64bit_time( 1497 tvb, ntlmv2_tree, offset, hf_ntlmssp_ntlmv2_response_time); 1498 proto_tree_add_item( 1499 ntlmv2_tree, hf_ntlmssp_ntlmv2_response_chal, tvb, 1500 offset, 8, ENC_NA); 1501 offset += 8; 1502 1503 proto_tree_add_item(ntlmv2_tree, hf_ntlmssp_ntlmv2_response_z, tvb, offset, 4, ENC_NA); 1504 offset += 4; 1505 1506 offset = dissect_ntlmssp_target_info_list(tvb, pinfo, ntlmv2_tree, offset, len - (offset - orig_offset), &ntlmssp_ntlmv2_response_tif); 1507 1508 if ((offset - orig_offset) < len) { 1509 proto_tree_add_item(ntlmv2_tree, hf_ntlmssp_ntlmv2_response_z, tvb, offset, 4, ENC_NA); 1510 offset += 4; 1511 } 1512 1513 if ((offset - orig_offset) < len) { 1514 proto_tree_add_item(ntlmv2_tree, hf_ntlmssp_ntlmv2_response_pad, tvb, offset, len - (offset - orig_offset), ENC_NA); 1515 } 1516 1517 return offset+len; 1518 } 1519 1520 /* tapping into ntlmssph not yet implemented */ 1521 static int 1522 dissect_ntlmssp_negotiate (tvbuff_t *tvb, int offset, proto_tree *ntlmssp_tree, ntlmssp_header_t *ntlmssph _U_) 1523 { 1524 guint32 negotiate_flags; 1525 int data_start; 1526 int data_end; 1527 int item_start; 1528 int item_end; 1529 1530 /* NTLMSSP Negotiate Flags */ 1531 negotiate_flags = tvb_get_letohl (tvb, offset); 1532 proto_tree_add_bitmask(ntlmssp_tree, tvb, offset, hf_ntlmssp_negotiate_flags, ett_ntlmssp_negotiate_flags, ntlmssp_negotiate_flags, ENC_LITTLE_ENDIAN); 1533 offset += 4; 1534 1535 /* 1536 * XXX - the davenport document says that these might not be 1537 * sent at all, presumably meaning the length of the message 1538 * isn't enough to contain them. 1539 */ 1540 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE, 1541 hf_ntlmssp_negotiate_domain, 1542 &data_start, &data_end, NULL); 1543 1544 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, FALSE, 1545 hf_ntlmssp_negotiate_workstation, 1546 &item_start, &item_end, NULL); 1547 data_start = MIN(data_start, item_start); 1548 data_end = MAX(data_end, item_end); 1549 1550 /* If there are more bytes before the data block dissect a version field 1551 if NTLMSSP_NEGOTIATE_VERSION is set in the flags (see MS-NLMP) */ 1552 if (offset < data_start) { 1553 if (negotiate_flags & NTLMSSP_NEGOTIATE_VERSION) 1554 dissect_ntlmssp_version(tvb, offset, ntlmssp_tree); 1555 } 1556 return data_end; 1557 } 1558 1559 1560 static int 1561 dissect_ntlmssp_challenge_target_info_blob (packet_info *pinfo, tvbuff_t *tvb, int offset, 1562 proto_tree *ntlmssp_tree, 1563 int *end) 1564 { 1565 guint16 challenge_target_info_length = tvb_get_letohs(tvb, offset); 1566 guint16 challenge_target_info_maxlen = tvb_get_letohs(tvb, offset+2); 1567 guint32 challenge_target_info_offset = tvb_get_letohl(tvb, offset+4); 1568 proto_item *tf = NULL; 1569 proto_tree *challenge_target_info_tree = NULL; 1570 1571 /* the target info list is just a blob */ 1572 if (0 == challenge_target_info_length) { 1573 *end = (challenge_target_info_offset > ((guint)offset)+8 ? challenge_target_info_offset : ((guint)offset)+8); 1574 proto_tree_add_none_format(ntlmssp_tree, hf_ntlmssp_challenge_target_info, tvb, offset, 8, 1575 "Target Info List: Empty"); 1576 return offset+8; 1577 } 1578 1579 if (ntlmssp_tree) { 1580 tf = proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_challenge_target_info, tvb, 1581 challenge_target_info_offset, challenge_target_info_length, ENC_NA); 1582 challenge_target_info_tree = proto_item_add_subtree(tf, ett_ntlmssp_challenge_target_info); 1583 } 1584 proto_tree_add_uint(challenge_target_info_tree, hf_ntlmssp_challenge_target_info_len, 1585 tvb, offset, 2, challenge_target_info_length); 1586 offset += 2; 1587 proto_tree_add_uint(challenge_target_info_tree, hf_ntlmssp_challenge_target_info_maxlen, 1588 tvb, offset, 2, challenge_target_info_maxlen); 1589 offset += 2; 1590 proto_tree_add_uint(challenge_target_info_tree, hf_ntlmssp_challenge_target_info_offset, 1591 tvb, offset, 4, challenge_target_info_offset); 1592 offset += 4; 1593 1594 dissect_ntlmssp_target_info_list(tvb, pinfo, challenge_target_info_tree, 1595 challenge_target_info_offset, challenge_target_info_length, 1596 &ntlmssp_challenge_target_info_tif); 1597 1598 *end = challenge_target_info_offset + challenge_target_info_length; 1599 return offset; 1600 } 1601 1602 /* tapping into ntlmssph not yet implemented */ 1603 static int 1604 dissect_ntlmssp_challenge (tvbuff_t *tvb, packet_info *pinfo, int offset, 1605 proto_tree *ntlmssp_tree, ntlmssp_header_t *ntlmssph _U_) 1606 { 1607 guint32 negotiate_flags = 0; 1608 int item_start, item_end; 1609 int data_start, data_end; /* MIN and MAX seen */ 1610 guint8 clientkey[NTLMSSP_KEY_LEN]; /* NTLMSSP cipher key for client */ 1611 guint8 serverkey[NTLMSSP_KEY_LEN]; /* NTLMSSP cipher key for server*/ 1612 ntlmssp_info *conv_ntlmssp_info = NULL; 1613 conversation_t *conversation; 1614 gboolean unicode_strings = FALSE; 1615 guint8 tmp[8]; 1616 guint8 sspkey[NTLMSSP_KEY_LEN]; /* NTLMSSP cipher key */ 1617 int ssp_key_len; /* Either 8 or 16 (40 bit or 128) */ 1618 1619 /* 1620 * Use the negotiate flags in this message, if they're present 1621 * in the capture, to determine whether strings are Unicode or 1622 * not. 1623 * 1624 * offset points at TargetNameFields; skip pats it. 1625 */ 1626 if (tvb_bytes_exist(tvb, offset+8, 4)) { 1627 negotiate_flags = tvb_get_letohl (tvb, offset+8); 1628 if (negotiate_flags & NTLMSSP_NEGOTIATE_UNICODE) 1629 unicode_strings = TRUE; 1630 } 1631 1632 /* Target name */ 1633 /* 1634 * XXX - the davenport document (and MS-NLMP) calls this "Target Name", 1635 * presumably because non-domain targets are supported. 1636 * XXX - Original name "domain" changed to "target_name" to match MS-NLMP 1637 */ 1638 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, unicode_strings, 1639 hf_ntlmssp_challenge_target_name, 1640 &item_start, &item_end, NULL); 1641 data_start = item_start; 1642 data_end = item_end; 1643 1644 /* NTLMSSP Negotiate Flags */ 1645 proto_tree_add_bitmask(ntlmssp_tree, tvb, offset, hf_ntlmssp_negotiate_flags, ett_ntlmssp_negotiate_flags, ntlmssp_negotiate_flags, ENC_LITTLE_ENDIAN); 1646 offset += 4; 1647 1648 /* NTLMSSP NT Lan Manager Challenge */ 1649 proto_tree_add_item (ntlmssp_tree, 1650 hf_ntlmssp_ntlm_server_challenge, 1651 tvb, offset, 8, ENC_NA); 1652 1653 /* 1654 * Store the flags and the RC4 state information with the conversation, 1655 * as they're needed in order to dissect subsequent messages. 1656 */ 1657 conversation = find_or_create_conversation(pinfo); 1658 1659 tvb_memcpy(tvb, tmp, offset, 8); /* challenge */ 1660 /* We can face more than one NTLM exchange over the same couple of IP and ports ...*/ 1661 conv_ntlmssp_info = (ntlmssp_info *)conversation_get_proto_data(conversation, proto_ntlmssp); 1662 /* XXX: The following code is (re)executed every time a particular frame is dissected 1663 * (in whatever order). Thus it seems to me that "multiple exchanges" might not be 1664 * handled well depending on the order that frames are visited after the initial dissection. 1665 */ 1666 if (!conv_ntlmssp_info || memcmp(tmp, conv_ntlmssp_info->server_challenge, 8) != 0) { 1667 conv_ntlmssp_info = wmem_new0(wmem_file_scope(), ntlmssp_info); 1668 wmem_register_callback(wmem_file_scope(), ntlmssp_sessions_destroy_cb, conv_ntlmssp_info); 1669 /* Insert the flags into the conversation */ 1670 conv_ntlmssp_info->flags = negotiate_flags; 1671 conv_ntlmssp_info->saw_challenge = TRUE; 1672 /* Insert the RC4 state information into the conversation */ 1673 tvb_memcpy(tvb, conv_ntlmssp_info->server_challenge, offset, 8); 1674 /* Between the challenge and the user provided password, we can build the 1675 NTLMSSP key and initialize the cipher if we are not in EXTENDED SECURITY 1676 in this case we need the client challenge as well*/ 1677 /* BTW this is true just if we are in LM Authentication if not the logic is a bit different. 1678 * Right now it's not very clear what is LM Authentication it __seems__ to be when 1679 * NEGOTIATE NT ONLY is not set and NEGOSIATE EXTENDED SECURITY is not set as well*/ 1680 if (!(conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY)) 1681 { 1682 conv_ntlmssp_info->rc4_state_initialized = FALSE; 1683 /* XXX - Make sure there is 24 bytes for the key */ 1684 conv_ntlmssp_info->ntlm_response.contents = (guint8 *)wmem_alloc0(wmem_file_scope(), 24); 1685 conv_ntlmssp_info->lm_response.contents = (guint8 *)wmem_alloc0(wmem_file_scope(), 24); 1686 1687 create_ntlmssp_v1_key(conv_ntlmssp_info->server_challenge, 1688 NULL, sspkey, NULL, conv_ntlmssp_info->flags, 1689 conv_ntlmssp_info->ntlm_response.contents, 1690 conv_ntlmssp_info->lm_response.contents, 1691 ntlmssph, pinfo, ntlmssp_tree); 1692 if (memcmp(sspkey, gbl_zeros, NTLMSSP_KEY_LEN) != 0) { 1693 get_sealing_rc4key(sspkey, conv_ntlmssp_info->flags, &ssp_key_len, clientkey, serverkey); 1694 if (!gcry_cipher_open(&conv_ntlmssp_info->rc4_handle_client, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)) { 1695 if (gcry_cipher_setkey(conv_ntlmssp_info->rc4_handle_client, sspkey, ssp_key_len)) { 1696 gcry_cipher_close(conv_ntlmssp_info->rc4_handle_client); 1697 conv_ntlmssp_info->rc4_handle_client = NULL; 1698 } 1699 } 1700 if (!gcry_cipher_open(&conv_ntlmssp_info->rc4_handle_server, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)) { 1701 if (gcry_cipher_setkey(conv_ntlmssp_info->rc4_handle_server, sspkey, ssp_key_len)) { 1702 gcry_cipher_close(conv_ntlmssp_info->rc4_handle_server); 1703 conv_ntlmssp_info->rc4_handle_server = NULL; 1704 } 1705 } 1706 if (conv_ntlmssp_info->rc4_handle_client && conv_ntlmssp_info->rc4_handle_server) { 1707 conv_ntlmssp_info->server_dest_port = pinfo->destport; 1708 conv_ntlmssp_info->rc4_state_initialized = TRUE; 1709 } 1710 } 1711 } 1712 conversation_add_proto_data(conversation, proto_ntlmssp, conv_ntlmssp_info); 1713 } 1714 offset += 8; 1715 1716 /* If no more bytes (ie: no "reserved", ...) before start of data block, then return */ 1717 /* XXX: According to Davenport "This form is seen in older Win9x-based systems" */ 1718 /* Also: I've seen a capture with an HTTP CONNECT proxy-authentication */ 1719 /* message wherein the challenge from the proxy has this form. */ 1720 if (offset >= data_start) { 1721 return data_end; 1722 } 1723 1724 /* Reserved (function not completely known) */ 1725 /* 1726 * XXX - SSP key? The davenport document says 1727 * 1728 * The context field is typically populated when Negotiate Local 1729 * Call is set. It contains an SSPI context handle, which allows 1730 * the client to "short-circuit" authentication and effectively 1731 * circumvent responding to the challenge. Physically, the context 1732 * is two long values. This is covered in greater detail later, 1733 * in the "Local Authentication" section. 1734 * 1735 * It also says that that information may be omitted. 1736 */ 1737 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_reserved, 1738 tvb, offset, 8, ENC_NA); 1739 offset += 8; 1740 1741 /* 1742 * The presence or absence of this field is not obviously correlated 1743 * with any flags in the previous NEGOTIATE message or in this 1744 * message (other than the "Workstation Supplied" and "Domain 1745 * Supplied" flags in the NEGOTIATE message, at least in the capture 1746 * I've seen - but those also correlate with the presence of workstation 1747 * and domain name fields, so it doesn't seem to make sense that they 1748 * actually *indicate* whether the subsequent CHALLENGE has an 1749 * address list). 1750 */ 1751 if (offset < data_start) { 1752 offset = dissect_ntlmssp_challenge_target_info_blob(pinfo, tvb, offset, ntlmssp_tree, &item_end); 1753 /* XXX: This code assumes that the address list in the data block */ 1754 /* is always after the target name. Is this OK ? */ 1755 data_end = MAX(data_end, item_end); 1756 } 1757 1758 /* If there are more bytes before the data block dissect a version field 1759 if NTLMSSP_NEGOTIATE_VERSION is set in the flags (see MS-NLMP) */ 1760 if (offset < data_start) { 1761 if (negotiate_flags & NTLMSSP_NEGOTIATE_VERSION) 1762 offset = dissect_ntlmssp_version(tvb, offset, ntlmssp_tree); 1763 } 1764 1765 return MAX(offset, data_end); 1766 } 1767 1768 static int 1769 dissect_ntlmssp_auth (tvbuff_t *tvb, packet_info *pinfo, int offset, 1770 proto_tree *ntlmssp_tree, ntlmssp_header_t *ntlmssph) 1771 { 1772 int item_start, item_end; 1773 int data_start, data_end = 0; 1774 gboolean have_negotiate_flags = FALSE; 1775 guint32 negotiate_flags; 1776 guint8 sspkey[NTLMSSP_KEY_LEN]; /* exported session key */ 1777 guint8 clientkey[NTLMSSP_KEY_LEN]; /* NTLMSSP cipher key for client */ 1778 guint8 serverkey[NTLMSSP_KEY_LEN]; /* NTLMSSP cipher key for server*/ 1779 guint8 encryptedsessionkey[NTLMSSP_KEY_LEN]; 1780 ntlmssp_blob sessionblob; 1781 gboolean unicode_strings = FALSE; 1782 ntlmssp_info *conv_ntlmssp_info; 1783 conversation_t *conversation; 1784 int ssp_key_len; 1785 1786 conv_ntlmssp_info = (ntlmssp_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_ntlmssp, NTLMSSP_CONV_INFO_KEY); 1787 if (conv_ntlmssp_info == NULL) { 1788 /* 1789 * There isn't any. Is there any from this conversation? If so, 1790 * it means this is the first time we've dissected this frame, so 1791 * we should give it flag info. 1792 */ 1793 /* XXX: Create conv_ntlmssp_info & etc if no previous CHALLENGE seen */ 1794 /* so we'll have a place to store flags. */ 1795 /* This is a bit brute-force but looks like it will be OK. */ 1796 conversation = find_or_create_conversation(pinfo); 1797 conv_ntlmssp_info = (ntlmssp_info *)conversation_get_proto_data(conversation, proto_ntlmssp); 1798 if (conv_ntlmssp_info == NULL) { 1799 conv_ntlmssp_info = wmem_new0(wmem_file_scope(), ntlmssp_info); 1800 wmem_register_callback(wmem_file_scope(), ntlmssp_sessions_destroy_cb, conv_ntlmssp_info); 1801 conversation_add_proto_data(conversation, proto_ntlmssp, conv_ntlmssp_info); 1802 } 1803 /* XXX: The *conv_ntlmssp_info struct attached to the frame is the 1804 same as the one attached to the conversation. That is: *both* point to 1805 the exact same struct in memory. Is this what is indended ? */ 1806 p_add_proto_data(wmem_file_scope(), pinfo, proto_ntlmssp, NTLMSSP_CONV_INFO_KEY, conv_ntlmssp_info); 1807 } 1808 1809 /* 1810 * Get flag info from the original negotiate message, if any. 1811 * This is because the flag information is sometimes missing from 1812 * the AUTHENTICATE message, so we can't figure out whether 1813 * strings are Unicode or not by looking at *our* flags. 1814 * 1815 * MS-NLMP says: 1816 * 1817 * In 2.2.1.1 NEGOTIATE_MESSAGE: 1818 * 1819 * NegotiateFlags (4 bytes): A NEGOTIATE structure that contains a set 1820 * of flags, as defined in section 2.2.2.5. The client sets flags to 1821 * indicate options it supports. 1822 * 1823 * In 2.2.1.2 CHALLENGE_MESSAGE: 1824 * 1825 * NegotiateFlags (4 bytes): A NEGOTIATE structure that contains a set 1826 * of flags, as defined by section 2.2.2.5. The server sets flags to 1827 * indicate options it supports or, if there has been a NEGOTIATE_MESSAGE 1828 * (section 2.2.1.1), the choices it has made from the options offered 1829 * by the client. 1830 * 1831 * In 2.2.1.3 AUTHENTICATE_MESSAGE: 1832 * 1833 * NegotiateFlags (4 bytes): In connectionless mode, a NEGOTIATE 1834 * structure that contains a set of flags (section 2.2.2.5) and 1835 * represents the conclusion of negotiation--the choices the client 1836 * has made from the options the server offered in the CHALLENGE_MESSAGE. 1837 * In connection-oriented mode, a NEGOTIATE structure that contains the 1838 * set of bit flags (section 2.2.2.5) negotiated in the previous messages. 1839 * 1840 * As 1.3.1 NTLM Authentication Call Flow indicates, in connectionless 1841 * mode, there's no NEGOTIATE_MESSAGE, just a CHALLENGE_MESSAGE and 1842 * an AUTHENTICATE_MESSAGE. 1843 * 1844 * So, for connectionless mode, with no NEGOTIATE_MESSAGE, the flags 1845 * that are the result of negotiation are in the AUTHENTICATE_MESSAGE; 1846 * only at the time the AUTHENTICATE_MESSAGE is sent does the client 1847 * know what the server is offering, so, at that point, it can indicate 1848 * to the server which of those it supports, with the final result 1849 * specifying the capabilities offered by the server that are also 1850 * supported by the client. 1851 * 1852 * For connection-oriented mode, at the time of the CHALLENGE_MESSAGE, 1853 * the server knows what capabilities the client supports, as those 1854 * we specified in the NEGOTIATE_MESSAGE, so it returns the set of 1855 * capabilities, from the set that the client supports, that it also 1856 * supports, so the CHALLENGE_MESSAGE contains the final result. The 1857 * AUTHENTICATE_MESSAGE "contains the set of bit flags ... negotiated 1858 * in the previous messages", so it should contain the same set of 1859 * bit flags that were in the CHALLENGE_MESSAGE. 1860 * 1861 * So we use the flags in this message, the AUTHENTICATE_MESSAGE, if 1862 * they're present; if this is connectionless mode, the flags in the 1863 * CHALLENGE_MESSAGE aren't sufficient, as they don't indicate what 1864 * the client supports, and if this is connection-oriented mode, the 1865 * flags here should match what's in the CHALLENGE_MESSAGE. 1866 * 1867 * The flags might be missing from this message; the message could 1868 * have been cut short by the snapshot length, and even if it's not, 1869 * some older protocol implementations omit it. If they're missing, 1870 * we fall back on what's in the CHALLENGE_MESSAGE. 1871 * 1872 * XXX: I've seen a capture which does an HTTP CONNECT which: 1873 * - has the NEGOTIATE & CHALLENGE messages in one TCP connection; 1874 * - has the AUTHENTICATE message in a second TCP connection; 1875 * (The authentication aparently succeeded). 1876 * For that case, in order to get the flags from the CHALLENGE_MESSAGE, 1877 * we'd somehow have to manage NTLMSSP exchanges that cross TCP 1878 * connection boundaries. 1879 * 1880 * offset points at LmChallengeResponseFields; skip past 1881 * LmChallengeResponseFields, NtChallengeResponseFields, 1882 * DomainNameFields, UserNameFields, WorkstationFields, 1883 * and EncryptedRandomSessionKeyFields. 1884 */ 1885 if (tvb_bytes_exist(tvb, offset+8+8+8+8+8+8, 4)) { 1886 /* 1887 * See where the Lan Manager response's blob begins; 1888 * the data area starts at, or before, that location. 1889 */ 1890 data_start = tvb_get_letohl(tvb, offset+4); 1891 1892 /* 1893 * See where the NTLM response's blob begins; the data area 1894 * starts at, or before, that location. 1895 */ 1896 item_start = tvb_get_letohl(tvb, offset+8+4); 1897 data_start = MIN(data_start, item_start); 1898 1899 /* 1900 * See where the domain name's blob begins; the data area 1901 * starts at, or before, that location. 1902 */ 1903 item_start = tvb_get_letohl(tvb, offset+8+8+4); 1904 data_start = MIN(data_start, item_start); 1905 1906 /* 1907 * See where the user name's blob begins; the data area 1908 * starts at, or before, that location. 1909 */ 1910 item_start = tvb_get_letohl(tvb, offset+8+8+8+4); 1911 data_start = MIN(data_start, item_start); 1912 1913 /* 1914 * See where the host name's blob begins; the data area 1915 * starts at, or before, that location. 1916 */ 1917 item_start = tvb_get_letohl(tvb, offset+8+8+8+8+4); 1918 data_start = MIN(data_start, item_start); 1919 1920 /* 1921 * See if we have a session key and flags. 1922 */ 1923 if (offset+8+8+8+8+8 < data_start) { 1924 /* 1925 * We have a session key and flags. 1926 */ 1927 negotiate_flags = tvb_get_letohl (tvb, offset+8+8+8+8+8+8); 1928 have_negotiate_flags = TRUE; 1929 if (negotiate_flags & NTLMSSP_NEGOTIATE_UNICODE) 1930 unicode_strings = TRUE; 1931 } 1932 } 1933 if (!have_negotiate_flags) { 1934 /* 1935 * The flags from this message aren't present; if we have the 1936 * flags from the CHALLENGE message, use them. 1937 */ 1938 if (conv_ntlmssp_info != NULL && conv_ntlmssp_info->saw_challenge) { 1939 if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_UNICODE) 1940 unicode_strings = TRUE; 1941 } 1942 } 1943 1944 /* 1945 * Sometimes the session key and flags are missing. 1946 * Sometimes the session key is present but the flags are missing. 1947 * XXX Who stay so ? Reading spec I would rather say the opposite: flags are 1948 * always present, session information are always there as well but sometime 1949 * session information could be null (in case of no session) 1950 * Sometimes they're both present. 1951 * 1952 * This does not correlate with any flags in the previous CHALLENGE 1953 * message, and only correlates with "Negotiate Unicode", "Workstation 1954 * Supplied", and "Domain Supplied" in the NEGOTIATE message - but 1955 * those don't make sense as flags to use to determine this. 1956 * 1957 * So we check all of the descriptors to figure out where the data 1958 * area begins, and if the session key or the flags would be in the 1959 * middle of the data area, we assume the field in question is 1960 * missing. 1961 * 1962 * XXX - Reading Davenport and MS-NLMP: as I see it the possibilities are: 1963 * a. No session-key; no flags; no version ("Win9x") 1964 * b. Session-key & flags. 1965 * c. Session-key, flags & version. 1966 * In cases b and c the session key may be "null". 1967 * 1968 */ 1969 1970 /* Lan Manager response */ 1971 data_start = tvb_get_letohl(tvb, offset+4); 1972 offset = dissect_ntlmssp_blob(tvb, pinfo, ntlmssp_tree, offset, 1973 hf_ntlmssp_auth_lmresponse, 1974 &item_end, 1975 conv_ntlmssp_info == NULL ? NULL : 1976 &conv_ntlmssp_info->lm_response); 1977 data_end = MAX(data_end, item_end); 1978 1979 /* NTLM response */ 1980 item_start = tvb_get_letohl(tvb, offset+4); 1981 offset = dissect_ntlmssp_blob(tvb, pinfo, ntlmssp_tree, offset, 1982 hf_ntlmssp_auth_ntresponse, 1983 &item_end, 1984 conv_ntlmssp_info == NULL ? NULL : 1985 &conv_ntlmssp_info->ntlm_response); 1986 data_start = MIN(data_start, item_start); 1987 data_end = MAX(data_end, item_end); 1988 1989 /* domain name */ 1990 item_start = tvb_get_letohl(tvb, offset+4); 1991 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, 1992 unicode_strings, 1993 hf_ntlmssp_auth_domain, 1994 &item_start, &item_end, &(ntlmssph->domain_name)); 1995 /*ntlmssph->domain_name_len = item_end-item_start;*/ 1996 data_start = MIN(data_start, item_start); 1997 data_end = MAX(data_end, item_end); 1998 1999 /* user name */ 2000 item_start = tvb_get_letohl(tvb, offset+4); 2001 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, 2002 unicode_strings, 2003 hf_ntlmssp_auth_username, 2004 &item_start, &item_end, &(ntlmssph->acct_name)); 2005 /*ntlmssph->acct_name_len = item_end-item_start;*/ 2006 data_start = MIN(data_start, item_start); 2007 data_end = MAX(data_end, item_end); 2008 2009 col_append_sep_fstr(pinfo->cinfo, COL_INFO, ", ", "User: %s\\%s", 2010 ntlmssph->domain_name, ntlmssph->acct_name); 2011 2012 /* hostname */ 2013 item_start = tvb_get_letohl(tvb, offset+4); 2014 offset = dissect_ntlmssp_string(tvb, offset, ntlmssp_tree, 2015 unicode_strings, 2016 hf_ntlmssp_auth_hostname, 2017 &item_start, &item_end, &(ntlmssph->host_name)); 2018 data_start = MIN(data_start, item_start); 2019 data_end = MAX(data_end, item_end); 2020 2021 sessionblob.length = 0; 2022 if (offset < data_start) { 2023 /* Session Key */ 2024 offset = dissect_ntlmssp_blob(tvb, pinfo, ntlmssp_tree, offset, 2025 hf_ntlmssp_auth_sesskey, 2026 &item_end, &sessionblob); 2027 data_end = MAX(data_end, item_end); 2028 } 2029 2030 if (offset < data_start) { 2031 /* NTLMSSP Negotiate Flags */ 2032 negotiate_flags = tvb_get_letohl (tvb, offset); 2033 proto_tree_add_bitmask(ntlmssp_tree, tvb, offset, hf_ntlmssp_negotiate_flags, ett_ntlmssp_negotiate_flags, ntlmssp_negotiate_flags, ENC_LITTLE_ENDIAN); 2034 offset += 4; 2035 2036 /* If no previous flags seen (ie: no previous CHALLENGE) use flags 2037 from the AUTHENTICATE message). 2038 Assumption: (flags == 0) means flags not previously seen */ 2039 if ((conv_ntlmssp_info != NULL) && (conv_ntlmssp_info->flags == 0)) { 2040 conv_ntlmssp_info->flags = negotiate_flags; 2041 } 2042 } else 2043 negotiate_flags = 0; 2044 2045 /* If there are more bytes before the data block dissect a version field 2046 if NTLMSSP_NEGOTIATE_VERSION is set in the flags (see MS-NLMP) */ 2047 if (offset < data_start) { 2048 if (negotiate_flags & NTLMSSP_NEGOTIATE_VERSION) 2049 offset = dissect_ntlmssp_version(tvb, offset, ntlmssp_tree); 2050 } 2051 2052 /* If there are still more bytes before the data block dissect an MIC (message integrity_code) field */ 2053 /* (See MS-NLMP) */ 2054 if (offset < data_start) { 2055 proto_tree_add_item(ntlmssp_tree, hf_ntlmssp_message_integrity_code, tvb, offset, 16, ENC_NA); 2056 offset += 16; 2057 } 2058 2059 if (sessionblob.length > NTLMSSP_KEY_LEN) { 2060 expert_add_info_format(pinfo, NULL, &ei_ntlmssp_blob_len_too_long, "Session blob length too long: %u", sessionblob.length); 2061 } else if (sessionblob.length != 0) { 2062 memcpy(encryptedsessionkey, sessionblob.contents, sessionblob.length); 2063 /* Try to attach to an existing conversation if not then it's useless to try to do so 2064 * because we are missing important information (ie. server challenge) 2065 */ 2066 if (conv_ntlmssp_info) { 2067 /* If we are in EXTENDED SECURITY then we can now initialize cipher */ 2068 if ((conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY)) 2069 { 2070 conv_ntlmssp_info->rc4_state_initialized = FALSE; 2071 ntlmssp_create_session_key(pinfo, 2072 ntlmssp_tree, 2073 ntlmssph, 2074 conv_ntlmssp_info->flags, 2075 conv_ntlmssp_info->server_challenge, 2076 encryptedsessionkey, 2077 &conv_ntlmssp_info->ntlm_response, 2078 &conv_ntlmssp_info->lm_response); 2079 /* ssp is the exported session key */ 2080 memcpy(sspkey, ntlmssph->session_key, NTLMSSP_KEY_LEN); 2081 if (memcmp(sspkey, gbl_zeros, NTLMSSP_KEY_LEN) != 0) { 2082 get_sealing_rc4key(sspkey, conv_ntlmssp_info->flags, &ssp_key_len, clientkey, serverkey); 2083 get_siging_key((guint8*)&conv_ntlmssp_info->sign_key_server, (guint8*)&conv_ntlmssp_info->sign_key_client, sspkey, ssp_key_len); 2084 if (!gcry_cipher_open (&conv_ntlmssp_info->rc4_handle_server, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)) { 2085 if (gcry_cipher_setkey(conv_ntlmssp_info->rc4_handle_server, serverkey, ssp_key_len)) { 2086 gcry_cipher_close(conv_ntlmssp_info->rc4_handle_server); 2087 conv_ntlmssp_info->rc4_handle_server = NULL; 2088 } 2089 } 2090 if (!gcry_cipher_open (&conv_ntlmssp_info->rc4_handle_client, GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM, 0)) { 2091 if (gcry_cipher_setkey(conv_ntlmssp_info->rc4_handle_client, clientkey, ssp_key_len)) { 2092 gcry_cipher_close(conv_ntlmssp_info->rc4_handle_client); 2093 conv_ntlmssp_info->rc4_handle_client = NULL; 2094 } 2095 } 2096 if (conv_ntlmssp_info->rc4_handle_server && conv_ntlmssp_info->rc4_handle_client) { 2097 conv_ntlmssp_info->server_dest_port = pinfo->destport; 2098 conv_ntlmssp_info->rc4_state_initialized = TRUE; 2099 } 2100 } 2101 } 2102 } 2103 } 2104 return MAX(offset, data_end); 2105 } 2106 2107 static guint8* 2108 get_sign_key(packet_info *pinfo, int cryptpeer) 2109 { 2110 conversation_t *conversation; 2111 ntlmssp_info *conv_ntlmssp_info; 2112 2113 conversation = find_conversation_pinfo(pinfo, 0); 2114 if (conversation == NULL) { 2115 /* We don't have a conversation. In this case, stop processing 2116 because we do not have enough info to decrypt the payload */ 2117 return NULL; 2118 } 2119 else { 2120 /* We have a conversation, check for encryption state */ 2121 conv_ntlmssp_info = (ntlmssp_info *)conversation_get_proto_data(conversation, 2122 proto_ntlmssp); 2123 if (conv_ntlmssp_info == NULL) { 2124 /* No encryption state tied to the conversation. Therefore, we 2125 cannot decrypt the payload */ 2126 return NULL; 2127 } 2128 else { 2129 /* We have the encryption state in the conversation. So return the 2130 crypt state tied to the requested peer 2131 */ 2132 if (cryptpeer == 1) { 2133 return (guint8*)&conv_ntlmssp_info->sign_key_client; 2134 } else { 2135 return (guint8*)&conv_ntlmssp_info->sign_key_server; 2136 } 2137 } 2138 } 2139 } 2140 2141 /* 2142 * Get the encryption state tied to this conversation. cryptpeer indicates 2143 * whether to retrieve the client key (1) or the server key (0) 2144 */ 2145 static gcry_cipher_hd_t 2146 get_encrypted_state(packet_info *pinfo, int cryptpeer) 2147 { 2148 conversation_t *conversation; 2149 ntlmssp_info *conv_ntlmssp_info; 2150 2151 conversation = find_conversation_pinfo(pinfo, 0); 2152 if (conversation == NULL) { 2153 /* We don't have a conversation. In this case, stop processing 2154 because we do not have enough info to decrypt the payload */ 2155 return NULL; 2156 } 2157 else { 2158 /* We have a conversation, check for encryption state */ 2159 conv_ntlmssp_info = (ntlmssp_info *)conversation_get_proto_data(conversation, 2160 proto_ntlmssp); 2161 if (conv_ntlmssp_info == NULL) { 2162 /* No encryption state tied to the conversation. Therefore, we 2163 cannot decrypt the payload */ 2164 return NULL; 2165 } 2166 else { 2167 /* We have the encryption state in the conversation. So return the 2168 crypt state tied to the requested peer 2169 */ 2170 if (cryptpeer == 1) { 2171 return conv_ntlmssp_info->rc4_handle_client; 2172 } else { 2173 return conv_ntlmssp_info->rc4_handle_server; 2174 } 2175 } 2176 } 2177 } 2178 2179 static tvbuff_t* 2180 decrypt_data_payload(tvbuff_t *tvb, int offset, guint32 encrypted_block_length, 2181 packet_info *pinfo, proto_tree *tree _U_, gpointer key); 2182 static void 2183 decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length, 2184 packet_info *pinfo, proto_tree *tree, gpointer key); 2185 2186 static int 2187 dissect_ntlmssp_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) 2188 { 2189 volatile int offset = 0; 2190 proto_tree *volatile ntlmssp_tree = NULL; 2191 proto_item *tf = NULL; 2192 guint32 length; 2193 guint32 encrypted_block_length; 2194 guint8 key[NTLMSSP_KEY_LEN]; 2195 /* the magic ntlm is the identifier of a NTLMSSP packet that's 00 00 00 01 */ 2196 guint32 ntlm_magic_size = 4; 2197 guint32 ntlm_signature_size = 8; 2198 guint32 ntlm_seq_size = 4; 2199 2200 length = tvb_captured_length (tvb); 2201 /* signature + seq + real payload */ 2202 encrypted_block_length = length - ntlm_magic_size; 2203 2204 if (encrypted_block_length < (ntlm_signature_size + ntlm_seq_size)) { 2205 /* Don't know why this would happen, but if it does, don't even bother 2206 attempting decryption/dissection */ 2207 return offset + length; 2208 } 2209 2210 /* Setup a new tree for the NTLMSSP payload */ 2211 if (tree) { 2212 tf = proto_tree_add_item (tree, 2213 hf_ntlmssp_verf, 2214 tvb, offset, -1, ENC_NA); 2215 2216 ntlmssp_tree = proto_item_add_subtree (tf, 2217 ett_ntlmssp); 2218 } 2219 2220 /* 2221 * Catch the ReportedBoundsError exception; the stuff we've been 2222 * handed doesn't necessarily run to the end of the packet, it's 2223 * an item inside a packet, so if it happens to be malformed (or 2224 * we, or a dissector we call, has a bug), so that an exception 2225 * is thrown, we want to report the error, but return and let 2226 * our caller dissect the rest of the packet. 2227 * 2228 * If it gets a BoundsError, we can stop, as there's nothing more 2229 * in the packet after our blob to see, so we just re-throw the 2230 * exception. 2231 */ 2232 TRY { 2233 /* Version number */ 2234 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_vers, 2235 tvb, offset, 4, ENC_LITTLE_ENDIAN); 2236 offset += 4; 2237 2238 /* Encrypted body */ 2239 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_body, 2240 tvb, offset, ntlm_signature_size + ntlm_seq_size, ENC_NA); 2241 memset(key, 0, sizeof(key)); 2242 tvb_memcpy(tvb, key, offset, ntlm_signature_size + ntlm_seq_size); 2243 /* Try to decrypt */ 2244 decrypt_data_payload (tvb, offset+(ntlm_signature_size + ntlm_seq_size), encrypted_block_length-(ntlm_signature_size + ntlm_seq_size), pinfo, ntlmssp_tree, key); 2245 decrypt_verifier (tvb, offset, ntlm_signature_size + ntlm_seq_size, pinfo, ntlmssp_tree, key); 2246 /* let's try to hook ourselves here */ 2247 2248 offset += 12; 2249 } CATCH_NONFATAL_ERRORS { 2250 show_exception(tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE); 2251 } ENDTRY; 2252 2253 return offset; 2254 } 2255 2256 static tvbuff_t* 2257 decrypt_data_payload(tvbuff_t *tvb, int offset, guint32 encrypted_block_length, 2258 packet_info *pinfo, proto_tree *tree _U_, gpointer key) 2259 { 2260 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */ 2261 ntlmssp_packet_info *packet_ntlmssp_info; 2262 ntlmssp_packet_info *stored_packet_ntlmssp_info = NULL; 2263 2264 /* Check to see if we already have state for this packet */ 2265 packet_ntlmssp_info = (ntlmssp_packet_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_ntlmssp, NTLMSSP_PACKET_INFO_KEY); 2266 if (packet_ntlmssp_info == NULL) { 2267 /* We don't have any packet state, so create one */ 2268 packet_ntlmssp_info = wmem_new0(wmem_file_scope(), ntlmssp_packet_info); 2269 p_add_proto_data(wmem_file_scope(), pinfo, proto_ntlmssp, NTLMSSP_PACKET_INFO_KEY, packet_ntlmssp_info); 2270 } 2271 if (!packet_ntlmssp_info->payload_decrypted) { 2272 conversation_t *conversation; 2273 ntlmssp_info *conv_ntlmssp_info; 2274 2275 /* Pull the challenge info from the conversation */ 2276 conversation = find_conversation_pinfo(pinfo, 0); 2277 if (conversation == NULL) { 2278 /* There is no conversation, thus no encryption state */ 2279 return NULL; 2280 } 2281 2282 conv_ntlmssp_info = (ntlmssp_info *)conversation_get_proto_data(conversation, 2283 proto_ntlmssp); 2284 if (conv_ntlmssp_info == NULL) { 2285 /* There is no NTLMSSP state tied to the conversation */ 2286 return NULL; 2287 } 2288 if (!conv_ntlmssp_info->rc4_state_initialized) { 2289 /* The crypto sybsystem is not initialized. This means that either 2290 the conversation did not include a challenge, or that we do not have the right password */ 2291 return NULL; 2292 } 2293 if (key != NULL) { 2294 stored_packet_ntlmssp_info = (ntlmssp_packet_info *)g_hash_table_lookup(hash_packet, key); 2295 } 2296 if (stored_packet_ntlmssp_info != NULL && stored_packet_ntlmssp_info->payload_decrypted == TRUE) { 2297 /* Mat TBD (stderr, "Found a already decrypted packet\n");*/ 2298 memcpy(packet_ntlmssp_info, stored_packet_ntlmssp_info, sizeof(ntlmssp_packet_info)); 2299 /* Mat TBD printnbyte(packet_ntlmssp_info->decrypted_payload, encrypted_block_length, "Data: ", "\n");*/ 2300 } 2301 else { 2302 gcry_cipher_hd_t rc4_handle; 2303 gcry_cipher_hd_t rc4_handle_peer; 2304 2305 /* Get the pair of RC4 state structures. One is used for to decrypt the 2306 payload. The other is used to re-encrypt the payload to represent 2307 the peer */ 2308 if (conv_ntlmssp_info->server_dest_port == pinfo->destport) { 2309 /* client */ 2310 rc4_handle = get_encrypted_state(pinfo, 1); 2311 rc4_handle_peer = get_encrypted_state(pinfo, 0); 2312 } else { 2313 /* server */ 2314 rc4_handle = get_encrypted_state(pinfo, 0); 2315 rc4_handle_peer = get_encrypted_state(pinfo, 1); 2316 } 2317 2318 if (rc4_handle == NULL) { 2319 /* There is no encryption state, so we cannot decrypt */ 2320 return NULL; 2321 } 2322 2323 /* Store the decrypted contents in the packet state struct 2324 (of course at this point, they aren't decrypted yet) */ 2325 packet_ntlmssp_info->decrypted_payload = (guint8 *)tvb_memdup(wmem_file_scope(), tvb, offset, 2326 encrypted_block_length); 2327 packet_ntlmssp_info->payload_len = encrypted_block_length; 2328 decrypted_payloads = g_slist_prepend(decrypted_payloads, 2329 packet_ntlmssp_info->decrypted_payload); 2330 if (key != NULL) { 2331 g_hash_table_insert(hash_packet, key, packet_ntlmssp_info); 2332 } 2333 2334 /* Do the decryption of the payload */ 2335 gcry_cipher_decrypt(rc4_handle, packet_ntlmssp_info->decrypted_payload, encrypted_block_length, NULL, 0); 2336 2337 /* decrypt the verifier */ 2338 /*printnchar(packet_ntlmssp_info->decrypted_payload, encrypted_block_length, "data: ", "\n");*/ 2339 /* We setup a temporary buffer so we can re-encrypt the payload after 2340 decryption. This is to update the opposite peer's RC4 state 2341 it's useful when we have only one key for both conversation 2342 in case of KEY_EXCH we have independent key so this is not needed*/ 2343 if (!(NTLMSSP_NEGOTIATE_KEY_EXCH & conv_ntlmssp_info->flags)) { 2344 guint8 *peer_block; 2345 peer_block = (guint8 *)wmem_memdup(wmem_packet_scope(), packet_ntlmssp_info->decrypted_payload, encrypted_block_length); 2346 gcry_cipher_decrypt(rc4_handle_peer, peer_block, encrypted_block_length, NULL, 0); 2347 } 2348 2349 packet_ntlmssp_info->payload_decrypted = TRUE; 2350 } 2351 } 2352 2353 /* Show the decrypted buffer in a new window */ 2354 decr_tvb = tvb_new_child_real_data(tvb, packet_ntlmssp_info->decrypted_payload, 2355 encrypted_block_length, 2356 encrypted_block_length); 2357 2358 add_new_data_source(pinfo, decr_tvb, 2359 "Decrypted data"); 2360 return decr_tvb; 2361 } 2362 2363 static int 2364 dissect_ntlmssp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) 2365 { 2366 volatile int offset = 0; 2367 proto_tree *volatile ntlmssp_tree = NULL; 2368 proto_item *tf, *type_item; 2369 ntlmssp_header_t *ntlmssph; 2370 2371 ntlmssph = wmem_new(wmem_packet_scope(), ntlmssp_header_t); 2372 ntlmssph->type = 0; 2373 ntlmssph->domain_name = NULL; 2374 ntlmssph->acct_name = NULL; 2375 ntlmssph->host_name = NULL; 2376 memset(ntlmssph->session_key, 0, NTLMSSP_KEY_LEN); 2377 2378 /* Setup a new tree for the NTLMSSP payload */ 2379 tf = proto_tree_add_item (tree, 2380 proto_ntlmssp, 2381 tvb, offset, -1, ENC_NA); 2382 2383 ntlmssp_tree = proto_item_add_subtree (tf, ett_ntlmssp); 2384 2385 /* 2386 * Catch the ReportedBoundsError exception; the stuff we've been 2387 * handed doesn't necessarily run to the end of the packet, it's 2388 * an item inside a packet, so if it happens to be malformed (or 2389 * we, or a dissector we call, has a bug), so that an exception 2390 * is thrown, we want to report the error, but return and let 2391 * our caller dissect the rest of the packet. 2392 * 2393 * If it gets a BoundsError, we can stop, as there's nothing more 2394 * in the packet after our blob to see, so we just re-throw the 2395 * exception. 2396 */ 2397 TRY { 2398 /* NTLMSSP constant */ 2399 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_auth, 2400 tvb, offset, 8, ENC_ASCII|ENC_NA); 2401 offset += 8; 2402 2403 /* NTLMSSP Message Type */ 2404 type_item = proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_message_type, 2405 tvb, offset, 4, ENC_LITTLE_ENDIAN); 2406 ntlmssph->type = tvb_get_letohl (tvb, offset); 2407 offset += 4; 2408 2409 col_append_sep_str(pinfo->cinfo, COL_INFO, ", ", 2410 val_to_str_const(ntlmssph->type, 2411 ntlmssp_message_types, 2412 "Unknown NTLMSSP message type")); 2413 2414 /* Call the appropriate dissector based on the Message Type */ 2415 switch (ntlmssph->type) { 2416 2417 case NTLMSSP_NEGOTIATE: 2418 dissect_ntlmssp_negotiate (tvb, offset, ntlmssp_tree, ntlmssph); 2419 break; 2420 2421 case NTLMSSP_CHALLENGE: 2422 dissect_ntlmssp_challenge (tvb, pinfo, offset, ntlmssp_tree, ntlmssph); 2423 break; 2424 2425 case NTLMSSP_AUTH: 2426 dissect_ntlmssp_auth (tvb, pinfo, offset, ntlmssp_tree, ntlmssph); 2427 break; 2428 2429 default: 2430 /* Unrecognized message type */ 2431 expert_add_info(pinfo, type_item, &ei_ntlmssp_message_type); 2432 break; 2433 } 2434 } CATCH_NONFATAL_ERRORS { 2435 2436 show_exception(tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE); 2437 } ENDTRY; 2438 2439 tap_queue_packet(ntlmssp_tap, pinfo, ntlmssph); 2440 return tvb_captured_length(tvb); 2441 } 2442 2443 /* 2444 * See page 45 of "DCE/RPC over SMB" by Luke Kenneth Casson Leighton. 2445 */ 2446 static void 2447 decrypt_verifier(tvbuff_t *tvb, int offset, guint32 encrypted_block_length, 2448 packet_info *pinfo, proto_tree *tree, gpointer key) 2449 { 2450 proto_tree *decr_tree; 2451 conversation_t *conversation; 2452 guint8* sign_key; 2453 gcry_cipher_hd_t rc4_handle; 2454 gcry_cipher_hd_t rc4_handle_peer; 2455 tvbuff_t *decr_tvb; /* Used to display decrypted buffer */ 2456 guint8 *peer_block; 2457 guint8 *check_buf; 2458 guint8 calculated_md5[NTLMSSP_KEY_LEN]; 2459 ntlmssp_info *conv_ntlmssp_info; 2460 ntlmssp_packet_info *packet_ntlmssp_info; 2461 int decrypted_offset = 0; 2462 int sequence = 0; 2463 ntlmssp_packet_info *stored_packet_ntlmssp_info = NULL; 2464 2465 packet_ntlmssp_info = (ntlmssp_packet_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_ntlmssp, NTLMSSP_PACKET_INFO_KEY); 2466 if (packet_ntlmssp_info == NULL) { 2467 /* We don't have data for this packet */ 2468 return; 2469 } 2470 conversation = find_conversation_pinfo(pinfo, 0); 2471 if (conversation == NULL) { 2472 /* There is no conversation, thus no encryption state */ 2473 return; 2474 } 2475 conv_ntlmssp_info = (ntlmssp_info *)conversation_get_proto_data(conversation, 2476 proto_ntlmssp); 2477 if (conv_ntlmssp_info == NULL) { 2478 /* There is no NTLMSSP state tied to the conversation */ 2479 return; 2480 } 2481 2482 if (key != NULL) { 2483 stored_packet_ntlmssp_info = (ntlmssp_packet_info *)g_hash_table_lookup(hash_packet, key); 2484 } 2485 if (stored_packet_ntlmssp_info != NULL && stored_packet_ntlmssp_info->verifier_decrypted == TRUE) { 2486 /* Mat TBD fprintf(stderr, "Found a already decrypted packet\n");*/ 2487 /* In Theory it's aleady the case, and we should be more clever ... like just copying buffers ...*/ 2488 packet_ntlmssp_info = stored_packet_ntlmssp_info; 2489 } 2490 else { 2491 if (!packet_ntlmssp_info->verifier_decrypted) { 2492 if (!conv_ntlmssp_info->rc4_state_initialized) { 2493 /* The crypto sybsystem is not initialized. This means that either 2494 the conversation did not include a challenge, or we are doing 2495 something other than NTLMSSP v1 */ 2496 return; 2497 } 2498 if (conv_ntlmssp_info->server_dest_port == pinfo->destport) { 2499 /* client talk to server */ 2500 rc4_handle = get_encrypted_state(pinfo, 1); 2501 sign_key = get_sign_key(pinfo, 1); 2502 rc4_handle_peer = get_encrypted_state(pinfo, 0); 2503 } else { 2504 rc4_handle = get_encrypted_state(pinfo, 0); 2505 sign_key = get_sign_key(pinfo, 0); 2506 rc4_handle_peer = get_encrypted_state(pinfo, 1); 2507 } 2508 2509 if (rc4_handle == NULL || rc4_handle_peer == NULL) { 2510 /* There is no encryption state, so we cannot decrypt */ 2511 return; 2512 } 2513 2514 /* Setup the buffer to decrypt to */ 2515 tvb_memcpy(tvb, packet_ntlmssp_info->verifier, 2516 offset, MIN(encrypted_block_length, sizeof(packet_ntlmssp_info->verifier))); 2517 2518 /*if (!(NTLMSSP_NEGOTIATE_KEY_EXCH & packet_ntlmssp_info->flags)) {*/ 2519 if (conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY) { 2520 if ((NTLMSSP_NEGOTIATE_KEY_EXCH & conv_ntlmssp_info->flags)) { 2521 /* The spec says that if we have have a key exchange then we have a the signature that is crypted 2522 * otherwise it's just a hmac_md5(keysign, concat(message, sequence))[0..7] 2523 */ 2524 if (gcry_cipher_decrypt(rc4_handle, packet_ntlmssp_info->verifier, 8, NULL, 0)) { 2525 return; 2526 } 2527 } 2528 /* 2529 * Try to check the HMAC MD5 of the message against those calculated works great with LDAP payload but 2530 * don't with DCE/RPC calls. 2531 * Some analysis need to be done ... 2532 */ 2533 if (sign_key != NULL) { 2534 check_buf = (guint8 *)wmem_alloc(wmem_packet_scope(), packet_ntlmssp_info->payload_len+4); 2535 tvb_memcpy(tvb, &sequence, offset+8, 4); 2536 memcpy(check_buf, &sequence, 4); 2537 memcpy(check_buf+4, packet_ntlmssp_info->decrypted_payload, packet_ntlmssp_info->payload_len); 2538 if (ws_hmac_buffer(GCRY_MD_MD5, calculated_md5, check_buf, (int)(packet_ntlmssp_info->payload_len+4), sign_key, NTLMSSP_KEY_LEN)) { 2539 return; 2540 } 2541 /* 2542 printnbyte(packet_ntlmssp_info->verifier, 8, "HMAC from packet: ", "\n"); 2543 printnbyte(calculated_md5, 8, "HMAC : ", "\n"); 2544 */ 2545 } 2546 } 2547 else { 2548 /* 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 */ 2549 /* Do the actual decryption of the verifier */ 2550 if (gcry_cipher_decrypt(rc4_handle, packet_ntlmssp_info->verifier, encrypted_block_length, NULL, 0)) { 2551 return; 2552 } 2553 } 2554 2555 2556 2557 /* We setup a temporary buffer so we can re-encrypt the payload after 2558 decryption. This is to update the opposite peer's RC4 state 2559 This is not needed when we just have EXTENDED SECURITY because the signature is not crypted 2560 and it's also not needed when we have key exchange because server and client have independent keys */ 2561 if (!(NTLMSSP_NEGOTIATE_KEY_EXCH & conv_ntlmssp_info->flags) && !(NTLMSSP_NEGOTIATE_EXTENDED_SECURITY & conv_ntlmssp_info->flags)) { 2562 peer_block = (guint8 *)wmem_memdup(wmem_packet_scope(), packet_ntlmssp_info->verifier, encrypted_block_length); 2563 if (gcry_cipher_decrypt(rc4_handle_peer, peer_block, encrypted_block_length, NULL, 0)) { 2564 return; 2565 } 2566 } 2567 2568 /* Mark the packet as decrypted so that subsequent attempts to dissect 2569 the packet use the already decrypted payload instead of attempting 2570 to decrypt again */ 2571 packet_ntlmssp_info->verifier_decrypted = TRUE; 2572 } 2573 } 2574 /* Show the decrypted buffer in a new window */ 2575 decr_tvb = tvb_new_child_real_data(tvb, packet_ntlmssp_info->verifier, 2576 encrypted_block_length, 2577 encrypted_block_length); 2578 add_new_data_source(pinfo, decr_tvb, 2579 "Decrypted NTLMSSP Verifier"); 2580 2581 /* Show the decrypted payload in the tree */ 2582 decr_tree = proto_tree_add_subtree_format(tree, decr_tvb, 0, -1, 2583 ett_ntlmssp, NULL, 2584 "Decrypted Verifier (%d byte%s)", 2585 encrypted_block_length, 2586 plurality(encrypted_block_length, "", "s")); 2587 2588 if (( conv_ntlmssp_info->flags & NTLMSSP_NEGOTIATE_EXTENDED_SECURITY)) { 2589 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_hmacmd5, 2590 decr_tvb, decrypted_offset, 8, ENC_NA); 2591 decrypted_offset += 8; 2592 2593 /* Incrementing sequence number of DCE conversation */ 2594 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_sequence, 2595 decr_tvb, decrypted_offset, 4, ENC_NA); 2596 } 2597 else { 2598 /* RANDOM PAD usually it's 0 */ 2599 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_randompad, 2600 decr_tvb, decrypted_offset, 4, ENC_LITTLE_ENDIAN); 2601 decrypted_offset += 4; 2602 2603 /* CRC32 of the DCE fragment data */ 2604 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_crc32, 2605 decr_tvb, decrypted_offset, 4, ENC_LITTLE_ENDIAN); 2606 decrypted_offset += 4; 2607 2608 /* Incrementing sequence number of DCE conversation */ 2609 proto_tree_add_item (decr_tree, hf_ntlmssp_verf_sequence, 2610 decr_tvb, decrypted_offset, 4, ENC_NA); 2611 } 2612 } 2613 2614 /* Used when NTLMSSP is done over DCE/RPC because in this case verifier and real payload are not contigious*/ 2615 static int 2616 dissect_ntlmssp_payload_only(tvbuff_t *tvb, packet_info *pinfo, _U_ proto_tree *tree, void *data) 2617 { 2618 volatile int offset = 0; 2619 proto_tree *volatile ntlmssp_tree = NULL; 2620 guint32 encrypted_block_length; 2621 tvbuff_t *volatile decr_tvb; 2622 tvbuff_t** ret_decr_tvb = (tvbuff_t**)data; 2623 2624 if (ret_decr_tvb) 2625 *ret_decr_tvb = NULL; 2626 /* the magic ntlm is the identifier of a NTLMSSP packet that's 00 00 00 01 2627 */ 2628 encrypted_block_length = tvb_captured_length (tvb); 2629 /* signature + seq + real payload */ 2630 2631 /* Setup a new tree for the NTLMSSP payload */ 2632 #if 0 2633 if (tree) { 2634 tf = proto_tree_add_item (tree, 2635 hf_ntlmssp_verf, 2636 tvb, offset, -1, ENC_NA); 2637 2638 ntlmssp_tree = proto_item_add_subtree (tf, 2639 ett_ntlmssp); 2640 } 2641 #endif 2642 /* 2643 * Catch the ReportedBoundsError exception; the stuff we've been 2644 * handed doesn't necessarily run to the end of the packet, it's 2645 * an item inside a packet, so if it happens to be malformed (or 2646 * we, or a dissector we call, has a bug), so that an exception 2647 * is thrown, we want to report the error, but return and let 2648 * our caller dissect the rest of the packet. 2649 * 2650 * If it gets a BoundsError, we can stop, as there's nothing more 2651 * in the packet after our blob to see, so we just re-throw the 2652 * exception. 2653 */ 2654 TRY { 2655 /* Version number */ 2656 2657 /* Try to decrypt */ 2658 decr_tvb = decrypt_data_payload (tvb, offset, encrypted_block_length, pinfo, ntlmssp_tree, NULL); 2659 if (ret_decr_tvb) 2660 *ret_decr_tvb = decr_tvb; 2661 /* let's try to hook ourselves here */ 2662 2663 } CATCH_NONFATAL_ERRORS { 2664 2665 show_exception(tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE); 2666 } ENDTRY; 2667 2668 return offset; 2669 } 2670 2671 /* Used when NTLMSSP is done over DCE/RPC because in this case verifier and real payload are not contigious 2672 * But in fact this function could be merged with wrap_dissect_ntlmssp_verf because it's only used there 2673 */ 2674 static int 2675 dissect_ntlmssp_verf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) 2676 { 2677 volatile int offset = 0; 2678 proto_tree *volatile ntlmssp_tree = NULL; 2679 proto_item *tf = NULL; 2680 guint32 verifier_length; 2681 guint32 encrypted_block_length; 2682 2683 verifier_length = tvb_captured_length (tvb); 2684 encrypted_block_length = verifier_length - 4; 2685 2686 if (encrypted_block_length < 12) { 2687 /* Don't know why this would happen, but if it does, don't even bother 2688 attempting decryption/dissection */ 2689 return offset + verifier_length; 2690 } 2691 2692 /* Setup a new tree for the NTLMSSP payload */ 2693 if (tree) { 2694 tf = proto_tree_add_item (tree, 2695 hf_ntlmssp_verf, 2696 tvb, offset, -1, ENC_NA); 2697 2698 ntlmssp_tree = proto_item_add_subtree (tf, 2699 ett_ntlmssp); 2700 } 2701 2702 /* 2703 * Catch the ReportedBoundsError exception; the stuff we've been 2704 * handed doesn't necessarily run to the end of the packet, it's 2705 * an item inside a packet, so if it happens to be malformed (or 2706 * we, or a dissector we call, has a bug), so that an exception 2707 * is thrown, we want to report the error, but return and let 2708 * our caller dissect the rest of the packet. 2709 * 2710 * If it gets a BoundsError, we can stop, as there's nothing more 2711 * in the packet after our blob to see, so we just re-throw the 2712 * exception. 2713 */ 2714 TRY { 2715 /* Version number */ 2716 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_vers, 2717 tvb, offset, 4, ENC_LITTLE_ENDIAN); 2718 offset += 4; 2719 2720 /* Encrypted body */ 2721 proto_tree_add_item (ntlmssp_tree, hf_ntlmssp_verf_body, 2722 tvb, offset, encrypted_block_length, ENC_NA); 2723 2724 /* Try to decrypt */ 2725 decrypt_verifier (tvb, offset, encrypted_block_length, pinfo, ntlmssp_tree, NULL); 2726 /* let's try to hook ourselves here */ 2727 2728 offset += 12; 2729 offset += encrypted_block_length; 2730 } CATCH_NONFATAL_ERRORS { 2731 2732 show_exception(tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE); 2733 } ENDTRY; 2734 2735 return offset; 2736 } 2737 2738 static tvbuff_t * 2739 wrap_dissect_ntlmssp_payload_only(tvbuff_t *header_tvb _U_, 2740 tvbuff_t *payload_tvb, 2741 tvbuff_t *trailer_tvb _U_, 2742 tvbuff_t *auth_tvb _U_, 2743 packet_info *pinfo, 2744 dcerpc_auth_info *auth_info _U_) 2745 { 2746 tvbuff_t *decrypted_tvb; 2747 2748 dissect_ntlmssp_payload_only(payload_tvb, pinfo, NULL, &decrypted_tvb); 2749 return decrypted_tvb; 2750 } 2751 2752 static guint 2753 header_hash(gconstpointer pointer) 2754 { 2755 guint32 crc = ~crc32c_calculate(pointer, NTLMSSP_KEY_LEN, CRC32C_PRELOAD); 2756 /* Mat TBD fprintf(stderr, "Val: %u\n", crc);*/ 2757 return crc; 2758 } 2759 2760 static gboolean 2761 header_equal(gconstpointer pointer1, gconstpointer pointer2) 2762 { 2763 if (!memcmp(pointer1, pointer2, 16)) { 2764 return TRUE; 2765 } 2766 else { 2767 return FALSE; 2768 } 2769 } 2770 2771 static void 2772 ntlmssp_init_protocol(void) 2773 { 2774 hash_packet = g_hash_table_new(header_hash, header_equal); 2775 } 2776 2777 static void 2778 ntlmssp_cleanup_protocol(void) 2779 { 2780 if (decrypted_payloads != NULL) { 2781 g_slist_free(decrypted_payloads); 2782 decrypted_payloads = NULL; 2783 } 2784 g_hash_table_destroy(hash_packet); 2785 } 2786 2787 2788 2789 static int 2790 wrap_dissect_ntlmssp(tvbuff_t *tvb, int offset, packet_info *pinfo, 2791 proto_tree *tree, dcerpc_info *di _U_, guint8 *drep _U_) 2792 { 2793 tvbuff_t *auth_tvb; 2794 2795 auth_tvb = tvb_new_subset_remaining(tvb, offset); 2796 2797 dissect_ntlmssp(auth_tvb, pinfo, tree, NULL); 2798 2799 return tvb_captured_length_remaining(tvb, offset); 2800 } 2801 2802 static int 2803 wrap_dissect_ntlmssp_verf(tvbuff_t *tvb, int offset, packet_info *pinfo, 2804 proto_tree *tree, dcerpc_info *di _U_, guint8 *drep _U_) 2805 { 2806 tvbuff_t *auth_tvb; 2807 2808 auth_tvb = tvb_new_subset_remaining(tvb, offset); 2809 return dissect_ntlmssp_verf(auth_tvb, pinfo, tree, NULL); 2810 } 2811 2812 static dcerpc_auth_subdissector_fns ntlmssp_sign_fns = { 2813 wrap_dissect_ntlmssp, /* Bind */ 2814 wrap_dissect_ntlmssp, /* Bind ACK */ 2815 wrap_dissect_ntlmssp, /* AUTH3 */ 2816 wrap_dissect_ntlmssp_verf, /* Request verifier */ 2817 wrap_dissect_ntlmssp_verf, /* Response verifier */ 2818 NULL, /* Request data */ 2819 NULL /* Response data */ 2820 }; 2821 2822 static dcerpc_auth_subdissector_fns ntlmssp_seal_fns = { 2823 wrap_dissect_ntlmssp, /* Bind */ 2824 wrap_dissect_ntlmssp, /* Bind ACK */ 2825 wrap_dissect_ntlmssp, /* AUTH3 */ 2826 wrap_dissect_ntlmssp_verf, /* Request verifier */ 2827 wrap_dissect_ntlmssp_verf, /* Response verifier */ 2828 wrap_dissect_ntlmssp_payload_only, /* Request data */ 2829 wrap_dissect_ntlmssp_payload_only /* Response data */ 2830 }; 2831 2832 static const value_string MSV1_0_CRED_VERSION[] = { 2833 { 0x00000000, "MSV1_0_CRED_VERSION" }, 2834 { 0x00000002, "MSV1_0_CRED_VERSION_V2" }, 2835 { 0x00000004, "MSV1_0_CRED_VERSION_V3" }, 2836 { 0xffff0001, "MSV1_0_CRED_VERSION_IUM" }, 2837 { 0xffff0002, "MSV1_0_CRED_VERSION_REMOTE" }, 2838 { 0xfffffffe, "MSV1_0_CRED_VERSION_RESERVED_1" }, 2839 { 0xffffffff, "MSV1_0_CRED_VERSION_INVALID" }, 2840 { 0, NULL } 2841 }; 2842 2843 #define MSV1_0_CRED_LM_PRESENT 0x0001 2844 #define MSV1_0_CRED_NT_PRESENT 0x0002 2845 #define MSV1_0_CRED_REMOVED 0x0004 2846 #define MSV1_0_CRED_CREDKEY_PRESENT 0x0008 2847 #define MSV1_0_CRED_SHA_PRESENT 0x0010 2848 2849 static int* const MSV1_0_CRED_FLAGS_bits[] = { 2850 &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_LM_PRESENT, 2851 &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_NT_PRESENT, 2852 &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_REMOVED, 2853 &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_CREDKEY_PRESENT, 2854 &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_SHA_PRESENT, 2855 NULL 2856 }; 2857 2858 static const value_string MSV1_0_CREDENTIAL_KEY_TYPE[] = { 2859 { 0, "InvalidCredKey" }, 2860 { 1, "IUMCredKey" }, 2861 { 2, "DomainUserCredKey" }, 2862 { 3, "LocalUserCredKey" }, 2863 { 4, "ExternallySuppliedCredKey" }, 2864 { 0, NULL } 2865 }; 2866 2867 #define MSV1_0_CREDENTIAL_KEY_LENGTH 20 2868 2869 int 2870 dissect_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL(tvbuff_t *tvb, int offset, proto_tree *tree) 2871 { 2872 proto_item *item; 2873 proto_tree *subtree; 2874 guint32 EncryptedCredsSize; 2875 2876 if (tvb_captured_length(tvb) < 36) 2877 return offset; 2878 2879 item = proto_tree_add_item(tree, hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL, tvb, 2880 offset, -1, ENC_NA); 2881 subtree = proto_item_add_subtree(item, ett_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL); 2882 2883 proto_tree_add_item(subtree, hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_Version, tvb, 2884 offset, 4, ENC_LITTLE_ENDIAN); 2885 offset+=4; 2886 2887 proto_tree_add_bitmask(subtree, tvb, offset, 2888 hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_Flags, 2889 ett_ntlmssp, MSV1_0_CRED_FLAGS_bits, ENC_LITTLE_ENDIAN); 2890 offset+=4; 2891 2892 proto_tree_add_item(subtree, hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_CredentialKey, 2893 tvb, offset, MSV1_0_CREDENTIAL_KEY_LENGTH, ENC_NA); 2894 offset+=MSV1_0_CREDENTIAL_KEY_LENGTH; 2895 2896 proto_tree_add_item(subtree, hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_CredentialKeyType, 2897 tvb, offset, 4, ENC_LITTLE_ENDIAN); 2898 offset+=4; 2899 2900 EncryptedCredsSize = tvb_get_letohl(tvb, offset); 2901 proto_tree_add_item(subtree, hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_EncryptedCredsSize, 2902 tvb, offset, 4, ENC_LITTLE_ENDIAN); 2903 offset+=4; 2904 2905 if (EncryptedCredsSize == 0) 2906 return offset; 2907 2908 if (tvb_captured_length(tvb) < (36 + EncryptedCredsSize)) 2909 return offset; 2910 2911 proto_tree_add_item(subtree, hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_EncryptedCreds, 2912 tvb, offset, EncryptedCredsSize, ENC_NA); 2913 offset+=EncryptedCredsSize; 2914 2915 return offset; 2916 } 2917 2918 2919 void 2920 proto_register_ntlmssp(void) 2921 { 2922 2923 static hf_register_info hf[] = { 2924 { &hf_ntlmssp_auth, 2925 { "NTLMSSP identifier", "ntlmssp.identifier", 2926 FT_STRING, BASE_NONE, NULL, 0x0, 2927 NULL, HFILL } 2928 }, 2929 { &hf_ntlmssp_message_type, 2930 { "NTLM Message Type", "ntlmssp.messagetype", 2931 FT_UINT32, BASE_HEX, VALS(ntlmssp_message_types), 0x0, 2932 NULL, HFILL } 2933 }, 2934 { &hf_ntlmssp_negotiate_flags, 2935 { "Negotiate Flags", "ntlmssp.negotiateflags", 2936 FT_UINT32, BASE_HEX, NULL, 0x0, 2937 NULL, HFILL } 2938 }, 2939 { &hf_ntlmssp_negotiate_flags_01, 2940 { "Negotiate UNICODE", "ntlmssp.negotiateunicode", 2941 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_UNICODE, 2942 NULL, HFILL } 2943 }, 2944 { &hf_ntlmssp_negotiate_flags_02, 2945 { "Negotiate OEM", "ntlmssp.negotiateoem", 2946 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_OEM, 2947 NULL, HFILL } 2948 }, 2949 { &hf_ntlmssp_negotiate_flags_04, 2950 { "Request Target", "ntlmssp.requesttarget", 2951 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_REQUEST_TARGET, 2952 NULL, HFILL } 2953 }, 2954 { &hf_ntlmssp_negotiate_flags_08, 2955 { "Request 0x00000008", "ntlmssp.negotiate00000008", 2956 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00000008, 2957 NULL, HFILL } 2958 }, 2959 { &hf_ntlmssp_negotiate_flags_10, 2960 { "Negotiate Sign", "ntlmssp.negotiatesign", 2961 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_SIGN, 2962 NULL, HFILL } 2963 }, 2964 { &hf_ntlmssp_negotiate_flags_20, 2965 { "Negotiate Seal", "ntlmssp.negotiateseal", 2966 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_SEAL, 2967 NULL, HFILL } 2968 }, 2969 { &hf_ntlmssp_negotiate_flags_40, 2970 { "Negotiate Datagram", "ntlmssp.negotiatedatagram", 2971 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_DATAGRAM, 2972 NULL, HFILL } 2973 }, 2974 { &hf_ntlmssp_negotiate_flags_80, 2975 { "Negotiate Lan Manager Key", "ntlmssp.negotiatelmkey", 2976 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_LM_KEY, 2977 NULL, HFILL } 2978 }, 2979 { &hf_ntlmssp_negotiate_flags_100, 2980 { "Negotiate 0x00000100", "ntlmssp.negotiate00000100", 2981 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00000100, 2982 NULL, HFILL } 2983 }, 2984 { &hf_ntlmssp_negotiate_flags_200, 2985 { "Negotiate NTLM key", "ntlmssp.negotiatentlm", 2986 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_NTLM, 2987 NULL, HFILL } 2988 }, 2989 { &hf_ntlmssp_negotiate_flags_400, 2990 { "Negotiate NT Only", "ntlmssp.negotiatentonly", 2991 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_NT_ONLY, 2992 NULL, HFILL } 2993 }, 2994 { &hf_ntlmssp_negotiate_flags_800, 2995 { "Negotiate Anonymous", "ntlmssp.negotiateanonymous", 2996 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_ANONYMOUS, 2997 NULL, HFILL } 2998 }, 2999 { &hf_ntlmssp_negotiate_flags_1000, 3000 { "Negotiate OEM Domain Supplied", "ntlmssp.negotiateoemdomainsupplied", 3001 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED, 3002 NULL, HFILL } 3003 }, 3004 { &hf_ntlmssp_negotiate_flags_2000, 3005 { "Negotiate OEM Workstation Supplied", "ntlmssp.negotiateoemworkstationsupplied", 3006 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED, 3007 NULL, HFILL } 3008 }, 3009 { &hf_ntlmssp_negotiate_flags_4000, 3010 { "Negotiate 0x00004000", "ntlmssp.negotiate00004000", 3011 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00004000, 3012 NULL, HFILL } 3013 }, 3014 { &hf_ntlmssp_negotiate_flags_8000, 3015 { "Negotiate Always Sign", "ntlmssp.negotiatealwayssign", 3016 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_ALWAYS_SIGN, 3017 NULL, HFILL } 3018 }, 3019 { &hf_ntlmssp_negotiate_flags_10000, 3020 { "Target Type Domain", "ntlmssp.targettypedomain", 3021 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_TARGET_TYPE_DOMAIN, 3022 NULL, HFILL } 3023 }, 3024 { &hf_ntlmssp_negotiate_flags_20000, 3025 { "Target Type Server", "ntlmssp.targettypeserver", 3026 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_TARGET_TYPE_SERVER, 3027 NULL, HFILL } 3028 }, 3029 { &hf_ntlmssp_negotiate_flags_40000, 3030 { "Target Type Share", "ntlmssp.targettypeshare", 3031 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_TARGET_TYPE_SHARE, 3032 NULL, HFILL } 3033 }, 3034 3035 /* Negotiate Flags */ 3036 { &hf_ntlmssp_negotiate_flags_80000, 3037 { "Negotiate Extended Security", "ntlmssp.negotiatentlm2", 3038 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_EXTENDED_SECURITY, 3039 NULL, HFILL } 3040 }, 3041 { &hf_ntlmssp_negotiate_flags_100000, 3042 { "Negotiate Identify", "ntlmssp.negotiateidentify", 3043 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_IDENTIFY, 3044 NULL, HFILL } 3045 }, 3046 { &hf_ntlmssp_negotiate_flags_200000, 3047 { "Negotiate 0x00200000", "ntlmssp.negotiatent00200000", 3048 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_00200000, 3049 NULL, HFILL } 3050 }, 3051 { &hf_ntlmssp_negotiate_flags_400000, 3052 { "Request Non-NT Session", "ntlmssp.requestnonntsession", 3053 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_REQUEST_NON_NT_SESSION, 3054 NULL, HFILL } 3055 }, 3056 { &hf_ntlmssp_negotiate_flags_800000, 3057 { "Negotiate Target Info", "ntlmssp.negotiatetargetinfo", 3058 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_TARGET_INFO, 3059 NULL, HFILL } 3060 }, 3061 { &hf_ntlmssp_negotiate_flags_1000000, 3062 { "Negotiate 0x01000000", "ntlmssp.negotiatent01000000", 3063 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_01000000, 3064 NULL, HFILL } 3065 }, 3066 { &hf_ntlmssp_negotiate_flags_2000000, 3067 { "Negotiate Version", "ntlmssp.negotiateversion", 3068 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_VERSION, 3069 NULL, HFILL } 3070 }, 3071 { &hf_ntlmssp_negotiate_flags_4000000, 3072 { "Negotiate 0x04000000", "ntlmssp.negotiatent04000000", 3073 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_04000000, 3074 NULL, HFILL } 3075 }, 3076 { &hf_ntlmssp_negotiate_flags_8000000, 3077 { "Negotiate 0x08000000", "ntlmssp.negotiatent08000000", 3078 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_08000000, 3079 NULL, HFILL } 3080 }, 3081 { &hf_ntlmssp_negotiate_flags_10000000, 3082 { "Negotiate 0x10000000", "ntlmssp.negotiatent10000000", 3083 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_10000000, 3084 NULL, HFILL } 3085 }, 3086 { &hf_ntlmssp_negotiate_flags_20000000, 3087 { "Negotiate 128", "ntlmssp.negotiate128", 3088 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_128, 3089 "128-bit encryption is supported", HFILL } 3090 }, 3091 { &hf_ntlmssp_negotiate_flags_40000000, 3092 { "Negotiate Key Exchange", "ntlmssp.negotiatekeyexch", 3093 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_KEY_EXCH, 3094 NULL, HFILL } 3095 }, 3096 { &hf_ntlmssp_negotiate_flags_80000000, 3097 { "Negotiate 56", "ntlmssp.negotiate56", 3098 FT_BOOLEAN, 32, TFS (&tfs_set_notset), NTLMSSP_NEGOTIATE_56, 3099 "56-bit encryption is supported", HFILL } 3100 }, 3101 #if 0 3102 { &hf_ntlmssp_negotiate_workstation_strlen, 3103 { "Calling workstation name length", "ntlmssp.negotiate.callingworkstation.strlen", 3104 FT_UINT16, BASE_DEC, NULL, 0x0, 3105 NULL, HFILL } 3106 }, 3107 #endif 3108 #if 0 3109 { &hf_ntlmssp_negotiate_workstation_maxlen, 3110 { "Calling workstation name max length", "ntlmssp.negotiate.callingworkstation.maxlen", 3111 FT_UINT16, BASE_DEC, NULL, 0x0, 3112 NULL, HFILL } 3113 }, 3114 #endif 3115 #if 0 3116 { &hf_ntlmssp_negotiate_workstation_buffer, 3117 { "Calling workstation name buffer", "ntlmssp.negotiate.callingworkstation.buffer", 3118 FT_UINT32, BASE_HEX, NULL, 0x0, 3119 NULL, HFILL } 3120 }, 3121 #endif 3122 { &hf_ntlmssp_negotiate_workstation, 3123 { "Calling workstation name", "ntlmssp.negotiate.callingworkstation", 3124 FT_STRING, BASE_NONE, NULL, 0x0, 3125 NULL, HFILL } 3126 }, 3127 #if 0 3128 { &hf_ntlmssp_negotiate_domain_strlen, 3129 { "Calling workstation domain length", "ntlmssp.negotiate.domain.strlen", 3130 FT_UINT16, BASE_DEC, NULL, 0x0, 3131 NULL, HFILL } 3132 }, 3133 #endif 3134 #if 0 3135 { &hf_ntlmssp_negotiate_domain_maxlen, 3136 { "Calling workstation domain max length", "ntlmssp.negotiate.domain.maxlen", 3137 FT_UINT16, BASE_DEC, NULL, 0x0, 3138 NULL, HFILL } 3139 }, 3140 #endif 3141 #if 0 3142 { &hf_ntlmssp_negotiate_domain_buffer, 3143 { "Calling workstation domain buffer", "ntlmssp.negotiate.domain.buffer", 3144 FT_UINT32, BASE_HEX, NULL, 0x0, 3145 NULL, HFILL } 3146 }, 3147 #endif 3148 { &hf_ntlmssp_negotiate_domain, 3149 { "Calling workstation domain", "ntlmssp.negotiate.domain", 3150 FT_STRING, BASE_NONE, NULL, 0x0, 3151 NULL, HFILL } 3152 }, 3153 { &hf_ntlmssp_ntlm_client_challenge, 3154 { "LMv2 Client Challenge", "ntlmssp.ntlmclientchallenge", 3155 FT_BYTES, BASE_NONE, NULL, 0x0, 3156 "The 8-byte LMv2 challenge message generated by the client", HFILL } 3157 }, 3158 { &hf_ntlmssp_ntlm_server_challenge, 3159 { "NTLM Server Challenge", "ntlmssp.ntlmserverchallenge", 3160 FT_BYTES, BASE_NONE, NULL, 0x0, 3161 NULL, HFILL } 3162 }, 3163 { &hf_ntlmssp_reserved, 3164 { "Reserved", "ntlmssp.reserved", 3165 FT_BYTES, BASE_NONE, NULL, 0x0, 3166 NULL, HFILL } 3167 }, 3168 3169 { &hf_ntlmssp_challenge_target_name, 3170 { "Target Name", "ntlmssp.challenge.target_name", 3171 FT_STRING, BASE_NONE, NULL, 0x0, 3172 NULL, HFILL } 3173 }, 3174 { &hf_ntlmssp_auth_domain, 3175 { "Domain name", "ntlmssp.auth.domain", 3176 FT_STRING, BASE_NONE, NULL, 0x0, 3177 NULL, HFILL } 3178 }, 3179 { &hf_ntlmssp_auth_username, 3180 { "User name", "ntlmssp.auth.username", 3181 FT_STRING, BASE_NONE, NULL, 0x0, 3182 NULL, HFILL } 3183 }, 3184 { &hf_ntlmssp_auth_hostname, 3185 { "Host name", "ntlmssp.auth.hostname", 3186 FT_STRING, BASE_NONE, NULL, 0x0, 3187 NULL, HFILL } 3188 }, 3189 { &hf_ntlmssp_auth_lmresponse, 3190 { "Lan Manager Response", "ntlmssp.auth.lmresponse", 3191 FT_BYTES, BASE_NONE, NULL, 0x0, 3192 NULL, HFILL } 3193 }, 3194 { &hf_ntlmssp_auth_ntresponse, 3195 { "NTLM Response", "ntlmssp.auth.ntresponse", 3196 FT_BYTES, BASE_NONE, NULL, 0x0, 3197 NULL, HFILL } 3198 }, 3199 { &hf_ntlmssp_auth_sesskey, 3200 { "Session Key", "ntlmssp.auth.sesskey", 3201 FT_BYTES, BASE_NONE, NULL, 0x0, 3202 NULL, HFILL } 3203 }, 3204 { &hf_ntlmssp_string_len, 3205 { "Length", "ntlmssp.string.length", 3206 FT_UINT16, BASE_DEC, NULL, 0x0, 3207 NULL, HFILL} 3208 }, 3209 { &hf_ntlmssp_string_maxlen, 3210 { "Maxlen", "ntlmssp.string.maxlen", 3211 FT_UINT16, BASE_DEC, NULL, 0x0, 3212 NULL, HFILL} 3213 }, 3214 { &hf_ntlmssp_string_offset, 3215 { "Offset", "ntlmssp.string.offset", 3216 FT_UINT32, BASE_DEC, NULL, 0x0, 3217 NULL, HFILL} 3218 }, 3219 { &hf_ntlmssp_blob_len, 3220 { "Length", "ntlmssp.blob.length", 3221 FT_UINT16, BASE_DEC, NULL, 0x0, 3222 NULL, HFILL} 3223 }, 3224 { &hf_ntlmssp_blob_maxlen, 3225 { "Maxlen", "ntlmssp.blob.maxlen", 3226 FT_UINT16, BASE_DEC, NULL, 0x0, 3227 NULL, HFILL} 3228 }, 3229 { &hf_ntlmssp_blob_offset, 3230 { "Offset", "ntlmssp.blob.offset", 3231 FT_UINT32, BASE_DEC, NULL, 0x0, 3232 NULL, HFILL} 3233 }, 3234 { &hf_ntlmssp_version, 3235 { "Version", "ntlmssp.version", 3236 FT_NONE, BASE_NONE, NULL, 0x0, 3237 NULL, HFILL} 3238 }, 3239 { &hf_ntlmssp_version_major, 3240 { "Major Version", "ntlmssp.version.major", 3241 FT_UINT8, BASE_DEC, NULL, 0x0, 3242 NULL, HFILL} 3243 }, 3244 { &hf_ntlmssp_version_minor, 3245 { "Minor Version", "ntlmssp.version.minor", 3246 FT_UINT8, BASE_DEC, NULL, 0x0, 3247 NULL, HFILL} 3248 }, 3249 { &hf_ntlmssp_version_build_number, 3250 { "Build Number", "ntlmssp.version.build_number", 3251 FT_UINT16, BASE_DEC, NULL, 0x0, 3252 NULL, HFILL} 3253 }, 3254 { &hf_ntlmssp_version_ntlm_current_revision, 3255 { "NTLM Current Revision", "ntlmssp.version.ntlm_current_revision", 3256 FT_UINT8, BASE_DEC, NULL, 0x0, 3257 NULL, HFILL} 3258 }, 3259 3260 /* Target Info */ 3261 { &hf_ntlmssp_challenge_target_info, 3262 { "Target Info", "ntlmssp.challenge.target_info", 3263 FT_NONE, BASE_NONE, NULL, 0x0, 3264 NULL, HFILL} 3265 }, 3266 { &hf_ntlmssp_challenge_target_info_len, 3267 { "Length", "ntlmssp.challenge.target_info.length", 3268 FT_UINT16, BASE_DEC, NULL, 0x0, 3269 NULL, HFILL} 3270 }, 3271 { &hf_ntlmssp_challenge_target_info_maxlen, 3272 { "Maxlen", "ntlmssp.challenge.target_info.maxlen", 3273 FT_UINT16, BASE_DEC, NULL, 0x0, 3274 NULL, HFILL} 3275 }, 3276 { &hf_ntlmssp_challenge_target_info_offset, 3277 { "Offset", "ntlmssp.challenge.target_info.offset", 3278 FT_UINT32, BASE_DEC, NULL, 0x0, 3279 NULL, HFILL} 3280 }, 3281 3282 { &hf_ntlmssp_challenge_target_info_item_type, 3283 { "Target Info Item Type", "ntlmssp.challenge.target_info.item.type", 3284 FT_UINT16, BASE_HEX | BASE_EXT_STRING, &ntlm_name_types_ext, 0x0, 3285 NULL, HFILL } 3286 }, 3287 { &hf_ntlmssp_challenge_target_info_item_len, 3288 { "Target Info Item Length", "ntlmssp.challenge.target_info.item.length", 3289 FT_UINT16, BASE_DEC, NULL, 0x0, 3290 NULL, HFILL} 3291 }, 3292 3293 { &hf_ntlmssp_challenge_target_info_end, 3294 { "List End", "ntlmssp.challenge.target_info.end", 3295 FT_NONE, BASE_NONE, NULL, 0x0, 3296 NULL, HFILL } 3297 }, 3298 { &hf_ntlmssp_challenge_target_info_nb_computer_name, 3299 { "NetBIOS Computer Name", "ntlmssp.challenge.target_info.nb_computer_name", 3300 FT_STRING, BASE_NONE, NULL, 0x0, 3301 "Server NetBIOS Computer Name", HFILL } 3302 }, 3303 { &hf_ntlmssp_challenge_target_info_nb_domain_name, 3304 { "NetBIOS Domain Name", "ntlmssp.challenge.target_info.nb_domain_name", 3305 FT_STRING, BASE_NONE, NULL, 0x0, 3306 "Server NetBIOS Domain Name", HFILL } 3307 }, 3308 { &hf_ntlmssp_challenge_target_info_dns_computer_name, 3309 { "DNS Computer Name", "ntlmssp.challenge.target_info.dns_computer_name", 3310 FT_STRING, BASE_NONE, NULL, 0x0, 3311 NULL, HFILL } 3312 }, 3313 { &hf_ntlmssp_challenge_target_info_dns_domain_name, 3314 { "DNS Domain Name", "ntlmssp.challenge.target_info.dns_domain_name", 3315 FT_STRING, BASE_NONE, NULL, 0x0, 3316 NULL, HFILL } 3317 }, 3318 { &hf_ntlmssp_challenge_target_info_dns_tree_name, 3319 { "DNS Tree Name", "ntlmssp.challenge.target_info.dns_tree_name", 3320 FT_STRING, BASE_NONE, NULL, 0x0, 3321 NULL, HFILL } 3322 }, 3323 { &hf_ntlmssp_challenge_target_info_flags, 3324 { "Flags", "ntlmssp.challenge.target_info.flags", 3325 FT_UINT32, BASE_HEX, NULL, 0x0, 3326 NULL, HFILL } 3327 }, 3328 { &hf_ntlmssp_challenge_target_info_timestamp, 3329 { "Timestamp", "ntlmssp.challenge.target_info.timestamp", 3330 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0, 3331 NULL, HFILL } 3332 }, 3333 { &hf_ntlmssp_challenge_target_info_restrictions, 3334 { "Restrictions", "ntlmssp.challenge.target_info.restrictions", 3335 FT_BYTES, BASE_NONE, NULL, 0, 3336 NULL, HFILL } 3337 }, 3338 { &hf_ntlmssp_challenge_target_info_target_name, 3339 { "Target Name", "ntlmssp.challenge.target_info.target_name", 3340 FT_STRING, BASE_NONE, NULL, 0x0, 3341 NULL, HFILL } 3342 }, 3343 { &hf_ntlmssp_challenge_target_info_channel_bindings, 3344 { "Channel Bindings", "ntlmssp.challenge.target_info.channel_bindings", 3345 FT_BYTES, BASE_NONE, NULL, 0x0, 3346 NULL, HFILL } 3347 }, 3348 3349 { &hf_ntlmssp_ntlmv2_response_item_type, 3350 { "NTLMV2 Response Item Type", "ntlmssp.ntlmv2_response.item.type", 3351 FT_UINT16, BASE_HEX | BASE_EXT_STRING, &ntlm_name_types_ext, 0x0, 3352 NULL, HFILL } 3353 }, 3354 { &hf_ntlmssp_ntlmv2_response_item_len, 3355 { "NTLMV2 Response Item Length", "ntlmssp.ntlmv2_response.item.length", 3356 FT_UINT16, BASE_DEC, NULL, 0x0, 3357 NULL, HFILL} 3358 }, 3359 3360 { &hf_ntlmssp_ntlmv2_response_end, 3361 { "List End", "ntlmssp.ntlmv2_response.end", 3362 FT_NONE, BASE_NONE, NULL, 0x0, 3363 NULL, HFILL } 3364 }, 3365 { &hf_ntlmssp_ntlmv2_response_nb_computer_name, 3366 { "NetBIOS Computer Name", "ntlmssp.ntlmv2_response.nb_computer_name", 3367 FT_STRING, BASE_NONE, NULL, 0x0, 3368 "Server NetBIOS Computer Name", HFILL } 3369 }, 3370 { &hf_ntlmssp_ntlmv2_response_nb_domain_name, 3371 { "NetBIOS Domain Name", "ntlmssp.ntlmv2_response.nb_domain_name", 3372 FT_STRING, BASE_NONE, NULL, 0x0, 3373 "Server NetBIOS Domain Name", HFILL } 3374 }, 3375 { &hf_ntlmssp_ntlmv2_response_dns_computer_name, 3376 { "DNS Computer Name", "ntlmssp.ntlmv2_response.dns_computer_name", 3377 FT_STRING, BASE_NONE, NULL, 0x0, 3378 NULL, HFILL } 3379 }, 3380 { &hf_ntlmssp_ntlmv2_response_dns_domain_name, 3381 { "DNS Domain Name", "ntlmssp.ntlmv2_response.dns_domain_name", 3382 FT_STRING, BASE_NONE, NULL, 0x0, 3383 NULL, HFILL } 3384 }, 3385 { &hf_ntlmssp_ntlmv2_response_dns_tree_name, 3386 { "DNS Tree Name", "ntlmssp.ntlmv2_response.dns_tree_name", 3387 FT_STRING, BASE_NONE, NULL, 0x0, 3388 NULL, HFILL } 3389 }, 3390 { &hf_ntlmssp_ntlmv2_response_flags, 3391 { "Flags", "ntlmssp.ntlmv2_response.flags", 3392 FT_UINT32, BASE_HEX, NULL, 0x0, 3393 NULL, HFILL } 3394 }, 3395 { &hf_ntlmssp_ntlmv2_response_timestamp, 3396 { "Timestamp", "ntlmssp.ntlmv2_response.timestamp", 3397 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_LOCAL, NULL, 0, 3398 NULL, HFILL } 3399 }, 3400 { &hf_ntlmssp_ntlmv2_response_restrictions, 3401 { "Restrictions", "ntlmssp.ntlmv2_response.restrictions", 3402 FT_BYTES, BASE_NONE, NULL, 0, 3403 NULL, HFILL } 3404 }, 3405 { &hf_ntlmssp_ntlmv2_response_target_name, 3406 { "Target Name", "ntlmssp.ntlmv2_response.target_name", 3407 FT_STRING, BASE_NONE, NULL, 0x0, 3408 NULL, HFILL } 3409 }, 3410 { &hf_ntlmssp_ntlmv2_response_channel_bindings, 3411 { "Channel Bindings", "ntlmssp.ntlmv2_response.channel_bindings", 3412 FT_BYTES, BASE_NONE, NULL, 0x0, 3413 NULL, HFILL } 3414 }, 3415 3416 { &hf_ntlmssp_message_integrity_code, 3417 { "MIC", "ntlmssp.authenticate.mic", 3418 FT_BYTES, BASE_NONE, NULL, 0x0, 3419 "Message Integrity Code", HFILL} 3420 }, 3421 { &hf_ntlmssp_verf, 3422 { "NTLMSSP Verifier", "ntlmssp.verf", 3423 FT_NONE, BASE_NONE, NULL, 0x0, 3424 NULL, HFILL } 3425 }, 3426 { &hf_ntlmssp_verf_vers, 3427 { "Version Number", "ntlmssp.verf.vers", 3428 FT_UINT32, BASE_DEC, NULL, 0x0, 3429 NULL, HFILL } 3430 }, 3431 { &hf_ntlmssp_verf_body, 3432 { "Verifier Body", "ntlmssp.verf.body", 3433 FT_BYTES, BASE_NONE, NULL, 0x0, 3434 NULL, HFILL } 3435 }, 3436 #if 0 3437 { &hf_ntlmssp_decrypted_payload, 3438 { "NTLM Decrypted Payload", "ntlmssp.decrypted_payload", 3439 FT_BYTES, BASE_NONE, NULL, 0x0, 3440 NULL, HFILL } 3441 }, 3442 #endif 3443 { &hf_ntlmssp_verf_randompad, 3444 { "Random Pad", "ntlmssp.verf.randompad", 3445 FT_UINT32, BASE_HEX, NULL, 0x0, 3446 NULL, HFILL } 3447 }, 3448 { &hf_ntlmssp_verf_crc32, 3449 { "Verifier CRC32", "ntlmssp.verf.crc32", 3450 FT_UINT32, BASE_HEX, NULL, 0x0, 3451 NULL, HFILL } 3452 }, 3453 { &hf_ntlmssp_verf_hmacmd5, 3454 { "HMAC MD5", "ntlmssp.verf.hmacmd5", 3455 FT_BYTES, BASE_NONE, NULL, 0x0, 3456 NULL, HFILL } 3457 }, 3458 { &hf_ntlmssp_verf_sequence, 3459 { "Sequence", "ntlmssp.verf.sequence", 3460 FT_BYTES, BASE_NONE, NULL, 0x0, 3461 NULL, HFILL } 3462 }, 3463 3464 { &hf_ntlmssp_ntlmv2_response, 3465 { "NTLMv2 Response", "ntlmssp.ntlmv2_response", 3466 FT_BYTES, BASE_NONE, NULL, 0x0, 3467 NULL, HFILL } 3468 }, 3469 { &hf_ntlmssp_ntlmv2_response_ntproofstr, 3470 { "NTProofStr", "ntlmssp.ntlmv2_response.ntproofstr", 3471 FT_BYTES, BASE_NONE, NULL, 0x0, 3472 "The HMAC-MD5 of the challenge", HFILL } 3473 }, 3474 { &hf_ntlmssp_ntlmv2_response_rversion, 3475 { "Response Version", "ntlmssp.ntlmv2_response.rversion", 3476 FT_UINT8, BASE_DEC, NULL, 0x0, 3477 "The 1-byte response version, currently set to 1", HFILL } 3478 }, 3479 { &hf_ntlmssp_ntlmv2_response_hirversion, 3480 { "Hi Response Version", "ntlmssp.ntlmv2_response.hirversion", 3481 FT_UINT8, BASE_DEC, NULL, 0x0, 3482 "The 1-byte highest response version understood by the client, currently set to 1", HFILL } 3483 }, 3484 { &hf_ntlmssp_ntlmv2_response_z, 3485 { "Z", "ntlmssp.ntlmv2_response.z", 3486 FT_BYTES, BASE_NONE, NULL, 0x0, 3487 "byte array of zero bytes", HFILL } 3488 }, 3489 { &hf_ntlmssp_ntlmv2_response_pad, 3490 { "padding", "ntlmssp.ntlmv2_response.pad", 3491 FT_BYTES, BASE_NONE, NULL, 0x0, 3492 NULL, HFILL } 3493 }, 3494 { &hf_ntlmssp_ntlmv2_response_time, 3495 { "Time", "ntlmssp.ntlmv2_response.time", 3496 FT_ABSOLUTE_TIME, ABSOLUTE_TIME_UTC, NULL, 0, 3497 "The 8-byte little-endian time in UTC", HFILL } 3498 }, 3499 { &hf_ntlmssp_ntlmv2_response_chal, 3500 { "NTLMv2 Client Challenge", "ntlmssp.ntlmv2_response.chal", 3501 FT_BYTES, BASE_NONE, NULL, 0x0, 3502 "The 8-byte NTLMv2 challenge message generated by the client", HFILL } 3503 }, 3504 { &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL, 3505 { "NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL", "ntlmssp.NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL", 3506 FT_NONE, BASE_NONE, NULL, 0, 3507 NULL, HFILL }}, 3508 { &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_Version, 3509 { "Version", "ntlmssp.NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL.Version", 3510 FT_UINT32, BASE_HEX, VALS(MSV1_0_CRED_VERSION), 0, 3511 NULL, HFILL }}, 3512 { &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_Flags, 3513 { "Flags", "ntlmssp.NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL.Flags", 3514 FT_UINT32, BASE_HEX, NULL, 0, 3515 NULL, HFILL }}, 3516 { &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_LM_PRESENT, 3517 { "lm_present", "ntlmssp.NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL.LM_PRESENT", 3518 FT_BOOLEAN, 32, NULL, MSV1_0_CRED_LM_PRESENT, 3519 NULL, HFILL }}, 3520 { &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_NT_PRESENT, 3521 { "nt_present", "ntlmssp.NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL.NT_PRESENT", 3522 FT_BOOLEAN, 32, NULL, MSV1_0_CRED_NT_PRESENT, 3523 NULL, HFILL }}, 3524 { &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_REMOVED, 3525 { "removed", "ntlmssp.NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL.REMOVED", 3526 FT_BOOLEAN, 32, NULL, MSV1_0_CRED_REMOVED, 3527 NULL, HFILL }}, 3528 { &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_CREDKEY_PRESENT, 3529 { "credkey_present", "ntlmssp.NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL.CREDKEY_PRESENT", 3530 FT_BOOLEAN, 32, NULL, MSV1_0_CRED_CREDKEY_PRESENT, 3531 NULL, HFILL }}, 3532 { &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_FLAG_SHA_PRESENT, 3533 { "sha_present", "ntlmssp.NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL.SHA_PRESENT", 3534 FT_BOOLEAN, 32, NULL, MSV1_0_CRED_SHA_PRESENT, 3535 NULL, HFILL }}, 3536 { &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_CredentialKey, 3537 { "CredentialKey", "ntlmssp.NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL.CredentialKey", 3538 FT_BYTES, BASE_NONE, NULL, 0, 3539 NULL, HFILL }}, 3540 { &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_CredentialKeyType, 3541 { "CredentialKeyType", "ntlmssp.NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL.CredentialKeyType", 3542 FT_UINT32, BASE_DEC, VALS(MSV1_0_CREDENTIAL_KEY_TYPE), 0, 3543 NULL, HFILL }}, 3544 { &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_EncryptedCredsSize, 3545 { "EncryptedCredsSize", "ntlmssp.NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL.EncryptedCredsSize", 3546 FT_UINT32, BASE_DEC, NULL, 0, 3547 NULL, HFILL }}, 3548 { &hf_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL_EncryptedCreds, 3549 { "EncryptedCreds", "ntlmssp.NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL.EncryptedCreds", 3550 FT_BYTES, BASE_NONE, NULL, 0, 3551 NULL, HFILL }}, 3552 }; 3553 3554 3555 static gint *ett[] = { 3556 &ett_ntlmssp, 3557 &ett_ntlmssp_negotiate_flags, 3558 &ett_ntlmssp_string, 3559 &ett_ntlmssp_blob, 3560 &ett_ntlmssp_version, 3561 &ett_ntlmssp_challenge_target_info, 3562 &ett_ntlmssp_challenge_target_info_item, 3563 &ett_ntlmssp_ntlmv2_response, 3564 &ett_ntlmssp_ntlmv2_response_item, 3565 &ett_ntlmssp_NTLM_REMOTE_SUPPLEMENTAL_CREDENTIAL, 3566 }; 3567 static ei_register_info ei[] = { 3568 { &ei_ntlmssp_v2_key_too_long, { "ntlmssp.v2_key_too_long", PI_UNDECODED, PI_WARN, "NTLM v2 key is too long", EXPFILL }}, 3569 { &ei_ntlmssp_blob_len_too_long, { "ntlmssp.blob.length.too_long", PI_UNDECODED, PI_WARN, "Session blob length too long", EXPFILL }}, 3570 { &ei_ntlmssp_target_info_attr, { "ntlmssp.target_info_attr.unknown", PI_UNDECODED, PI_WARN, "unknown NTLMSSP Target Info Attribute", EXPFILL }}, 3571 { &ei_ntlmssp_message_type, { "ntlmssp.messagetype.unknown", PI_PROTOCOL, PI_WARN, "Unrecognized NTLMSSP Message", EXPFILL }}, 3572 { &ei_ntlmssp_auth_nthash, { "ntlmssp.authenticated", PI_SECURITY, PI_CHAT, "Authenticated NTHASH", EXPFILL }}, 3573 { &ei_ntlmssp_sessionbasekey, { "ntlmssp.sessionbasekey", PI_SECURITY, PI_CHAT, "SessionBaseKey", EXPFILL }}, 3574 { &ei_ntlmssp_sessionkey, { "ntlmssp.sessionkey", PI_SECURITY, PI_CHAT, "SessionKey", EXPFILL }}, 3575 }; 3576 module_t *ntlmssp_module; 3577 expert_module_t* expert_ntlmssp; 3578 3579 proto_ntlmssp = proto_register_protocol ( 3580 "NTLM Secure Service Provider", /* name */ 3581 "NTLMSSP", /* short name */ 3582 "ntlmssp" /* abbrev */ 3583 ); 3584 proto_register_field_array (proto_ntlmssp, hf, array_length (hf)); 3585 proto_register_subtree_array (ett, array_length (ett)); 3586 expert_ntlmssp = expert_register_protocol(proto_ntlmssp); 3587 expert_register_field_array(expert_ntlmssp, ei, array_length(ei)); 3588 register_init_routine(&ntlmssp_init_protocol); 3589 register_cleanup_routine(&ntlmssp_cleanup_protocol); 3590 3591 ntlmssp_module = prefs_register_protocol(proto_ntlmssp, NULL); 3592 3593 prefs_register_string_preference(ntlmssp_module, "nt_password", 3594 "NT Password", 3595 "NT Password (used to decrypt payloads)", 3596 &ntlmssp_option_nt_password); 3597 3598 ntlmssp_handle = register_dissector("ntlmssp", dissect_ntlmssp, proto_ntlmssp); 3599 ntlmssp_wrap_handle = register_dissector("ntlmssp_payload", dissect_ntlmssp_payload, proto_ntlmssp); 3600 register_dissector("ntlmssp_data_only", dissect_ntlmssp_payload_only, proto_ntlmssp); 3601 register_dissector("ntlmssp_verf", dissect_ntlmssp_verf, proto_ntlmssp); 3602 } 3603 3604 void 3605 proto_reg_handoff_ntlmssp(void) 3606 { 3607 /* Register protocol with the GSS-API module */ 3608 3609 gssapi_init_oid("1.3.6.1.4.1.311.2.2.10", proto_ntlmssp, ett_ntlmssp, 3610 ntlmssp_handle, ntlmssp_wrap_handle, 3611 "NTLMSSP - Microsoft NTLM Security Support Provider"); 3612 3613 /* Register authenticated pipe dissector */ 3614 3615 /* 3616 * XXX - the verifiers here seem to have a version of 1 and a body of all 3617 * zeroes. 3618 * 3619 * XXX - DCE_C_AUTHN_LEVEL_CONNECT is, according to the DCE RPC 1.1 3620 * spec, upgraded to DCE_C_AUTHN_LEVEL_PKT. Should we register 3621 * any other levels here? 3622 */ 3623 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_CONNECT, 3624 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP, 3625 &ntlmssp_sign_fns); 3626 3627 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT, 3628 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP, 3629 &ntlmssp_sign_fns); 3630 3631 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_INTEGRITY, 3632 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP, 3633 &ntlmssp_sign_fns); 3634 3635 register_dcerpc_auth_subdissector(DCE_C_AUTHN_LEVEL_PKT_PRIVACY, 3636 DCE_C_RPC_AUTHN_PROTOCOL_NTLMSSP, 3637 &ntlmssp_seal_fns); 3638 ntlmssp_tap = register_tap("ntlmssp"); 3639 3640 } 3641 3642 /* 3643 * Editor modelines - https://www.wireshark.org/tools/modelines.html 3644 * 3645 * Local variables: 3646 * c-basic-offset: 2 3647 * tab-width: 8 3648 * indent-tabs-mode: nil 3649 * End: 3650 * 3651 * vi: set shiftwidth=2 tabstop=8 expandtab: 3652 * :indentSize=2:tabSize=8:noTabs=true: 3653 */ 3654