mirror of
https://github.com/rofl0r/proxychains-ng
synced 2026-05-14 17:42:36 +08:00
Compare commits
10 Commits
@@ -19,7 +19,7 @@ DOBJS = src/daemon/hsearch.o \
|
|||||||
src/daemon/sblist.o src/daemon/sblist_delete.o \
|
src/daemon/sblist.o src/daemon/sblist_delete.o \
|
||||||
src/daemon/daemon.o src/daemon/udpserver.o
|
src/daemon/daemon.o src/daemon/udpserver.o
|
||||||
|
|
||||||
LOBJS = src/nameinfo.o src/version.o \
|
LOBJS = src/version.o \
|
||||||
src/core.o src/common.o src/libproxychains.o \
|
src/core.o src/common.o src/libproxychains.o \
|
||||||
src/allocator_thread.o src/rdns.o \
|
src/allocator_thread.o src/rdns.o \
|
||||||
src/hostsreader.o src/hash.o src/debug.o
|
src/hostsreader.o src/hash.o src/debug.o
|
||||||
@@ -30,7 +30,7 @@ GENH = src/version.h
|
|||||||
CFLAGS += -Wall -O0 -g -std=c99 -D_GNU_SOURCE -pipe
|
CFLAGS += -Wall -O0 -g -std=c99 -D_GNU_SOURCE -pipe
|
||||||
NO_AS_NEEDED = -Wl,--no-as-needed
|
NO_AS_NEEDED = -Wl,--no-as-needed
|
||||||
LIBDL = -ldl
|
LIBDL = -ldl
|
||||||
LDFLAGS = -fPIC $(NO_AS_NEEDED) $(LIBDL) -lpthread
|
LDFLAGS = -fPIC $(NO_AS_NEEDED) $(LIBDL) $(PTHREAD)
|
||||||
INC =
|
INC =
|
||||||
PIC = -fPIC
|
PIC = -fPIC
|
||||||
AR = $(CROSS_COMPILE)ar
|
AR = $(CROSS_COMPILE)ar
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
ProxyChains-NG ver 4.14 README
|
ProxyChains-NG ver 4.15 README
|
||||||
=============================
|
=============================
|
||||||
|
|
||||||
ProxyChains is a UNIX program, that hooks network-related libc functions
|
ProxyChains is a UNIX program, that hooks network-related libc functions
|
||||||
@@ -52,6 +52,18 @@ ProxyChains-NG ver 4.14 README
|
|||||||
|
|
||||||
Changelog:
|
Changelog:
|
||||||
----------
|
----------
|
||||||
|
Version 4.15
|
||||||
|
- fix configure script for buggy binutils version
|
||||||
|
- initialize rand_seed with nano-second granularity
|
||||||
|
- add support for numeric ipv6 in getaddrinfo
|
||||||
|
- fix bug in getaddrinfo when node is null and !passive
|
||||||
|
- add dnat feature
|
||||||
|
- add raw proxy type
|
||||||
|
- add haiku support
|
||||||
|
- add proxy_dns_old to emulate proxychains 3.1 behaviour
|
||||||
|
- add new proxy_dns_daemon feature (experimental)
|
||||||
|
- various other fixes
|
||||||
|
|
||||||
Version 4.14
|
Version 4.14
|
||||||
- allow alternative proto://user:pass@ip:port syntax for proxylist
|
- allow alternative proto://user:pass@ip:port syntax for proxylist
|
||||||
- fix endless loop in round robin mode when all proxies are down (#147)
|
- fix endless loop in round robin mode when all proxies are down (#147)
|
||||||
@@ -236,7 +248,7 @@ Known Problems:
|
|||||||
|
|
||||||
Community:
|
Community:
|
||||||
----------
|
----------
|
||||||
#proxychains on irc.freenode.net
|
#proxychains on irc.libera.chat
|
||||||
|
|
||||||
Donations:
|
Donations:
|
||||||
----------
|
----------
|
||||||
|
|||||||
@@ -19,11 +19,12 @@ check_compile() {
|
|||||||
printf "checking %s ... " "$1"
|
printf "checking %s ... " "$1"
|
||||||
printf "$3" > "$tmpc"
|
printf "$3" > "$tmpc"
|
||||||
local res=0
|
local res=0
|
||||||
$CC $OUR_CPPFLAGS $CPPFLAGS $2 $CFLAGS "$tmpc" -o /dev/null >/dev/null 2>&1 \
|
$CC $OUR_CPPFLAGS $CPPFLAGS $2 $CFLAGS "$tmpc" -o "$tmpc".out >/dev/null 2>&1 \
|
||||||
|| res=1
|
|| res=1
|
||||||
test x$res = x0 && \
|
test x$res = x0 && \
|
||||||
{ printf "yes\n" ; test x"$2" = x || OUR_CPPFLAGS="$OUR_CPPFLAGS $2" ; } \
|
{ printf "yes\n" ; test x"$2" = x || OUR_CPPFLAGS="$OUR_CPPFLAGS $2" ; } \
|
||||||
|| printf "no\n"
|
|| printf "no\n"
|
||||||
|
rm -f "$tmpc".out
|
||||||
return $res
|
return $res
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,7 +50,10 @@ check_compile_run() {
|
|||||||
|
|
||||||
check_link_silent() {
|
check_link_silent() {
|
||||||
printf "$2" > "$tmpc"
|
printf "$2" > "$tmpc"
|
||||||
$CC $OUR_CPPFLAGS $CPPFLAGS $1 $CFLAGS "$tmpc" -o /dev/null >/dev/null 2>&1
|
local res=0
|
||||||
|
$CC $OUR_CPPFLAGS $CPPFLAGS $1 $CFLAGS "$tmpc" -o "$tmpc".out >/dev/null 2>&1 || res=1
|
||||||
|
rm -f "$tmpc".out
|
||||||
|
return $res
|
||||||
}
|
}
|
||||||
|
|
||||||
check_link() {
|
check_link() {
|
||||||
@@ -165,6 +169,9 @@ check_compile 'whether we have pipe2() and O_CLOEXEC' "-DHAVE_PIPE2" \
|
|||||||
check_compile 'whether we have SOCK_CLOEXEC' "-DHAVE_SOCK_CLOEXEC" \
|
check_compile 'whether we have SOCK_CLOEXEC' "-DHAVE_SOCK_CLOEXEC" \
|
||||||
'#define _GNU_SOURCE\n#include <sys/socket.h>\nint main() {\nreturn socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, 0);}'
|
'#define _GNU_SOURCE\n#include <sys/socket.h>\nint main() {\nreturn socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, 0);}'
|
||||||
|
|
||||||
|
check_compile 'whether we have clock_gettime' "-DHAVE_CLOCK_GETTIME" \
|
||||||
|
'#define _GNU_SOURCE\n#include <time.h>\nint main() {\nstruct timespec now;clock_gettime(CLOCK_REALTIME, &now);\nreturn now.tv_sec ^ now.tv_nsec;}'
|
||||||
|
|
||||||
check_define __APPLE__ && {
|
check_define __APPLE__ && {
|
||||||
mac_detected=true
|
mac_detected=true
|
||||||
check_define __x86_64__ && mac_64=true
|
check_define __x86_64__ && mac_64=true
|
||||||
@@ -208,6 +215,15 @@ fi
|
|||||||
echo "$LD_SONAME_FLAG"
|
echo "$LD_SONAME_FLAG"
|
||||||
echo "LD_SET_SONAME = -Wl,$LD_SONAME_FLAG," >> config.mak
|
echo "LD_SET_SONAME = -Wl,$LD_SONAME_FLAG," >> config.mak
|
||||||
|
|
||||||
|
if check_link "checking whether we can use -lpthread" "-lpthread" \
|
||||||
|
"int main(){return 0;}" ; then
|
||||||
|
echo "PTHREAD = -lpthread" >> config.mak
|
||||||
|
else
|
||||||
|
check_link "checking whether we can use -pthread" "-pthread" \
|
||||||
|
"int main(){return 0;}" || fail "no pthread support detected"
|
||||||
|
echo "PTHREAD = -pthread" >> config.mak
|
||||||
|
fi
|
||||||
|
|
||||||
make_cmd=make
|
make_cmd=make
|
||||||
if ismac ; then
|
if ismac ; then
|
||||||
echo LDSO_SUFFIX=dylib>>config.mak
|
echo LDSO_SUFFIX=dylib>>config.mak
|
||||||
|
|||||||
+20
-50
@@ -475,8 +475,7 @@ static proxy_data *select_proxy(select_type how, proxy_data * pd, unsigned int p
|
|||||||
case RANDOMLY:
|
case RANDOMLY:
|
||||||
do {
|
do {
|
||||||
k++;
|
k++;
|
||||||
i = rand() % (proxy_count-proxychains_fixed_chain);
|
i = rand() % proxy_count;
|
||||||
i += proxychains_fixed_chain;
|
|
||||||
} while(pd[i].ps != PLAY_STATE && k < proxy_count * 100);
|
} while(pd[i].ps != PLAY_STATE && k < proxy_count * 100);
|
||||||
break;
|
break;
|
||||||
case FIFOLY:
|
case FIFOLY:
|
||||||
@@ -564,38 +563,9 @@ static int chain_step(int ns, proxy_data * pfrom, proxy_data * pto) {
|
|||||||
return retcode;
|
return retcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int strict_connect(
|
|
||||||
unsigned *alive_count,
|
|
||||||
unsigned *offset,
|
|
||||||
int *ns,
|
|
||||||
proxy_data **p1, proxy_data **p2,
|
|
||||||
unsigned proxy_count, proxy_data * pd)
|
|
||||||
{
|
|
||||||
*alive_count = calc_alive(pd, proxy_count);
|
|
||||||
*offset = 0;
|
|
||||||
if(!(*p1 = select_proxy(FIFOLY, pd, proxy_count, offset))) {
|
|
||||||
PDEBUG("select_proxy failed\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
if(SUCCESS != start_chain(ns, *p1, ST)) {
|
|
||||||
PDEBUG("start_chain failed\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
while(*offset < proxy_count) {
|
|
||||||
if(!(*p2 = select_proxy(FIFOLY, pd, proxy_count, offset)))
|
|
||||||
break;
|
|
||||||
if(SUCCESS != chain_step(*ns, *p1, *p2)) {
|
|
||||||
PDEBUG("chain_step failed\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*p1 = *p2;
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int connect_proxy_chain(int sock, ip_type target_ip,
|
int connect_proxy_chain(int sock, ip_type target_ip,
|
||||||
unsigned short target_port, proxy_data * pd,
|
unsigned short target_port, proxy_data * pd,
|
||||||
unsigned int proxy_count, chain_type ct) {
|
unsigned int proxy_count, chain_type ct, unsigned int max_chain) {
|
||||||
proxy_data p4;
|
proxy_data p4;
|
||||||
proxy_data *p1, *p2, *p3;
|
proxy_data *p1, *p2, *p3;
|
||||||
int ns = -1;
|
int ns = -1;
|
||||||
@@ -605,7 +575,6 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
|||||||
unsigned int curr_len = 0;
|
unsigned int curr_len = 0;
|
||||||
unsigned int looped = 0; // went back to start of list in RR mode
|
unsigned int looped = 0; // went back to start of list in RR mode
|
||||||
unsigned int rr_loop_max = 14;
|
unsigned int rr_loop_max = 14;
|
||||||
unsigned int max_chain = proxychains_max_chain;
|
|
||||||
|
|
||||||
p3 = &p4;
|
p3 = &p4;
|
||||||
|
|
||||||
@@ -614,14 +583,9 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
|||||||
again:
|
again:
|
||||||
rc = -1;
|
rc = -1;
|
||||||
DUMP_PROXY_CHAIN(pd, proxy_count);
|
DUMP_PROXY_CHAIN(pd, proxy_count);
|
||||||
if(proxychains_fixed_chain) {
|
|
||||||
if(!strict_connect(&alive_count, &offset, &ns, &p1, &p2, proxychains_fixed_chain, pd))
|
|
||||||
goto error_strict;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (ct) {
|
switch (ct) {
|
||||||
case DYNAMIC_TYPE:
|
case DYNAMIC_TYPE:
|
||||||
if(proxychains_fixed_chain) goto dyn_fixed_resume;
|
|
||||||
alive_count = calc_alive(pd, proxy_count);
|
alive_count = calc_alive(pd, proxy_count);
|
||||||
offset = 0;
|
offset = 0;
|
||||||
do {
|
do {
|
||||||
@@ -637,7 +601,6 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
|||||||
goto again;
|
goto again;
|
||||||
}
|
}
|
||||||
p1 = p2;
|
p1 = p2;
|
||||||
dyn_fixed_resume:;
|
|
||||||
}
|
}
|
||||||
//proxychains_write_log(TP);
|
//proxychains_write_log(TP);
|
||||||
p3->ip = target_ip;
|
p3->ip = target_ip;
|
||||||
@@ -647,7 +610,6 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ROUND_ROBIN_TYPE:
|
case ROUND_ROBIN_TYPE:
|
||||||
// FIXME: add support for fixed_len
|
|
||||||
alive_count = calc_alive(pd, proxy_count);
|
alive_count = calc_alive(pd, proxy_count);
|
||||||
offset = proxychains_proxy_offset;
|
offset = proxychains_proxy_offset;
|
||||||
if(alive_count < max_chain)
|
if(alive_count < max_chain)
|
||||||
@@ -698,8 +660,25 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case STRICT_TYPE:
|
case STRICT_TYPE:
|
||||||
if(!strict_connect(&alive_count, &offset, &ns, &p1, &p2, proxy_count, pd))
|
alive_count = calc_alive(pd, proxy_count);
|
||||||
|
offset = 0;
|
||||||
|
if(!(p1 = select_proxy(FIFOLY, pd, proxy_count, &offset))) {
|
||||||
|
PDEBUG("select_proxy failed\n");
|
||||||
goto error_strict;
|
goto error_strict;
|
||||||
|
}
|
||||||
|
if(SUCCESS != start_chain(&ns, p1, ST)) {
|
||||||
|
PDEBUG("start_chain failed\n");
|
||||||
|
goto error_strict;
|
||||||
|
}
|
||||||
|
while(offset < proxy_count) {
|
||||||
|
if(!(p2 = select_proxy(FIFOLY, pd, proxy_count, &offset)))
|
||||||
|
break;
|
||||||
|
if(SUCCESS != chain_step(ns, p1, p2)) {
|
||||||
|
PDEBUG("chain_step failed\n");
|
||||||
|
goto error_strict;
|
||||||
|
}
|
||||||
|
p1 = p2;
|
||||||
|
}
|
||||||
//proxychains_write_log(TP);
|
//proxychains_write_log(TP);
|
||||||
p3->ip = target_ip;
|
p3->ip = target_ip;
|
||||||
p3->port = target_port;
|
p3->port = target_port;
|
||||||
@@ -708,12 +687,6 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case RANDOM_TYPE:
|
case RANDOM_TYPE:
|
||||||
if(proxychains_fixed_chain) {
|
|
||||||
if(alive_count < max_chain)
|
|
||||||
goto error_more;
|
|
||||||
curr_len = proxychains_fixed_chain - 1;
|
|
||||||
goto random_fixed_resume;
|
|
||||||
}
|
|
||||||
alive_count = calc_alive(pd, proxy_count);
|
alive_count = calc_alive(pd, proxy_count);
|
||||||
if(alive_count < max_chain)
|
if(alive_count < max_chain)
|
||||||
goto error_more;
|
goto error_more;
|
||||||
@@ -722,9 +695,6 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
|||||||
if(!(p1 = select_proxy(RANDOMLY, pd, proxy_count, &offset)))
|
if(!(p1 = select_proxy(RANDOMLY, pd, proxy_count, &offset)))
|
||||||
goto error_more;
|
goto error_more;
|
||||||
} while(SUCCESS != start_chain(&ns, p1, RT) && offset < max_chain);
|
} while(SUCCESS != start_chain(&ns, p1, RT) && offset < max_chain);
|
||||||
|
|
||||||
random_fixed_resume:;
|
|
||||||
|
|
||||||
while(++curr_len < max_chain) {
|
while(++curr_len < max_chain) {
|
||||||
if(!(p2 = select_proxy(RANDOMLY, pd, proxy_count, &offset)))
|
if(!(p2 = select_proxy(RANDOMLY, pd, proxy_count, &offset)))
|
||||||
goto error_more;
|
goto error_more;
|
||||||
|
|||||||
+2
-4
@@ -84,7 +84,8 @@ typedef struct {
|
|||||||
} proxy_data;
|
} proxy_data;
|
||||||
|
|
||||||
int connect_proxy_chain (int sock, ip_type target_ip, unsigned short target_port,
|
int connect_proxy_chain (int sock, ip_type target_ip, unsigned short target_port,
|
||||||
proxy_data * pd, unsigned int proxy_count, chain_type ct );
|
proxy_data * pd, unsigned int proxy_count, chain_type ct,
|
||||||
|
unsigned int max_chain );
|
||||||
|
|
||||||
void proxychains_write_log(char *str, ...);
|
void proxychains_write_log(char *str, ...);
|
||||||
|
|
||||||
@@ -129,9 +130,6 @@ void proxy_freeaddrinfo(struct addrinfo *res);
|
|||||||
void core_initialize(void);
|
void core_initialize(void);
|
||||||
void core_unload(void);
|
void core_unload(void);
|
||||||
|
|
||||||
extern unsigned int proxychains_max_chain;
|
|
||||||
extern unsigned int proxychains_fixed_chain;
|
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+68
-44
@@ -71,7 +71,6 @@ unsigned int proxychains_proxy_count = 0;
|
|||||||
unsigned int proxychains_proxy_offset = 0;
|
unsigned int proxychains_proxy_offset = 0;
|
||||||
int proxychains_got_chain_data = 0;
|
int proxychains_got_chain_data = 0;
|
||||||
unsigned int proxychains_max_chain = 1;
|
unsigned int proxychains_max_chain = 1;
|
||||||
unsigned int proxychains_fixed_chain = 0;
|
|
||||||
int proxychains_quiet_mode = 0;
|
int proxychains_quiet_mode = 0;
|
||||||
enum dns_lookup_flavor proxychains_resolver = DNSLF_LIBC;
|
enum dns_lookup_flavor proxychains_resolver = DNSLF_LIBC;
|
||||||
localaddr_arg localnet_addr[MAX_LOCALNET];
|
localaddr_arg localnet_addr[MAX_LOCALNET];
|
||||||
@@ -105,31 +104,28 @@ static void* load_sym(char* symname, void* proxyfunc) {
|
|||||||
|
|
||||||
#define INIT() init_lib_wrapper(__FUNCTION__)
|
#define INIT() init_lib_wrapper(__FUNCTION__)
|
||||||
|
|
||||||
#define SETUP_SYM(X) do { if (! true_ ## X ) true_ ## X = load_sym( # X, X ); } while(0)
|
|
||||||
|
|
||||||
#include "allocator_thread.h"
|
#include "allocator_thread.h"
|
||||||
|
|
||||||
const char *proxychains_get_version(void);
|
const char *proxychains_get_version(void);
|
||||||
|
|
||||||
static void setup_hooks(void) {
|
static void setup_hooks(void);
|
||||||
SETUP_SYM(connect);
|
|
||||||
SETUP_SYM(sendto);
|
|
||||||
SETUP_SYM(gethostbyname);
|
|
||||||
SETUP_SYM(getaddrinfo);
|
|
||||||
SETUP_SYM(freeaddrinfo);
|
|
||||||
SETUP_SYM(gethostbyaddr);
|
|
||||||
SETUP_SYM(getnameinfo);
|
|
||||||
#ifdef IS_SOLARIS
|
|
||||||
SETUP_SYM(__xnet_connect);
|
|
||||||
#endif
|
|
||||||
SETUP_SYM(close);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int close_fds[16];
|
static int close_fds[16];
|
||||||
static int close_fds_cnt = 0;
|
static int close_fds_cnt = 0;
|
||||||
|
|
||||||
|
static unsigned get_rand_seed(void) {
|
||||||
|
#ifdef HAVE_CLOCK_GETTIME
|
||||||
|
struct timespec now;
|
||||||
|
clock_gettime(CLOCK_REALTIME, &now);
|
||||||
|
return now.tv_sec ^ now.tv_nsec;
|
||||||
|
#else
|
||||||
|
return time(NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void do_init(void) {
|
static void do_init(void) {
|
||||||
srand(time(NULL));
|
srand(get_rand_seed());
|
||||||
core_initialize();
|
core_initialize();
|
||||||
|
|
||||||
/* read the config file */
|
/* read the config file */
|
||||||
@@ -439,16 +435,6 @@ inv_host:
|
|||||||
}
|
}
|
||||||
len = atoi(++pc);
|
len = atoi(++pc);
|
||||||
proxychains_max_chain = (len ? len : 1);
|
proxychains_max_chain = (len ? len : 1);
|
||||||
} else if(STR_STARTSWITH(buff, "fixed_len")) {
|
|
||||||
char *pc;
|
|
||||||
int len;
|
|
||||||
pc = strchr(buff, '=');
|
|
||||||
if(!pc) {
|
|
||||||
fprintf(stderr, "error: missing equals sign '=' in fixed_len directive.\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
len = atoi(++pc);
|
|
||||||
proxychains_fixed_chain = (len ? len : 1);
|
|
||||||
} else if(!strcmp(buff, "quiet_mode")) {
|
} else if(!strcmp(buff, "quiet_mode")) {
|
||||||
proxychains_quiet_mode = 1;
|
proxychains_quiet_mode = 1;
|
||||||
} else if(!strcmp(buff, "proxy_dns_old")) {
|
} else if(!strcmp(buff, "proxy_dns_old")) {
|
||||||
@@ -531,14 +517,6 @@ inv_host:
|
|||||||
fprintf(stderr, "error: no valid proxy found in config\n");
|
fprintf(stderr, "error: no valid proxy found in config\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
if(proxychains_max_chain <= proxychains_fixed_chain) {
|
|
||||||
fprintf(stderr, "error: fixed_len needs to be smaller than chain_len\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
if(proxychains_fixed_chain > count) {
|
|
||||||
fprintf(stderr, "error: fixed_len > proxycount\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
*proxy_count = count;
|
*proxy_count = count;
|
||||||
proxychains_got_chain_data = 1;
|
proxychains_got_chain_data = 1;
|
||||||
PDEBUG("proxy_dns: %s\n", rdns_resolver_string(proxychains_resolver));
|
PDEBUG("proxy_dns: %s\n", rdns_resolver_string(proxychains_resolver));
|
||||||
@@ -546,7 +524,14 @@ inv_host:
|
|||||||
|
|
||||||
/******* HOOK FUNCTIONS *******/
|
/******* HOOK FUNCTIONS *******/
|
||||||
|
|
||||||
int close(int fd) {
|
#define EXPAND( args...) args
|
||||||
|
#ifdef MONTEREY_HOOKING
|
||||||
|
#define HOOKFUNC(R, N, args...) R pxcng_ ## N ( EXPAND(args) )
|
||||||
|
#else
|
||||||
|
#define HOOKFUNC(R, N, args...) R N ( EXPAND(args) )
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HOOKFUNC(int, close, int fd) {
|
||||||
if(!init_l) {
|
if(!init_l) {
|
||||||
if(close_fds_cnt>=(sizeof close_fds/sizeof close_fds[0])) goto err;
|
if(close_fds_cnt>=(sizeof close_fds/sizeof close_fds[0])) goto err;
|
||||||
close_fds[close_fds_cnt++] = fd;
|
close_fds[close_fds_cnt++] = fd;
|
||||||
@@ -567,7 +552,8 @@ int close(int fd) {
|
|||||||
static int is_v4inv6(const struct in6_addr *a) {
|
static int is_v4inv6(const struct in6_addr *a) {
|
||||||
return !memcmp(a->s6_addr, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
|
return !memcmp(a->s6_addr, "\0\0\0\0\0\0\0\0\0\0\xff\xff", 12);
|
||||||
}
|
}
|
||||||
int connect(int sock, const struct sockaddr *addr, unsigned int len) {
|
|
||||||
|
HOOKFUNC(int, connect, int sock, const struct sockaddr *addr, unsigned int len) {
|
||||||
INIT();
|
INIT();
|
||||||
PFUNC();
|
PFUNC();
|
||||||
|
|
||||||
@@ -649,7 +635,7 @@ int connect(int sock, const struct sockaddr *addr, unsigned int len) {
|
|||||||
ret = connect_proxy_chain(sock,
|
ret = connect_proxy_chain(sock,
|
||||||
dest_ip,
|
dest_ip,
|
||||||
htons(port),
|
htons(port),
|
||||||
proxychains_pd, proxychains_proxy_count, proxychains_ct);
|
proxychains_pd, proxychains_proxy_count, proxychains_ct, proxychains_max_chain);
|
||||||
|
|
||||||
fcntl(sock, F_SETFL, flags);
|
fcntl(sock, F_SETFL, flags);
|
||||||
if(ret != SUCCESS)
|
if(ret != SUCCESS)
|
||||||
@@ -658,13 +644,13 @@ int connect(int sock, const struct sockaddr *addr, unsigned int len) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef IS_SOLARIS
|
#ifdef IS_SOLARIS
|
||||||
int __xnet_connect(int sock, const struct sockaddr *addr, unsigned int len) {
|
HOOKFUNC(int, __xnet_connect, int sock, const struct sockaddr *addr, unsigned int len)
|
||||||
return connect(sock, addr, len);
|
return connect(sock, addr, len);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static struct gethostbyname_data ghbndata;
|
static struct gethostbyname_data ghbndata;
|
||||||
struct hostent *gethostbyname(const char *name) {
|
HOOKFUNC(struct hostent*, gethostbyname, const char *name) {
|
||||||
INIT();
|
INIT();
|
||||||
PDEBUG("gethostbyname: %s\n", name);
|
PDEBUG("gethostbyname: %s\n", name);
|
||||||
|
|
||||||
@@ -678,7 +664,7 @@ struct hostent *gethostbyname(const char *name) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) {
|
HOOKFUNC(int, getaddrinfo, const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) {
|
||||||
INIT();
|
INIT();
|
||||||
PDEBUG("getaddrinfo: %s %s\n", node ? node : "null", service ? service : "null");
|
PDEBUG("getaddrinfo: %s %s\n", node ? node : "null", service ? service : "null");
|
||||||
|
|
||||||
@@ -688,7 +674,7 @@ int getaddrinfo(const char *node, const char *service, const struct addrinfo *hi
|
|||||||
return true_getaddrinfo(node, service, hints, res);
|
return true_getaddrinfo(node, service, hints, res);
|
||||||
}
|
}
|
||||||
|
|
||||||
void freeaddrinfo(struct addrinfo *res) {
|
HOOKFUNC(void, freeaddrinfo, struct addrinfo *res) {
|
||||||
INIT();
|
INIT();
|
||||||
PDEBUG("freeaddrinfo %p \n", (void *) res);
|
PDEBUG("freeaddrinfo %p \n", (void *) res);
|
||||||
|
|
||||||
@@ -698,7 +684,7 @@ void freeaddrinfo(struct addrinfo *res) {
|
|||||||
proxy_freeaddrinfo(res);
|
proxy_freeaddrinfo(res);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pc_getnameinfo(const struct sockaddr *sa, socklen_t salen,
|
HOOKFUNC(int, getnameinfo, const struct sockaddr *sa, socklen_t salen,
|
||||||
char *host, socklen_t hostlen, char *serv,
|
char *host, socklen_t hostlen, char *serv,
|
||||||
socklen_t servlen, int flags)
|
socklen_t servlen, int flags)
|
||||||
{
|
{
|
||||||
@@ -742,7 +728,7 @@ int pc_getnameinfo(const struct sockaddr *sa, socklen_t salen,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type) {
|
HOOKFUNC(struct hostent*, gethostbyaddr, const void *addr, socklen_t len, int type) {
|
||||||
INIT();
|
INIT();
|
||||||
PDEBUG("TODO: proper gethostbyaddr hook\n");
|
PDEBUG("TODO: proper gethostbyaddr hook\n");
|
||||||
|
|
||||||
@@ -778,7 +764,7 @@ struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type) {
|
|||||||
# define MSG_FASTOPEN 0x20000000
|
# define MSG_FASTOPEN 0x20000000
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
|
HOOKFUNC(ssize_t, sendto, int sockfd, const void *buf, size_t len, int flags,
|
||||||
const struct sockaddr *dest_addr, socklen_t addrlen) {
|
const struct sockaddr *dest_addr, socklen_t addrlen) {
|
||||||
INIT();
|
INIT();
|
||||||
PFUNC();
|
PFUNC();
|
||||||
@@ -792,3 +778,41 @@ ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
|
|||||||
}
|
}
|
||||||
return true_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
|
return true_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef MONTEREY_HOOKING
|
||||||
|
#define SETUP_SYM(X) do { if (! true_ ## X ) true_ ## X = &X; } while(0)
|
||||||
|
#else
|
||||||
|
#define SETUP_SYM(X) do { if (! true_ ## X ) true_ ## X = load_sym( # X, X ); } while(0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void setup_hooks(void) {
|
||||||
|
SETUP_SYM(connect);
|
||||||
|
SETUP_SYM(sendto);
|
||||||
|
SETUP_SYM(gethostbyname);
|
||||||
|
SETUP_SYM(getaddrinfo);
|
||||||
|
SETUP_SYM(freeaddrinfo);
|
||||||
|
SETUP_SYM(gethostbyaddr);
|
||||||
|
SETUP_SYM(getnameinfo);
|
||||||
|
#ifdef IS_SOLARIS
|
||||||
|
SETUP_SYM(__xnet_connect);
|
||||||
|
#endif
|
||||||
|
SETUP_SYM(close);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MONTEREY_HOOKING
|
||||||
|
|
||||||
|
#define DYLD_INTERPOSE(_replacement,_replacee) \
|
||||||
|
__attribute__((used)) static struct{ const void* replacement; const void* replacee; } _interpose_##_replacee \
|
||||||
|
__attribute__((section ("__DATA,__interpose"))) = { (const void*)(unsigned long)&_replacement, (const void*)(unsigned long)&_replacee };
|
||||||
|
#define DYLD_HOOK(F) DYLD_INTERPOSE(pxcng_ ## F, F)
|
||||||
|
|
||||||
|
DYLD_HOOK(connect);
|
||||||
|
DYLD_HOOK(sendto);
|
||||||
|
DYLD_HOOK(gethostbyname);
|
||||||
|
DYLD_HOOK(getaddrinfo);
|
||||||
|
DYLD_HOOK(freeaddrinfo);
|
||||||
|
DYLD_HOOK(gethostbyaddr);
|
||||||
|
DYLD_HOOK(getnameinfo);
|
||||||
|
DYLD_HOOK(close);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
#include <sys/socket.h>
|
|
||||||
|
|
||||||
extern int pc_getnameinfo(const void *sa, socklen_t salen,
|
|
||||||
char *host, socklen_t hostlen, char *serv,
|
|
||||||
socklen_t servlen, int flags);
|
|
||||||
|
|
||||||
|
|
||||||
int getnameinfo(const void *sa, socklen_t salen,
|
|
||||||
char *host, socklen_t hostlen, char *serv,
|
|
||||||
socklen_t servlen, int flags) {
|
|
||||||
return pc_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -45,12 +45,6 @@ strict_chain
|
|||||||
# Make sense only if random_chain or round_robin_chain
|
# Make sense only if random_chain or round_robin_chain
|
||||||
#chain_len = 2
|
#chain_len = 2
|
||||||
|
|
||||||
# use this if you want to use e.g. random_chain but always have
|
|
||||||
# e.g. tor as first proxy. in that case only chain_len - fixed_len proxies
|
|
||||||
# will be used for random chain.
|
|
||||||
# currently only implemented for dynamic_chain and random_chain.
|
|
||||||
#fixed_len = 1
|
|
||||||
|
|
||||||
# Quiet mode (no output from library)
|
# Quiet mode (no output from library)
|
||||||
#quiet_mode
|
#quiet_mode
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
#include <netdb.h>
|
#include <netdb.h>
|
||||||
#include <netinet/in.h>
|
#include <netinet/in.h>
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#ifndef NI_MAXHOST
|
#ifndef NI_MAXHOST
|
||||||
#define NI_MAXHOST 1025
|
#define NI_MAXHOST 1025
|
||||||
@@ -43,9 +45,42 @@ static int doit(const char* host, const char* service) {
|
|||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* reproduce use of getaddrinfo as used by nmap 7.91's canonicalize_address */
|
||||||
|
int canonicalize_address(struct sockaddr_storage *ss, struct sockaddr_storage *output) {
|
||||||
|
char canonical_ip_string[NI_MAXHOST];
|
||||||
|
struct addrinfo *ai;
|
||||||
|
int rc;
|
||||||
|
/* Convert address to string. */
|
||||||
|
rc = getnameinfo((struct sockaddr *) ss, sizeof(*ss),
|
||||||
|
canonical_ip_string, sizeof(canonical_ip_string), NULL, 0, NI_NUMERICHOST);
|
||||||
|
assert(rc == 0);
|
||||||
|
struct addrinfo hints = {
|
||||||
|
.ai_family = ss->ss_family,
|
||||||
|
.ai_socktype = SOCK_DGRAM,
|
||||||
|
.ai_flags = AI_NUMERICHOST,
|
||||||
|
};
|
||||||
|
rc = getaddrinfo(canonical_ip_string, NULL, &hints, &ai);
|
||||||
|
if (rc != 0 || ai == NULL)
|
||||||
|
return -1;
|
||||||
|
assert(ai->ai_addrlen > 0 && ai->ai_addrlen <= (int) sizeof(*output));
|
||||||
|
memcpy(output, ai->ai_addr, ai->ai_addrlen);
|
||||||
|
freeaddrinfo(ai);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
int ret;
|
int ret;
|
||||||
ret = doit("www.example.com", NULL);
|
ret = doit("www.example.com", NULL);
|
||||||
ret = doit("www.example.com", "80");
|
ret = doit("www.example.com", "80");
|
||||||
|
struct sockaddr_storage o, ss = {.ss_family = PF_INET};
|
||||||
|
struct sockaddr_in *v4 = &ss;
|
||||||
|
struct sockaddr_in6 *v6 = &ss;
|
||||||
|
memcpy(&v4->sin_addr, "\x7f\0\0\1", 4);
|
||||||
|
ret = canonicalize_address(&ss, &o);
|
||||||
|
assert (ret == 0);
|
||||||
|
ss.ss_family = PF_INET6;
|
||||||
|
memcpy(&v6->sin6_addr, "\0\0\0\0" "\0\0\0\0" "\0\0\0\0""\0\0\0\1", 16);
|
||||||
|
ret = canonicalize_address(&ss, &o);
|
||||||
|
assert (ret == 0);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -123,5 +123,17 @@ int main() {
|
|||||||
|
|
||||||
ASSERT(ret == 0);
|
ASSERT(ret == 0);
|
||||||
|
|
||||||
|
b.sin6_port = 0;
|
||||||
|
b.sin6_scope_id = 0;
|
||||||
|
memcpy(&b.sin6_addr,"\0\0\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\1", 16);
|
||||||
|
|
||||||
|
if ((ret = getnameinfo((void*)sb, sizeof b, hbuf, sizeof(hbuf), NULL,
|
||||||
|
0, NI_NUMERICHOST)) == 0)
|
||||||
|
printf("host=%s\n", hbuf);
|
||||||
|
else
|
||||||
|
printf("%s\n", gai_strerror(ret));
|
||||||
|
|
||||||
|
ASSERT(ret == 0);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user