Coverage Report

Created: 2025-12-27 06:52

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