From 2ab631918d8c75c6382a2dcf3a321fb956801f8a Mon Sep 17 00:00:00 2001 From: rofl0r Date: Sun, 20 Sep 2020 22:11:17 +0100 Subject: [PATCH] add support for "proxy_dns_old" to use old 3.1 DNS lookup method some lamer on IRC by the name of annoner/R3M0RS3/penis was complaining that 3.1 is a lot better than proxychains-ng, because it happens to work with the browser he's interested in. since this wasn't the first time this is requested, let's give this those lamers what they want: lame code! --- src/core.c | 86 +++++++++++++++++++++++++++++++++++++++++++- src/core.h | 1 + src/libproxychains.c | 14 +++++--- src/proxychains.conf | 10 +++++- src/proxyresolv | 17 +++++---- 5 files changed, 115 insertions(+), 13 deletions(-) diff --git a/src/core.c b/src/core.c index 9e5f93c..42bd3e9 100644 --- a/src/core.c +++ b/src/core.c @@ -745,6 +745,86 @@ static void gethostbyname_data_setstring(struct gethostbyname_data* data, char* } extern ip_type4 hostsreader_get_numeric_ip_for_name(const char* name); +struct hostent* proxy_gethostbyname_old(const char *name) +{ + static struct hostent hostent_space; + static in_addr_t resolved_addr; + static char* resolved_addr_p; + static char addr_name[1024*8]; + + int pipe_fd[2]; + char buff[256]; + in_addr_t addr; + pid_t pid; + int status; + size_t l; + struct hostent* hp; + + hostent_space.h_addr_list = &resolved_addr_p; + *hostent_space.h_addr_list = (char*)&resolved_addr; + resolved_addr = 0; + + gethostname(buff,sizeof(buff)); + if(!strcmp(buff,name)) + goto got_buff; + + memset(buff, 0, sizeof(buff)); + + // TODO: this works only once, so cache it ... + // later + while ((hp=gethostent())) + if (!strcmp(hp->h_name,name)) + return hp; + + if(pipe(pipe_fd)) + goto err; + pid = fork(); + switch(pid) { + + case 0: // child + proxychains_write_log("|DNS-request| %s \n", name); + close(pipe_fd[0]); + dup2(pipe_fd[1],1); + close(pipe_fd[1]); + + // putenv("LD_PRELOAD="); + execlp("proxyresolv","proxyresolv",name,NULL); + perror("can't exec proxyresolv"); + exit(2); + + case -1: //error + close(pipe_fd[0]); + close(pipe_fd[1]); + perror("can't fork"); + goto err; + + default: + close(pipe_fd[1]); + waitpid(pid, &status, 0); + buff[0] = 0; + read(pipe_fd[0],&buff,sizeof(buff)); + close(pipe_fd[0]); +got_buff: + l = strlen(buff); + if(l && buff[l-1] == '\n') buff[l-1] = 0; + addr = inet_addr(buff); + if (addr == (in_addr_t) (-1)) + goto err_dns; + memcpy(*(hostent_space.h_addr_list), + &addr ,sizeof(struct in_addr)); + hostent_space.h_name = addr_name; + hostent_space.h_length = sizeof (in_addr_t); + } + proxychains_write_log("|DNS-response| %s is %s\n", + name, inet_ntoa(*(struct in_addr*)&addr)); + return &hostent_space; +err_dns: + proxychains_write_log("|DNS-response|: %s does not exist\n", name); + perror("err_dns"); +err: + return NULL; +} + struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data* data) { PFUNC(); char buff[256]; @@ -872,7 +952,11 @@ int proxy_getaddrinfo(const char *node, const char *service, const struct addrin free(space); return EAI_NONAME; } - hp = proxy_gethostbyname(node, &ghdata); + if(proxychains_resolver == 2) + hp = proxy_gethostbyname_old(node); + else + hp = proxy_gethostbyname(node, &ghdata); + if(hp) memcpy(&((struct sockaddr_in *) &space->sockaddr_space)->sin_addr, *(hp->h_addr_list), sizeof(in_addr_t)); diff --git a/src/core.h b/src/core.h index a9ad88b..d54806d 100644 --- a/src/core.h +++ b/src/core.h @@ -121,6 +121,7 @@ struct gethostbyname_data { }; struct hostent* proxy_gethostbyname(const char *name, struct gethostbyname_data *data); +struct hostent* proxy_gethostbyname_old(const char *name); int proxy_getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res); diff --git a/src/libproxychains.c b/src/libproxychains.c index 513351e..ad75636 100644 --- a/src/libproxychains.c +++ b/src/libproxychains.c @@ -146,7 +146,7 @@ static void do_init(void) { while(close_fds_cnt) true_close(close_fds[--close_fds_cnt]); init_l = 1; - if(proxychains_resolver) rdns_init(); + if(proxychains_resolver == 1) rdns_init(); } static void init_lib_wrapper(const char* caller) { @@ -328,7 +328,7 @@ static void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_typ pd[count].port = htons((unsigned short) port_n); ip_type* host_ip = &pd[count].ip; if(1 != inet_pton(host_ip->is_v6 ? AF_INET6 : AF_INET, host, host_ip->addr.v6)) { - if(*ct == STRICT_TYPE && proxychains_resolver && count > 0) { + if(*ct == STRICT_TYPE && proxychains_resolver == 1 && count > 0) { /* we can allow dns hostnames for all but the first proxy in the list if chaintype is strict, as remote lookup can be done */ rdns_init(); ip_type4 internal_ip = at_get_ip_for_host(host, strlen(host)); @@ -431,6 +431,8 @@ inv_host: proxychains_max_chain = (len ? len : 1); } else if(strstr(buff, "quiet_mode")) { proxychains_quiet_mode = 1; + } else if(strstr(buff, "proxy_dns_old")) { + proxychains_resolver = 2; } else if(strstr(buff, "proxy_dns")) { proxychains_resolver = 1; } else if(strstr(buff, "dnat")) { @@ -495,7 +497,7 @@ inv_host: } *proxy_count = count; proxychains_got_chain_data = 1; - PDEBUG("proxy_dns: %s\n", proxychains_resolver ? "ON" : "OFF"); + PDEBUG("proxy_dns: %s\n", proxychains_resolver ? (proxychains_resolver == 2 ? "OLD" : "ON") : "OFF"); } /******* HOOK FUNCTIONS *******/ @@ -507,7 +509,7 @@ int close(int fd) { errno = 0; return 0; } - if(!proxychains_resolver) return true_close(fd); + if(proxychains_resolver != 1) return true_close(fd); /* prevent rude programs (like ssh) from closing our pipes */ if(fd != req_pipefd[0] && fd != req_pipefd[1] && @@ -622,8 +624,10 @@ struct hostent *gethostbyname(const char *name) { INIT(); PDEBUG("gethostbyname: %s\n", name); - if(proxychains_resolver) + if(proxychains_resolver == 1) return proxy_gethostbyname(name, &ghbndata); + else if(proxychains_resolver == 2) + return proxy_gethostbyname_old(name); else return true_gethostbyname(name); diff --git a/src/proxychains.conf b/src/proxychains.conf index 65c04ad..fb08ae1 100644 --- a/src/proxychains.conf +++ b/src/proxychains.conf @@ -49,7 +49,15 @@ strict_chain #quiet_mode # Proxy DNS requests - no leak for DNS data -proxy_dns +# this uses the proxychains4 style method to do remote dns +proxy_dns + +# use the old proxyresolv script to proxy DNS requests +# in proxychains 3.1 style. requires proxyresolv in $PATH +# plus a dynamically linked `dig` binary. +# this is a lot slower than `proxy_dns`, doesn't support .onion URLs, +# but might be more compatible with complex software like webbrowsers. +#proxy_dns_old # set the class A subnet number to use for the internal remote DNS mapping # we use the reserved 224.x.x.x range by default, diff --git a/src/proxyresolv b/src/proxyresolv index ae932c2..f10a412 100755 --- a/src/proxyresolv +++ b/src/proxyresolv @@ -1,10 +1,8 @@ #!/bin/sh -# This is a legacy script that uses "dig" to do DNS lookups via TCP. -# it is not actively maintained since proxychains no longer depends -# on it. i leave it here as a bonus. +# This is a legacy script that uses "dig" or "drill" to do DNS lookups via TCP. # DNS server used to resolve names -DNS_SERVER=8.8.8.8 +test -z "$DNS_SERVER" && DNS_SERVER=8.8.8.8 if [ $# = 0 ] ; then @@ -14,5 +12,12 @@ if [ $# = 0 ] ; then fi -export LD_PRELOAD=libproxychains4.so -dig $1 @$DNS_SERVER +tcp | awk '/A.?[0-9]+\.[0-9]+\.[0-9]/{print $5;}' +test -z $LD_PRELOAD && export LD_PRELOAD=libproxychains4.so + +if type dig 1>/dev/null 2>&1 ; then +dig $1 @$DNS_SERVER +tcp | awk '/A.?[0-9]+\.[0-9]+\.[0-9]/{print $5;}' +elif type drill 1>/dev/null 2>&1 ; then +drill -t4 $1 @$DNS_SERVER | awk '/A.+[0-9]+\.[0-9]+\.[0-9]/{print $5;}' +else +echo "error: neither dig nor drill found" >&2 +fi