10 Commits

Author SHA1 Message Date
ValdikSS
c4d0ba1297 Skip impostor and loopback packets. Fixes #53. 2018-07-24 15:49:50 +03:00
ValdikSS
d6c2b825aa Update README.md 2018-07-20 16:37:19 +03:00
ValdikSS
aad03f2e4a Enable PIE, High Entropy ASLR and add more warnings to Makefile 2018-07-19 21:31:38 +03:00
ValdikSS
a028cb01f4 WinDivert 1.4 support 2018-07-19 21:31:38 +03:00
ValdikSS
38b1ff1a92 Fix -f and -e options 2018-07-19 21:31:37 +03:00
ValdikSS
3bd92d67ac Merge pull request #83 from KOLANICH/editorconfig
Added .editorconfig
2018-06-26 22:08:15 +03:00
KOLANICH
464bbcbb6b Added .editorconfig 2018-05-16 18:35:31 +03:00
ValdikSS
50e70ace76 Handle HTTP redirects within IPv6 Flow Label = 0x00 packets 2018-02-17 18:26:16 +03:00
ValdikSS
135c97ae69 Move program source code to src directory 2018-02-17 15:22:38 +03:00
ValdikSS
c377119136 Update README.md 2018-02-17 15:21:51 +03:00
20 changed files with 116 additions and 69 deletions

8
.editorconfig Normal file
View File

@@ -0,0 +1,8 @@
root = true
[*]
charset = utf-8
indent_style = space
indent_size = 4
insert_final_newline = true
end_of_line = lf

View File

@@ -1,37 +0,0 @@
ifndef MSYSTEM
CPREFIX = x86_64-w64-mingw32-
endif
WINDIVERTHEADERS = ../../include
WINDIVERTLIBS = ../binary
TARGET = goodbyedpi.exe
LIBS = -L$(WINDIVERTLIBS) -lWinDivert -lws2_32
CC = $(CPREFIX)gcc
CCWINDRES = $(CPREFIX)windres
CFLAGS = -Wall -Wextra -I$(WINDIVERTHEADERS) -L$(WINDIVERTLIBS) \
-O2 -pie -fPIE -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2
LDFLAGS = -Wl,-O1,--sort-common,--as-needed
.PHONY: default all clean
default: manifest $(TARGET)
all: default
OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c)) goodbyedpi-rc.o
HEADERS = $(wildcard *.h)
%.o: %.c $(HEADERS)
$(CC) $(CFLAGS) -c $< -o $@
manifest:
$(CCWINDRES) goodbyedpi-rc.rc goodbyedpi-rc.o
.PRECIOUS: $(TARGET) $(OBJECTS)
$(TARGET): $(OBJECTS)
$(CC) $(OBJECTS) -Wall $(LDFLAGS) $(LIBS) -s -o $@
clean:
-rm -f *.o
-rm -f $(TARGET)

View File

@@ -28,6 +28,8 @@ Usage: goodbyedpi.exe [OPTION...]
This option can be supplied multiple times. This option can be supplied multiple times.
--dns-addr [value] redirect UDP DNS requests to the supplied IP address (experimental) --dns-addr [value] redirect UDP DNS requests to the supplied IP address (experimental)
--dns-port [value] redirect UDP DNS requests to the supplied port (53 by default) --dns-port [value] redirect UDP DNS requests to the supplied port (53 by default)
--dnsv6-addr [value] redirect UDPv6 DNS requests to the supplied IPv6 address (experimental)
--dnsv6-port [value] redirect UDPv6 DNS requests to the supplied port (53 by default)
--dns-verb print verbose DNS redirection messages --dns-verb print verbose DNS redirection messages
--blacklist [txtfile] perform HTTP tricks only to host names and subdomains from --blacklist [txtfile] perform HTTP tricks only to host names and subdomains from
supplied text file. This option can be supplied multiple times. supplied text file. This option can be supplied multiple times.
@@ -77,13 +79,20 @@ To build x86 exe run:
And for x86_64: And for x86_64:
`make CPREFIX=x86_64-w64-mingw32- WINDIVERTHEADERS=/path/to/windivert/include WINDIVERTLIBS=/path/to/windivert/amd64` `make CPREFIX=x86_64-w64-mingw32- BIT64=1 WINDIVERTHEADERS=/path/to/windivert/include WINDIVERTLIBS=/path/to/windivert/amd64`
# How to install as Windows Service # How to install as Windows Service
Use `service_install_russia_blacklist.cmd`, `service_install_russia_blacklist_dnsredir.cmd` and `service_remove.cmd` scripts. Use `service_install_russia_blacklist.cmd`, `service_install_russia_blacklist_dnsredir.cmd` and `service_remove.cmd` scripts.
Modify them according to your own needs. Modify them according to your own needs.
# Known issues
* Horribly outdated Windows 7 installations are not able to load WinDivert driver due to missing support for SHA256 digital signatures. Install [KB3033929](https://www.microsoft.com/en-us/download/details.aspx?id=46078), or better, update the whole system using Windows Update.
* DNS redirection doesn't work with MalwareBytes Web Protection enabled. Bug: [#53](https://github.com/ValdikSS/GoodbyeDPI/issues/53).
* Some SSL/TLS stacks unable to process fragmented ClientHello packets, and HTTPS websites won't open. Bug: [#4](https://github.com/ValdikSS/GoodbyeDPI/issues/4), [#64](https://github.com/ValdikSS/GoodbyeDPI/issues/64).
# Similar projects # Similar projects
[zapret](https://github.com/bol-van/zapret) by @bol-van (for Linux). [zapret](https://github.com/bol-van/zapret) by @bol-van (for Linux).

50
src/Makefile Normal file
View File

@@ -0,0 +1,50 @@
ifndef MSYSTEM
CPREFIX = x86_64-w64-mingw32-
endif
WINDIVERTHEADERS = ../../../include
WINDIVERTLIBS = ../../binary
MINGWLIB = /usr/x86_64-w64-mingw32/lib/
TARGET = goodbyedpi.exe
# Linking SSP does not work for some reason, the executable doesn't start.
#LIBS = -L$(WINDIVERTLIBS) -Wl,-Bstatic -lssp -Wl,-Bdynamic -lWinDivert -lws2_32
LIBS = -L$(WINDIVERTLIBS) -lWinDivert -lws2_32
CC = $(CPREFIX)gcc
CCWINDRES = $(CPREFIX)windres
CFLAGS = -std=c99 -pie -fPIE -pipe -I$(WINDIVERTHEADERS) -L$(WINDIVERTLIBS) \
-O2 -D_FORTIFY_SOURCE=2 \
-Wall -Wextra -Wpedantic -Wformat=2 -Wshadow -Wstrict-aliasing=1 -Werror=format-security \
-Wfloat-equal -Wcast-align -Wsign-conversion \
#-fstack-protector-strong
LDFLAGS = -Wl,-O1,-pie,--dynamicbase,--nxcompat,--sort-common,--as-needed \
-Wl,--image-base,0x140000000 -Wl,--disable-auto-image-base
ifdef BIT64
LDFLAGS += -Wl,--high-entropy-va -Wl,--pic-executable,-e,mainCRTStartup
else
LDFLAGS += -Wl,--pic-executable,-e,_mainCRTStartup
endif
.PHONY: default all clean
default: manifest $(TARGET)
all: default
OBJECTS = $(patsubst %.c, %.o, $(wildcard *.c utils/*.c)) goodbyedpi-rc.o
HEADERS = $(wildcard *.h utils/*.h)
%.o: %.c $(HEADERS)
$(CC) $(CFLAGS) -c $< -o $@
manifest:
$(CCWINDRES) goodbyedpi-rc.rc goodbyedpi-rc.o
.PRECIOUS: $(TARGET) $(OBJECTS)
$(TARGET): $(OBJECTS)
$(CC) $(OBJECTS) $(LDFLAGS) $(LIBS) -s -o $@
clean:
-rm -f *.o utils/*.o
-rm -f $(TARGET)

View File

@@ -8,8 +8,8 @@
#include <windows.h> #include <windows.h>
#include <stdio.h> #include <stdio.h>
#include "goodbyedpi.h" #include "goodbyedpi.h"
#include "uthash.h" #include "utils/uthash.h"
#include "getline.h" #include "utils/getline.h"
typedef struct blackwhitelist_record { typedef struct blackwhitelist_record {
const char *host; const char *host;

View File

@@ -15,7 +15,7 @@
#include <stdio.h> #include <stdio.h>
#include "goodbyedpi.h" #include "goodbyedpi.h"
#include "dnsredir.h" #include "dnsredir.h"
#include "uthash.h" #include "utils/uthash.h"
/* key ('4' for IPv4 or '6' for IPv6 + srcip[16] + srcport[2]) */ /* key ('4' for IPv4 or '6' for IPv6 + srcip[16] + srcport[2]) */
#define UDP_CONNRECORD_KEY_LEN 19 #define UDP_CONNRECORD_KEY_LEN 19

View File

@@ -13,7 +13,7 @@
#include <ws2tcpip.h> #include <ws2tcpip.h>
#include "windivert.h" #include "windivert.h"
#include "goodbyedpi.h" #include "goodbyedpi.h"
#include "repl_str.h" #include "utils/repl_str.h"
#include "service.h" #include "service.h"
#include "dnsredir.h" #include "dnsredir.h"
#include "blackwhitelist.h" #include "blackwhitelist.h"
@@ -59,22 +59,23 @@ WINSOCK_API_LINKAGE INT WSAAPI inet_pton(INT Family, LPCSTR pStringBuf, PVOID pA
/* #IPID# is a template to find&replace */ /* #IPID# is a template to find&replace */
#define IPID_TEMPLATE "#IPID#" #define IPID_TEMPLATE "#IPID#"
#define FILTER_STRING_TEMPLATE \ #define FILTER_STRING_TEMPLATE \
"(tcp and " \ "(tcp and !impostor and !loopback and " \
"(inbound and (" \ "((inbound and (" \
"(" \ "(" \
"(" \ "(" \
"((ip.Id >= 0x0 and ip.Id <= 0xF) " IPID_TEMPLATE \ "(ipv6 or (ip.Id >= 0x0 and ip.Id <= 0xF) " IPID_TEMPLATE \
") and " \ ") and " \
"tcp.SrcPort == 80 and tcp.Ack" \ "tcp.SrcPort == 80 and tcp.Ack" \
") or " \ ") or " \
"((tcp.SrcPort == 80 or tcp.SrcPort == 443) and tcp.Ack and tcp.Syn)" \ "((tcp.SrcPort == 80 or tcp.SrcPort == 443) and tcp.Ack and tcp.Syn)" \
")" \ ")" \
" and (" DIVERT_NO_LOCALNETSv4_SRC " or " DIVERT_NO_LOCALNETSv6_SRC ")) or " \ " and (" DIVERT_NO_LOCALNETSv4_SRC " or " DIVERT_NO_LOCALNETSv6_SRC "))) or " \
"(outbound and " \ "(outbound and " \
"(tcp.DstPort == 80 or tcp.DstPort == 443) and tcp.Ack and " \ "(tcp.DstPort == 80 or tcp.DstPort == 443) and tcp.Ack and " \
"(" DIVERT_NO_LOCALNETSv4_DST " or " DIVERT_NO_LOCALNETSv6_DST "))" \ "(" DIVERT_NO_LOCALNETSv4_DST " or " DIVERT_NO_LOCALNETSv6_DST "))" \
"))" "))"
#define FILTER_PASSIVE_STRING_TEMPLATE "inbound and ip and tcp and " \ #define FILTER_PASSIVE_STRING_TEMPLATE "inbound and ip and tcp and " \
"!impostor and !loopback and " \
"((ip.Id <= 0xF and ip.Id >= 0x0) " IPID_TEMPLATE ") and " \ "((ip.Id <= 0xF and ip.Id >= 0x0) " IPID_TEMPLATE ") and " \
"(tcp.SrcPort == 443 or tcp.SrcPort == 80) and tcp.Rst and " \ "(tcp.SrcPort == 443 or tcp.SrcPort == 80) and tcp.Rst and " \
DIVERT_NO_LOCALNETSv4_SRC DIVERT_NO_LOCALNETSv4_SRC
@@ -131,8 +132,10 @@ static char *filter_string = NULL;
static char *filter_passive_string = NULL; static char *filter_passive_string = NULL;
static void add_filter_str(int proto, int port) { static void add_filter_str(int proto, int port) {
const char *udp = " or (udp and (udp.SrcPort == %d or udp.DstPort == %d))"; const char *udp = " or (udp and !impostor and !loopback and " \
const char *tcp = " or (tcp and (tcp.SrcPort == %d or tcp.DstPort == %d))"; "(udp.SrcPort == %d or udp.DstPort == %d))";
const char *tcp = " or (tcp and !impostor and !loopback and " \
"(tcp.SrcPort == %d or tcp.DstPort == %d))";
char *current_filter = filter_string; char *current_filter = filter_string;
int new_filter_size = strlen(current_filter) + int new_filter_size = strlen(current_filter) +
@@ -351,8 +354,8 @@ int main(int argc, char *argv[]) {
do_host_mixedcase = 0, do_host_mixedcase = 0,
do_dnsv4_redirect = 0, do_dnsv6_redirect = 0, do_dnsv4_redirect = 0, do_dnsv6_redirect = 0,
do_dns_verb = 0, do_blacklist = 0; do_dns_verb = 0, do_blacklist = 0;
unsigned int http_fragment_size = 2; unsigned int http_fragment_size = 0;
unsigned int https_fragment_size = 2; unsigned int https_fragment_size = 0;
uint32_t dnsv4_addr = 0; uint32_t dnsv4_addr = 0;
struct in6_addr dnsv6_addr = {0}; struct in6_addr dnsv6_addr = {0};
struct in6_addr dns_temp_addr = {0}; struct in6_addr dns_temp_addr = {0};
@@ -399,6 +402,7 @@ int main(int argc, char *argv[]) {
if (argc == 1) { if (argc == 1) {
/* enable mode -1 by default */ /* enable mode -1 by default */
http_fragment_size = https_fragment_size = 2;
do_passivedpi = do_host = do_host_removespace \ do_passivedpi = do_host = do_host_removespace \
= do_fragment_http = do_fragment_https \ = do_fragment_http = do_fragment_https \
= do_fragment_http_persistent \ = do_fragment_http_persistent \
@@ -593,6 +597,11 @@ int main(int argc, char *argv[]) {
} }
} }
if (!http_fragment_size)
http_fragment_size = 2;
if (!https_fragment_size)
https_fragment_size = 2;
printf("Block passive: %d, Fragment HTTP: %d, Fragment persistent HTTP: %d, " printf("Block passive: %d, Fragment HTTP: %d, Fragment persistent HTTP: %d, "
"Fragment HTTPS: %d, " "Fragment HTTPS: %d, "
"hoSt: %d, Host no space: %d, Additional space: %d, Mix Host: %d, " "hoSt: %d, Host no space: %d, Additional space: %d, Mix Host: %d, "
@@ -701,9 +710,21 @@ int main(int argc, char *argv[]) {
/* Drop packets from filter with HTTP 30x Redirect */ /* Drop packets from filter with HTTP 30x Redirect */
if (do_passivedpi && is_passivedpi_redirect(packet_data, packet_dataLen)) { if (do_passivedpi && is_passivedpi_redirect(packet_data, packet_dataLen)) {
if (packet_v4) {
//printf("Dropping HTTP Redirect packet!\n"); //printf("Dropping HTTP Redirect packet!\n");
should_reinject = 0; should_reinject = 0;
} }
else if (packet_v6 && WINDIVERT_IPV6HDR_GET_FLOWLABEL(ppIpV6Hdr) == 0x0) {
/* Contrary to IPv4 where we get only packets with IP ID 0x0-0xF,
* for IPv6 we got all the incoming data packets since we can't
* filter them in a driver.
*
* Handle only IPv6 Flow Label == 0x0 for now
*/
//printf("Dropping HTTP Redirect packet!\n");
should_reinject = 0;
}
}
} }
/* Handle OUTBOUND packet on port 80, search for Host header */ /* Handle OUTBOUND packet on port 80, search for Host header */
else if (addr.Direction == WINDIVERT_DIRECTION_OUTBOUND && else if (addr.Direction == WINDIVERT_DIRECTION_OUTBOUND &&
@@ -752,7 +773,7 @@ int main(int argc, char *argv[]) {
); );
WinDivertHelperCalcChecksums( WinDivertHelperCalcChecksums(
packet, packetLen - packet_dataLen + http_fragment_size, 0 packet, packetLen - packet_dataLen + http_fragment_size, &addr, 0
); );
WinDivertSend( WinDivertSend(
w_filter, packet, w_filter, packet,
@@ -957,11 +978,7 @@ int main(int argc, char *argv[]) {
if (should_reinject) { if (should_reinject) {
//printf("Re-injecting!\n"); //printf("Re-injecting!\n");
if (should_recalc_checksum) { if (should_recalc_checksum) {
WinDivertHelperCalcChecksums(packet, packetLen, 0); WinDivertHelperCalcChecksums(packet, packetLen, &addr, NULL);
}
else {
WinDivertHelperCalcChecksums(packet, packetLen,
WINDIVERT_HELPER_NO_REPLACE);
} }
WinDivertSend(w_filter, packet, packetLen, &addr, NULL); WinDivertSend(w_filter, packet, packetLen, &addr, NULL);
} }

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="GoodbyeDPI" type="win32"/> <assemblyIdentity version="1.0.0.0" processorArchitecture="X86" name="GoodbyeDPI" type="win32"/>
<description>Divert</description> <description>GoodbyeDPI</description>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2"> <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security> <security>
<requestedPrivileges> <requestedPrivileges>

View File

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB