1
0
mirror of https://github.com/rofl0r/proxychains-ng synced 2026-05-13 17:03:07 +08:00

Compare commits

...

29 Commits

15 changed files with 279 additions and 80 deletions
+8 -9
View File
@@ -18,7 +18,7 @@ OBJS = $(SRCS:.c=.o)
LOBJS = src/nameinfo.o \
src/core.o src/common.o src/libproxychains.o src/shm.o \
src/allocator_thread.o src/ip_type.o src/stringdump.o \
src/hostentdb.o src/hash.o
src/hostentdb.o src/hash.o src/debug.o
CFLAGS += -Wall -O0 -g -std=c99 -D_GNU_SOURCE -pipe
NO_AS_NEEDED = -Wl,--no-as-needed
@@ -33,8 +33,6 @@ LDSO_SUFFIX = so
LD_SET_SONAME = -Wl,-soname=
INSTALL_FLAGS = -D -m
-include config.mak
LDSO_PATHNAME = libproxychains4.$(LDSO_SUFFIX)
SHARED_LIBS = $(LDSO_PATHNAME)
@@ -42,6 +40,7 @@ ALL_LIBS = $(SHARED_LIBS)
PXCHAINS = proxychains4
ALL_TOOLS = $(PXCHAINS)
-include config.mak
CFLAGS+=$(USER_CFLAGS) $(MAC_CFLAGS)
CFLAGS_MAIN=-DLIB_DIR=\"$(libdir)\" -DSYSCONFDIR=\"$(sysconfdir)\" -DDLL_NAME=\"$(LDSO_PATHNAME)\"
@@ -50,13 +49,13 @@ CFLAGS_MAIN=-DLIB_DIR=\"$(libdir)\" -DSYSCONFDIR=\"$(sysconfdir)\" -DDLL_NAME=\"
all: $(ALL_LIBS) $(ALL_TOOLS)
install-config:
install -d $(DESTDIR)/$(sysconfdir)
install $(INSTALL_FLAGS) 644 src/proxychains.conf $(DESTDIR)/$(sysconfdir)/
install -d $(DESTDIR)$(sysconfdir)
install $(INSTALL_FLAGS) 644 src/proxychains.conf $(DESTDIR)$(sysconfdir)/
install:
install -d $(DESTDIR)/$(bindir)/ $(DESTDIR)/$(libdir)/
install $(INSTALL_FLAGS) 755 $(ALL_TOOLS) $(DESTDIR)/$(bindir)/
install $(INSTALL_FLAGS) 644 $(ALL_LIBS) $(DESTDIR)/$(libdir)/
install -d $(DESTDIR)$(bindir)/ $(DESTDIR)$(libdir)/
install $(INSTALL_FLAGS) 755 $(ALL_TOOLS) $(DESTDIR)$(bindir)/
install $(INSTALL_FLAGS) 644 $(ALL_LIBS) $(DESTDIR)$(libdir)/
clean:
rm -f $(ALL_LIBS)
@@ -73,4 +72,4 @@ $(ALL_TOOLS): $(OBJS)
$(CC) src/main.o src/common.o -o $(PXCHAINS)
.PHONY: all clean install
.PHONY: all clean install install-config
+70 -19
View File
@@ -1,27 +1,51 @@
ProxyChains ver 4.3 README
==========================
ProxyChains-NG ver 4.7 README
=============================
ProxyChains is a UNIX program, that hooks network-related libc functions
in dynamically linked programs via a preloaded DLL and redirects the
connections through SOCKS4a/5 or HTTP proxies.
in DYNAMICALLY LINKED programs via a preloaded DLL (dlsym(), LD_PRELOAD)
and redirects the connections through SOCKS4a/5 or HTTP proxies.
It supports TCP only (no UDP/ICMP etc).
The way it works is basically a HACK; so it is possible that it doesn't
work with your program, especially when it's a script, or starts
numerous processes like background daemons or uses dlopen() to load
"modules" (bug in glibc dynlinker).
It should work with simple compiled (C/C++) dynamically linked programs
though.
If your program doesn't work with proxychains, consider using an
iptables based solution instead; this is much more robust.
Supported Platforms: Linux, BSD, Mac.
*********** ATTENTION ***********
this program works only on dynamically linked programs.
also both proxychains and the program to call must use
the same dynamic linker (i.e. same libc).
why ? because in order to hook to libc functions like
connect(), dynamic loader facilities are used, namely
dl_sym() and LD_PRELOAD.
this program can be used to circumvent censorship.
doing so can be VERY DANGEROUS in certain countries.
*********************************
ALWAYS MAKE SURE THAT PROXYCHAINS WORKS AS EXPECTED
BEFORE USING IT FOR ANYTHING SERIOUS.
this involves both the program and the proxy that you're going to
use.
for example, you can connect to some "what is my ip" service
like ifconfig.me to make sure that it's not using your real ip.
ONLY USE PROXYCHAINS IF YOU KNOW WHAT YOU'RE DOING.
THE AUTHORS AND MAINTAINERS OF PROXYCHAINS DO NOT TAKE ANY
RESPONSIBILITY FOR ANY ABUSE OR MISUSE OF THIS SOFTWARE AND
THE RESULTING CONSEQUENCES.
*** Installation ***
# needs a working C compiler, preferably gcc
./configure
./configure --prefix=/usr --sysconfdir=/etc
make
[optional] sudo make install
[optional] sudo make install-config (installs proxychains.conf)
if you dont install, you can use proxychains from the build directory
like this: ./proxychains4 -f src/proxychains.conf telnet google.com 80
@@ -29,6 +53,25 @@ ProxyChains ver 4.3 README
Changelog:
----------
Version 4.7:
- new round_robin chaintype by crazz.
- fix bug with lazy allocation when GCC constructor was not used.
- new configure flag --fat-binary to create a "fat" binary/library on OS X
- return EBADF rather than EINTR in close hook.
it's legal for a program to retry close() calls when they receive
EINTR, which could cause an infinite loop, as seen in chromium.
Version 4.6:
- some cosmetic fixes to Makefile, fix a bug when non-numeric ip was
user as proxy server address.
Version 4.5:
- hook close() to prevent OpenSSH from messing with internal infrastructure.
this caused ssh client to segfault when proxified.
Version 4.4:
- FreeBSD port
- fixes some installation issues on Debian and Mac.
Version 4.3:
- fixes programs that do dns-lookups in child processes (fork()ed),
like irssi. to achieve this, support for compilation without pthreads
@@ -78,10 +121,9 @@ Some cool features:
random order from the list ( user defined length of chain ).
exact order (as they appear in the list )
dynamic order (smart exclude dead proxies from chain)
* You can use it with any TCP client application, even network scanners
yes, yes - you can make portscan via proxy (or chained proxies)
for example with Nmap scanner by fyodor (www.insecire.org/nmap).
proxychains nmap -sT -PO -p 80 -iR (find some webservers through proxy)
* You can use it with most TCP client applications, possibly even network
scanners, as long as they use standard libc functionality.
pcap based scanning does not work.
* You can use it with servers, like squid, sendmail, or whatever.
* DNS resolving through proxy.
@@ -90,13 +132,13 @@ Configuration:
--------------
proxychains looks for config file in following order:
1) file listed in environment variable ${PROXYCHAINS_CONF_FILE} or
1) file listed in environment variable PROXYCHAINS_CONF_FILE or
provided as a -f argument to proxychains script or binary.
2) ./proxychains.conf
3) $(HOME)/.proxychains/proxychains.conf
4) /etc/proxychains.conf **
4) $(sysconfdir)/proxychains.conf **
**see more in /etc/proxychains.conf
** usually /etc/proxychains.conf
Usage Example:
@@ -119,3 +161,12 @@ Usage Example:
in this example it will resolve targethost.com through proxy(or chained proxies)
specified by proxychains.conf
Community:
----------
#proxychains on irc.freenode.net
Donations:
----------
bitcoins donations are welcome - please send to this address:
1C9LBpuy56veBqw5N33sZMoZW8mwCw3tPh
Vendored
+23 -10
View File
@@ -2,6 +2,18 @@
prefix=/usr/local
ismac() {
uname -s | grep Darwin >/dev/null
}
isx86_64() {
uname -m | grep -i X86_64 >/dev/null
}
isbsd() {
uname -s | grep BSD >/dev/null
}
usage() {
echo "supported arguments"
echo "--prefix=/path default: $prefix"
@@ -10,6 +22,7 @@ usage() {
echo "--libdir=/path default: $prefix/lib"
echo "--includedir=/path default: $prefix/include"
echo "--sysconfdir=/path default: $prefix/etc"
ismac && isx86_64 && echo "--fat-binary : build for both i386 and x86_64 architectures on 64-bit Macs"
echo "--help : show this text"
exit 1
}
@@ -21,6 +34,8 @@ spliteq() {
# or echo "$arg" | sed 's/[^=]*=//'
}
fat_binary=
parsearg() {
case "$1" in
--prefix=*) prefix=`spliteq $1`;;
@@ -29,18 +44,11 @@ parsearg() {
--libdir=*) libdir=`spliteq $1`;;
--includedir=*) includedir=`spliteq $1`;;
--sysconfdir=*) sysconfdir=`spliteq $1`;;
--fat-binary) fat_binary=1;;
--help) usage;;
esac
}
ismac() {
uname -s | grep Darwin >/dev/null
}
isbsd() {
uname -s | grep BSD >/dev/null
}
while true ; do
case $1 in
-*) parsearg "$1"; shift;;
@@ -85,12 +93,17 @@ if ismac ; then
echo NO_AS_NEEDED=>>config.mak
echo LDSO_SUFFIX=dylib>>config.mak
echo MAC_CFLAGS+=-DIS_MAC=1>>config.mak
if isx86_64 && [ "$fat_binary" = 1 ] ; then
echo "Configuring a fat binary for i386 and x86_64"
echo MAC_CFLAGS+=-arch i386 -arch x86_64>>config.mak
echo LDFLAGS+=-arch i386 -arch x86_64>>config.mak
fi
echo LD_SET_SONAME=-Wl,-install_name,>>config.mak
echo INSTALL_FLAGS=-m>>config.mak
elif isbsd ; then
echo LIBDL=>>config.mak
echo "CFLAGS+=-DIS_BSD">>config.mak
echo INSTALL_FLAGS=-m>>config.mak
fi
echo done, now run make \&\& make install
echo "Done, now run make && make install"
+10 -3
View File
@@ -8,6 +8,7 @@
#include <string.h>
#include <stdint.h>
#include <stddef.h>
#include <errno.h>
#include "allocator_thread.h"
#include "shm.h"
#include "debug.h"
@@ -147,8 +148,8 @@ struct at_msghdr {
static pthread_t allocator_thread;
static pthread_attr_t allocator_thread_attr;
static int req_pipefd[2];
static int resp_pipefd[2];
int req_pipefd[2];
int resp_pipefd[2];
static int wait_data(int readfd) {
PFUNC();
@@ -158,7 +159,13 @@ static int wait_data(int readfd) {
int ret;
while((ret = select(readfd+1, &fds, NULL, NULL, NULL)) <= 0) {
if(ret < 0) {
perror("select2");
int e = errno;
if(e == EINTR) continue;
#ifdef __GLIBC__
char emsg[1024];
char* x = strerror_r(errno, emsg, sizeof emsg);
dprintf(2, "select2: %s\n", x);
#endif
return 0;
}
}
+3
View File
@@ -6,6 +6,9 @@
#define MSG_LEN_MAX 256
extern int req_pipefd[2];
extern int resp_pipefd[2];
void at_init(void);
void at_close(void);
size_t at_get_host_for_ip(ip_type ip, char* readbuf);
+20
View File
@@ -3,6 +3,26 @@
#include <unistd.h>
#include <stdio.h>
const char *proxy_type_strmap[] = {
"http",
"socks4",
"socks5",
};
const char *chain_type_strmap[] = {
"dynamic_chain",
"strict_chain",
"random_chain",
"round_robin_chain",
};
const char *proxy_state_strmap[] = {
"play",
"down",
"blocked",
"busy",
};
// stolen from libulz (C) rofl0r
void pc_stringfromipv4(unsigned char *ip_buf_4_bytes, char *outbuf_16_bytes) {
unsigned char *p;
+4
View File
@@ -11,6 +11,10 @@
#include <stddef.h>
extern const char *proxy_type_strmap[];
extern const char *chain_type_strmap[];
extern const char *proxy_state_strmap[];
char *get_config_path(char* default_path, char* pbuf, size_t bufsize);
void pc_stringfromipv4(unsigned char *ip_buf_4_bytes, char *outbuf_16_bytes);
+57 -2
View File
@@ -27,7 +27,7 @@
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/poll.h>
#include <poll.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <time.h>
@@ -43,6 +43,7 @@
extern int tcp_read_time_out;
extern int tcp_connect_time_out;
extern int proxychains_quiet_mode;
extern unsigned int proxychains_proxy_offset;
extern unsigned int remote_dns_subnet;
static int poll_retry(struct pollfd *fds, nfds_t nfsd, int timeout) {
@@ -267,8 +268,10 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, c
}
// if not ok (200) or response greather than BUFF_SIZE return BLOCKED;
if(len == BUFF_SIZE || !(buff[9] == '2' && buff[10] == '0' && buff[11] == '0'))
if(len == BUFF_SIZE || !(buff[9] == '2' && buff[10] == '0' && buff[11] == '0')) {
PDEBUG("HTTP proxy blocked: buff=\"%s\"\n", buff);
return BLOCKED;
}
return SUCCESS;
}
@@ -427,6 +430,7 @@ static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, c
#define DT "Dynamic chain"
#define ST "Strict chain"
#define RT "Random chain"
#define RRT "Round Robin chain"
static int start_chain(int *fd, proxy_data * pd, char *begin_mark) {
struct sockaddr_in addr;
@@ -554,15 +558,20 @@ int connect_proxy_chain(int sock, ip_type target_ip,
proxy_data p4;
proxy_data *p1, *p2, *p3;
int ns = -1;
int rc = -1;
unsigned int offset = 0;
unsigned int alive_count = 0;
unsigned int curr_len = 0;
unsigned int curr_pos = 0;
unsigned int looped = 0; // went back to start of list in RR mode
p3 = &p4;
PFUNC();
again:
rc = -1;
DUMP_PROXY_CHAIN(pd, proxy_count);
switch (ct) {
case DYNAMIC_TYPE:
@@ -589,6 +598,52 @@ int connect_proxy_chain(int sock, ip_type target_ip,
goto error;
break;
case ROUND_ROBIN_TYPE:
alive_count = calc_alive(pd, proxy_count);
curr_pos = offset = proxychains_proxy_offset;
if(alive_count < max_chain)
goto error_more;
PDEBUG("1:rr_offset = %d, curr_pos = %d\n", offset, curr_pos);
/* Check from current RR offset til end */
for (;rc != SUCCESS;) {
if (!(p1 = select_proxy(FIFOLY, pd, proxy_count, &offset))) {
/* We've reached the end of the list, go to the start */
offset = 0;
looped++;
continue;
} else if (looped && rc > 0 && offset >= curr_pos) {
PDEBUG("GOTO MORE PROXIES 0\n");
/* We've gone back to the start and now past our starting position */
proxychains_proxy_offset = 0;
goto error_more;
}
PDEBUG("2:rr_offset = %d\n", offset);
rc=start_chain(&ns, p1, RRT);
}
/* Create rest of chain using RR */
for(curr_len = 1; curr_len < max_chain;) {
PDEBUG("3:rr_offset = %d, curr_len = %d, max_chain = %d\n", offset, curr_len, max_chain);
p2 = select_proxy(FIFOLY, pd, proxy_count, &offset);
if(!p2) {
/* Try from the beginning to where we started */
offset = 0;
continue;
} else if(SUCCESS != chain_step(ns, p1, p2)) {
PDEBUG("GOTO AGAIN 1\n");
goto again;
} else
p1 = p2;
curr_len++;
}
//proxychains_write_log(TP);
p3->ip = target_ip;
p3->port = target_port;
proxychains_proxy_offset = offset+1;
PDEBUG("pd_offset = %d, curr_len = %d\n", proxychains_proxy_offset, curr_len);
if(SUCCESS != chain_step(ns, p1, p3))
goto error;
break;
case STRICT_TYPE:
alive_count = calc_alive(pd, proxy_count);
offset = 0;
+4 -2
View File
@@ -47,8 +47,9 @@ typedef enum {
typedef enum {
DYNAMIC_TYPE,
STRICT_TYPE,
RANDOM_TYPE}
chain_type;
RANDOM_TYPE,
ROUND_ROBIN_TYPE
} chain_type;
typedef enum {
PLAY_STATE,
@@ -82,6 +83,7 @@ int connect_proxy_chain (int sock, ip_type target_ip, unsigned short target_port
void proxychains_write_log(char *str, ...);
typedef int (*close_t)(int);
typedef int (*connect_t)(int, const struct sockaddr *, socklen_t);
typedef struct hostent* (*gethostbyname_t)(const char *);
typedef int (*freeaddrinfo_t)(struct addrinfo *);
+21
View File
@@ -0,0 +1,21 @@
#ifdef DEBUG
# include "core.h"
# include "common.h"
# include "debug.h"
void DUMP_PROXY_CHAIN(proxy_data *pchain, unsigned int count) {
char ip_buf[16];
for (; count; pchain++, count--) {
pc_stringfromipv4(&pchain->ip.octet[0], ip_buf);
PDEBUG("[%s] %s %s:%d", proxy_state_strmap[pchain->ps],
proxy_type_strmap[pchain->pt],
ip_buf, htons(pchain->port));
if (*pchain->user || *pchain->pass) {
PSTDERR(" [u=%s,p=%s]", pchain->user, pchain->pass);
}
PSTDERR("\n");
}
}
#endif
+7 -1
View File
@@ -3,9 +3,15 @@
#ifdef DEBUG
# include <stdio.h>
# define PDEBUG(fmt, args...) do { dprintf(2,"DEBUG:"fmt, ## args); } while(0)
# define PSTDERR(fmt, args...) do { dprintf(2,fmt, ## args); } while(0)
# define PDEBUG(fmt, args...) PSTDERR("DEBUG:"fmt, ## args)
# include "core.h"
void DUMP_PROXY_CHAIN(proxy_data *pchain, unsigned int count);
#else
# define PDEBUG(fmt, args...) do {} while (0)
# define DUMP_PROXY_CHAIN(args...) do {} while (0)
#endif
# define PFUNC() do { PDEBUG("pid[%d]:%s\n", getpid(), __FUNCTION__); } while(0)
+28 -2
View File
@@ -45,6 +45,7 @@
#define SOCKFAMILY(x) (satosin(x)->sin_family)
#define MAX_CHAIN 512
close_t true_close;
connect_t true_connect;
gethostbyname_t true_gethostbyname;
getaddrinfo_t true_getaddrinfo;
@@ -57,6 +58,7 @@ int tcp_connect_time_out;
chain_type proxychains_ct;
proxy_data proxychains_pd[MAX_CHAIN];
unsigned int proxychains_proxy_count = 0;
unsigned int proxychains_proxy_offset = 0;
int proxychains_got_chain_data = 0;
unsigned int proxychains_max_chain = 1;
int proxychains_quiet_mode = 0;
@@ -104,6 +106,7 @@ static void do_init(void) {
/* read the config file */
get_chain_data(proxychains_pd, &proxychains_proxy_count, &proxychains_ct);
DUMP_PROXY_CHAIN(proxychains_pd, proxychains_proxy_count);
proxychains_write_log(LOG_PREFIX "DLL init\n");
@@ -113,6 +116,7 @@ static void do_init(void) {
SETUP_SYM(freeaddrinfo);
SETUP_SYM(gethostbyaddr);
SETUP_SYM(getnameinfo);
SETUP_SYM(close);
init_l = 1;
}
@@ -166,7 +170,11 @@ static void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_typ
*ct = DYNAMIC_TYPE;
env = get_config_path(getenv(PROXYCHAINS_CONF_FILE_ENV_VAR), buff, sizeof(buff));
file = fopen(env, "r");
if( ( file = fopen(env, "r") ) == NULL )
{
perror("couldnt read configuration file");
exit(1);
}
env = getenv(PROXYCHAINS_QUIET_MODE_ENV_VAR);
if(env && *env == '1')
@@ -186,7 +194,12 @@ static void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_typ
sscanf(buff, "%s %s %d %s %s", type, host, &port_n, pd[count].user, pd[count].pass);
pd[count].ip.as_int = (uint32_t) inet_addr(host);
in_addr_t host_ip = inet_addr(host);
if(host_ip == INADDR_NONE) {
fprintf(stderr, "proxy %s has invalid value or is not numeric\n", host);
exit(1);
}
pd[count].ip.as_int = (uint32_t) host_ip;
pd[count].port = htons((unsigned short) port_n);
if(!strcmp(type, "http")) {
@@ -209,6 +222,8 @@ static void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_typ
*ct = STRICT_TYPE;
} else if(strstr(buff, "dynamic_chain")) {
*ct = DYNAMIC_TYPE;
} else if(strstr(buff, "round_robin_chain")) {
*ct = ROUND_ROBIN_TYPE;
} else if(strstr(buff, "tcp_read_time_out")) {
sscanf(buff, "%s %d", user, &tcp_read_time_out);
} else if(strstr(buff, "tcp_connect_time_out")) {
@@ -282,6 +297,17 @@ static void get_chain_data(proxy_data * pd, unsigned int *proxy_count, chain_typ
/******* HOOK FUNCTIONS *******/
int close(int fd) {
INIT();
/* prevent rude programs (like ssh) from closing our pipes */
if(fd != req_pipefd[0] && fd != req_pipefd[1] &&
fd != resp_pipefd[0] && fd != resp_pipefd[1]) {
return true_close(fd);
}
errno = EBADF;
return -1;
}
int connect(int sock, const struct sockaddr *addr, unsigned int len) {
PFUNC();
int socktype = 0, flags = 0, ret = 0;
-26
View File
@@ -1,26 +0,0 @@
#!/bin/sh
echo "ProxyChains-3.1 (http://proxychains.sf.net)"
usage() {
echo " usage:"
echo " $0 [h] [f config-file] <prog> [args]"
exit
}
if [ $# = 0 ] ; then
usage
fi
if [ $1 = "-h" ]; then
usage
fi
if [ "$1" = "-f" ]; then
export PROXYCHAINS_CONF_FILE=$2;
shift;
shift;
fi
export LD_PRELOAD=libproxychains.so.3
exec "$@"
+18 -2
View File
@@ -22,13 +22,27 @@ strict_chain
# all proxies must be online to play in chain
# otherwise EINTR is returned to the app
#
#round_robin_chain
#
# Round Robin - Each connection will be done via chained proxies
# of chain_len length
# all proxies chained in the order as they appear in the list
# at least one proxy must be online to play in chain
# (dead proxies are skipped).
# the start of the current proxy chain is the proxy after the last
# proxy in the previously invoked proxy chain.
# if the end of the proxy chain is reached while looking for proxies
# start at the beginning again.
# otherwise EINTR is returned to the app
# These semantics are not guaranteed in a multithreaded environment.
#
#random_chain
#
# Random - Each connection will be done via random proxy
# (or proxy chain, see chain_len) from the list.
# this option is good to test your IDS :)
# Make sense only if random_chain
# Make sense only if random_chain or round_robin_chain
#chain_len = 2
# Quiet mode (no output from library)
@@ -77,9 +91,11 @@ tcp_connect_time_out 8000
# localnet 192.168.0.0/255.255.0.0
# ProxyList format
# type host port [user pass]
# type ip port [user pass]
# (values separated by 'tab' or 'blank')
#
# only numeric ipv4 addresses are valid
#
#
# Examples:
#
+6 -4
View File
@@ -1,8 +1,10 @@
#!/bin/sh
# This script is called by proxychains to resolve DNS names
# 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.
# DNS server used to resolve names
DNS_SERVER=4.2.2.2
DNS_SERVER=8.8.8.8
if [ $# = 0 ] ; then
@@ -12,5 +14,5 @@ if [ $# = 0 ] ; then
fi
export LD_PRELOAD=libproxychains.so
dig $1 @$DNS_SERVER +tcp | awk '/A.+[0-9]+\.[0-9]+\.[0-9]/{print $5;}'
export LD_PRELOAD=libproxychains4.so
dig $1 @$DNS_SERVER +tcp | awk '/A.?[0-9]+\.[0-9]+\.[0-9]/{print $5;}'