nmap: fix ncat proxy mode with upstream patches
authorValdikSS ValdikSS <iam@valdikss.org.ru>
Fri, 16 Jun 2023 14:53:08 +0000 (17:53 +0300)
committerNuno Goncalves <nunojpg@gmail.com>
Tue, 20 Jun 2023 16:00:42 +0000 (17:00 +0100)
ncat utility from nmap package has a bug in 7.90 and 7.91 version which
prevent it from working via proxy.

Signed-off-by: ValdikSS ValdikSS <iam@valdikss.org.ru>
net/nmap/patches/041-proxyfix.patch [new file with mode: 0644]
net/nmap/patches/042-proxyfix.patch [new file with mode: 0644]
net/nmap/patches/043-proxyfix.patch [new file with mode: 0644]

diff --git a/net/nmap/patches/041-proxyfix.patch b/net/nmap/patches/041-proxyfix.patch
new file mode 100644 (file)
index 0000000..cfb5ea2
--- /dev/null
@@ -0,0 +1,32 @@
+From 169d7e5a922ef8e63b51ee2bdf4fd4ad60ed2689 Mon Sep 17 00:00:00 2001
+From: dmiller <dmiller@e0a8ed71-7df4-0310-8962-fdc924857419>
+Date: Thu, 19 Nov 2020 17:34:24 +0000
+Subject: [PATCH] Restore call to post_connect in non-ssl case. Fixes #2149
+
+---
+ ncat/ncat_connect.c | 11 ++++++++---
+ 1 file changed, 8 insertions(+), 3 deletions(-)
+
+--- a/ncat/ncat_connect.c
++++ b/ncat/ncat_connect.c
+@@ -1064,12 +1064,17 @@ int ncat_connect(void)
+             bye("Failed to set hostname on iod.");
+         if (o.ssl)
+         {
++            /* connect_handler creates stdin_nsi and calls post_connect */
+             nsock_reconnect_ssl(mypool, cs.sock_nsi, connect_handler, o.conntimeout, NULL, NULL);
+         }
++        else
++        {
++            /* Create IOD for nsp->stdin */
++            if ((cs.stdin_nsi = nsock_iod_new2(mypool, 0, NULL)) == NULL)
++                bye("Failed to create stdin nsiod.");
+-        /* Create IOD for nsp->stdin */
+-        if ((cs.stdin_nsi = nsock_iod_new2(mypool, 0, NULL)) == NULL)
+-            bye("Failed to create stdin nsiod.");
++            post_connect(mypool, cs.sock_nsi);
++        }
+     }
+     /* connect */
diff --git a/net/nmap/patches/042-proxyfix.patch b/net/nmap/patches/042-proxyfix.patch
new file mode 100644 (file)
index 0000000..8c51692
--- /dev/null
@@ -0,0 +1,59 @@
+From 3913c631365d140d13723df90adcc383ad77086c Mon Sep 17 00:00:00 2001
+From: nnposter <nnposter@e0a8ed71-7df4-0310-8962-fdc924857419>
+Date: Tue, 16 Mar 2021 02:09:39 +0000
+Subject: [PATCH] Use more descriptive error messages
+
+---
+ ncat/ncat_connect.c | 14 +++++++-------
+ 1 file changed, 7 insertions(+), 7 deletions(-)
+
+--- a/ncat/ncat_connect.c
++++ b/ncat/ncat_connect.c
+@@ -681,15 +681,15 @@ static int do_proxy_socks5(void)
+         return -1;
+     }
+-    /* first response just two bytes, version and auth method */
++    /* connect response just two bytes, version and auth method */
+     if (socket_buffer_readcount(&stateful_buf, socksbuf, 2) < 0) {
+-        loguser("Error: malformed first response from proxy.\n");
++        loguser("Error: malformed connect response from proxy.\n");
+         close(sd);
+         return -1;
+     }
+     if (socksbuf[0] != SOCKS5_VERSION) {
+-        loguser("Error: got wrong server version in response.\n");
++        loguser("Error: wrong SOCKS version in connect response.\n");
+         close(sd);
+         return -1;
+     }
+@@ -744,8 +744,8 @@ static int do_proxy_socks5(void)
+              * Server response for username/password authentication:
+              * field 1: version, 1 byte
+              * field 2: status code, 1 byte.
+-             * 0x00 = success
+-             * any other value = failure, connection must be closed
++             *          0x00 = success
++             *          any other value = failure, connection must be closed
+              */
+             socks5auth.ver = 1;
+@@ -805,7 +805,7 @@ static int do_proxy_socks5(void)
+         if (o.verbose)
+             loguser("Host %s will be resolved by the proxy.\n", o.target);
+         socks5msg2.atyp = SOCKS5_ATYP_NAME;
+-        targetlen=strlen(o.target);
++        targetlen = strlen(o.target);
+         if (targetlen > SOCKS5_DST_MAXLEN){
+             loguser("Error: hostname length exceeds %d.\n", SOCKS5_DST_MAXLEN);
+             close(sd);
+@@ -849,7 +849,7 @@ static int do_proxy_socks5(void)
+     /* TODO just two bytes for now, need to read more for bind */
+     if (socket_buffer_readcount(&stateful_buf, socksbuf, 2) < 0) {
+-        loguser("Error: malformed second response from proxy.\n");
++        loguser("Error: malformed request response from proxy.\n");
+         close(sd);
+         return -1;
+     }
diff --git a/net/nmap/patches/043-proxyfix.patch b/net/nmap/patches/043-proxyfix.patch
new file mode 100644 (file)
index 0000000..9e392cd
--- /dev/null
@@ -0,0 +1,104 @@
+From 024bbf84f137b6e937f8a702cb0718544e48483a Mon Sep 17 00:00:00 2001
+From: nnposter <nnposter@e0a8ed71-7df4-0310-8962-fdc924857419>
+Date: Tue, 16 Mar 2021 02:34:35 +0000
+Subject: [PATCH] Make sure that SOCKS proxied server data are processed There
+ was a race condition where proxied server data could arrive appended to the
+ final SOCKS handshake response, causing the data to get skipped.
+
+---
+ ncat/ncat_connect.c | 44 +++++++++++++++++++++++++++++++++++++++++---
+ 1 files changed, 41 insertions(+), 3 deletions(-)
+
+--- a/ncat/ncat_connect.c
++++ b/ncat/ncat_connect.c
+@@ -552,6 +552,8 @@ static int do_proxy_socks4(void)
+     union sockaddr_u addr;
+     size_t sslen;
+     int sd;
++    size_t remainderlen;
++    char* remainder;
+     if (getaddrfamily(o.target) == 2) {
+         loguser("Error: IPv6 addresses are not supported with Socks4.\n");
+@@ -629,6 +631,10 @@ static int do_proxy_socks4(void)
+         return -1;
+     }
++    /* whatever is left in the buffer is part of the proxied connection */
++    remainder = socket_buffer_remainder(&stateful_buf, &remainderlen);
++    Write(STDOUT_FILENO, remainder, remainderlen);
++
+     return sd;
+ }
+@@ -641,7 +647,7 @@ static int do_proxy_socks5(void)
+     struct socket_buffer stateful_buf;
+     struct socks5_connect socks5msg;
+     uint16_t proxyport = htons(o.portno);
+-    char socksbuf[8];
++    char socksbuf[4];
+     int sd;
+     size_t dstlen, targetlen;
+     struct socks5_request socks5msg2;
+@@ -653,6 +659,10 @@ static int do_proxy_socks5(void)
+     void *addrbuf;
+     size_t addrlen;
+     char addrstr[INET6_ADDRSTRLEN];
++    size_t bndaddrlen;
++    char bndaddr[16 + 2]; /* IPv4/IPv6 address and port */
++    size_t remainderlen;
++    char* remainder;
+     sd = do_connect(SOCK_STREAM);
+     if (sd == -1) {
+@@ -847,13 +857,18 @@ static int do_proxy_socks5(void)
+         return -1;
+     }
+-    /* TODO just two bytes for now, need to read more for bind */
+-    if (socket_buffer_readcount(&stateful_buf, socksbuf, 2) < 0) {
++    if (socket_buffer_readcount(&stateful_buf, socksbuf, 4) < 0) {
+         loguser("Error: malformed request response from proxy.\n");
+         close(sd);
+         return -1;
+     }
++    if (socksbuf[0] != SOCKS5_VERSION) {
++        loguser("Error: wrong SOCKS version in request response.\n");
++        close(sd);
++        return -1;
++    }
++
+     switch(socksbuf[1]) {
+         case 0:
+             if (o.verbose)
+@@ -897,6 +912,29 @@ static int do_proxy_socks5(void)
+             return -1;
+     }
++    switch (socksbuf[3]) {
++    case SOCKS5_ATYP_IPv4:
++        bndaddrlen = 4 + 2;
++        break;
++    case SOCKS5_ATYP_IPv6:
++        bndaddrlen = 16 + 2;
++        break;
++    default:
++        loguser("Error: invalid proxy bind address type.\n");
++        close(sd);
++        return -1;
++    }
++
++    if (socket_buffer_readcount(&stateful_buf, bndaddr, bndaddrlen) < 0) {
++        loguser("Error: malformed request response from proxy.\n");
++        close(sd);
++        return -1;
++    }
++
++    /* whatever is left in the buffer is part of the proxied connection */
++    remainder = socket_buffer_remainder(&stateful_buf, &remainderlen);
++    Write(STDOUT_FILENO, remainder, remainderlen);
++
+     return(sd);
+ }