mirror of
https://github.com/ValdikSS/GoodbyeDPI.git
synced 2024-12-22 14:26:08 +00:00
OpenVPN detection & fragmentation/fake packet support
This commit is contained in:
parent
4f18a73239
commit
ecc681a60b
@ -19,7 +19,7 @@ CFLAGS = -std=c99 -pie -fPIE -pipe -I$(WINDIVERTHEADERS) -L$(WINDIVERTLIBS) \
|
|||||||
-Wnull-dereference -Warray-bounds=2 -Wimplicit-fallthrough=3 \
|
-Wnull-dereference -Warray-bounds=2 -Wimplicit-fallthrough=3 \
|
||||||
-Wstringop-overflow=4 \
|
-Wstringop-overflow=4 \
|
||||||
-Wformat-signedness -Wstrict-overflow=2 -Wcast-align=strict \
|
-Wformat-signedness -Wstrict-overflow=2 -Wcast-align=strict \
|
||||||
-Wfloat-equal -Wcast-align -Wsign-conversion \
|
-Wfloat-equal -Wcast-align -Wsign-conversion -Wno-stringop-overflow -Wno-stringop-overread \
|
||||||
#-fstack-protector-strong
|
#-fstack-protector-strong
|
||||||
LDFLAGS = -fstack-protector -Wl,-O1,-pie,--dynamicbase,--nxcompat,--sort-common,--as-needed \
|
LDFLAGS = -fstack-protector -Wl,-O1,-pie,--dynamicbase,--nxcompat,--sort-common,--as-needed \
|
||||||
-Wl,--image-base,0x140000000 -Wl,--disable-auto-image-base
|
-Wl,--image-base,0x140000000 -Wl,--disable-auto-image-base
|
||||||
|
@ -171,6 +171,7 @@ static struct option long_options[] = {
|
|||||||
{"native-frag", no_argument, 0, '*' },
|
{"native-frag", no_argument, 0, '*' },
|
||||||
{"reverse-frag",no_argument, 0, '(' },
|
{"reverse-frag",no_argument, 0, '(' },
|
||||||
{"max-payload", optional_argument, 0, '|' },
|
{"max-payload", optional_argument, 0, '|' },
|
||||||
|
{"openvpn", no_argument, 0, '#' },
|
||||||
{0, 0, 0, 0 }
|
{0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -433,6 +434,16 @@ static int extract_sni(const char *pktdata, unsigned int pktlen,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int is_openvpn_handshake(const char *pktdata, unsigned int pktlen) {
|
||||||
|
/*
|
||||||
|
* 0x38 is P_CONTROL_HARD_RESET_CLIENT_V2 + peer_id(0),
|
||||||
|
* 0x50 is P_CONTROL_HARD_RESET_CLIENT_V3 + peer_id(0)
|
||||||
|
*/
|
||||||
|
return pktlen >= 16
|
||||||
|
&& ntohs(((uint16_t*)pktdata)[0]) == pktlen - 2
|
||||||
|
&& (pktdata[2] == '\x38' || pktdata[2] == '\x50');
|
||||||
|
}
|
||||||
|
|
||||||
static inline void change_window_size(const PWINDIVERT_TCPHDR ppTcpHdr, unsigned int size) {
|
static inline void change_window_size(const PWINDIVERT_TCPHDR ppTcpHdr, unsigned int size) {
|
||||||
if (size >= 1 && size <= 0xFFFFu) {
|
if (size >= 1 && size <= 0xFFFFu) {
|
||||||
ppTcpHdr->Window = htons((u_short)size);
|
ppTcpHdr->Window = htons((u_short)size);
|
||||||
@ -543,6 +554,7 @@ int main(int argc, char *argv[]) {
|
|||||||
} packet_type;
|
} packet_type;
|
||||||
int i, should_reinject, should_recalc_checksum = 0;
|
int i, should_reinject, should_recalc_checksum = 0;
|
||||||
int sni_ok = 0;
|
int sni_ok = 0;
|
||||||
|
int openvpn_handshake = 0;
|
||||||
int opt;
|
int opt;
|
||||||
int packet_v4, packet_v6;
|
int packet_v4, packet_v6;
|
||||||
HANDLE w_filter = NULL;
|
HANDLE w_filter = NULL;
|
||||||
@ -569,6 +581,7 @@ int main(int argc, char *argv[]) {
|
|||||||
do_dns_verb = 0, do_tcp_verb = 0, do_blacklist = 0,
|
do_dns_verb = 0, do_tcp_verb = 0, do_blacklist = 0,
|
||||||
do_allow_no_sni = 0,
|
do_allow_no_sni = 0,
|
||||||
do_fake_packet = 0,
|
do_fake_packet = 0,
|
||||||
|
do_openvpn = 0,
|
||||||
do_auto_ttl = 0,
|
do_auto_ttl = 0,
|
||||||
do_wrong_chksum = 0,
|
do_wrong_chksum = 0,
|
||||||
do_wrong_seq = 0,
|
do_wrong_seq = 0,
|
||||||
@ -849,6 +862,9 @@ int main(int argc, char *argv[]) {
|
|||||||
free(autottl_copy);
|
free(autottl_copy);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case '#': // --openvpn
|
||||||
|
do_openvpn = 1;
|
||||||
|
break;
|
||||||
case '%': // --wrong-chksum
|
case '%': // --wrong-chksum
|
||||||
do_fake_packet = 1;
|
do_fake_packet = 1;
|
||||||
do_wrong_chksum = 1;
|
do_wrong_chksum = 1;
|
||||||
@ -924,6 +940,7 @@ int main(int argc, char *argv[]) {
|
|||||||
" (like file transfers) in already established sessions.\n"
|
" (like file transfers) in already established sessions.\n"
|
||||||
" May skip some huge HTTP requests from being processed.\n"
|
" May skip some huge HTTP requests from being processed.\n"
|
||||||
" Default (if set): --max-payload 1200.\n"
|
" Default (if set): --max-payload 1200.\n"
|
||||||
|
" --openvpn Detect OpenVPN TCP and fragment/send fake packet.\n"
|
||||||
"\n");
|
"\n");
|
||||||
puts("LEGACY modesets:\n"
|
puts("LEGACY modesets:\n"
|
||||||
" -1 -p -r -s -f 2 -k 2 -n -e 2 (most compatible mode)\n"
|
" -1 -p -r -s -f 2 -k 2 -n -e 2 (most compatible mode)\n"
|
||||||
@ -971,7 +988,8 @@ int main(int argc, char *argv[]) {
|
|||||||
"Fake requests, TTL: %s (fixed: %hu, auto: %hu-%hu-%hu, min distance: %hu)\n" /* 16 */
|
"Fake requests, TTL: %s (fixed: %hu, auto: %hu-%hu-%hu, min distance: %hu)\n" /* 16 */
|
||||||
"Fake requests, wrong checksum: %d\n" /* 17 */
|
"Fake requests, wrong checksum: %d\n" /* 17 */
|
||||||
"Fake requests, wrong SEQ/ACK: %d\n" /* 18 */
|
"Fake requests, wrong SEQ/ACK: %d\n" /* 18 */
|
||||||
"Max payload size: %hu\n", /* 19 */
|
"Max payload size: %hu\n" /* 19 */
|
||||||
|
"OpenVPN: %d\n", /* 20 */
|
||||||
do_passivedpi, /* 1 */
|
do_passivedpi, /* 1 */
|
||||||
(do_fragment_http ? http_fragment_size : 0), /* 2 */
|
(do_fragment_http ? http_fragment_size : 0), /* 2 */
|
||||||
(do_fragment_http_persistent ? http_fragment_size : 0),/* 3 */
|
(do_fragment_http_persistent ? http_fragment_size : 0),/* 3 */
|
||||||
@ -992,7 +1010,8 @@ int main(int argc, char *argv[]) {
|
|||||||
do_auto_ttl ? auto_ttl_max : 0, ttl_min_nhops,
|
do_auto_ttl ? auto_ttl_max : 0, ttl_min_nhops,
|
||||||
do_wrong_chksum, /* 17 */
|
do_wrong_chksum, /* 17 */
|
||||||
do_wrong_seq, /* 18 */
|
do_wrong_seq, /* 18 */
|
||||||
max_payload_size /* 19 */
|
max_payload_size, /* 19 */
|
||||||
|
do_openvpn /* 20 */
|
||||||
);
|
);
|
||||||
|
|
||||||
if (do_fragment_http && http_fragment_size > 2 && !do_native_frag) {
|
if (do_fragment_http && http_fragment_size > 2 && !do_native_frag) {
|
||||||
@ -1119,7 +1138,7 @@ int main(int argc, char *argv[]) {
|
|||||||
*/
|
*/
|
||||||
else if (addr.Outbound &&
|
else if (addr.Outbound &&
|
||||||
((do_fragment_https ? packet_dataLen == https_fragment_size : 0) ||
|
((do_fragment_https ? packet_dataLen == https_fragment_size : 0) ||
|
||||||
packet_dataLen > 16) &&
|
packet_dataLen >= 16) &&
|
||||||
ppTcpHdr->DstPort != htons(80) &&
|
ppTcpHdr->DstPort != htons(80) &&
|
||||||
(do_fake_packet || do_native_frag)
|
(do_fake_packet || do_native_frag)
|
||||||
)
|
)
|
||||||
@ -1129,7 +1148,9 @@ int main(int argc, char *argv[]) {
|
|||||||
* But if the packet is more than 2 bytes, check ClientHello byte.
|
* But if the packet is more than 2 bytes, check ClientHello byte.
|
||||||
*/
|
*/
|
||||||
if ((packet_dataLen == 2 && memcmp(packet_data, "\x16\x03", 2) == 0) ||
|
if ((packet_dataLen == 2 && memcmp(packet_data, "\x16\x03", 2) == 0) ||
|
||||||
(packet_dataLen >= 3 && memcmp(packet_data, "\x16\x03\x01", 3) == 0))
|
(packet_dataLen >= 3 && memcmp(packet_data, "\x16\x03\x01", 3) == 0) ||
|
||||||
|
(do_openvpn && (openvpn_handshake = is_openvpn_handshake(packet_data, packet_dataLen)))
|
||||||
|
)
|
||||||
{
|
{
|
||||||
if (do_blacklist) {
|
if (do_blacklist) {
|
||||||
sni_ok = extract_sni(packet_data, packet_dataLen,
|
sni_ok = extract_sni(packet_data, packet_dataLen,
|
||||||
@ -1140,6 +1161,7 @@ int main(int argc, char *argv[]) {
|
|||||||
blackwhitelist_check_hostname(host_addr, host_len)
|
blackwhitelist_check_hostname(host_addr, host_len)
|
||||||
) ||
|
) ||
|
||||||
(do_blacklist && !sni_ok && do_allow_no_sni) ||
|
(do_blacklist && !sni_ok && do_allow_no_sni) ||
|
||||||
|
(do_openvpn && openvpn_handshake) ||
|
||||||
(!do_blacklist)
|
(!do_blacklist)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user