10 Commits

Author SHA1 Message Date
ValdikSS
9bfce3156e Make mode -9 the default, instead of -5
Auto-ttl gives many false positives in TTL detection, which breaks non-blocked websites.
Use the combination of wrong-seq and wrong-chksum and hope to the best.
Also block QUIC to workaround possible throttling, as right now it is not dissected.
2024-07-31 14:49:15 +03:00
ValdikSS
f7362094d3 New modes: -8 and -9
-8 is -7 with added --wrong-seq, it sends two subsequent fake packets, one with
incorrect sequence, and another one with incorrect checksum.

-9 is -8 with QUIC block.
2024-07-31 14:49:15 +03:00
ValdikSS
f1aece75ae New mode: -7 - As -6 but with wrong chksum 2024-07-31 14:49:15 +03:00
ValdikSS
60dd3cb004 Make ClientHello ignore --max-payload limits
Receive TLS ClientHello despite max-payload limit set, to get all
the benefits of the option (decreased CPU consumption) but still
handle all TLS connections, including Kyber.
2024-07-31 14:49:15 +03:00
ValdikSS
d031ae65bf New option: -q - block QUIC/HTTP3
Only Initial packet in Long Header Packets are blocked.
The packet should be at least 1200 bytes in size.
2024-07-31 14:49:10 +03:00
ValdikSS
905d3c98a6 Revert "Add Unicorn HTTPS for iOS": doesn't do anything
This reverts commit 95c5ca81b2.
2024-07-26 03:44:16 +03:00
ValdikSS
b08836de50 Use WinDivert 2.2.0-D for Windows 7 compatibility 2024-07-25 00:51:47 +03:00
ValdikSS
cf1f2a8674 Actions: use $GITHUB_OUTPUT instead of ::set-output 2024-07-23 07:14:35 +03:00
ValdikSS
16464646a9 Use WinDivert 2.2.2 2024-07-23 07:11:47 +03:00
ValdikSS
ba015cf44e Update Github Actions "actions" to newest versions 2024-07-23 07:11:18 +03:00
3 changed files with 68 additions and 20 deletions

View File

@@ -7,21 +7,21 @@ on:
workflow_dispatch: workflow_dispatch:
env: env:
WINDIVERT_URL: https://www.reqrypt.org/download/WinDivert-2.2.0-A.zip WINDIVERT_URL: https://reqrypt.org/download/WinDivert-2.2.0-D.zip
WINDIVERT_NAME: WinDivert-2.2.0-A.zip WINDIVERT_NAME: WinDivert-2.2.0-D.zip
WINDIVERT_BASENAME: WinDivert-2.2.0-A WINDIVERT_BASENAME: WinDivert-2.2.0-D
WINDIVERT_SHA256: 2a7630aac0914746fbc565ac862fa096e3e54233883ac52d17c83107496b7a7f WINDIVERT_SHA256: 1d461cfdfa7ba88ebcfbb3603b71b703e9f72aba8aeff99a75ce293e6f89d2ba
jobs: jobs:
build: build:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v4
- name: Declare short commit variable - name: Declare short commit variable
id: vars id: vars
run: | run: |
echo "::set-output name=sha_short::$(git rev-parse --short HEAD)" echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
- name: Install MinGW-w64 - name: Install MinGW-w64
run: > run: >
@@ -31,7 +31,7 @@ jobs:
- name: Download WinDivert from cache - name: Download WinDivert from cache
id: windivert-cache id: windivert-cache
uses: actions/cache@v2 uses: actions/cache@v4
with: with:
path: ${{ env. WINDIVERT_NAME }} path: ${{ env. WINDIVERT_NAME }}
key: ${{ env. WINDIVERT_SHA256 }} key: ${{ env. WINDIVERT_SHA256 }}
@@ -56,7 +56,7 @@ jobs:
cp src/goodbyedpi.exe ${{ env.WINDIVERT_BASENAME }}/x64/*.{dll,sys} goodbyedpi_x86_64_${{ steps.vars.outputs.sha_short }} cp src/goodbyedpi.exe ${{ env.WINDIVERT_BASENAME }}/x64/*.{dll,sys} goodbyedpi_x86_64_${{ steps.vars.outputs.sha_short }}
- name: Upload output file x86_64 - name: Upload output file x86_64
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v4
with: with:
name: goodbyedpi_x86_64_${{ steps.vars.outputs.sha_short }} name: goodbyedpi_x86_64_${{ steps.vars.outputs.sha_short }}
path: goodbyedpi_x86_64_${{ steps.vars.outputs.sha_short }} path: goodbyedpi_x86_64_${{ steps.vars.outputs.sha_short }}
@@ -72,7 +72,7 @@ jobs:
cp src/goodbyedpi.exe ${{ env.WINDIVERT_BASENAME }}/x86/*.{dll,sys} goodbyedpi_x86_${{ steps.vars.outputs.sha_short }} cp src/goodbyedpi.exe ${{ env.WINDIVERT_BASENAME }}/x86/*.{dll,sys} goodbyedpi_x86_${{ steps.vars.outputs.sha_short }}
- name: Upload output file x86 - name: Upload output file x86
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v4
with: with:
name: goodbyedpi_x86_${{ steps.vars.outputs.sha_short }} name: goodbyedpi_x86_${{ steps.vars.outputs.sha_short }}
path: goodbyedpi_x86_${{ steps.vars.outputs.sha_short }} path: goodbyedpi_x86_${{ steps.vars.outputs.sha_short }}

View File

@@ -22,6 +22,7 @@ Download [latest version from Releases page](https://github.com/ValdikSS/Goodbye
``` ```
Usage: goodbyedpi.exe [OPTION...] Usage: goodbyedpi.exe [OPTION...]
-p block passive DPI -p block passive DPI
-q block QUIC/HTTP3
-r replace Host with hoSt -r replace Host with hoSt
-s remove space between host header and its value -s remove space between host header and its value
-m mix Host header case (test.com -> tEsT.cOm) -m mix Host header case (test.com -> tEsT.cOm)
@@ -77,8 +78,13 @@ LEGACY modesets:
-4 -p -r -s (best speed) -4 -p -r -s (best speed)
Modern modesets (more stable, more compatible, faster): Modern modesets (more stable, more compatible, faster):
-5 -f 2 -e 2 --auto-ttl --reverse-frag --max-payload (this is the default) -5 -f 2 -e 2 --auto-ttl --reverse-frag --max-payload
-6 -f 2 -e 2 --wrong-seq --reverse-frag --max-payload -6 -f 2 -e 2 --wrong-seq --reverse-frag --max-payload
-7 -f 2 -e 2 --wrong-chksum --reverse-frag --max-payload
-8 -f 2 -e 2 --wrong-seq --wrong-chksum --reverse-frag --max-payload
-9 -f 2 -e 2 --wrong-seq --wrong-chksum --reverse-frag --max-payload -q (this is the default)
Note: combination of --wrong-seq and --wrong-chksum generates two different fake packets.
``` ```
To check if your ISP's DPI could be circumvented, first make sure that your provider does not poison DNS answers by enabling "Secure DNS (DNS over HTTPS)" option in your browser. To check if your ISP's DPI could be circumvented, first make sure that your provider does not poison DNS answers by enabling "Secure DNS (DNS over HTTPS)" option in your browser.
@@ -150,7 +156,6 @@ Modify them according to your own needs.
- **[SpoofDPI](https://github.com/xvzc/SpoofDPI)** by @xvzc (for macOS and Linux) - **[SpoofDPI](https://github.com/xvzc/SpoofDPI)** by @xvzc (for macOS and Linux)
- **[GhosTCP](https://github.com/macronut/ghostcp)** by @macronut (for Windows) - **[GhosTCP](https://github.com/macronut/ghostcp)** by @macronut (for Windows)
- **[ByeDPI](https://github.com/hufrea/byedpi)** for Linux/Windows + **[ByeDPIAndroid](https://github.com/dovecoteescapee/ByeDPIAndroid/)** for Android (no root) - **[ByeDPI](https://github.com/hufrea/byedpi)** for Linux/Windows + **[ByeDPIAndroid](https://github.com/dovecoteescapee/ByeDPIAndroid/)** for Android (no root)
- **[Unicorn HTTPS](https://apps.apple.com/kr/app/unicorn-https/id1466584968?l=en)** for iOS
# Kudos # Kudos

View File

@@ -78,6 +78,9 @@ WINSOCK_API_LINKAGE INT WSAAPI inet_pton(INT Family, LPCSTR pStringBuf, PVOID pA
"(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_BLOCK_QUIC "outbound and !impostor and !loopback and udp " \
"and udp.DstPort == 443 and udp.PayloadLength >= 1200 " \
"and udp.Payload[0] >= 0xC0 and udp.Payload32[1b] == 0x01"
#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 " \ "!impostor and !loopback and " \
"((ip.Id <= 0xF and ip.Id >= 0x0) " IPID_TEMPLATE ") and " \ "((ip.Id <= 0xF and ip.Id >= 0x0) " IPID_TEMPLATE ") and " \
@@ -218,7 +221,10 @@ static void add_ip_id_str(int id) {
static void add_maxpayloadsize_str(unsigned short maxpayload) { static void add_maxpayloadsize_str(unsigned short maxpayload) {
char *newstr; char *newstr;
/* 0x47455420 is "GET ", 0x504F5354 is "POST", big endian. */ /* 0x47455420 is "GET ", 0x504F5354 is "POST", big endian. */
const char *maxpayloadsize_str = "and (tcp.PayloadLength ? tcp.PayloadLength < %hu or tcp.Payload32[0] == 0x47455420 or tcp.Payload32[0] == 0x504F5354 : true)"; const char *maxpayloadsize_str =
"and (tcp.PayloadLength ? tcp.PayloadLength < %hu " \
"or tcp.Payload32[0] == 0x47455420 or tcp.Payload32[0] == 0x504F5354 " \
"or (tcp.Payload[0] == 0x16 and tcp.Payload[1] == 0x03 and tcp.Payload[2] <= 0x03): true)";
char *addfilter = malloc(strlen(maxpayloadsize_str) + 16); char *addfilter = malloc(strlen(maxpayloadsize_str) + 16);
sprintf(addfilter, maxpayloadsize_str, maxpayload); sprintf(addfilter, maxpayloadsize_str, maxpayload);
@@ -559,7 +565,8 @@ int main(int argc, char *argv[]) {
conntrack_info_t dns_conn_info; conntrack_info_t dns_conn_info;
tcp_conntrack_info_t tcp_conn_info; tcp_conntrack_info_t tcp_conn_info;
int do_passivedpi = 0, do_fragment_http = 0, int do_passivedpi = 0, do_block_quic = 0,
do_fragment_http = 0,
do_fragment_http_persistent = 0, do_fragment_http_persistent = 0,
do_fragment_http_persistent_nowait = 0, do_fragment_http_persistent_nowait = 0,
do_fragment_https = 0, do_host = 0, do_fragment_https = 0, do_host = 0,
@@ -631,17 +638,19 @@ int main(int argc, char *argv[]) {
); );
if (argc == 1) { if (argc == 1) {
/* enable mode -5 by default */ /* enable mode -9 by default */
do_fragment_http = do_fragment_https = 1; do_fragment_http = do_fragment_https = 1;
do_reverse_frag = do_native_frag = 1; do_reverse_frag = do_native_frag = 1;
http_fragment_size = https_fragment_size = 2; http_fragment_size = https_fragment_size = 2;
do_fragment_http_persistent = do_fragment_http_persistent_nowait = 1; do_fragment_http_persistent = do_fragment_http_persistent_nowait = 1;
do_fake_packet = 1; do_fake_packet = 1;
do_auto_ttl = 1; do_wrong_chksum = 1;
do_wrong_seq = 1;
do_block_quic = 1;
max_payload_size = 1200; max_payload_size = 1200;
} }
while ((opt = getopt_long(argc, argv, "123456prsaf:e:mwk:n", long_options, NULL)) != -1) { while ((opt = getopt_long(argc, argv, "123456789pqrsaf:e:mwk:n", long_options, NULL)) != -1) {
switch (opt) { switch (opt) {
case '1': case '1':
do_passivedpi = do_host = do_host_removespace \ do_passivedpi = do_host = do_host_removespace \
@@ -682,9 +691,27 @@ int main(int argc, char *argv[]) {
do_wrong_seq = 1; do_wrong_seq = 1;
max_payload_size = 1200; max_payload_size = 1200;
break; break;
case '9': // +7+8
do_block_quic = 1;
// fall through
case '8': // +7
do_wrong_seq = 1;
// fall through
case '7':
do_fragment_http = do_fragment_https = 1;
do_reverse_frag = do_native_frag = 1;
http_fragment_size = https_fragment_size = 2;
do_fragment_http_persistent = do_fragment_http_persistent_nowait = 1;
do_fake_packet = 1;
do_wrong_chksum = 1;
max_payload_size = 1200;
break;
case 'p': case 'p':
do_passivedpi = 1; do_passivedpi = 1;
break; break;
case 'q':
do_block_quic = 1;
break;
case 'r': case 'r':
do_host = 1; do_host = 1;
break; break;
@@ -884,6 +911,7 @@ int main(int argc, char *argv[]) {
default: default:
puts("Usage: goodbyedpi.exe [OPTION...]\n" puts("Usage: goodbyedpi.exe [OPTION...]\n"
" -p block passive DPI\n" " -p block passive DPI\n"
" -q block QUIC/HTTP3\n"
" -r replace Host with hoSt\n" " -r replace Host with hoSt\n"
" -s remove space between host header and its value\n" " -s remove space between host header and its value\n"
" -a additional space between Method and Request-URI (enables -s, may break sites)\n" " -a additional space between Method and Request-URI (enables -s, may break sites)\n"
@@ -938,8 +966,13 @@ int main(int argc, char *argv[]) {
" -4 -p -r -s (best speed)" " -4 -p -r -s (best speed)"
"\n" "\n"
"Modern modesets (more stable, more compatible, faster):\n" "Modern modesets (more stable, more compatible, faster):\n"
" -5 -f 2 -e 2 --auto-ttl --reverse-frag --max-payload (this is the default)\n" " -5 -f 2 -e 2 --auto-ttl --reverse-frag --max-payload\n"
" -6 -f 2 -e 2 --wrong-seq --reverse-frag --max-payload\n"); " -6 -f 2 -e 2 --wrong-seq --reverse-frag --max-payload\n"
" -7 -f 2 -e 2 --wrong-chksum --reverse-frag --max-payload\n"
" -8 -f 2 -e 2 --wrong-seq --wrong-chksum --reverse-frag --max-payload\n"
" -9 -f 2 -e 2 --wrong-seq --wrong-chksum --reverse-frag --max-payload -q (this is the default)\n\n"
"Note: combination of --wrong-seq and --wrong-chksum generates two different fake packets.\n"
);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
@@ -960,6 +993,7 @@ int main(int argc, char *argv[]) {
} }
printf("Block passive: %d\n" /* 1 */ printf("Block passive: %d\n" /* 1 */
"Block QUIC/HTTP3: %d\n" /* 1 */
"Fragment HTTP: %u\n" /* 2 */ "Fragment HTTP: %u\n" /* 2 */
"Fragment persistent HTTP: %u\n" /* 3 */ "Fragment persistent HTTP: %u\n" /* 3 */
"Fragment HTTPS: %u\n" /* 4 */ "Fragment HTTPS: %u\n" /* 4 */
@@ -979,7 +1013,7 @@ int main(int argc, char *argv[]) {
"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 */
do_passivedpi, /* 1 */ do_passivedpi, do_block_quic, /* 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 */
(do_fragment_https ? https_fragment_size : 0), /* 4 */ (do_fragment_https ? https_fragment_size : 0), /* 4 */
@@ -1031,6 +1065,15 @@ int main(int argc, char *argv[]) {
filter_num++; filter_num++;
} }
if (do_block_quic) {
filters[filter_num] = init(
FILTER_PASSIVE_BLOCK_QUIC,
WINDIVERT_FLAG_DROP);
if (filters[filter_num] == NULL)
die();
filter_num++;
}
/* /*
* IPv4 & IPv6 filter for inbound HTTP redirection packets and * IPv4 & IPv6 filter for inbound HTTP redirection packets and
* active DPI circumvention * active DPI circumvention