From a5d47cf53ebc25b6308705b928c0f747757aa9de Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Thu, 25 Jun 2026 12:57:02 -0300 Subject: [PATCH 01/10] Fix: useragent in nasl_http2.c Reported as an use-after-free issue, but the problem was that I was using the wrong variable. Now uses the right one ua --- nasl/nasl_http2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nasl/nasl_http2.c b/nasl/nasl_http2.c index 64f6f00ff..0b28c82c6 100644 --- a/nasl/nasl_http2.c +++ b/nasl/nasl_http2.c @@ -355,7 +355,7 @@ _http2_req (lex_ctxt *lexic, KEYWORD keyword) } if (ua) { - curl_easy_setopt (handle, CURLOPT_USERAGENT, g_strdup (url->str)); + curl_easy_setopt (handle, CURLOPT_USERAGENT, g_strdup (ua)); g_free (ua); } From eee4efc560f09c2e7300e3160199e24431ab52a1 Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Thu, 25 Jun 2026 13:34:08 -0300 Subject: [PATCH 02/10] Fix: avoid stack overflow when password length is greater than 21 --- nasl/nasl_crypto.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/nasl/nasl_crypto.c b/nasl/nasl_crypto.c index 2758e104f..607618a54 100644 --- a/nasl/nasl_crypto.c +++ b/nasl/nasl_crypto.c @@ -675,6 +675,8 @@ nasl_ntlmv1_hash (lex_ctxt *lexic) if (pass_len < 16) pass_len = 16; + if (pass_len > 21) + pass_len = 21; bzero (p21, sizeof (p21)); memcpy (p21, password, pass_len); From 1ddac93adff7861a0991a8a3993d308ef90f5c32 Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Thu, 25 Jun 2026 14:16:02 -0300 Subject: [PATCH 03/10] Fix: check buffer lenght before memcpy --- nasl/nasl_crypto.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/nasl/nasl_crypto.c b/nasl/nasl_crypto.c index 607618a54..dfc0ea487 100644 --- a/nasl/nasl_crypto.c +++ b/nasl/nasl_crypto.c @@ -257,6 +257,12 @@ nasl_get_sign (lex_ctxt *lexic) uint8_t calc_md5_mac[16]; simple_packet_signature_ntlmssp ((uint8_t *) mac_key, buf, seq_num, calc_md5_mac); + if (buflen != get_var_size_by_name (lexic, "buf") || buflen < 26) + { + nasl_perror (lexic, "OOB read/write\n"); + return NULL; + } + memcpy (buf + 18, calc_md5_mac, 8); char *ret = g_malloc0 (buflen); memcpy (ret, buf, buflen); From dbef9498bc460244c2d0e181fd96fb885eaa700f Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Mon, 6 Jul 2026 10:09:41 -0300 Subject: [PATCH 04/10] Fix: solve OOB read --- nasl/nasl_crypto.c | 13 ++++++++++--- nasl/smb_signing.c | 23 ++++++++++++++++++----- nasl/smb_signing.h | 4 ++-- 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/nasl/nasl_crypto.c b/nasl/nasl_crypto.c index dfc0ea487..5d92ecb73 100644 --- a/nasl/nasl_crypto.c +++ b/nasl/nasl_crypto.c @@ -254,15 +254,22 @@ nasl_get_sign (lex_ctxt *lexic) "buflen:, seq_number:)\n"); return NULL; } - uint8_t calc_md5_mac[16]; - simple_packet_signature_ntlmssp ((uint8_t *) mac_key, buf, seq_num, - calc_md5_mac); if (buflen != get_var_size_by_name (lexic, "buf") || buflen < 26) { nasl_perror (lexic, "OOB read/write\n"); return NULL; } + uint8_t calc_md5_mac[16]; + if (simple_packet_signature_ntlmssp ((uint8_t *) mac_key, buf, + (size_t) buflen, seq_num, + calc_md5_mac) + != 0) + { + nasl_perror (lexic, "get_signature: OOB read\n"); + return NULL; + } + memcpy (buf + 18, calc_md5_mac, 8); char *ret = g_malloc0 (buflen); memcpy (ret, buf, buflen); diff --git a/nasl/smb_signing.c b/nasl/smb_signing.c index bafbdeb12..b8642683b 100644 --- a/nasl/smb_signing.c +++ b/nasl/smb_signing.c @@ -18,14 +18,28 @@ */ #include "smb_signing.h" +#include -void -simple_packet_signature_ntlmssp (uint8_t *mac_key, const uchar *buf, +int +simple_packet_signature_ntlmssp (uint8_t *mac_key, const uchar *buf, size_t buf_len, uint32 seq_number, unsigned char *calc_md5_mac) { const size_t offset_end_of_sig = (smb_ss_field + 8); unsigned char sequence_buf[8]; struct MD5Context md5_ctx; + const uint32 claimed_len = smb_len (buf); + size_t tail_len; + + if (buf == NULL || buf_len < offset_end_of_sig) + return -1; + + if (claimed_len < offset_end_of_sig - 4) + return -1; + + tail_len = claimed_len - (offset_end_of_sig - 4); + + if (tail_len > buf_len - offset_end_of_sig) + return -1; /* * Firstly put the sequence number into the first 4 bytes. @@ -33,7 +47,6 @@ simple_packet_signature_ntlmssp (uint8_t *mac_key, const uchar *buf, * * We do this here, to avoid modifying the packet. */ - SIVAL (sequence_buf, 0, seq_number); SIVAL (sequence_buf, 4, 0); @@ -54,9 +67,9 @@ simple_packet_signature_ntlmssp (uint8_t *mac_key, const uchar *buf, MD5Update (&md5_ctx, sequence_buf, sizeof (sequence_buf)); /* copy in the rest of the packet in, skipping the signature */ - MD5Update (&md5_ctx, buf + offset_end_of_sig, - smb_len (buf) - (offset_end_of_sig - 4)); + MD5Update (&md5_ctx, buf + offset_end_of_sig, tail_len); /* calculate the MD5 sig */ MD5Final (calc_md5_mac, &md5_ctx); + return 0; } diff --git a/nasl/smb_signing.h b/nasl/smb_signing.h index 286561bd4..e8d3aa955 100644 --- a/nasl/smb_signing.h +++ b/nasl/smb_signing.h @@ -32,9 +32,9 @@ #define uint8 uint8_t #endif -void +int simple_packet_signature_ntlmssp (uint8_t *mac_key, const uchar *buf, - uint32 seq_number, + size_t buf_len, uint32 seq_number, unsigned char *calc_md5_mac); #endif From 7e140936e093d7c8bcb144ed4a9a3aef98943f1d Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Mon, 6 Jul 2026 14:02:14 -0300 Subject: [PATCH 05/10] Fix: Unbounded VLA / stack overflow / integer overflow --- nasl/nasl_crypto.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/nasl/nasl_crypto.c b/nasl/nasl_crypto.c index 5d92ecb73..487d1bf9e 100644 --- a/nasl/nasl_crypto.c +++ b/nasl/nasl_crypto.c @@ -29,6 +29,7 @@ #include "smb_signing.h" #include +#include #include #include #include @@ -542,6 +543,19 @@ nasl_ntlmv2_response (lex_ctxt *lexic) "ntlmv2_hash:, address_list:, address_list_len:)\n"); return NULL; } + + if (address_list_len <= get_var_size_by_name (lexic, "address_list")) + { + nasl_perror (lexic, "ntlmv2_response: address_list and address_list_len " + "have different sized\n"); + return NULL; + } + if (address_list_len > UINT16_MAX) + { + nasl_perror (lexic, + "ntlmv2_response: address_list_len exceed Max lenght\n"); + return NULL; + } uint8_t lm_response[24]; uint8_t nt_response[16 + 28 + address_list_len]; uint8_t session_key[16]; From 5ef971de62897684a4adba2bc37bc74a7859ea2f Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Tue, 7 Jul 2026 16:26:05 -0300 Subject: [PATCH 06/10] Fix: nasl_ntlmv2_hash(). Do length validation. --- nasl/nasl_crypto.c | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/nasl/nasl_crypto.c b/nasl/nasl_crypto.c index 487d1bf9e..7be451073 100644 --- a/nasl/nasl_crypto.c +++ b/nasl/nasl_crypto.c @@ -29,7 +29,6 @@ #include "smb_signing.h" #include -#include #include #include #include @@ -263,8 +262,7 @@ nasl_get_sign (lex_ctxt *lexic) uint8_t calc_md5_mac[16]; if (simple_packet_signature_ntlmssp ((uint8_t *) mac_key, buf, - (size_t) buflen, seq_num, - calc_md5_mac) + (size_t) buflen, seq_num, calc_md5_mac) != 0) { nasl_perror (lexic, "get_signature: OOB read\n"); @@ -916,17 +914,30 @@ nasl_ntlmv2_hash (lex_ctxt *lexic) /* NTLMv2 */ - /* We also get to specify some random data */ + /* We also get to specify some random data. + To avoid DoS we set an uper limit for client chal length. + At the moment of fixing this, the max lenght used in a nasl script is 64. + */ + if (client_chal_length > 4096) + { + nasl_perror (lexic, "Length to big. Max is 4096\n"); + return NULL; + } + ntlmv2_client_data = g_malloc0 (client_chal_length); for (i = 0; i < client_chal_length; i++) ntlmv2_client_data[i] = rand () % 256; if (hash_len != 16) - nasl_perror (lexic, "owf_in must have a length of 16\n"); + { + nasl_perror (lexic, "owf_in must have a length of 16\n"); + return NULL; + } /* Given that data, and the challenge from the server, generate a response */ - SMBOWFencrypt_ntv2_ntlmssp (ntlm_v2_hash, server_chal, 8, ntlmv2_client_data, - client_chal_length, ntlmv2_response); + SMBOWFencrypt_ntv2_ntlmssp ( + ntlm_v2_hash, server_chal, get_var_size_by_name (lexic, "cryptkey"), + ntlmv2_client_data, client_chal_length, ntlmv2_response); /* put it into nt_response, for the code below to put into the packet */ final_response = g_malloc0 (client_chal_length + sizeof (ntlmv2_response)); From d86d8479124e7998fc436947eccaa006d20d764f Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Wed, 8 Jul 2026 09:17:16 -0300 Subject: [PATCH 07/10] Fix:nasl_snmp.c: read() return stored in size_t --- nasl/nasl_snmp.c | 12 ++++++------ nasl/smb_signing.c | 6 ++++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/nasl/nasl_snmp.c b/nasl/nasl_snmp.c index c4bf38088..706cbc1f9 100644 --- a/nasl/nasl_snmp.c +++ b/nasl/nasl_snmp.c @@ -419,19 +419,19 @@ check_spwan_output (int fd, snmp_result_t result, int fd_flag) while (1) { char buf[4096]; - size_t bytes; + ssize_t bytes; bytes = read (fd, buf, sizeof (buf)); - if (!bytes) - break; - else if (bytes > 0) - g_string_append_len (string, buf, bytes); - else + if (bytes < 0) { g_warning ("snmpget: %s", strerror (errno)); g_string_free (string, TRUE); return -1; } + if (!bytes) + break; + else if (bytes > 0) + g_string_append_len (string, buf, bytes); } // Split the result and store the oid and name diff --git a/nasl/smb_signing.c b/nasl/smb_signing.c index b8642683b..f1b18726b 100644 --- a/nasl/smb_signing.c +++ b/nasl/smb_signing.c @@ -18,11 +18,13 @@ */ #include "smb_signing.h" + #include int -simple_packet_signature_ntlmssp (uint8_t *mac_key, const uchar *buf, size_t buf_len, - uint32 seq_number, unsigned char *calc_md5_mac) +simple_packet_signature_ntlmssp (uint8_t *mac_key, const uchar *buf, + size_t buf_len, uint32 seq_number, + unsigned char *calc_md5_mac) { const size_t offset_end_of_sig = (smb_ss_field + 8); unsigned char sequence_buf[8]; From 70dc3f572a87b6083836862e4c69c93d825de90a Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Wed, 8 Jul 2026 12:49:13 -0300 Subject: [PATCH 08/10] Fix: use-after-free in nasl_snmpv1v2c_get() --- nasl/nasl_snmp.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/nasl/nasl_snmp.c b/nasl/nasl_snmp.c index 706cbc1f9..d86591acc 100644 --- a/nasl/nasl_snmp.c +++ b/nasl/nasl_snmp.c @@ -11,6 +11,7 @@ #include "nasl_snmp.h" #include "../misc/plugutils.h" +#include "glib.h" #include "nasl_lex_ctxt.h" #include @@ -683,13 +684,19 @@ nasl_snmpv1v2c_get (lex_ctxt *lexic, int version, u_char action) // is stored. if (result->oid_str != NULL && g_strstr_len (result->oid_str, 3, "iso")) { - next_oid_str = result->oid_str + 2; - next_oid_str[0] = '1'; - result->oid_str = g_strdup (next_oid_str); + char *orig = result->oid_str; + char *tmp = result->oid_str + 2; + tmp[0] = '1'; + result->oid_str = g_strdup (tmp); + g_free (orig); + g_free (next_oid_str); + next_oid_str = g_strdup (result->oid_str); } else if (result->oid_str != NULL) - next_oid_str = result->oid_str; - + { + g_free (next_oid_str); + next_oid_str = g_strdup (result->oid_str); + } /* Free request only, since members are pointers to the nasl lexic context which will be free()'d later */ g_free (request); From 46ef948f4010cccb6edd8691cf439d27ce1140c9 Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Thu, 9 Jul 2026 10:25:35 -0300 Subject: [PATCH 09/10] Fix: Stack overflow in nasl_win_cmd_exec() --- nasl/nasl_smb.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/nasl/nasl_smb.c b/nasl/nasl_smb.c index 451be0be4..d21693844 100644 --- a/nasl/nasl_smb.c +++ b/nasl/nasl_smb.c @@ -423,9 +423,16 @@ nasl_win_cmd_exec (lex_ctxt *lexic) else { delimiter = strchr (kdc, ','); + int kdc_len = delimiter - kdc; + if (delimiter && (kdc_len > INET6_ADDRSTRLEN - 1)) + { + g_warning ("kdc hostname value too long (max 45 chars)"); + return NULL; + } + if (delimiter != NULL) { - strncpy (first_kdc, kdc, delimiter - kdc); + strncpy (first_kdc, kdc, kdc_len); } else { From 5347fdec944ee9bd53647597ae200381187ee21f Mon Sep 17 00:00:00 2001 From: Juan Jose Nicola Date: Thu, 9 Jul 2026 11:51:54 -0300 Subject: [PATCH 10/10] Fix: OOB read / potential heap overflow nasl_packet_forgery* --- nasl/nasl_packet_forgery.c | 15 +++++++++++++-- nasl/nasl_packet_forgery_v6.c | 14 ++++++++++++-- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/nasl/nasl_packet_forgery.c b/nasl/nasl_packet_forgery.c index 6b5e7a978..d4f4dc040 100644 --- a/nasl/nasl_packet_forgery.c +++ b/nasl/nasl_packet_forgery.c @@ -370,9 +370,9 @@ insert_ip_options (lex_ctxt *lexic) int pad_len; char zero = '0'; int i; - int hl; + size_t hl; - if (ip == NULL) + if (ip == NULL || value == NULL) { nasl_perror (lexic, "Usage : insert_ip_options(ip:, code:, " "length:, value:\n"); @@ -384,7 +384,11 @@ insert_ip_options (lex_ctxt *lexic) pad_len = 0; hl = ip->ip_hl * 4 < UNFIX (ip->ip_len) ? ip->ip_hl * 4 : UNFIX (ip->ip_len); + if (hl > size) + return NULL; // malformed. + new_packet = g_malloc0 (size + 4 + value_size + pad_len); + bcopy (ip, new_packet, hl); uc_code = (u_char) code; @@ -898,6 +902,13 @@ get_tcp_option (lex_ctxt *lexic) ip = (struct ip *) packet; ipsz = get_var_size_by_name (lexic, "tcp"); + if (ipsz < (int) sizeof (struct ip)) + return NULL; + + // check that ip + tcp is bigger that the original packet + if (ip->ip_hl * 4 + 20 > ipsz) + return NULL; + // ip header length is given in 32 bits words = 4 bytes. if (ip->ip_hl * 4 > ipsz) return NULL; /* Invalid packet */ diff --git a/nasl/nasl_packet_forgery_v6.c b/nasl/nasl_packet_forgery_v6.c index 633f37eae..d8d57597f 100644 --- a/nasl/nasl_packet_forgery_v6.c +++ b/nasl/nasl_packet_forgery_v6.c @@ -407,9 +407,9 @@ insert_ip_v6_options (lex_ctxt *lexic) int pad_len; char zero = '0'; int i; - int pl; + size_t pl; - if (ip6 == NULL) + if (ip6 == NULL && value == NULL) { nasl_perror (lexic, "Usage : %s(ip6:, code:, " @@ -423,6 +423,10 @@ insert_ip_v6_options (lex_ctxt *lexic) pad_len = 0; pl = 40 < UNFIX (ip6->ip6_plen) ? 40 : UNFIX (ip6->ip6_plen); + + if (pl > size) + return NULL; // malformed packet. + new_packet = g_malloc0 (size + 4 + value_size + pad_len); bcopy (ip6, new_packet, pl); @@ -863,6 +867,12 @@ get_tcp_v6_option (lex_ctxt *lexic) /* valid ipv6 header check */ ipsz = get_var_size_by_name (lexic, "tcp"); + if (ipsz < (int) sizeof (struct ip6_hdr)) + return NULL; // mal formed. + + if (40 + 20 > ipsz) + return NULL; + if (UNFIX (ip6->ip6_plen) > ipsz) return NULL; /* Invalid packet */