Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/haad/proxychains.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Hamsik <haaaad@gmail.com>2020-07-21 23:41:19 +0300
committerGitHub <noreply@github.com>2020-07-21 23:41:19 +0300
commit5dd8450452a31d2b466372b7d0284149795a9b64 (patch)
treeb8faed658b3d79963dbd81ccddf2f51ab6ff561c
parent8dea4f9297275d8115d573104f164b298c9f84df (diff)
parentd7096b4f98e17c791f98aa13ce451c1650147ca3 (diff)
Merge pull request #99 from tomgilon/dnat
Add dnat feature
-rw-r--r--src/core.h6
-rw-r--r--src/libproxychains.c78
-rw-r--r--src/proxychains.conf18
3 files changed, 102 insertions, 0 deletions
diff --git a/src/core.h b/src/core.h
index c0be4f6..61e4534 100644
--- a/src/core.h
+++ b/src/core.h
@@ -20,6 +20,7 @@
#define __CORE_HEADER
#define BUFF_SIZE 8*1024 // used to read responses from proxies.
#define MAX_LOCALNET 64
+#define MAX_DNAT 64
typedef union {
unsigned char octet[4];
@@ -94,6 +95,11 @@ typedef struct {
} localaddr_arg;
typedef struct {
+ struct in_addr orig_dst, new_dst;
+ unsigned short orig_port, new_port;
+} dnat_arg;
+
+typedef struct {
ip_type ip;
unsigned short port;
proxy_type pt;
diff --git a/src/libproxychains.c b/src/libproxychains.c
index 46d11c7..23eeb53 100644
--- a/src/libproxychains.c
+++ b/src/libproxychains.c
@@ -66,6 +66,8 @@ chain_type proxychains_ct;
proxy_data proxychains_pd[MAX_CHAIN];
size_t num_localnet_addr = 0;
+dnat_arg dnats[MAX_DNAT];
+size_t num_dnats = 0;
#ifdef THREAD_SAFE
pthread_once_t init_once = PTHREAD_ONCE_INIT;
@@ -188,6 +190,8 @@ static void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_typ
char *env;
char local_in_addr_port[32];
char local_in_addr[32], local_in_port[32], local_netmask[32];
+ char dnat_orig_addr_port[32], dnat_new_addr_port[32];
+ char dnat_orig_addr[32], dnat_orig_port[32], dnat_new_addr[32], dnat_new_port[32];
FILE *file = NULL;
if(proxychains_got_chain_data)
@@ -297,6 +301,55 @@ static void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_typ
proxychains_quiet_mode = 1;
} else if(strstr(buff, "proxy_dns")) {
proxychains_resolver = 1;
+ } else if(strstr(buff, "dnat")) {
+ if(sscanf(buff, "%s %21[^ ] %21s\n", user, dnat_orig_addr_port, dnat_new_addr_port) < 3) {
+ fprintf(stderr, "dnat format error");
+ exit(1);
+ }
+ /* clean previously used buffer */
+ memset(dnat_orig_port, 0, sizeof(dnat_orig_port) / sizeof(dnat_orig_port[0]));
+ memset(dnat_new_port, 0, sizeof(dnat_new_port) / sizeof(dnat_new_port[0]));
+
+ (void)sscanf(dnat_orig_addr_port, "%15[^:]:%5s", dnat_orig_addr, dnat_orig_port);
+ (void)sscanf(dnat_new_addr_port, "%15[^:]:%5s", dnat_new_addr, dnat_new_port);
+
+ if(num_dnats < MAX_DNAT) {
+ int error;
+ error =
+ inet_pton(AF_INET, dnat_orig_addr,
+ &dnats[num_dnats].orig_dst);
+ if(error <= 0) {
+ fprintf(stderr, "dnat original destination address error\n");
+ exit(1);
+ }
+
+ error =
+ inet_pton(AF_INET, dnat_new_addr,
+ &dnats[num_dnats].new_dst);
+ if(error <= 0) {
+ fprintf(stderr, "dnat effective destination address error\n");
+ exit(1);
+ }
+
+ if(dnat_orig_port[0]) {
+ dnats[num_dnats].orig_port =
+ (short) atoi(dnat_orig_port);
+ } else {
+ dnats[num_dnats].orig_port = 0;
+ }
+
+ if(dnat_new_port[0]) {
+ dnats[num_dnats].new_port =
+ (short) atoi(dnat_new_port);
+ } else {
+ dnats[num_dnats].new_port = 0;
+ }
+
+ PDEBUG("added dnat: orig-dst=%s orig-port=%d new-dst=%s new-port=%d\n", dnat_orig_addr, dnats[num_dnats].orig_port, dnat_new_addr, dnats[num_dnats].new_port);
+ ++num_dnats;
+ } else {
+ fprintf(stderr, "# of dnat exceed %d.\n", MAX_DNAT);
+ }
}
}
}
@@ -350,6 +403,8 @@ int connect(int sock, const struct sockaddr *addr, socklen_t len) {
char str[256];
#endif
struct in_addr *p_addr_in;
+ struct sockaddr_in new_addr;
+ dnat_arg *dnat = NULL;
unsigned short port;
size_t i;
int remote_dns_connect = 0;
@@ -373,6 +428,29 @@ int connect(int sock, const struct sockaddr *addr, socklen_t len) {
// check if connect called from proxydns
remote_dns_connect = (ntohl(p_addr_in->s_addr) >> 24 == remote_dns_subnet);
+ // more specific first
+ for(i = 0; i < num_dnats && !remote_dns_connect && !dnat; i++)
+ if((dnats[i].orig_dst.s_addr == p_addr_in->s_addr))
+ if(dnats[i].orig_port && (dnats[i].orig_port == port))
+ dnat = &dnats[i];
+
+ for(i = 0; i < num_dnats && !remote_dns_connect && !dnat; i++)
+ if(dnats[i].orig_dst.s_addr == p_addr_in->s_addr)
+ if(!dnats[i].orig_port)
+ dnat = &dnats[i];
+
+ if (dnat) {
+ if (dnat->new_port)
+ new_addr.sin_port = htons(dnat->new_port);
+ else
+ new_addr.sin_port = htons(port);
+ new_addr.sin_addr = dnat->new_dst;
+
+ addr = (struct sockaddr *)&new_addr;
+ p_addr_in = &((struct sockaddr_in *) addr)->sin_addr;
+ port = ntohs(((struct sockaddr_in *) addr)->sin_port);
+ }
+
for(i = 0; i < num_localnet_addr && !remote_dns_connect; i++) {
if((localnet_addr[i].in_addr.s_addr & localnet_addr[i].netmask.s_addr)
== (p_addr_in->s_addr & localnet_addr[i].netmask.s_addr)) {
diff --git a/src/proxychains.conf b/src/proxychains.conf
index 14a0e63..07f4a7e 100644
--- a/src/proxychains.conf
+++ b/src/proxychains.conf
@@ -73,6 +73,24 @@ localnet 127.0.0.0/255.0.0.0
## Exclude connections to ANYwhere with port 80
# localnet 0.0.0.0:80/0.0.0.0
+
+### Examples for dnat
+## Trying to proxy connections to destinations which are dnatted,
+## will result in proxying connections to the new given destinations.
+## Whenever I connect to 1.1.1.1 on port 1234 actually connect to 1.1.1.2 on port 443
+# dnat 1.1.1.1:1234 1.1.1.2:443
+
+## Whenever I connect to 1.1.1.1 on port 443 actually connect to 1.1.1.2 on port 443
+## (no need to write :443 again)
+# dnat 1.1.1.2:443 1.1.1.2
+
+## No matter what port I connect to on 1.1.1.1 port actually connect to 1.1.1.2 on port 443
+# dnat 1.1.1.1 1.1.1.2:443
+
+## Always, instead of connecting to 1.1.1.1, connect to 1.1.1.2
+# dnat 1.1.1.1 1.1.1.2
+
+
# ProxyList format
# type host port [user pass]
# (values separated by 'tab' or 'blank')