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

Compare commits

..

42 Commits

20 changed files with 899 additions and 163 deletions
-65
View File
@@ -1,65 +0,0 @@
ProxyChains version history (public releases)
====================
ver 3.1
changed:
* dns resolver script fix
* prototypes in core.h
-------------------------------------------------------------------------
ver 3.0
added:
* new feature - DNS from behind proxy
* proxyresolv - stand alone command
* proxychains.conf - new option to enable/disable DNS support
changed:
* bugfixes in core lib
* fixed strict chain
* fixed random chain
* output text
* autotools fix
-------------------------------------------------------------------------
ver 2.1
* bugfuxes
-------------------------------------------------------------------------
ver 2.0
* major core rewrite
* new config options
-------------------------------------------------------------------------
ver 1.8.2
* minor bugfixes
* improved compilation on FreeBSD & OpenBSD sysems.
* improved compilation on Sun Solaris systems .
* cross platform (UNIX) issues
-------------------------------------------------------------------------
ver 1.8.0
added:
* Socks5 protocol
* Socks4 protocol
* HTTP proxy auth basic
* Socks4 user auth
* Socks5 user/pass auth
* more chain options (random, strict, dynamic )
* configurable timeout for TCP connect.
* configurable timeout for TCP read.
* INSTALL file (explains how to install properly)
changed:
* configuration file entries (proxychains.conf)
* configuration file lookup
-------------------------------------------------------------------------
ver 0.0.1
* TCP calls interception
* HTTP CONNECT proxy protocol.
+13 -11
View File
@@ -15,12 +15,15 @@ sysconfdir=$(prefix)/etc
SRCS = $(sort $(wildcard src/*.c))
OBJS = $(SRCS:.c=.o)
LOBJS = src/core.o src/common.o src/libproxychains.o src/shm.o \
LOBJS = src/nameinfo.o src/legacy.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
LDFLAGS = -shared -fPIC -Wl,--no-as-needed -ldl -lpthread
NO_AS_NEEDED = -Wl,--no-as-needed
LIBDL = -ldl
LDFLAGS = -shared -fPIC $(NO_AS_NEEDED) $(LIBDL) -lpthread
INC =
PIC = -fPIC
AR = $(CROSS_COMPILE)ar
@@ -30,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)
@@ -39,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)\"
@@ -47,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)
@@ -70,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
+72 -19
View File
@@ -1,33 +1,78 @@
ProxyChains ver 4.3 README
==========================
ProxyChains-NG ver 4.8 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
Changelog:
----------
Version 4.8:
- fix for odd cornercase where getaddrinfo was used with AI_NUMERICHOST
to test for a numeric ip instead of resolving it (fixes nmap).
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),
@@ -78,10 +123,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 +134,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 +163,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
+27 -6
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,14 +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
}
while true ; do
case $1 in
-*) parsearg "$1"; shift;;
@@ -78,11 +90,20 @@ echo libdir=$libdir>>config.mak
echo includedir=$includedir>>config.mak
echo sysconfdir=$sysconfdir>>config.mak
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;
}
}
+5 -1
View File
@@ -6,10 +6,14 @@
#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);
ip_type at_get_ip_for_host(char* host, size_t len);
//RcB: DEP "allocator_thread.c"
#endif
#endif
+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);
+63 -5
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;
@@ -770,8 +825,11 @@ int proxy_getaddrinfo(const char *node, const char *service, const struct addrin
// printf("proxy_getaddrinfo node %s service %s\n",node,service);
space = calloc(1, sizeof(struct addrinfo_data));
if(!space) goto err1;
if(node && !inet_aton(node, &((struct sockaddr_in *) &space->sockaddr_space)->sin_addr)) {
/* some folks (nmap) use getaddrinfo() with AI_NUMERICHOST to check whether a string
containing a numeric ip was passed. we must return failure in that case. */
if(hints && (hints->ai_flags & AI_NUMERICHOST)) return EAI_NONAME;
hp = proxy_gethostbyname(node, &ghdata);
if(hp)
memcpy(&((struct sockaddr_in *) &space->sockaddr_space)->sin_addr,
@@ -786,7 +844,7 @@ int proxy_getaddrinfo(const char *node, const char *service, const struct addrin
*res = p = &space->addrinfo_space;
assert((size_t)p == (size_t) space);
p->ai_addr = &space->sockaddr_space;
if(node)
strncpy(space->addr_name, node, sizeof(space->addr_name));
@@ -802,7 +860,7 @@ int proxy_getaddrinfo(const char *node, const char *service, const struct addrin
} else {
p->ai_flags = (AI_V4MAPPED | AI_ADDRCONFIG);
}
goto out;
err2:
free(space);
+6 -3
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 *);
@@ -123,4 +125,5 @@ void core_unload(void);
//RcB: DEP "core.c"
//RcB: DEP "libproxychains.c"
//RcB: LINK "-Wl,--no-as-needed -ldl -lpthread"
//RcB: LINK "-Wl,--no-as-needed -ldl -lpthread"
+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
+9 -2
View File
@@ -3,11 +3,18 @@
#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)
#endif
#endif
+8 -1
View File
@@ -2,6 +2,8 @@
#include <string.h>
#include <netdb.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include "ip_type.h"
#include "hash.h"
@@ -26,11 +28,16 @@ static void hdb_add(struct hostent_list* hl, char* host, ip_type ip) {
}
static void hdb_fill(struct hostent_list *hl) {
#ifndef IS_BSD
struct hostent* hp;
while((hp = gethostent()))
if(hp->h_addrtype == AF_INET && hp->h_length == sizeof(in_addr_t)) {
hdb_add(hl, hp->h_name, (ip_type) { .as_int = *((in_addr_t*)(hp->h_addr_list[0])) });
}
#else
/* FreeBSD hangs on gethostent(). since this feature is not crucial, we just do nothing */
(void) hl;
#endif
}
void hdb_init(struct hostent_list *hl) {
@@ -53,4 +60,4 @@ ip_type hdb_get(struct hostent_list *hl, char* host) {
}
}
return ip_type_invalid;
}
}
+481
View File
@@ -0,0 +1,481 @@
int __res_ninit() {
return 0;
}
void __pthread_register_cancel(void* p) {
}
void __pthread_unregister_cancel(void *p) {
}
#include <setjmp.h>
int __sigsetjmp(sigjmp_buf buf, int save) {
return sigsetjmp(buf, save);
}
static __thread void* thread_arg;
static __thread int (*thread_compar)(const void*, const void*, void*);
static int my_thread_compare_func(const void* a, const void* b) {
return thread_compar(a, b, thread_arg);
}
#include <stddef.h>
#include <stdlib.h>
void qsort_r(void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*, void*), void *arg) {
thread_arg = arg;
thread_compar = compar;
return qsort(base, nmemb, size, my_thread_compare_func);
}
int backtrace(void **buffer, int size) {
return 0;
}
char **backtrace_symbols(void *const *buffer, int size) {
return 0;
}
#include <pthread.h>
int __register_atfork(void (*prepare) (void), void (*parent) (void), void (*child) (void), void * __dso_handle) {
return pthread_atfork(prepare, parent, child);
}
#define _GNU_SOURCE
#include <poll.h>
#include <setjmp.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <syslog.h>
#include <unistd.h>
#include <wchar.h>
__attribute((noreturn)) void __chk_fail(void)
{
write(2, "buffer overflow detected\n", 25);
abort();
}
int __asprintf_chk(char **s, int flag, const char *fmt, ...)
{
va_list ap;
int r;
va_start(ap,fmt);
r = vasprintf(s, fmt, ap);
va_end(ap);
return r;
}
size_t __confstr_chk(int name, char *buf, size_t len, size_t size)
{
return confstr(name, buf, len);
}
int __dprintf_chk(int fd, int flag, const char *fmt, ...)
{
va_list ap;
int r;
va_start(ap,fmt);
r = vdprintf(fd, fmt, ap);
va_end(ap);
return r;
}
char *__fgets_chk(char *s, size_t size, int n, FILE *f)
{
return fgets(s, n, f);
}
char *__fgets_unlocked_chk(char *s, size_t size, int n, FILE *f)
{
return fgets_unlocked(s, n, f);
}
wchar_t *__fgetws_chk(wchar_t *s, size_t size, int n, FILE *f)
{
return fgetws(s, n, f);
}
wchar_t *fgetws_unlocked(wchar_t *, int, FILE *);
wchar_t *__fgetws_unlocked_chk(wchar_t *s, size_t size, int n, FILE *f)
{
return fgetws_unlocked(s, n, f);
}
int __fprintf_chk(FILE *f, int flag, const char *fmt, ...)
{
va_list ap;
int r;
va_start(ap,fmt);
r = vfprintf(f, fmt, ap);
va_end(ap);
return r;
}
int __fwprintf_chk(FILE *f, int flag, const wchar_t *fmt, ...)
{
va_list ap;
int r;
va_start(ap,fmt);
r = vfwprintf(f, fmt, ap);
va_end(ap);
return r;
}
size_t __fread_chk(void *p, size_t size, size_t sz, size_t n, FILE *f)
{
return fread(p, sz, n, f);
}
size_t __fread_unlocked_chk(void *p, size_t size, size_t sz, size_t n, FILE *f)
{
return fread_unlocked(p, sz, n, f);
}
char *__getcwd_chk(char *buf, size_t len, size_t size)
{
return getcwd(buf, len);
}
int __getdomainname_chk(char *buf, size_t len, size_t size)
{
return getdomainname(buf, len);
}
int __getgroups_chk(int n, gid_t *list, size_t listlen)
{
return getgroups(n, list);
}
int __gethostname_chk(char *buf, size_t len, size_t size)
{
return gethostname(buf, len);
}
int __getlogin_r_chk(char *buf, size_t len, size_t size)
{
return getlogin_r(buf, len);
}
char *__gets_chk(char *buf, size_t size)
{
return gets(buf);
}
__attribute((noreturn)) void __longjmp_chk(jmp_buf buf, int v)
{
longjmp(buf, v);
}
size_t __mbsnrtowcs_chk(wchar_t *dst, const char **src, size_t n, size_t len, mbstate_t *st, size_t dstsize)
{
return mbsnrtowcs(dst, src, n, len, st);
}
size_t __mbsrtowcs_chk(wchar_t *dst, const char **src, size_t len, mbstate_t *st, size_t dstsize)
{
return mbsrtowcs(dst, src, len, st);
}
size_t __mbstowcs_chk(wchar_t *dst, const char *src, size_t len, size_t dstsize)
{
return mbstowcs(dst, src, len);
}
void *__memcpy_chk(void *dst, void *src, size_t len, size_t dstsize)
{
return memcpy(dst, src, len);
}
void *__mempcpy_chk(void *dst, void *src, size_t len, size_t dstsize)
{
return mempcpy(dst, src, len);
}
void *__memmove_chk(void *dst, void *src, size_t len, size_t dstsize)
{
return memmove(dst, src, len);
}
void *__memset_chk(void *s, int c, size_t n, size_t size)
{
return memset(s, c, n);
}
int __poll_chk(struct pollfd *fds, nfds_t n, int timeout, size_t fdslen)
{
return poll(fds, n, timeout);
}
int __ppoll_chk(struct pollfd *fds, nfds_t n, const struct timespec *timeout, const sigset_t *mask, size_t fdslen)
{
return ppoll(fds, n, timeout, mask);
}
ssize_t __pread_chk(int fd, void *buf, size_t n, off_t off, size_t bufsize)
{
return pread(fd, buf, n, off);
}
#undef weak_alias
#define weak_alias(old, new) \
extern __typeof(old) new __attribute__((weak, alias(#old)))
weak_alias(__pread_chk, __pread64_chk);
int __printf_chk(int flag, const char *fmt, ...)
{
va_list ap;
int r;
va_start(ap,fmt);
r = vprintf(fmt, ap);
va_end(ap);
return r;
}
int __ptsname_r_chk(int fd, char *buf, size_t len, size_t size)
{
return ptsname_r(fd, buf, len);
}
ssize_t __read_chk(int fd, void *buf, size_t n, size_t bufsize)
{
return read(fd, buf, n);
}
ssize_t __readlinkat_chk(int fd, const char *path, void *buf, size_t n, size_t bufsize)
{
return readlinkat(fd, path, buf, n);
}
ssize_t __readlink_chk(const char *path, void *buf, size_t n, size_t bufsize)
{
return readlink(path, buf, n);
}
char *__realpath_chk(const char *name, char *resolved, size_t resolvedsize)
{
return realpath(name, resolved);
}
ssize_t __recv_chk(int fd, void *buf, size_t n, size_t bufsize, int flags)
{
return recv(fd, buf, n, flags);
}
ssize_t __recvfrom_chk(int fd, void *buf, size_t n, size_t bufsize, int flags, struct sockaddr *addr, socklen_t *addrlen)
{
return recvfrom(fd, buf, n, flags, addr, addrlen);
}
int __sprintf_chk(char *s, int flag, size_t size, const char *fmt, ...)
{
va_list ap;
int r;
va_start(ap,fmt);
r = vsprintf(s, fmt, ap);
va_end(ap);
return r;
}
int __snprintf_chk(char *s, size_t n, int flag, size_t size, const char *fmt, ...)
{
va_list ap;
int r;
va_start(ap,fmt);
r = vsnprintf(s, n, fmt, ap);
va_end(ap);
return r;
}
char *__stpcpy_chk(char *dst, const char *src, size_t dstsize)
{
return stpcpy(dst, src);
}
char *__stpncpy_chk(char *dst, const char *src, size_t n, size_t dstsize)
{
return stpncpy(dst, src, n);
}
char *__strcat_chk(char *dst, const char *src, size_t dstsize)
{
return strcat(dst, src);
}
char *__strcpy_chk(char *dst, const char *src, size_t dstsize)
{
return strcpy(dst, src);
}
char *__strncat_chk(char *dst, const char *src, size_t n, size_t dstsize)
{
return strncat(dst, src, n);
}
char *__strncpy_chk(char *dst, const char *src, size_t n, size_t dstsize)
{
return strncpy(dst, src, n);
}
int __swprintf_chk(wchar_t *s, size_t n, int flag, size_t size, const wchar_t *fmt, ...)
{
va_list ap;
int r;
va_start(ap,fmt);
r = vswprintf(s, n, fmt, ap);
va_end(ap);
return r;
}
void __syslog_chk(int pri, int flag, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vsyslog(pri, fmt, ap);
va_end(ap);
}
int __ttyname_r_chk(int fd, char *buf, size_t len, size_t size)
{
return ttyname_r(fd, buf, len);
}
int __vasprintf_chk(char **s, int flag, const char *fmt, va_list ap)
{
return vasprintf(s, fmt, ap);
}
int __vdprintf_chk(int fd, int flag, const char *fmt, va_list ap)
{
return vdprintf(fd, fmt, ap);
}
int __vfprintf_chk(FILE *f, int flag, const char *fmt, va_list ap)
{
return vfprintf(f, fmt, ap);
}
int __vfwprintf_chk(FILE *f, int flag, const wchar_t *fmt, va_list ap)
{
return vfwprintf(f, fmt, ap);
}
int __vprintf_chk(int flag, const char *fmt, va_list ap)
{
return vprintf(fmt, ap);
}
int __vsnprintf_chk(char *s, size_t n, int flag, size_t size, const char *fmt, va_list ap)
{
return vsnprintf(s, n, fmt, ap);
}
int __vsprintf_chk(char *s, int flag, size_t size, const char *fmt, va_list ap)
{
return vsprintf(s, fmt, ap);
}
int __vswprintf_chk(wchar_t *s, size_t n, int flag, size_t size, const wchar_t *fmt, va_list ap)
{
return vswprintf(s, n, fmt, ap);
}
void __vsyslog_chk(int pri, int flag, const char *fmt, va_list ap)
{
vsyslog(pri, fmt, ap);
}
int __vwprintf_chk(int flag, const wchar_t *fmt, va_list ap)
{
return vwprintf(fmt, ap);
}
wchar_t *__wcpcpy_chk(wchar_t *dst, const wchar_t *src, size_t dstsize)
{
return wcpcpy(dst, src);
}
wchar_t *__wcpncpy_chk(wchar_t *dst, const wchar_t *src, size_t n, size_t dstsize)
{
return wcpncpy(dst, src, n);
}
size_t __wcrtomb_chk(char *s, wchar_t c, mbstate_t *st, size_t size)
{
return wcrtomb(s, c, st);
}
wchar_t *__wcscat_chk(wchar_t *dst, const wchar_t *src, size_t dstlen)
{
return wcscat(dst, src);
}
wchar_t *__wcscpy_chk(wchar_t *dst, const wchar_t *src, size_t dstlen)
{
return wcscpy(dst, src);
}
wchar_t *__wcsncat_chk(wchar_t *dst, const wchar_t *src, size_t n, size_t dstlen)
{
return wcsncat(dst, src, n);
}
wchar_t *__wcsncpy_chk(wchar_t *dst, const wchar_t *src, size_t n, size_t dstlen)
{
return wcsncpy(dst, src, n);
}
size_t __wcsnrtombs_chk(char *dst, const wchar_t **src, size_t n, size_t len, mbstate_t *st, size_t dstsize)
{
return wcsnrtombs(dst, src, n, len, st);
}
size_t __wcsrtombs_chk(char *dst, const wchar_t **src, size_t len, mbstate_t *st, size_t dstsize)
{
return wcsrtombs(dst, src, len, st);
}
size_t __wcstombs_chk(char *dst, const wchar_t *src, size_t len, size_t dstsize)
{
return wcstombs(dst, src, len);
}
int __wctomb_chk(char *s, wchar_t c, size_t size)
{
return wctomb(s, c);
}
wchar_t *__wmemcpy_chk(wchar_t *dst, const wchar_t *src, size_t n, size_t dstlen)
{
return wmemcpy(dst, src, n);
}
wchar_t *__wmemmove_chk(wchar_t *dst, const wchar_t *src, size_t n, size_t dstlen)
{
return wmemmove(dst, src, n);
}
wchar_t *__wmempcpy_chk(wchar_t *dst, const wchar_t *src, size_t n, size_t dstlen)
{
return mempcpy(dst, src, n*sizeof*src);
}
wchar_t *__wmemset_chk(wchar_t *s, wchar_t c, size_t n, size_t slen)
{
return wmemset(s, c, n);
}
int __wprintf_chk(int flag, const wchar_t *fmt, ...)
{
va_list ap;
int r;
va_start(ap,fmt);
r = vwprintf(fmt, ap);
va_end(ap);
return r;
}
+40 -15
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;
@@ -381,32 +407,31 @@ void freeaddrinfo(struct addrinfo *res) {
return;
}
// work around a buggy prototype in GLIBC. according to the bugtracker it has been fixed in git at 02 May 2011.
// 2.14 came out in June 2011 so that should be the first fixed version
#if defined(__GLIBC__) && (__GLIBC__ < 3) && (__GLIBC_MINOR__ < 14)
int getnameinfo(const struct sockaddr *sa,
socklen_t salen, char *host, socklen_t hostlen, char *serv, socklen_t servlen, unsigned int flags)
#else
int getnameinfo(const struct sockaddr *sa,
socklen_t salen, char *host, socklen_t hostlen, char *serv, socklen_t servlen, int flags)
#endif
int pc_getnameinfo(const struct sockaddr *sa, socklen_t salen,
char *host, socklen_t hostlen, char *serv,
socklen_t servlen, int flags)
{
char ip_buf[16];
int ret = 0;
INIT();
PDEBUG("getnameinfo: %s %s\n", host, serv);
PFUNC();
if(!proxychains_resolver) {
ret = true_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags);
} else {
if(salen < sizeof(struct sockaddr_in) || SOCKFAMILY(*sa) != AF_INET)
return EAI_FAMILY;
if(hostlen) {
pc_stringfromipv4((unsigned char*) &(SOCKADDR_2(*sa)), ip_buf);
strncpy(host, ip_buf, hostlen);
if(snprintf(host, hostlen, "%s", ip_buf) >= hostlen)
return EAI_OVERFLOW;
}
if(servlen) {
if(snprintf(serv, servlen, "%d", ntohs(SOCKPORT(*sa))) >= servlen)
return EAI_OVERFLOW;
}
if(servlen)
snprintf(serv, servlen, "%d", ntohs(SOCKPORT(*sa)));
}
return ret;
}
+13
View File
@@ -0,0 +1,13 @@
#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);
}
-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;}'
+83
View File
@@ -0,0 +1,83 @@
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <sys/socket.h>
#include <netinet/in.h>
#define satosin(x) ((struct sockaddr_in *) &(x))
#define SOCKADDR(x) (satosin(x)->sin_addr.s_addr)
#define SOCKADDR_2(x) (satosin(x)->sin_addr)
#define SOCKPORT(x) (satosin(x)->sin_port)
#define SOCKFAMILY(x) (satosin(x)->sin_family)
int main() {
struct sockaddr a = {0}, *sa = &a;
char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
SOCKPORT(a) = htons(80);
memcpy( &( (struct sockaddr_in*) sa ) ->sin_addr , (char[]) {127,0,0,1}, 4);
int ret;
if ((ret = getnameinfo(sa, 0, hbuf, sizeof(hbuf), sbuf,
sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) == 0)
printf("host=%s, serv=%s\n", hbuf, sbuf);
else
printf("%s\n", gai_strerror(ret));
assert(ret == EAI_FAMILY);
if ((ret = getnameinfo(sa, sizeof a, hbuf, sizeof(hbuf), sbuf,
sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) == 0)
printf("host=%s, serv=%s\n", hbuf, sbuf);
else
printf("%s\n", gai_strerror(ret));
assert(ret == EAI_FAMILY);
SOCKFAMILY(a) = AF_INET;
if ((ret = getnameinfo(sa, sizeof a, hbuf, 1, sbuf,
sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) == 0)
printf("host=%s, serv=%s\n", hbuf, sbuf);
else
printf("%s\n", gai_strerror(ret));
assert(ret == EAI_OVERFLOW);
if ((ret = getnameinfo(sa, sizeof a, hbuf, 0, sbuf,
1, NI_NUMERICHOST | NI_NUMERICSERV)) == 0)
printf("host=%s, serv=%s\n", hbuf, sbuf);
else
printf("%s\n", gai_strerror(ret));
assert(ret == EAI_OVERFLOW);
if ((ret = getnameinfo(sa, sizeof a, hbuf, 0, sbuf,
sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) == 0)
printf("host=%s, serv=%s\n", hbuf, sbuf);
else
printf("%s\n", gai_strerror(ret));
assert(ret == 0);
if ((ret = getnameinfo(sa, sizeof a, hbuf, sizeof hbuf, sbuf,
0, NI_NUMERICHOST | NI_NUMERICSERV)) == 0)
printf("host=%s, serv=%s\n", hbuf, sbuf);
else
printf("%s\n", gai_strerror(ret));
assert(ret == 0);
if ((ret = getnameinfo(sa, sizeof a, hbuf, sizeof(hbuf), sbuf,
sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV)) == 0)
printf("host=%s, serv=%s\n", hbuf, sbuf);
else
printf("%s\n", gai_strerror(ret));
assert(ret == 0);
return 0;
}