5.30 hosts support
This commit is contained in:
2
Makefile
2
Makefile
@@ -15,7 +15,7 @@ sysconfdir=$(prefix)/etc
|
||||
|
||||
SRCS = $(sort $(wildcard src/*.c))
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
LOBJS = src/core.o src/common.o src/libproxybound.o
|
||||
LOBJS = src/core.o src/common.o src/libproxybound.o src/hostsreader.o src/ip-type.o
|
||||
|
||||
CFLAGS += -Wall -O0 -g -std=c99 -D_GNU_SOURCE -pipe
|
||||
LDFLAGS = -shared -fPIC -Wl,--no-as-needed -ldl -lpthread
|
||||
|
128
README
128
README
@@ -1,128 +0,0 @@
|
||||
ProxyBound v5.20
|
||||
================
|
||||
|
||||
ProxyBound 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. This is based on
|
||||
proxychains-ng by rofl0r, proxychains by haad and torsocks by dgoulet
|
||||
|
||||
Features:
|
||||
=========
|
||||
|
||||
- Proxify applications (like mainstream proxychains)
|
||||
- Works with tcp (like mainstream proxychains)
|
||||
- No leaks over udp/raw/icmp/etc...
|
||||
- Unsupported protocols are blocked
|
||||
- Works with chrome/chromium/similar
|
||||
- Incompatible applications are terminated with a proper message
|
||||
- Many additional settings over environment variable
|
||||
- etc.
|
||||
|
||||
|
||||
Used environment variable:
|
||||
==========================
|
||||
|
||||
- PROXYBOUND_CONF_FILE: Path to config file (default ./proxybound.conf then /etc/proxybound.conf)
|
||||
- PROXYBOUND_QUIET_MODE: Quiet mode (1 or 0, default 0)
|
||||
- PROXYBOUND_SOCKS5_HOST: Specify unique socks 5 proxy to use (default not used)
|
||||
- PROXYBOUND_SOCKS5_PORT: Socks 5 port (default not used)
|
||||
- PROXYBOUND_FORCE_DNS: Force dns resolv requests through (1 or 0, default 1)
|
||||
- PROXYBOUND_ALLOW_DNS: Allow direct dns, allow udp port 53 and 853 (1 or 0, default 0)
|
||||
- PROXYBOUND_ALLOW_LEAKS: Allow/Block unproxyfied protocols "UDP/ICMP/RAW", blocked by default (1 or 0, default 0)
|
||||
- PROXYBOUND_WORKING_INDICATOR: Create '/tmp/proxybound.tmp' when dll is working as intended (1 or 0, default 0)
|
||||
|
||||
How it works:
|
||||
=============
|
||||
|
||||
Proxybound hook libc functions like connect(), dynamic loader
|
||||
facilities are used, namely dl_sym() and LD_PRELOAD thus
|
||||
dynamically linked programs are required.
|
||||
|
||||
Limits :
|
||||
========
|
||||
- IPv6 is blocked and is not supported
|
||||
- Some applications are incompatible (they will be explicitly terminated 2 sec after startup, to avoid leaks)
|
||||
|
||||
Install:
|
||||
========
|
||||
|
||||
./configure
|
||||
make
|
||||
[optional] sudo make install
|
||||
|
||||
if you dont install, you can use proxybound from the build directory
|
||||
like this: ./proxybound -f src/proxybound.conf telnet google.com 80
|
||||
|
||||
Changelog:
|
||||
==========
|
||||
|
||||
Version 5.20:
|
||||
- add PROXYBOUND_ALLOW_DNS
|
||||
- update lock feature (send sendto sendmsg)
|
||||
- add function to terminate when app is not supported
|
||||
- add PROXYBOUND_WORKING_INDICATOR
|
||||
- Code cleaning
|
||||
- Update readme
|
||||
|
||||
Version 5.10:
|
||||
- leak lock feature (send sendto sendmsg)
|
||||
|
||||
Version 5.00:
|
||||
- Initial leak lock feature
|
||||
- Code cleaning
|
||||
- Update readme
|
||||
|
||||
Version 4.90:
|
||||
- Import simple SOCKS5 proxy mode from @haad/proxychains
|
||||
- Code cleaning
|
||||
- Update readme
|
||||
|
||||
Version 4.80:
|
||||
- Updates with some features from @haad/proxychains
|
||||
|
||||
Version 4.70:
|
||||
- Fix chrome compatibility
|
||||
|
||||
Version 4.60:
|
||||
- Code cleanning & update
|
||||
|
||||
Version 4.50:
|
||||
- Changing the name to ProxyBound
|
||||
|
||||
Version 4.40:
|
||||
- Import security issue fix CVE-2015-3887
|
||||
- Used v4.3 (4.03) for initial fork
|
||||
|
||||
Configuration:
|
||||
==============
|
||||
|
||||
Proxybound config file in following order:
|
||||
|
||||
1) File listed in environment variable ${PROXYBOUND_CONF_FILE} or
|
||||
provided as a -f argument to proxybound script or binary.
|
||||
2) ./proxybound.conf
|
||||
3) $(HOME)/.proxybound/proxybound.conf
|
||||
4) /etc/proxybound.conf
|
||||
|
||||
Usage Example:
|
||||
==============
|
||||
|
||||
$ export PROXYBOUND_QUIET_MODE="1"
|
||||
$ export LD_PRELOAD=/usr/local/lib/libproxybound.so
|
||||
$ export PROXYBOUND_CONF_FILE=/etc/proxybound.conf
|
||||
$ telnet targethost.com
|
||||
|
||||
In this example it will run telnet through proxy without using proxybound binary
|
||||
|
||||
$ proxybound telnet targethost.com
|
||||
|
||||
In this example it will run telnet through proxy(or chained proxies) specified by proxybound.conf
|
||||
|
||||
$ proxybound -f /etc/proxybound-other.conf targethost2.com
|
||||
|
||||
In this example it will use different configuration file then proxybound.conf to connect to targethost2.com host.
|
||||
|
||||
$ proxyresolv targethost.com
|
||||
|
||||
In this example it will resolve targethost.com through proxy(or chained proxies) specified by proxybound.conf
|
||||
|
150
README.md
Normal file
150
README.md
Normal file
@@ -0,0 +1,150 @@
|
||||
ProxyBound v5.30
|
||||
================
|
||||
|
||||
ProxyBound 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. This is based on proxychains-ng by rofl0r, proxychains by haad and torsocks by dgoulet
|
||||
|
||||
Features:
|
||||
=========
|
||||
|
||||
- Proxify applications (like mainstream proxychains)
|
||||
- Works with tcp (like mainstream proxychains)
|
||||
- No leaks over udp/raw/icmp/etc...
|
||||
- Unsupported protocols are blocked
|
||||
- Works with chrome/chromium/similar
|
||||
- Incompatible applications are terminated with a proper message
|
||||
- Many additional settings over environment variable
|
||||
- etc.
|
||||
|
||||
Used environment variable:
|
||||
==========================
|
||||
|
||||
```
|
||||
- PROXYBOUND_CONF_FILE: Path to config file (default ./proxybound.conf then /etc/proxybound.conf)
|
||||
- PROXYBOUND_QUIET_MODE: Quiet mode (1 or 0, default 0)
|
||||
- PROXYBOUND_SOCKS5_HOST: Specify unique socks 5 proxy to use (default not used)
|
||||
- PROXYBOUND_SOCKS5_PORT: Socks 5 port (default not used)
|
||||
- PROXYBOUND_FORCE_DNS: Force dns resolv requests through (1 or 0, default 1)
|
||||
- PROXYBOUND_ALLOW_DNS: Allow direct dns, allow udp port 53 and 853 (1 or 0, default 0)
|
||||
- PROXYBOUND_ALLOW_LEAKS: Allow/Block unproxyfied protocols "UDP/ICMP/RAW", blocked by default (1 or 0, default 0)
|
||||
- PROXYBOUND_WORKING_INDICATOR: Create '/tmp/proxybound.tmp' when dll is working as intended (1 or 0, default 0)
|
||||
```
|
||||
|
||||
How it works:
|
||||
=============
|
||||
|
||||
Proxybound hook libc functions like connect(), dynamic loader facilities are used, namely dl_sym() and LD_PRELOAD thus dynamically linked programs are required.
|
||||
|
||||
Limits :
|
||||
========
|
||||
|
||||
- IPv6 is blocked and is not supported
|
||||
- Some applications are incompatible (they will be explicitly terminated 2 sec after startup, to avoid leaks)
|
||||
|
||||
Install:
|
||||
========
|
||||
|
||||
```
|
||||
./configure
|
||||
make
|
||||
[optional] sudo make install
|
||||
```
|
||||
|
||||
if you dont install, you can use proxybound from the build directory like this: `./proxybound -f src/proxybound.conf telnet google.com 80`
|
||||
|
||||
Changelog:
|
||||
==========
|
||||
|
||||
**Version 5.30:**
|
||||
|
||||
- Code cleaning
|
||||
- Move readme to md
|
||||
- Add support for hosts file (upstream import)
|
||||
|
||||
**Version 5.20:**
|
||||
|
||||
- add PROXYBOUND_ALLOW_DNS
|
||||
- update lock feature (send sendto sendmsg)
|
||||
- add function to terminate when app is not supported
|
||||
- add PROXYBOUND_WORKING_INDICATOR
|
||||
- Code cleaning
|
||||
- Update readme
|
||||
|
||||
**Version 5.10:**
|
||||
|
||||
- leak lock feature (send sendto sendmsg)
|
||||
|
||||
**Version 5.00:**
|
||||
|
||||
- Initial leak lock feature
|
||||
- Code cleaning
|
||||
- Update readme
|
||||
|
||||
**Version 4.90:**
|
||||
|
||||
- Import simple SOCKS5 proxy mode from @haad/proxychains
|
||||
- Code cleaning
|
||||
- Update readme
|
||||
|
||||
**Version 4.80:**
|
||||
|
||||
- Updates with some features from @haad/proxychains
|
||||
|
||||
**Version 4.70:**
|
||||
|
||||
- Fix chrome compatibility
|
||||
|
||||
**Version 4.60:**
|
||||
|
||||
- Code cleanning & update
|
||||
|
||||
**Version 4.50:**
|
||||
|
||||
- Changing the name to ProxyBound
|
||||
|
||||
**Version 4.40:**
|
||||
|
||||
- Import security issue fix CVE-2015-3887
|
||||
- Used v4.3 (4.03) for initial fork
|
||||
|
||||
Configuration:
|
||||
==============
|
||||
|
||||
Proxybound config file in following order:
|
||||
|
||||
```
|
||||
1) File listed in environment variable ${PROXYBOUND_CONF_FILE} or
|
||||
provided as a -f argument to proxybound script or binary.
|
||||
2) ./proxybound.conf
|
||||
3) $(HOME)/.proxybound/proxybound.conf
|
||||
4) /etc/proxybound.conf
|
||||
```
|
||||
|
||||
Usage Example:
|
||||
==============
|
||||
|
||||
In this example it will run telnet through proxy without using proxybound binary
|
||||
|
||||
```
|
||||
$ export PROXYBOUND_QUIET_MODE="1"
|
||||
$ export LD_PRELOAD=/usr/local/lib/libproxybound.so
|
||||
$ export PROXYBOUND_CONF_FILE=/etc/proxybound.conf
|
||||
$ telnet targethost.com
|
||||
```
|
||||
|
||||
In this example it will run telnet through proxy(or chained proxies) specified by proxybound.conf
|
||||
|
||||
```
|
||||
$ proxybound telnet targethost.com
|
||||
```
|
||||
|
||||
In this example it will use different configuration file then proxybound.conf to connect to targethost2.com host.
|
||||
|
||||
```
|
||||
$ proxybound -f /etc/proxybound-other.conf targethost2.com
|
||||
```
|
||||
|
||||
In this example it will resolve targethost.com through proxy(or chained proxies) specified by proxybound.conf
|
||||
|
||||
```
|
||||
$ proxyresolv targethost.com
|
||||
```
|
36
src/core.c
36
src/core.c
@@ -21,7 +21,6 @@
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include <sys/utsname.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
@@ -34,22 +33,23 @@
|
||||
#include <sys/time.h>
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
#include "core.h"
|
||||
#include "common.h"
|
||||
|
||||
#ifdef THREAD_SAFE
|
||||
#include <pthread.h>
|
||||
pthread_mutex_t internal_ips_lock;
|
||||
pthread_mutex_t hostdb_lock;
|
||||
#endif
|
||||
|
||||
#include "core.h"
|
||||
#include "common.h"
|
||||
|
||||
extern int tcp_read_time_out;
|
||||
extern int tcp_connect_time_out;
|
||||
extern int proxybound_quiet_mode;
|
||||
extern unsigned int remote_dns_subnet;
|
||||
|
||||
internal_ip_lookup_table internal_ips = { 0, 0, NULL };
|
||||
extern ip_type hostsreader_get_numeric_ip_for_name(const char* name);
|
||||
|
||||
internal_ip_lookup_table internal_ips = { 0, 0, NULL };
|
||||
|
||||
uint32_t dalias_hash(char *s0) {
|
||||
unsigned char *s = (void *) s0;
|
||||
@@ -254,7 +254,6 @@ static int timed_connect(int sock, const struct sockaddr *addr, socklen_t len) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
#define INVALID_INDEX 0xFFFFFFFFU
|
||||
static int tunnel_to(int sock, ip_type ip, unsigned short port, proxy_type pt, char *user, char *pass) {
|
||||
char *dns_name = NULL;
|
||||
@@ -595,7 +594,6 @@ static unsigned int calc_alive(proxy_data * pd, unsigned int proxy_count) {
|
||||
return alive_count;
|
||||
}
|
||||
|
||||
|
||||
static int chain_step(int ns, proxy_data * pfrom, proxy_data * pto) {
|
||||
int retcode = -1;
|
||||
char *hostname;
|
||||
@@ -749,8 +747,6 @@ int connect_proxy_chain(int sock, ip_type target_ip,
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const ip_type local_host = { {127, 0, 0, 1} };
|
||||
|
||||
static void gethostbyname_data_setstring(struct gethostbyname_data* data, char* name) {
|
||||
snprintf(data->addr_name, sizeof(data->addr_name), "%s", name);
|
||||
data->hostent_space.h_name = data->addr_name;
|
||||
@@ -763,8 +759,6 @@ struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data*
|
||||
void *new_mem;
|
||||
size_t l;
|
||||
|
||||
struct hostent *hp;
|
||||
|
||||
data->resolved_addr_p[0] = (char *) &data->resolved_addr;
|
||||
data->resolved_addr_p[1] = NULL;
|
||||
|
||||
@@ -781,7 +775,7 @@ struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data*
|
||||
if(!strcmp(buff, name)) {
|
||||
data->resolved_addr = inet_addr(buff);
|
||||
if(data->resolved_addr == (in_addr_t) (-1))
|
||||
data->resolved_addr = (in_addr_t) (local_host.as_int);
|
||||
data->resolved_addr = (in_addr_t) (ip_type_localhost.as_int);
|
||||
goto retname;
|
||||
}
|
||||
|
||||
@@ -789,16 +783,16 @@ struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data*
|
||||
|
||||
// this iterates over the "known hosts" db, usually /etc/hosts
|
||||
MUTEX_LOCK(&hostdb_lock);
|
||||
while((hp = gethostent()))
|
||||
if(!strcmp(hp->h_name, name) && hp->h_addrtype == AF_INET && hp->h_length == sizeof(in_addr_t)) {
|
||||
data->resolved_addr = *((in_addr_t*)(hp->h_addr_list[0]));
|
||||
ip_type hdb_res = hostsreader_get_numeric_ip_for_name(name);
|
||||
//ip_type hdb_res = hdb_get(&hl, (char*) name);
|
||||
if(hdb_res.as_int != ip_type_invalid.as_int) {
|
||||
data->resolved_addr = hdb_res.as_int;
|
||||
MUTEX_UNLOCK(&hostdb_lock);
|
||||
goto retname;
|
||||
}
|
||||
|
||||
MUTEX_UNLOCK(&hostdb_lock);
|
||||
|
||||
hash = dalias_hash((char *) name);
|
||||
|
||||
MUTEX_LOCK(&internal_ips_lock);
|
||||
|
||||
// see if we already have this dns entry saved.
|
||||
@@ -811,6 +805,7 @@ struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data*
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// grow list if needed.
|
||||
if(internal_ips.capa < internal_ips.counter + 1) {
|
||||
PDEBUG("realloc\n");
|
||||
@@ -819,6 +814,7 @@ struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data*
|
||||
internal_ips.capa += 16;
|
||||
internal_ips.list = new_mem;
|
||||
} else {
|
||||
// goto ------------
|
||||
oom:
|
||||
proxybound_write_log("out of mem\n");
|
||||
goto err_plus_unlock;
|
||||
@@ -844,16 +840,16 @@ struct hostent *proxy_gethostbyname(const char *name, struct gethostbyname_data*
|
||||
|
||||
internal_ips.counter += 1;
|
||||
|
||||
// goto ------------
|
||||
have_ip:
|
||||
|
||||
MUTEX_UNLOCK(&internal_ips_lock);
|
||||
|
||||
// goto ------------
|
||||
retname:
|
||||
|
||||
gethostbyname_data_setstring(data, (char*) name);
|
||||
|
||||
return &data->hostent_space;
|
||||
|
||||
// goto ------------
|
||||
err_plus_unlock:
|
||||
MUTEX_UNLOCK(&internal_ips_lock);
|
||||
return NULL;
|
||||
|
@@ -20,17 +20,13 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include "ip-type.h"
|
||||
|
||||
#ifndef __CORE_HEADER
|
||||
#define __CORE_HEADER
|
||||
#define BUFF_SIZE 8*1024 // used to read responses from proxies.
|
||||
#define MAX_LOCALNET 64
|
||||
|
||||
typedef union {
|
||||
unsigned char octet[4];
|
||||
uint32_t as_int;
|
||||
} ip_type;
|
||||
|
||||
typedef struct {
|
||||
uint32_t hash;
|
||||
char* string;
|
||||
|
110
src/hostsreader.c
Normal file
110
src/hostsreader.c
Normal file
@@ -0,0 +1,110 @@
|
||||
/* simple reader for /etc/hosts
|
||||
it only supports comments, blank lines and lines consisting of an ipv4 hostname pair.
|
||||
this is required so we can return entries from the host db without messing up the
|
||||
non-thread-safe state of libc's gethostent(). */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "ip-type.h"
|
||||
|
||||
struct hostsreader {
|
||||
FILE *f;
|
||||
char* ip, *name;
|
||||
};
|
||||
|
||||
int hostsreader_open(struct hostsreader *ctx) {
|
||||
if(!(ctx->f = fopen("/etc/hosts", "r"))) return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void hostsreader_close(struct hostsreader *ctx) {
|
||||
fclose(ctx->f);
|
||||
}
|
||||
|
||||
static int isnumericipv4(const char* ipstring);
|
||||
int hostsreader_get(struct hostsreader *ctx, char* buf, size_t bufsize) {
|
||||
while(1) {
|
||||
if(!fgets(buf, bufsize, ctx->f)) return 0;
|
||||
if(*buf == '#') continue;
|
||||
char *p = buf;
|
||||
size_t l = bufsize;
|
||||
ctx->ip = p;
|
||||
while(*p && !isspace(*p) && l) {
|
||||
p++;
|
||||
l--;
|
||||
}
|
||||
if(!l || !*p || p == ctx->ip) continue;
|
||||
*p = 0;
|
||||
p++;
|
||||
while(*p && isspace(*p) && l) {
|
||||
p++;
|
||||
l--;
|
||||
}
|
||||
if(!l || !*p) continue;
|
||||
ctx->name = p;
|
||||
while(*p && !isspace(*p) && l) {
|
||||
p++;
|
||||
l--;
|
||||
}
|
||||
if(!l || !*p) continue;
|
||||
*p = 0;
|
||||
if(isnumericipv4(ctx->ip)) return 1;
|
||||
}
|
||||
}
|
||||
|
||||
char* hostsreader_get_ip_for_name(const char* name, char* buf, size_t bufsize) {
|
||||
struct hostsreader ctx;
|
||||
char *res = 0;
|
||||
if(!hostsreader_open(&ctx)) return 0;
|
||||
while(hostsreader_get(&ctx, buf, bufsize)) {
|
||||
if(!strcmp(ctx.name, name)) {
|
||||
res = ctx.ip;
|
||||
break;
|
||||
}
|
||||
}
|
||||
hostsreader_close(&ctx);
|
||||
return res;
|
||||
}
|
||||
|
||||
ip_type hostsreader_get_numeric_ip_for_name(const char* name) {
|
||||
char *hres;
|
||||
char buf[320];
|
||||
if((hres = hostsreader_get_ip_for_name(name, buf, sizeof buf))) {
|
||||
struct in_addr c;
|
||||
inet_aton(hres, &c);
|
||||
ip_type res;
|
||||
memcpy(res.octet, &c.s_addr, 4);
|
||||
return res;
|
||||
} else return ip_type_invalid;
|
||||
}
|
||||
|
||||
/* isnumericipv4() taken from libulz */
|
||||
static int isnumericipv4(const char* ipstring) {
|
||||
size_t x = 0, n = 0, d = 0;
|
||||
int wasdot = 0;
|
||||
while(1) {
|
||||
switch(ipstring[x]) {
|
||||
case 0: goto done;
|
||||
case '.':
|
||||
if(!n || wasdot) return 0;
|
||||
d++;
|
||||
wasdot = 1;
|
||||
break;
|
||||
case '0': case '1': case '2': case '3': case '4':
|
||||
case '5': case '6': case '7': case '8': case '9':
|
||||
n++;
|
||||
wasdot = 0;
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
x++;
|
||||
}
|
||||
done:
|
||||
if(d == 3 && n >= 4 && n <= 12) return 1;
|
||||
return 0;
|
||||
}
|
28
src/ip-type.h
Normal file
28
src/ip-type.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#include <stdint.h>
|
||||
|
||||
typedef union {
|
||||
unsigned char octet[4];
|
||||
uint32_t as_int;
|
||||
} ip_type;
|
||||
|
||||
const ip_type ip_type_invalid = { .as_int = -1 };
|
||||
const ip_type ip_type_localhost = { {127, 0, 0, 1} };
|
||||
|
||||
// Definition for ipv6
|
||||
/*
|
||||
typedef union {
|
||||
unsigned char octet[4];
|
||||
uint32_t as_int;
|
||||
} ip_type4;
|
||||
|
||||
typedef struct {
|
||||
union {
|
||||
ip_type4 v4;
|
||||
unsigned char v6[16];
|
||||
} addr;
|
||||
char is_v6;
|
||||
} ip_type;
|
||||
|
||||
const ip_type ip_type_invalid = { .addr.v4.as_int = -1 };
|
||||
const ip_type ip_type_localhost = { .addr.v4.octet = {127, 0, 0, 1} };
|
||||
*/
|
Reference in New Issue
Block a user