|
|
41d651 |
diff --git a/ncat/ncat_connect.c b/ncat/ncat_connect.c
|
|
|
41d651 |
index d8c73ab1b..5695800a3 100644
|
|
|
41d651 |
--- a/ncat/ncat_connect.c
|
|
|
41d651 |
+++ b/ncat/ncat_connect.c
|
|
|
41d651 |
@@ -1049,7 +1049,10 @@ int ncat_connect(void)
|
|
|
41d651 |
}
|
|
|
41d651 |
|
|
|
41d651 |
if (connect_socket == -1)
|
|
|
41d651 |
+ {
|
|
|
41d651 |
+ nsp_delete(mypool);
|
|
|
41d651 |
return 1;
|
|
|
41d651 |
+ }
|
|
|
41d651 |
/* Clear out whatever is left in the socket buffer which may be
|
|
|
41d651 |
already sent by proxy server along with http response headers. */
|
|
|
41d651 |
//line = socket_buffer_remainder(&stateful_buf, &n);
|
|
|
41d651 |
--- a/ncat/ncat.h
|
|
|
41d651 |
+++ b/ncat/ncat.h
|
|
|
41d651 |
@@ -177,13 +177,13 @@
|
|
|
41d651 |
|
|
|
41d651 |
struct socks5_connect {
|
|
|
41d651 |
char ver;
|
|
|
41d651 |
- char nmethods;
|
|
|
41d651 |
+ unsigned char nmethods;
|
|
|
41d651 |
char methods[3];
|
|
|
41d651 |
} __attribute__((packed));
|
|
|
41d651 |
|
|
|
41d651 |
struct socks5_auth {
|
|
|
41d651 |
- char ver; // must be always 1
|
|
|
41d651 |
- char data[SOCKS_BUFF_SIZE];
|
|
|
41d651 |
+ char ver; // must be always 1
|
|
|
41d651 |
+ unsigned char data[SOCKS_BUFF_SIZE];
|
|
|
41d651 |
} __attribute__((packed));
|
|
|
41d651 |
|
|
|
41d651 |
struct socks5_request {
|
|
|
41d651 |
@@ -263,6 +263,12 @@
|
|
|
41d651 |
#define SOCKS5_ATYP_NAME 3
|
|
|
41d651 |
#define SOCKS5_ATYP_IPv6 4
|
|
|
41d651 |
|
|
|
41d651 |
+#define SOCKS5_USR_MAXLEN 255
|
|
|
41d651 |
+#define SOCKS5_PWD_MAXLEN 255
|
|
|
41d651 |
+
|
|
|
41d651 |
+#if SOCKS_BUFF_SIZE < (1 + SOCKS5_USR_MAXLEN) + (1 + SOCKS5_PWD_MAXLEN)
|
|
|
41d651 |
+#error SOCKS_BUFF_SIZE is defined too small to handle SOCKS5 authentication
|
|
|
41d651 |
+#endif
|
|
|
41d651 |
|
|
|
41d651 |
/* Length of IPv6 address */
|
|
|
41d651 |
#ifndef INET6_ADDRSTRLEN
|
|
|
41d651 |
--- a/ncat/ncat_connect.c
|
|
|
41d651 |
+++ b/ncat/ncat_connect.c
|
|
|
41d651 |
@@ -664,9 +664,8 @@
|
|
|
41d651 |
int sd,len,lenfqdn;
|
|
|
41d651 |
struct socks5_request socks5msg2;
|
|
|
41d651 |
struct socks5_auth socks5auth;
|
|
|
41d651 |
- char *proxy_auth;
|
|
|
41d651 |
- char *username;
|
|
|
41d651 |
- char *password;
|
|
|
41d651 |
+ char *uptr, *pptr;
|
|
|
41d651 |
+ size_t authlen, ulen, plen;
|
|
|
41d651 |
|
|
|
41d651 |
sd = do_connect(SOCK_STREAM);
|
|
|
41d651 |
if (sd == -1) {
|
|
|
41d651 |
@@ -683,17 +682,13 @@
|
|
|
41d651 |
|
|
|
41d651 |
zmem(&socks5msg,sizeof(socks5msg));
|
|
|
41d651 |
socks5msg.ver = SOCKS5_VERSION;
|
|
|
41d651 |
- socks5msg.nmethods = 1;
|
|
|
41d651 |
- socks5msg.methods[0] = SOCKS5_AUTH_NONE;
|
|
|
41d651 |
- len = 3;
|
|
|
41d651 |
+ socks5msg.nmethods = 0;
|
|
|
41d651 |
+ socks5msg.methods[socks5msg.nmethods++] = SOCKS5_AUTH_NONE;
|
|
|
41d651 |
|
|
|
41d651 |
- if (o.proxy_auth){
|
|
|
41d651 |
- socks5msg.nmethods ++;
|
|
|
41d651 |
- socks5msg.methods[1] = SOCKS5_AUTH_USERPASS;
|
|
|
41d651 |
- len ++;
|
|
|
41d651 |
- }
|
|
|
41d651 |
+ if (o.proxy_auth)
|
|
|
41d651 |
+ socks5msg.methods[socks5msg.nmethods++] = SOCKS5_AUTH_USERPASS;
|
|
|
41d651 |
|
|
|
41d651 |
- if (send(sd, (char *) &socks5msg, len, 0) < 0) {
|
|
|
41d651 |
+ if (send(sd, (char *)&socks5msg, offsetof(struct socks5_connect, methods) + socks5msg.nmethods, 0) < 0) {
|
|
|
41d651 |
loguser("Error: proxy request: %s.\n", socket_strerror(socket_errno()));
|
|
|
41d651 |
close(sd);
|
|
|
41d651 |
return -1;
|
|
|
41d651 |
@@ -706,46 +701,47 @@
|
|
|
41d651 |
return -1;
|
|
|
41d651 |
}
|
|
|
41d651 |
|
|
|
41d651 |
- if (socksbuf[0] != 5){
|
|
|
41d651 |
+ if (socksbuf[0] != SOCKS5_VERSION) {
|
|
|
41d651 |
loguser("Error: got wrong server version in response.\n");
|
|
|
41d651 |
close(sd);
|
|
|
41d651 |
return -1;
|
|
|
41d651 |
}
|
|
|
41d651 |
|
|
|
41d651 |
- switch(socksbuf[1]) {
|
|
|
41d651 |
+ switch((unsigned char)socksbuf[1]) {
|
|
|
41d651 |
case SOCKS5_AUTH_NONE:
|
|
|
41d651 |
if (o.verbose)
|
|
|
41d651 |
loguser("No authentication needed.\n");
|
|
|
41d651 |
break;
|
|
|
41d651 |
|
|
|
41d651 |
- case SOCKS5_AUTH_GSSAPI:
|
|
|
41d651 |
- loguser("GSSAPI authentication method not supported.\n");
|
|
|
41d651 |
- close(sd);
|
|
|
41d651 |
- return -1;
|
|
|
41d651 |
-
|
|
|
41d651 |
case SOCKS5_AUTH_USERPASS:
|
|
|
41d651 |
if (o.verbose)
|
|
|
41d651 |
loguser("Doing username and password authentication.\n");
|
|
|
41d651 |
|
|
|
41d651 |
if(!o.proxy_auth){
|
|
|
41d651 |
- loguser("Error: proxy requested to do authentication, but no credentials were provided.\n");
|
|
|
41d651 |
+ /* Proxy must not select a method not offered by the client */
|
|
|
41d651 |
+ loguser("Error: proxy selected invalid authentication method.\n");
|
|
|
41d651 |
close(sd);
|
|
|
41d651 |
return -1;
|
|
|
41d651 |
}
|
|
|
41d651 |
|
|
|
41d651 |
- if (strlen(o.proxy_auth) > SOCKS_BUFF_SIZE-2){
|
|
|
41d651 |
- loguser("Error: username and password are too long to fit into buffer.\n");
|
|
|
41d651 |
+ /* Split up the proxy auth argument. */
|
|
|
41d651 |
+ uptr = o.proxy_auth;
|
|
|
41d651 |
+ pptr = strchr(o.proxy_auth, ':');
|
|
|
41d651 |
+ if (pptr == NULL) {
|
|
|
41d651 |
+ loguser("Error: invalid username:password combo.\n");
|
|
|
41d651 |
close(sd);
|
|
|
41d651 |
return -1;
|
|
|
41d651 |
}
|
|
|
41d651 |
|
|
|
41d651 |
- /* Split up the proxy auth argument. */
|
|
|
41d651 |
- proxy_auth = Strdup(o.proxy_auth);
|
|
|
41d651 |
- username = strtok(proxy_auth, ":");
|
|
|
41d651 |
- password = strtok(NULL, ":");
|
|
|
41d651 |
- if (password == NULL || username == NULL) {
|
|
|
41d651 |
- free(proxy_auth);
|
|
|
41d651 |
- loguser("Error: empty username or password.\n");
|
|
|
41d651 |
+ ulen = (pptr++) - uptr;
|
|
|
41d651 |
+ plen = strlen(pptr);
|
|
|
41d651 |
+ if (ulen > SOCKS5_USR_MAXLEN) {
|
|
|
41d651 |
+ loguser("Error: username length exceeds %d.\n", SOCKS5_USR_MAXLEN);
|
|
|
41d651 |
+ close(sd);
|
|
|
41d651 |
+ return -1;
|
|
|
41d651 |
+ }
|
|
|
41d651 |
+ if (plen > SOCKS5_PWD_MAXLEN) {
|
|
|
41d651 |
+ loguser("Error: password length exceeds %d.\n", SOCKS5_PWD_MAXLEN);
|
|
|
41d651 |
close(sd);
|
|
|
41d651 |
return -1;
|
|
|
41d651 |
}
|
|
|
41d651 |
@@ -766,15 +762,16 @@
|
|
|
41d651 |
*/
|
|
|
41d651 |
|
|
|
41d651 |
socks5auth.ver = 1;
|
|
|
41d651 |
- socks5auth.data[0] = strlen(username);
|
|
|
41d651 |
- memcpy(socks5auth.data+1,username,strlen(username));
|
|
|
41d651 |
- len = 2 + strlen(username); // (version + strlen) + username
|
|
|
41d651 |
+ authlen = 0;
|
|
|
41d651 |
+ socks5auth.data[authlen++] = ulen;
|
|
|
41d651 |
+ memcpy(socks5auth.data + authlen, uptr, ulen);
|
|
|
41d651 |
+ authlen += ulen;
|
|
|
41d651 |
|
|
|
41d651 |
- socks5auth.data[len-1]=strlen(password);
|
|
|
41d651 |
- memcpy(socks5auth.data+len,password,strlen(password));
|
|
|
41d651 |
- len += 1 + strlen(password);
|
|
|
41d651 |
+ socks5auth.data[authlen++] = plen;
|
|
|
41d651 |
+ memcpy(socks5auth.data + authlen, pptr, plen);
|
|
|
41d651 |
+ authlen += plen;
|
|
|
41d651 |
|
|
|
41d651 |
- if (send(sd, (char *) &socks5auth, len, 0) < 0) {
|
|
|
41d651 |
+ if (send(sd, (char *) &socks5auth, offsetof(struct socks5_auth, data) + authlen, 0) < 0) {
|
|
|
41d651 |
loguser("Error: sending proxy authentication.\n");
|
|
|
41d651 |
close(sd);
|
|
|
41d651 |
return -1;
|
|
|
41d651 |
@@ -794,8 +791,14 @@
|
|
|
41d651 |
|
|
|
41d651 |
break;
|
|
|
41d651 |
|
|
|
41d651 |
+ case SOCKS5_AUTH_FAILED:
|
|
|
41d651 |
+ loguser("Error: no acceptable authentication method proposed.\n");
|
|
|
41d651 |
+ close(sd);
|
|
|
41d651 |
+ return -1;
|
|
|
41d651 |
+
|
|
|
41d651 |
default:
|
|
|
41d651 |
- loguser("Error - can't choose any authentication method.\n");
|
|
|
41d651 |
+ /* Proxy must not select a method not offered by the client */
|
|
|
41d651 |
+ loguser("Error: proxy selected invalid authentication method.\n");
|
|
|
41d651 |
close(sd);
|
|
|
41d651 |
return -1;
|
|
|
41d651 |
}
|
|
|
41d651 |
@@ -832,6 +835,10 @@
|
|
|
41d651 |
socks5msg2.dst[0]=lenfqdn;
|
|
|
41d651 |
memcpy(socks5msg2.dst+1,o.target,lenfqdn);
|
|
|
41d651 |
len = 1 + lenfqdn;
|
|
|
41d651 |
+ break;
|
|
|
41d651 |
+
|
|
|
41d651 |
+ default: // this shall not happen
|
|
|
41d651 |
+ ncat_assert(0);
|
|
|
41d651 |
}
|
|
|
41d651 |
|
|
|
41d651 |
memcpy(socks5msg2.dst+len, &proxyport, sizeof(proxyport));
|