OpenVAS Scanner 23.32.3
nasl_crypto.c
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Greenbone AG
2 * SPDX-FileCopyrightText: 2002-2004 Tenable Network Security
3 *
4 * SPDX-License-Identifier: GPL-2.0-only
5 */
6
11
12/* MODIFICATION: added definitions for implementing NTLMSSP features */
13
14#include "nasl_crypto.h"
15
16#include "../misc/support.h"
17#include "exec.h"
18#include "hmacmd5.h"
19#include "nasl_crypto_helper.h"
20#include "nasl_debug.h"
21#include "nasl_func.h"
22#include "nasl_global_ctxt.h"
23#include "nasl_lex_ctxt.h"
24#include "nasl_tree.h"
25#include "nasl_var.h"
26#include "ntlmssp.h"
27#include "smb.h"
28#include "smb_crypt.h"
29#include "smb_signing.h"
30
31#include <assert.h>
32#include <ctype.h>
33#include <gcrypt.h>
34#include <glib.h>
35#include <gvm/base/logging.h>
36#include <stddef.h>
37#include <stdlib.h>
38
39#ifndef uchar
40#define uchar unsigned char
41#endif
42
43#ifndef uint8
44#define uint8 uint8_t
45#endif
46
47#ifndef uint32
48#define uint32 uint32_t
49#endif
50
51#undef G_LOG_DOMAIN
55#define G_LOG_DOMAIN "lib nasl"
56
57/*-------------------[ Std. HASH ]-------------------------------------*/
58static tree_cell *
59nasl_gcrypt_hash (lex_ctxt *lexic, int algorithm, void *data, size_t datalen,
60 void *key, size_t keylen)
61{
62 gcry_md_hd_t hd;
63 gcry_error_t err;
64 tree_cell *retc;
65 unsigned int dlen = gcry_md_get_algo_dlen (algorithm);
66
67 if (data == NULL)
68 return NULL;
69
70 err = gcry_md_open (&hd, algorithm, key ? GCRY_MD_FLAG_HMAC : 0);
71 if (err)
72 {
73 nasl_perror (lexic, "nasl_gcrypt_hash(): gcry_md_open failed: %s/%s\n",
74 gcry_strsource (err), gcry_strerror (err));
75 return NULL;
76 }
77
78 if (key)
79 {
80 err = gcry_md_setkey (hd, key, keylen);
81 if (err)
82 {
83 nasl_perror (lexic,
84 "nasl_gcrypt_hash():"
85 " gcry_md_setkey failed: %s/%s\n",
86 gcry_strsource (err), gcry_strerror (err));
87 return NULL;
88 }
89 }
90
91 gcry_md_write (hd, data, datalen);
92
94 retc->x.str_val = g_malloc0 (dlen + 1);
95 memcpy (retc->x.str_val, gcry_md_read (hd, algorithm), dlen + 1);
96 retc->size = dlen;
97
98 gcry_md_close (hd);
99
100 return retc;
101}
102
103static tree_cell *
104nasl_hash (lex_ctxt *lexic, int algorithm)
105{
106 char *data = get_str_var_by_num (lexic, 0);
107 int len = get_var_size_by_num (lexic, 0);
108
109 return nasl_gcrypt_hash (lexic, algorithm, data, len, NULL, 0);
110}
111
112tree_cell *
114{
115 return nasl_hash (lexic, GCRY_MD_MD2);
116}
117
118tree_cell *
120{
121 return nasl_hash (lexic, GCRY_MD_MD4);
122}
123
124tree_cell *
126{
127 return nasl_hash (lexic, GCRY_MD_MD5);
128}
129
130tree_cell *
132{
133 return nasl_hash (lexic, GCRY_MD_SHA1);
134}
135
136tree_cell *
138{
139 return nasl_hash (lexic, GCRY_MD_SHA256);
140}
141
142tree_cell *
144{
145 return nasl_hash (lexic, GCRY_MD_SHA512);
146}
147
148tree_cell *
150{
151 return nasl_hash (lexic, GCRY_MD_RMD160);
152}
153
154static tree_cell *
155nasl_cipher (int algorithm, void *data, size_t dlen, void *key, size_t klen)
156{
157 gcry_cipher_hd_t hd;
158 gcry_error_t error;
159 tree_cell *retc;
160 char *result;
161
162 if ((error = gcry_cipher_open (&hd, algorithm, GCRY_CIPHER_MODE_ECB, 0)))
163 {
164 g_message ("gcry_cipher_open: %s", gcry_strerror (error));
165 return NULL;
166 }
167 if ((error = gcry_cipher_setkey (hd, key, klen)))
168 {
169 g_message ("gcry_cipher_setkey: %s", gcry_strerror (error));
170 return NULL;
171 }
172 result = g_malloc0 (dlen);
173 if ((error = gcry_cipher_encrypt (hd, result, dlen, data, dlen)))
174 {
175 g_message ("gcry_cipher_encrypt: %s", gcry_strerror (error));
176 return NULL;
177 }
178 gcry_cipher_close (hd);
179
181 retc->x.str_val = result;
182 retc->size = dlen;
183 return retc;
184}
185
186tree_cell *
188{
189 char *data, *key;
190 size_t dlen, klen;
191
192 data = get_str_var_by_num (lexic, 0);
193 dlen = get_var_size_by_num (lexic, 0);
194 key = get_str_var_by_num (lexic, 1);
195 klen = get_var_size_by_num (lexic, 1);
196 return nasl_cipher (GCRY_CIPHER_DES, data, dlen, key, klen);
197}
198
199/*-------------------[ HMAC ]-------------------------------------*/
200
201static tree_cell *
202nasl_hmac (lex_ctxt *lexic, int algorithm)
203{
204 char *data = get_str_var_by_name (lexic, "data");
205 char *key = get_str_var_by_name (lexic, "key");
206 int data_len = get_var_size_by_name (lexic, "data");
207 int key_len = get_var_size_by_name (lexic, "key");
208
209 return nasl_gcrypt_hash (lexic, algorithm, data, data_len, key, key_len);
210}
211
212tree_cell *
214{
215 return nasl_hmac (lexic, GCRY_MD_MD2);
216}
217
218tree_cell *
220{
221 return nasl_hmac (lexic, GCRY_MD_MD5);
222}
223
224tree_cell *
226{
227 return nasl_hmac (lexic, GCRY_MD_SHA1);
228}
229
230tree_cell *
232{
233 return nasl_hmac (lexic, GCRY_MD_SHA384);
234}
235
236tree_cell *
238{
239 return nasl_hmac (lexic, GCRY_MD_RMD160);
240}
241
242/*-------------------[ Windows ]-------------------------------------*/
243tree_cell *
245{
246 char *mac_key = (char *) get_str_var_by_name (lexic, "key");
247 uint8_t *buf = (uint8_t *) get_str_var_by_name (lexic, "buf");
248 int buflen = get_int_var_by_name (lexic, "buflen", -1);
249 int seq_num = get_int_var_by_name (lexic, "seq_number", -1);
250 if (mac_key == NULL || buf == NULL || buflen == -1 || seq_num <= -1)
251 {
252 nasl_perror (lexic, "Syntax : get_signature(key:<k>, buf:<b>, "
253 "buflen:<bl>, seq_number:<s>)\n");
254 return NULL;
255 }
256 uint8_t calc_md5_mac[16];
257 simple_packet_signature_ntlmssp ((uint8_t *) mac_key, buf, seq_num,
258 calc_md5_mac);
259 memcpy (buf + 18, calc_md5_mac, 8);
260 char *ret = g_malloc0 (buflen);
261 memcpy (ret, buf, buflen);
262 tree_cell *retc;
264 retc->size = buflen;
265 retc->x.str_val = (char *) ret;
266 return retc;
267}
268
269tree_cell *
271{
272 void *key, *data, *signature;
273 int keylen, datalen;
274 tree_cell *retc;
275
276 key = get_str_var_by_name (lexic, "key");
277 data = get_str_var_by_name (lexic, "data");
278 datalen = get_var_size_by_name (lexic, "data");
279 keylen = get_var_size_by_name (lexic, "key");
280 if (!key || !data || keylen <= 0 || datalen <= 0)
281 {
282 nasl_perror (lexic, "Syntax : hmac_sha256(data:<b>, key:<k>)\n");
283 return NULL;
284 }
285 signature = hmac_sha256 (key, keylen, data, datalen);
286
288 retc->size = 32;
289 retc->x.str_val = (char *) signature;
290 return retc;
291}
292
293/* @brief PRF function from RFC 2246 chapter 5.
294 *
295 * @param hmac 0 for SHA256, 1 for SHA384, 2 for MD5, 3 for SHA1.
296 *
297 * */
298static void *
299tls_prf (const void *secret, size_t secret_len, const void *seed,
300 size_t seed_len, const void *label, size_t outlen, int hmac)
301{
302 char *result = NULL;
303 size_t pos = 0, lslen, hmac_size;
304 void *Ai;
305 void *lseed;
306 void *(*hmac_func) (const void *, int, const void *, int);
307
308 if (hmac == 0)
309 {
310 hmac_size = 32;
311 hmac_func = hmac_sha256;
312 }
313 else if (hmac == 1)
314 {
315 hmac_size = 48;
316 hmac_func = hmac_sha384;
317 }
318 else if (hmac == 2)
319 {
320 hmac_size = 16;
321 hmac_func = hmac_md5_for_prf;
322 }
323 else
324 {
325 hmac_size = 20;
326 hmac_func = hmac_sha1;
327 }
328
329 /*
330 * lseed = label + seed
331 * A0 = lseed (new seed)
332 * Ai = HMAC(secret, A(i - 1))
333 */
334 lslen = strlen (label) + seed_len;
335 lseed = g_malloc0 (lslen);
336 memcpy (lseed, label, strlen (label));
337 memcpy ((char *) lseed + strlen (label), seed, seed_len);
338
339 Ai = hmac_func (secret, secret_len, lseed, lslen);
340 if (!Ai)
341 {
342 g_free (lseed);
343 return NULL;
344 }
345
346 result = g_malloc0 (outlen);
347 while (pos < outlen)
348 {
349 void *tmp, *tmp2;
350 size_t clen;
351
352 /* HMAC_hash(secret, Ai + lseed) */
353 tmp = g_malloc0 (hmac_size + lslen);
354 memcpy (tmp, Ai, hmac_size);
355 memcpy ((char *) tmp + hmac_size, lseed, lslen);
356 tmp2 = hmac_func (secret, secret_len, tmp, hmac_size + lslen);
357 g_free (tmp);
358 /* concat to result */
359 clen = outlen - pos;
360 if (clen > hmac_size)
361 clen = hmac_size;
362 memcpy (result + pos, tmp2, clen);
363 pos += clen;
364 g_free (tmp2);
365
366 /* A(i+1) */
367 tmp = hmac_func (secret, secret_len, Ai, hmac_size);
368 g_free (Ai);
369 Ai = tmp;
370 }
371
372 g_free (Ai);
373 g_free (lseed);
374 return result;
375}
376
377/* @brief PRF function from RFC 4346 chapter 5. TLS v1.1
378 *
379 * Legacy function in which P_MD5 and PSHA1 are combined.
380 *
381 * Legacy function has been replaced with prf_sha256 and prf_sha348
382 * in TLS v1.2, as it can be read in chapter 1.2
383 * */
384static void *
385tls1_prf (const void *secret, size_t secret_len, const void *seed,
386 size_t seed_len, const void *label, size_t outlen)
387{
388 void *result, *secret1 = NULL, *secret2 = NULL;
389 unsigned int half_slen, odd = 0, i;
390 char *resultmd5 = NULL, *resultsha1 = NULL, *aux_res = NULL;
391
392 if (secret_len % 2 == 0)
393 half_slen = secret_len / 2;
394 else
395 {
396 half_slen = (secret_len + 1) / 2;
397 odd = 1;
398 }
399
400 secret1 = g_malloc0 (half_slen);
401 memcpy (secret1, secret, half_slen);
402 resultmd5 = tls_prf (secret1, half_slen, seed, seed_len, label, outlen, 2);
403 if (!resultmd5)
404 {
405 g_free (secret1);
406 return NULL;
407 }
408
409 secret2 = g_malloc0 (half_slen);
410 memcpy (secret2, (char *) secret + (half_slen - odd), half_slen);
411 resultsha1 = tls_prf (secret2, half_slen, seed, seed_len, label, outlen, 3);
412 if (!resultsha1)
413 {
414 g_free (resultmd5);
415 g_free (secret1);
416 g_free (secret2);
417 return NULL;
418 }
419
420 aux_res = g_malloc0 (outlen);
421 for (i = 0; i < outlen; i++)
422 aux_res[i] = resultmd5[i] ^ resultsha1[i];
423
424 result = g_malloc (outlen);
425 memcpy (result, aux_res, outlen);
426
427 g_free (resultmd5);
428 g_free (resultsha1);
429 g_free (secret1);
430 g_free (secret2);
431 g_free (aux_res);
432
433 return result;
434}
435
436static tree_cell *
437nasl_prf (lex_ctxt *lexic, int hmac)
438{
439 void *secret, *seed, *label, *result;
440 int secret_len, seed_len, label_len, outlen;
441 tree_cell *retc;
442
443 secret = get_str_var_by_name (lexic, "secret");
444 seed = get_str_var_by_name (lexic, "seed");
445 label = get_str_var_by_name (lexic, "label");
446 outlen = get_int_var_by_name (lexic, "outlen", -1);
447 seed_len = get_var_size_by_name (lexic, "seed");
448 secret_len = get_var_size_by_name (lexic, "secret");
449 label_len = get_var_size_by_name (lexic, "label");
450 if (!secret || !seed || secret_len <= 0 || seed_len <= 0 || !label
451 || label_len <= 0 || outlen <= 0)
452 {
453 nasl_perror (lexic, "Syntax : prf(secret, seed, label, outlen)\n");
454 return NULL;
455 }
456 if (hmac != 2)
457 result = tls_prf (secret, secret_len, seed, seed_len, label, outlen, hmac);
458 else
459 result = tls1_prf (secret, secret_len, seed, seed_len, label, outlen);
460
461 if (!result)
462 return NULL;
463
465 retc->size = outlen;
466 retc->x.str_val = (char *) result;
467 return retc;
468}
469
470tree_cell *
472{
473 return nasl_prf (lexic, 0);
474}
475
476tree_cell *
478{
479 return nasl_prf (lexic, 1);
480}
481
482tree_cell *
484{
485 return nasl_prf (lexic, 2);
486}
487
488tree_cell *
490{
491 return nasl_hmac (lexic, GCRY_MD_SHA512);
492}
493
494tree_cell *
496{
497 return nasl_smb_sign (G_CHECKSUM_SHA256, lexic);
498}
499
500tree_cell *
502{
503 return nasl_smb_sign (GCRY_MAC_CMAC_AES, lexic);
504}
505
506tree_cell *
508{
509 return nasl_smb_sign (GCRY_MAC_GMAC_AES, lexic);
510}
511
512tree_cell *
514{
515 char *cryptkey = (char *) get_str_var_by_name (lexic, "cryptkey");
516 char *user = (char *) get_str_var_by_name (lexic, "user");
517 char *domain = (char *) get_str_var_by_name (lexic, "domain");
518 unsigned char *ntlmv2_hash =
519 (unsigned char *) get_str_var_by_name (lexic, "ntlmv2_hash");
520 char *address_list = get_str_var_by_name (lexic, "address_list");
521 int address_list_len = get_int_var_by_name (lexic, "address_list_len", -1);
522
523 if (cryptkey == NULL || user == NULL || domain == NULL || ntlmv2_hash == NULL
524 || address_list == NULL || address_list_len < 0)
525 {
527 lexic, "Syntax : ntlmv2_response(cryptkey:<c>, user:<u>, domain:<d>, "
528 "ntlmv2_hash:<n>, address_list:<a>, address_list_len:<len>)\n");
529 return NULL;
530 }
531 uint8_t lm_response[24];
532 uint8_t nt_response[16 + 28 + address_list_len];
533 uint8_t session_key[16];
534 bzero (lm_response, sizeof (lm_response));
535 bzero (nt_response, sizeof (nt_response));
536 bzero (session_key, sizeof (session_key));
537
538 ntlmssp_genauth_ntlmv2 (user, domain, address_list, address_list_len,
539 cryptkey, lm_response, nt_response, session_key,
540 ntlmv2_hash);
541 tree_cell *retc;
542 int lm_response_len = 24;
543 int nt_response_len = 16 + 28 + address_list_len;
544 int len = lm_response_len + nt_response_len + sizeof (session_key);
545 char *ret = g_malloc0 (len);
546 memcpy (ret, lm_response, lm_response_len);
547 memcpy (ret + lm_response_len, session_key, sizeof (session_key));
548 memcpy (ret + lm_response_len + sizeof (session_key), nt_response,
549 nt_response_len);
551 retc->size = len;
552 retc->x.str_val = ret;
553 return retc;
554}
555
556tree_cell *
558{
559 char *cryptkey = (char *) get_str_var_by_name (lexic, "cryptkey");
560 char *password = get_str_var_by_name (lexic, "password");
561 uint8_t pass_len = get_var_size_by_name (lexic, "password");
562 void *nt_hash = get_str_var_by_name (lexic, "nt_hash");
563 int hash_len = get_var_size_by_name (lexic, "nt_hash");
564
565 if (!cryptkey || !password || !nt_hash || hash_len < 16)
566 {
567 nasl_perror (lexic, "Syntax : ntlm2_response(cryptkey:<c>, password:<p>, "
568 "nt_hash:<n[16]>)\n");
569 return NULL;
570 }
571
572 uint8_t lm_response[24];
573 uint8_t nt_response[24];
574 uint8_t session_key[16];
575
576 tree_cell *retc;
577 ntlmssp_genauth_ntlm2 (password, pass_len, lm_response, nt_response,
578 session_key, cryptkey, nt_hash);
579 int len = sizeof (lm_response) + sizeof (nt_response) + sizeof (session_key);
580 char *ret = g_malloc0 (len);
581 memcpy (ret, lm_response, sizeof (lm_response));
582 memcpy (ret + sizeof (lm_response), nt_response, sizeof (nt_response));
583 memcpy (ret + sizeof (lm_response) + sizeof (nt_response), session_key,
584 sizeof (session_key));
586 retc->size = len;
587 retc->x.str_val = ret;
588 return retc;
589}
590
591tree_cell *
593{
594 char *cryptkey = (char *) get_str_var_by_name (lexic, "cryptkey");
595 char *password = get_str_var_by_name (lexic, "password");
596 uint8_t pass_len = (uint8_t) get_var_size_by_name (lexic, "password");
597 void *nt_hash = get_str_var_by_name (lexic, "nt_hash");
598 int hash_len = get_var_size_by_name (lexic, "nt_hash");
599 int neg_flags = get_int_var_by_name (lexic, "neg_flags", -1);
600
601 if (!cryptkey || !password || !nt_hash || hash_len < 16 || neg_flags < 0)
602 {
603 nasl_perror (lexic, "Syntax : ntlm_response(cryptkey:<c>, password:<p>, "
604 "nt_hash:<n[16]>, neg_flags:<nf>)\n");
605 return NULL;
606 }
607
608 uint8_t lm_response[24];
609 uint8_t nt_response[24];
610 uint8_t session_key[16];
611
612 tree_cell *retc;
613
614 ntlmssp_genauth_ntlm (password, pass_len, lm_response, nt_response,
615 session_key, cryptkey, nt_hash, neg_flags);
616
617 int len = sizeof (lm_response) + sizeof (nt_response) + sizeof (session_key);
618 char *ret = g_malloc0 (len);
619 memcpy (ret, lm_response, sizeof (lm_response));
620 memcpy (ret + sizeof (lm_response), nt_response, sizeof (nt_response));
621 memcpy (ret + sizeof (lm_response) + sizeof (nt_response), session_key,
622 sizeof (session_key));
624 retc->size = len;
625 retc->x.str_val = ret;
626 return retc;
627}
628
629tree_cell *
631{
632 char *cryptkey = (char *) get_str_var_by_name (lexic, "cryptkey");
633 uint8_t *session_key = (uint8_t *) get_str_var_by_name (lexic, "session_key");
634 unsigned char *nt_hash =
635 (unsigned char *) get_str_var_by_name (lexic, "nt_hash");
636
637 if (cryptkey == NULL || session_key == NULL || nt_hash == NULL)
638 {
640 lexic,
641 "Syntax : key_exchange(cryptkey:<c>, session_key:<s>, nt_hash:<n> )\n");
642 return NULL;
643 }
644 uint8_t new_sess_key[16];
645 tree_cell *retc;
646 uint8_t *encrypted_session_key = NULL;
647 encrypted_session_key = ntlmssp_genauth_keyexchg (
648 session_key, cryptkey, nt_hash, (uint8_t *) &new_sess_key);
649 int len = 16 + 16;
650 char *ret = g_malloc0 (len);
651 memcpy (ret, new_sess_key, 16);
652 memcpy (ret + 16, encrypted_session_key, 16);
654 retc->size = len;
655 retc->x.str_val = ret;
656 return retc;
657}
658
659tree_cell *
661{
662 const uchar *cryptkey = (uchar *) get_str_var_by_name (lexic, "cryptkey");
663 char *password = get_str_var_by_name (lexic, "passhash");
664 int pass_len = get_var_size_by_name (lexic, "passhash");
665 unsigned char p21[21];
666 tree_cell *retc;
667 uchar *ret;
668
669 if (cryptkey == NULL || password == NULL)
670 {
671 nasl_perror (lexic, "Syntax : ntlmv1_hash(cryptkey:<c>, passhash:<p>)\n");
672 return NULL;
673 }
674
675 if (pass_len < 16)
676 pass_len = 16;
677
678 bzero (p21, sizeof (p21));
679 memcpy (p21, password, pass_len);
680
681 ret = g_malloc0 (24);
682
683 E_P24 (p21, cryptkey, ret);
685 retc->size = 24;
686 retc->x.str_val = (char *) ret;
687
688 return retc;
689}
690
691tree_cell *
693{
694 char *pass = get_str_var_by_num (lexic, 0);
695 gunichar2 *upass;
696 glong upass_len;
697 tree_cell *ret;
698
699 if (!pass)
700 {
701 nasl_perror (lexic, "Syntax : nt_owf_gen(<password>)\n");
702 return NULL;
703 }
704 upass = g_utf8_to_utf16 (pass, -1, NULL, &upass_len, NULL);
705 ret = nasl_gcrypt_hash (lexic, GCRY_MD_MD4, upass, upass_len * 2, NULL, 0);
706 g_free (upass);
707 return ret;
708}
709
710tree_cell *
712{
713 char *pass = get_str_var_by_num (lexic, 0);
714 int pass_len = get_var_size_by_num (lexic, 0);
715 tree_cell *retc;
716 uchar pwd[15];
717 uchar p16[16];
718 unsigned int i;
719
720 if (pass_len < 0 || pass == NULL)
721 {
722 nasl_perror (lexic, "Syntax : nt_lm_gen(password:<p>)\n");
723 return NULL;
724 }
725
726 bzero (pwd, sizeof (pwd));
727 strncpy ((char *) pwd, pass, sizeof (pwd) - 1);
728 for (i = 0; i < sizeof (pwd); i++)
729 pwd[i] = toupper (pwd[i]);
730
731 E_P16 (pwd, p16);
732
734 retc->size = 16;
735 retc->x.str_val = g_memdup2 (p16, 16);
736 return retc;
737}
738
739tree_cell *
741{
742 const uchar *in = (uchar *) get_str_var_by_name (lexic, "in");
743 int in_len = get_var_size_by_name (lexic, "in");
744 char *src;
745 smb_ucs2_t *out, *dst, val;
746 int i;
747 size_t byte_len;
748 tree_cell *retc;
749 if (in_len < 0 || in == NULL)
750 {
751 nasl_perror (lexic, "Syntax : insert_hexzeros(in:<i>)\n");
752 return NULL;
753 }
754
755 byte_len = sizeof (smb_ucs2_t) * (strlen ((char *) in) + 1);
756 out = g_malloc0 (byte_len);
757 dst = out;
758 src = (char *) in;
759
760 for (i = 0; i < in_len; i++)
761 {
762 val = *src;
763 *dst = val;
764 dst++;
765 src++;
766 if (val == 0)
767 break;
768 }
769
770 /* We don't want null termination */
771 byte_len = byte_len - 2;
772
774 retc->size = byte_len;
775 retc->x.str_val = (char *) out;
776 return retc;
777}
778
779/* Does both the NTLMv2 owfs of a user's password */
780tree_cell *
782{
783 const uchar *owf_in = (uchar *) get_str_var_by_name (lexic, "owf");
784 int owf_in_len = get_var_size_by_name (lexic, "owf");
785 char *user_in = get_str_var_by_name (lexic, "login");
786 int user_in_len = get_var_size_by_name (lexic, "login");
787 char *domain_in = get_str_var_by_name (lexic, "domain");
788 int domain_len = get_var_size_by_name (lexic, "domain");
789 char *src_user, *src_domain;
790 smb_ucs2_t *user, *dst_user, val_user;
791 smb_ucs2_t *domain, *dst_domain, val_domain;
792 int i;
793 size_t user_byte_len;
794 size_t domain_byte_len;
795 tree_cell *retc;
796 uchar *kr_buf;
797 HMACMD5Context ctx;
798
799 if (owf_in_len < 0 || owf_in == NULL || user_in_len < 0 || user_in == NULL
800 || domain_len < 0 || domain_in == NULL)
801 {
802 nasl_perror (lexic,
803 "Syntax : ntv2_owf_gen(owf:<o>, login:<l>, domain:<d>)\n");
804 return NULL;
805 }
806
807 assert (owf_in_len == 16);
808
809 user_byte_len = sizeof (smb_ucs2_t) * (strlen (user_in) + 1);
810 user = g_malloc0 (user_byte_len);
811 dst_user = user;
812 src_user = user_in;
813
814 for (i = 0; i < user_in_len; i++)
815 {
816 val_user = *src_user;
817 *dst_user = val_user;
818 dst_user++;
819 src_user++;
820 if (val_user == 0)
821 break;
822 }
823
824 domain_byte_len = sizeof (smb_ucs2_t) * (strlen (domain_in) + 1);
825 domain = g_malloc0 (domain_byte_len);
826 dst_domain = domain;
827 src_domain = domain_in;
828
829 for (i = 0; i < domain_len; i++)
830 {
831 val_domain = *src_domain;
832 *dst_domain = val_domain;
833
834 dst_domain++;
835 src_domain++;
836 if (val_domain == 0)
837 break;
838 }
839
840 strupper_w (user);
841 strupper_w (domain);
842
843 assert (user_byte_len >= 2);
844 assert (domain_byte_len >= 2);
845
846 /* We don't want null termination */
847 user_byte_len = user_byte_len - 2;
848 domain_byte_len = domain_byte_len - 2;
849
850 kr_buf = g_malloc0 (16);
851
852 hmac_md5_init_limK_to_64 (owf_in, 16, &ctx);
853 hmac_md5_update ((const unsigned char *) user, user_byte_len, &ctx);
854 hmac_md5_update ((const unsigned char *) domain, domain_byte_len, &ctx);
855 hmac_md5_final (kr_buf, &ctx);
856
857 g_free (user);
858 g_free (domain);
859
861 retc->size = 16;
862 retc->x.str_val = (char *) kr_buf;
863
864 return retc;
865}
866
867tree_cell *
869{
870 const uchar *server_chal = (uchar *) get_str_var_by_name (lexic, "cryptkey");
871 int sc_len = get_var_size_by_name (lexic, "cryptkey");
872 const uchar *ntlm_v2_hash = (uchar *) get_str_var_by_name (lexic, "passhash");
873 int hash_len = get_var_size_by_name (lexic, "passhash");
874 int client_chal_length = get_int_var_by_name (lexic, "length", -1);
875 tree_cell *retc;
876 unsigned char ntlmv2_response[16];
877 unsigned char *ntlmv2_client_data = NULL;
878 unsigned char *final_response;
879 int i;
880
881 if (sc_len < 0 || server_chal == NULL || hash_len < 0 || ntlm_v2_hash == NULL
882 || client_chal_length < 0)
883 {
885 lexic,
886 "Syntax : ntlmv2_hash(cryptkey:<c>, passhash:<p>, length:<l>)\n");
887 return NULL;
888 }
889
890 /* NTLMv2 */
891
892 /* We also get to specify some random data */
893 ntlmv2_client_data = g_malloc0 (client_chal_length);
894 for (i = 0; i < client_chal_length; i++)
895 ntlmv2_client_data[i] = rand () % 256;
896
897 assert (hash_len == 16);
898 /* Given that data, and the challenge from the server, generate a response */
899 SMBOWFencrypt_ntv2_ntlmssp (ntlm_v2_hash, server_chal, 8, ntlmv2_client_data,
900 client_chal_length, ntlmv2_response);
901
902 /* put it into nt_response, for the code below to put into the packet */
903 final_response = g_malloc0 (client_chal_length + sizeof (ntlmv2_response));
904 memcpy (final_response, ntlmv2_response, sizeof (ntlmv2_response));
905 /* after the first 16 bytes is the random data we generated above, so the
906 * server can verify us with it */
907 memcpy (final_response + sizeof (ntlmv2_response), ntlmv2_client_data,
908 client_chal_length);
909
910 g_free (ntlmv2_client_data);
911
913 retc->size = client_chal_length + sizeof (ntlmv2_response);
914 retc->x.str_val = (char *) final_response;
915
916 return retc;
917}
void hmac_md5_final(uchar *digest, HMACMD5Context *ctx)
Finish off hmac_md5 "inner" buffer and generate outer one.
Definition hmacmd5.c:64
void hmac_md5_update(const uchar *text, int text_len, HMACMD5Context *ctx)
Update hmac_md5 "inner" buffer.
Definition hmacmd5.c:55
void hmac_md5_init_limK_to_64(const uchar *key, int key_len, HMACMD5Context *ctx)
The microsoft version of hmac_md5 initialisation.
Definition hmacmd5.c:24
Unix SMB/CIFS implementation. HMAC MD5 code for use in NTLMv2.
#define uchar
Definition hmacmd5.h:22
uint16 smb_ucs2_t
Definition hmacmd5.h:52
void * hmac_sha1(const void *key, int keylen, const void *buf, int buflen)
void * hmac_md5_for_prf(const void *key, int keylen, const void *buf, int buflen)
void * hmac_sha384(const void *key, int keylen, const void *buf, int buflen)
tree_cell * nasl_smb_sign(const int algo, lex_ctxt *lexic)
void * hmac_sha256(const void *key, int keylen, const void *buf, int buflen)
static tree_cell * nasl_hmac(lex_ctxt *lexic, int algorithm)
tree_cell * nasl_get_smb2_sign(lex_ctxt *lexic)
tree_cell * nasl_ripemd160(lex_ctxt *lexic)
static tree_cell * nasl_cipher(int algorithm, void *data, size_t dlen, void *key, size_t klen)
tree_cell * nasl_hmac_sha1(lex_ctxt *lexic)
tree_cell * nasl_prf_sha256(lex_ctxt *lexic)
tree_cell * nasl_hmac_md2(lex_ctxt *lexic)
tree_cell * nasl_sha256(lex_ctxt *lexic)
tree_cell * nasl_smb_cmac_aes_sign(lex_ctxt *lexic)
tree_cell * nasl_hmac_sha256(lex_ctxt *lexic)
tree_cell * nasl_nt_owf_gen(lex_ctxt *lexic)
tree_cell * nasl_md2(lex_ctxt *lexic)
static tree_cell * nasl_gcrypt_hash(lex_ctxt *lexic, int algorithm, void *data, size_t datalen, void *key, size_t keylen)
Definition nasl_crypto.c:59
tree_cell * nasl_ntlm2_response(lex_ctxt *lexic)
tree_cell * nasl_ntlmv1_hash(lex_ctxt *lexic)
tree_cell * nasl_keyexchg(lex_ctxt *lexic)
static void * tls_prf(const void *secret, size_t secret_len, const void *seed, size_t seed_len, const void *label, size_t outlen, int hmac)
tree_cell * nasl_sha1(lex_ctxt *lexic)
tree_cell * nasl_ntlm_response(lex_ctxt *lexic)
tree_cell * nasl_hmac_sha512(lex_ctxt *lexic)
tree_cell * nasl_sha512(lex_ctxt *lexic)
tree_cell * nasl_smb_gmac_aes_sign(lex_ctxt *lexic)
tree_cell * nasl_md5(lex_ctxt *lexic)
static tree_cell * nasl_hash(lex_ctxt *lexic, int algorithm)
tree_cell * nasl_prf_sha384(lex_ctxt *lexic)
tree_cell * nasl_hmac_ripemd160(lex_ctxt *lexic)
tree_cell * nasl_tls1_prf(lex_ctxt *lexic)
tree_cell * nasl_hmac_sha384(lex_ctxt *lexic)
tree_cell * nasl_lm_owf_gen(lex_ctxt *lexic)
static void * tls1_prf(const void *secret, size_t secret_len, const void *seed, size_t seed_len, const void *label, size_t outlen)
tree_cell * nasl_md4(lex_ctxt *lexic)
static tree_cell * nasl_prf(lex_ctxt *lexic, int hmac)
tree_cell * nasl_hmac_md5(lex_ctxt *lexic)
tree_cell * nasl_get_sign(lex_ctxt *lexic)
tree_cell * nasl_ntv2_owf_gen(lex_ctxt *lexic)
tree_cell * nasl_cipher_des(lex_ctxt *lexic)
tree_cell * nasl_ntlmv2_response(lex_ctxt *lexic)
tree_cell * nasl_ntlmv2_hash(lex_ctxt *lexic)
tree_cell * nasl_insert_hexzeros(lex_ctxt *lexic)
void nasl_perror(lex_ctxt *lexic, char *msg,...)
Definition nasl_debug.c:105
const char * val
Definition nasl_init.c:440
struct struct_lex_ctxt lex_ctxt
int get_var_size_by_name(lex_ctxt *, const char *)
Definition nasl_var.c:1138
int get_var_size_by_num(lex_ctxt *, int)
Definition nasl_var.c:1145
char * get_str_var_by_name(lex_ctxt *, const char *)
Definition nasl_var.c:1118
char * get_str_var_by_num(lex_ctxt *, int)
Definition nasl_var.c:1108
long int get_int_var_by_name(lex_ctxt *, const char *, int)
Definition nasl_var.c:1101
uint8_t len
tree_cell * alloc_typed_cell(int typ)
Definition nasl_tree.c:25
@ CONST_DATA
Definition nasl_tree.h:82
struct TC tree_cell
void ntlmssp_genauth_ntlm(char *password, uint8_t pass_len, uint8_t *lm_response, uint8_t *nt_response, uint8_t *session_key, char *challenge_data, unsigned char *nt_hash, int neg_flags)
Definition ntlmssp.c:61
void ntlmssp_genauth_ntlm2(char *password, uint8_t pass_len, uint8_t *lm_response, uint8_t *nt_response, uint8_t *session_key, char *challenge_data, unsigned char *nt_hash)
Definition ntlmssp.c:30
void ntlmssp_genauth_ntlmv2(char *user, char *domain, char *address_list, int address_list_len, char *challenge_data, uint8_t *lm_response, uint8_t *nt_response, uint8_t *session_key, unsigned char *ntlmv2_hash)
Definition ntlmssp.c:19
uint8_t * ntlmssp_genauth_keyexchg(uint8_t *session_key, char *challenge_data, unsigned char *nt_hash, uint8_t *new_sess_key)
Definition ntlmssp.c:85
Functions to support Authentication(type3 message) for NTLMSSP (NTLMv2, NTLM2, NTLM,...
Unix SMB/CIFS implementation.
void E_P16(uchar *p14, uchar *p16)
Definition smb_crypt.c:302
void E_P24(const uchar *p21, const uchar *c8, uchar *p24)
Definition smb_crypt.c:310
Unix SMB/Netbios implementation. Version 1.9.
int strupper_w(smb_ucs2_t *s)
Definition smb_crypt2.c:35
void SMBOWFencrypt_ntv2_ntlmssp(const uchar *kr, const uint8_t *srv_chal, int srv_chal_len, const uint8_t *cli_chal, int cli_chal_len, uchar resp_buf[16])
void simple_packet_signature_ntlmssp(uint8_t *mac_key, const uchar *buf, uint32 seq_number, unsigned char *calc_md5_mac)
Definition smb_signing.c:23
Unix SMB/CIFS implementation. SMB Signing Code.
int size
Definition nasl_tree.h:99
union TC::@332262321161220155002104006201360276211317150140 x
char * str_val
Definition nasl_tree.h:103
Support macros for special platforms.