mirror of
https://github.com/matrix-construct/construct
synced 2024-11-16 23:10:54 +01:00
Add HTTP CONNECT proxy scanning
This commit is contained in:
parent
bccb7dedef
commit
fabe8b94c5
4 changed files with 89 additions and 6 deletions
|
@ -32,6 +32,7 @@ typedef enum protocol_t
|
||||||
PROTO_NONE,
|
PROTO_NONE,
|
||||||
PROTO_SOCKS4,
|
PROTO_SOCKS4,
|
||||||
PROTO_SOCKS5,
|
PROTO_SOCKS5,
|
||||||
|
PROTO_HTTP_CONNECT,
|
||||||
} protocol_t;
|
} protocol_t;
|
||||||
|
|
||||||
struct opm_lookup
|
struct opm_lookup
|
||||||
|
@ -88,12 +89,14 @@ static bool opm_enable = false;
|
||||||
static struct opm_listener listeners[2];
|
static struct opm_listener listeners[2];
|
||||||
|
|
||||||
static inline protocol_t
|
static inline protocol_t
|
||||||
get_protocol_from_string(const char *string)
|
get_protocol_from_string(const char *str)
|
||||||
{
|
{
|
||||||
if(strcasecmp(string, "socks4") == 0)
|
if(strcasecmp(str, "socks4") == 0)
|
||||||
return PROTO_SOCKS4;
|
return PROTO_SOCKS4;
|
||||||
else if(strcasecmp(string, "socks5") == 0)
|
else if(strcasecmp(str, "socks5") == 0)
|
||||||
return PROTO_SOCKS5;
|
return PROTO_SOCKS5;
|
||||||
|
else if(strcasecmp(str, "httpconnect") == 0)
|
||||||
|
return PROTO_HTTP_CONNECT;
|
||||||
else
|
else
|
||||||
return PROTO_NONE;
|
return PROTO_NONE;
|
||||||
}
|
}
|
||||||
|
@ -145,7 +148,7 @@ read_opm_reply(rb_fde_t *F, void *data)
|
||||||
{
|
{
|
||||||
struct opm_proxy *proxy = ptr->data;
|
struct opm_proxy *proxy = ptr->data;
|
||||||
|
|
||||||
if(strncmp(proxy->note, readbuf, sizeof(readbuf)) == 0)
|
if(strncmp(proxy->note, readbuf, strlen(proxy->note)) == 0)
|
||||||
{
|
{
|
||||||
rb_dlink_node *ptr, *nptr;
|
rb_dlink_node *ptr, *nptr;
|
||||||
|
|
||||||
|
@ -293,7 +296,7 @@ static void
|
||||||
socks5_connected(rb_fde_t *F, int error, void *data)
|
socks5_connected(rb_fde_t *F, int error, void *data)
|
||||||
{
|
{
|
||||||
struct opm_scan *scan = data;
|
struct opm_scan *scan = data;
|
||||||
struct opm_lookup *lookup;
|
struct opm_lookup *lookup;
|
||||||
struct opm_listener *listener;
|
struct opm_listener *listener;
|
||||||
struct auth_client *auth;
|
struct auth_client *auth;
|
||||||
uint8_t sendbuf[25]; /* Size we're building */
|
uint8_t sendbuf[25]; /* Size we're building */
|
||||||
|
@ -307,7 +310,7 @@ socks5_connected(rb_fde_t *F, int error, void *data)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
/* Build the version header and socks request
|
/* Build the version header and socks request
|
||||||
* version header (3 bytes): version, number of auth methods, auth type (0 for none)
|
* version header (3 bytes): version, number of auth methods, auth type (0 for none)
|
||||||
* connect req (3 bytes): version, command (1 = connect), reserved (0)
|
* connect req (3 bytes): version, command (1 = connect), reserved (0)
|
||||||
*/
|
*/
|
||||||
memcpy(c, "\x05\x01\x00\x05\x01\x00", 6); c += 6;
|
memcpy(c, "\x05\x01\x00\x05\x01\x00", 6); c += 6;
|
||||||
|
@ -352,6 +355,62 @@ end:
|
||||||
rb_free(scan);
|
rb_free(scan);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
http_connect_connected(rb_fde_t *F, int error, void *data)
|
||||||
|
{
|
||||||
|
struct opm_scan *scan = data;
|
||||||
|
struct opm_lookup *lookup;
|
||||||
|
struct opm_listener *listener;
|
||||||
|
struct auth_client *auth;
|
||||||
|
char sendbuf[128]; /* A bit bigger than we need but better safe than sorry */
|
||||||
|
char *c = sendbuf;
|
||||||
|
ssize_t ret;
|
||||||
|
|
||||||
|
if(scan == NULL || (auth = scan->auth) == NULL || (lookup = auth->data[PROVIDER_OPM]) == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(error || !opm_enable)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
switch(GET_SS_FAMILY(&auth->c_addr))
|
||||||
|
{
|
||||||
|
case AF_INET:
|
||||||
|
listener = &listeners[LISTEN_IPV4];
|
||||||
|
if(!listener->F)
|
||||||
|
goto end;
|
||||||
|
break;
|
||||||
|
#ifdef RB_IPV6
|
||||||
|
case AF_INET6:
|
||||||
|
listener = &listeners[LISTEN_IPV6];
|
||||||
|
if(!listener->F)
|
||||||
|
goto end;
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Simple enough to build */
|
||||||
|
snprintf(sendbuf, sizeof(sendbuf), "CONNECT %s:%hu HTTP/1.0\r\n\r\n", listener->ip, listener->port);
|
||||||
|
|
||||||
|
/* Send request */
|
||||||
|
if(rb_write(scan->F, sendbuf, strlen(sendbuf)) <= 0)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
/* Now the note in a separate write */
|
||||||
|
if(rb_write(scan->F, scan->proxy->note, strlen(scan->proxy->note) + 1) <= 0)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
/* MiroTik needs this, and as a separate write */
|
||||||
|
if(rb_write(scan->F, "\r\n", 2) <= 0)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
end:
|
||||||
|
rb_close(scan->F);
|
||||||
|
rb_dlinkDelete(&scan->node, &lookup->scans);
|
||||||
|
rb_free(scan);
|
||||||
|
}
|
||||||
|
|
||||||
/* Establish connections */
|
/* Establish connections */
|
||||||
static inline void
|
static inline void
|
||||||
establish_connection(struct auth_client *auth, struct opm_proxy *proxy)
|
establish_connection(struct auth_client *auth, struct opm_proxy *proxy)
|
||||||
|
@ -378,6 +437,8 @@ establish_connection(struct auth_client *auth, struct opm_proxy *proxy)
|
||||||
case PROTO_SOCKS5:
|
case PROTO_SOCKS5:
|
||||||
callback = socks5_connected;
|
callback = socks5_connected;
|
||||||
break;
|
break;
|
||||||
|
case PROTO_HTTP_CONNECT:
|
||||||
|
callback = http_connect_connected;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -697,6 +758,9 @@ create_opm_scanner(const char *key __unused, int parc __unused, const char **par
|
||||||
case PROTO_SOCKS5:
|
case PROTO_SOCKS5:
|
||||||
snprintf(proxy->note, sizeof(proxy->note), "socks5:%hu", proxy->port);
|
snprintf(proxy->note, sizeof(proxy->note), "socks5:%hu", proxy->port);
|
||||||
break;
|
break;
|
||||||
|
case PROTO_HTTP_CONNECT:
|
||||||
|
snprintf(proxy->note, sizeof(proxy->note), "httpconnect:%hu", proxy->port);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
warn_opers(L_CRIT, "OPM: got an unknown proxy type: %s (port %hu)", parv[0], proxy->port);
|
warn_opers(L_CRIT, "OPM: got an unknown proxy type: %s (port %hu)", parv[0], proxy->port);
|
||||||
exit(EX_PROVIDER_ERROR);
|
exit(EX_PROVIDER_ERROR);
|
||||||
|
|
|
@ -475,6 +475,12 @@ opm {
|
||||||
* with other scan types. Sensible defaults are given below.
|
* with other scan types. Sensible defaults are given below.
|
||||||
*/
|
*/
|
||||||
socks5_ports = 1080, 10800, 443, 80, 8080, 8000;
|
socks5_ports = 1080, 10800, 443, 80, 8080, 8000;
|
||||||
|
|
||||||
|
/* These are the ports to scan for HTTP connect proxies on (plaintext).
|
||||||
|
* They may overlap with other scan types. Sensible defaults are given
|
||||||
|
* below.
|
||||||
|
*/
|
||||||
|
httpconnect_ports = 80, 8080, 8000;
|
||||||
};
|
};
|
||||||
|
|
||||||
alias "NickServ" {
|
alias "NickServ" {
|
||||||
|
|
|
@ -950,6 +950,12 @@ opm {
|
||||||
* with other scan types. Sensible defaults are given below.
|
* with other scan types. Sensible defaults are given below.
|
||||||
*/
|
*/
|
||||||
socks5_ports = 80, 443, 1080, 8000, 8080, 10800;
|
socks5_ports = 80, 443, 1080, 8000, 8080, 10800;
|
||||||
|
|
||||||
|
/* These are the ports to scan for HTTP connect proxies on (plaintext).
|
||||||
|
* They may overlap with other scan types. Sensible defaults are given
|
||||||
|
* below.
|
||||||
|
*/
|
||||||
|
httpconnect_ports = 80, 8080, 8000;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -2290,6 +2290,12 @@ conf_set_opm_scan_ports_socks5(void *data)
|
||||||
conf_set_opm_scan_ports_all(data, "opm::socks5_ports", "socks5");
|
conf_set_opm_scan_ports_all(data, "opm::socks5_ports", "socks5");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
conf_set_opm_scan_ports_httpconnect(void *data)
|
||||||
|
{
|
||||||
|
conf_set_opm_scan_ports_all(data, "opm::httpconnect_ports", "httpconnect");
|
||||||
|
}
|
||||||
|
|
||||||
/* public functions */
|
/* public functions */
|
||||||
|
|
||||||
|
|
||||||
|
@ -2828,4 +2834,5 @@ newconf_init()
|
||||||
add_conf_item("opm", "listen_port", CF_INT, conf_set_opm_listen_port);
|
add_conf_item("opm", "listen_port", CF_INT, conf_set_opm_listen_port);
|
||||||
add_conf_item("opm", "socks4_ports", CF_INT | CF_FLIST, conf_set_opm_scan_ports_socks4);
|
add_conf_item("opm", "socks4_ports", CF_INT | CF_FLIST, conf_set_opm_scan_ports_socks4);
|
||||||
add_conf_item("opm", "socks5_ports", CF_INT | CF_FLIST, conf_set_opm_scan_ports_socks5);
|
add_conf_item("opm", "socks5_ports", CF_INT | CF_FLIST, conf_set_opm_scan_ports_socks5);
|
||||||
|
add_conf_item("opm", "httpconnect_ports", CF_INT | CF_FLIST, conf_set_opm_scan_ports_httpconnect);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue