Skip to content

Commit

Permalink
Add: possibility to fallback to LEGACY:%COMPAT:%UNSAFE_RENEGOTIATION
Browse files Browse the repository at this point in the history
When a TLS connection with `NORMAL:+ARCFOUR-128:%COMPAT` as well as with
a INSECURE_DH_PRIME_BITS fails then find-service will try a LEGACY
connection before falling back to an unencrypted connection.
  • Loading branch information
nichtsfrei committed May 3, 2022
1 parent a04e220 commit 57a1fd6
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 31 deletions.
15 changes: 13 additions & 2 deletions misc/network.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,9 @@ stream_get_err (int fd)
return p->last_err;
}

const char *tls_priorities = "NORMAL:+ARCFOUR-128:%COMPAT";
int tls_priority_flag = NO_PRIORITY_FLAGS;

/**
* @brief Returns a free file descriptor.
*/
Expand Down Expand Up @@ -438,6 +441,8 @@ set_gnutls_protocol (gnutls_session_t session, openvas_encaps_t encaps,
break;
}

g_debug ("%s: setting %s as priority_string based on %d", __func__,
priorities, encaps);
if ((err = gnutls_priority_set_direct (session, priorities, &errloc)))
{
g_message ("[%d] setting session priorities '%.20s': %s", getpid (),
Expand Down Expand Up @@ -1169,13 +1174,19 @@ open_stream_connection_ext (struct script_infos *args, unsigned int port,
return ret;
}

void
open_stream_tls_default_priorities (const char *p, const int pflag)
{
tls_priorities = p;
tls_priority_flag = pflag;
}

int
open_stream_connection (struct script_infos *args, unsigned int port,
int transport, int timeout)
{
return open_stream_connection_ext (args, port, transport, timeout,
"NORMAL:+ARCFOUR-128:%COMPAT",
NO_PRIORITY_FLAGS);
tls_priorities, tls_priority_flag);
}

/* Same as open_stream_auto_encaps but allows to force auto detection
Expand Down
3 changes: 3 additions & 0 deletions misc/network.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ get_sock_infos (int sock, int *r_transport, void **r_tls_session);
unsigned short *
getpts (char *, int *);

void
open_stream_tls_default_priorities (const char *p, const int pflag);

int
open_stream_connection (struct script_infos *, unsigned int, int, int);

Expand Down
92 changes: 63 additions & 29 deletions nasl/nasl_builtin_find_service.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@

#define NUM_CHILDREN "Number of connections done in parallel : "

// we cannot use the GNU ones due to number mismatch
#define TLS_PRIME_UNACCEPTABLE -2
#define TLS_FATAL_ALERT -3

#undef G_LOG_DOMAIN
/**
* @brief GLib logging domain.
Expand Down Expand Up @@ -1488,6 +1492,63 @@ may_be_time (time_t *rtime)
return 0;
}

static int
retry_stream_connection (int test_ssl, struct script_infos *desc, int port,
int timeout)
{
const char *p = "NORMAL:+ARCFOUR-128:%COMPAT";
const char *lp = "LEGACY:%COMPAT:%UNSAFE_RENEGOTIATION";
int cnx, trp;

if (test_ssl)
trp = OPENVAS_ENCAPS_TLScustom;
else
trp = OPENVAS_ENCAPS_IP;

cnx = open_stream_connection (desc, port, trp, timeout);
if (test_ssl)
{
switch (cnx)
{
case TLS_PRIME_UNACCEPTABLE:
// retry with insecure bit
g_debug ("%s: NO_PRIORITY_FLAGS failed, retrying with "
"INSECURE_DH_PRIME_BITS",
__func__);
cnx = open_stream_connection_ext (desc, port, trp, timeout, p,
INSECURE_DH_PRIME_BITS);
if (cnx >= 0)
{
open_stream_tls_default_priorities (p, INSECURE_DH_PRIME_BITS);
}
break;
case TLS_FATAL_ALERT:
// retry with legacy option
g_debug ("%s: %s failed, retrying with %s", __func__, p, lp);
cnx = open_stream_connection_ext (desc, port, trp, timeout, lp,
NO_PRIORITY_FLAGS);
if (cnx >= 0)
{
open_stream_tls_default_priorities (lp, NO_PRIORITY_FLAGS);
}
break;
default:
// do nothing
break;
}
// verify if retries went successful and if not retry without tls
if (cnx < 0)
{
g_debug ("%s: unable to establish a TLS connection to %s; falling "
"back to unencrypted connection",
__func__, plug_get_host_fqdn (desc));
cnx = open_stream_connection (desc, port, OPENVAS_ENCAPS_IP, timeout);
}
}

return cnx;
}

static int
plugin_do_run (struct script_infos *desc, GSList *h, int test_ssl)
{
Expand Down Expand Up @@ -1601,36 +1662,8 @@ plugin_do_run (struct script_infos *desc, GSList *h, int test_ssl)
g_free (banner);
banner = NULL;
}
/* If test_ssl is set, try with TLS first. */
if (test_ssl)
trp = OPENVAS_ENCAPS_TLScustom;
else
trp = OPENVAS_ENCAPS_IP;
gettimeofday (&tv1, NULL);
cnx = open_stream_connection (desc, port, trp, cnx_timeout);
if (cnx == -2 && test_ssl)
{
unsigned int flags = INSECURE_DH_PRIME_BITS;

gettimeofday (&tv1, NULL);
cnx = open_stream_connection_ext (
desc, port, trp, cnx_timeout, "NORMAL:+ARCFOUR-128:%COMPAT",
flags);
}
else if (cnx < 0 && test_ssl)
{
if (cnx == -3)
{
host_fqdn = plug_get_host_fqdn (desc);
g_message ("%s: A TLS fatal alert has been received "
"during the handshake with %s:%d",
__func__, host_fqdn, port);
g_free (host_fqdn);
}
trp = OPENVAS_ENCAPS_IP;
gettimeofday (&tv1, NULL);
cnx = open_stream_connection (desc, port, trp, cnx_timeout);
}
cnx = retry_stream_connection (test_ssl, desc, port, cnx_timeout);
gettimeofday (&tv2, NULL);
diff_tv = DIFFTV1000 (tv2, tv1);
}
Expand Down Expand Up @@ -2045,6 +2078,7 @@ plugin_do_run (struct script_infos *desc, GSList *h, int test_ssl)
&& strstr (
buffer,
"That item is not currently available")))

mark_gopher_server (desc, port);
else if (strstr (buffer,
"www-authenticate: basic realm=\"swat\""))
Expand Down

0 comments on commit 57a1fd6

Please sign in to comment.