mirror of
https://github.com/ValdikSS/GoodbyeDPI.git
synced 2025-12-17 21:04:36 +03:00
Compare commits
23 Commits
openvpn
...
quic_block
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6b2f3cfa74 | ||
|
|
9bfce3156e | ||
|
|
f7362094d3 | ||
|
|
f1aece75ae | ||
|
|
60dd3cb004 | ||
|
|
d031ae65bf | ||
|
|
905d3c98a6 | ||
|
|
b08836de50 | ||
|
|
cf1f2a8674 | ||
|
|
16464646a9 | ||
|
|
ba015cf44e | ||
|
|
3837635f2c | ||
|
|
95c5ca81b2 | ||
|
|
bbb7e4cea8 | ||
|
|
15eb10ac68 | ||
|
|
4c846c712d | ||
|
|
4a82fd442d | ||
|
|
b3c9ff8419 | ||
|
|
fc6fd98a62 | ||
|
|
6304328548 | ||
|
|
86867fe678 | ||
|
|
54349a1c31 | ||
|
|
54f810b6b0 |
18
.github/workflows/build.yml
vendored
18
.github/workflows/build.yml
vendored
@@ -7,21 +7,21 @@ on:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
WINDIVERT_URL: https://www.reqrypt.org/download/WinDivert-2.2.0-A.zip
|
||||
WINDIVERT_NAME: WinDivert-2.2.0-A.zip
|
||||
WINDIVERT_BASENAME: WinDivert-2.2.0-A
|
||||
WINDIVERT_SHA256: 2a7630aac0914746fbc565ac862fa096e3e54233883ac52d17c83107496b7a7f
|
||||
WINDIVERT_URL: https://reqrypt.org/download/WinDivert-2.2.0-D.zip
|
||||
WINDIVERT_NAME: WinDivert-2.2.0-D.zip
|
||||
WINDIVERT_BASENAME: WinDivert-2.2.0-D
|
||||
WINDIVERT_SHA256: 1d461cfdfa7ba88ebcfbb3603b71b703e9f72aba8aeff99a75ce293e6f89d2ba
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Declare short commit variable
|
||||
id: vars
|
||||
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
|
||||
run: >
|
||||
@@ -31,7 +31,7 @@ jobs:
|
||||
|
||||
- name: Download WinDivert from cache
|
||||
id: windivert-cache
|
||||
uses: actions/cache@v2
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: ${{ env. WINDIVERT_NAME }}
|
||||
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 }}
|
||||
|
||||
- name: Upload output file x86_64
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: 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 }}
|
||||
|
||||
- name: Upload output file x86
|
||||
uses: actions/upload-artifact@v2
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: goodbyedpi_x86_${{ steps.vars.outputs.sha_short }}
|
||||
path: goodbyedpi_x86_${{ steps.vars.outputs.sha_short }}
|
||||
|
||||
22
README.md
22
README.md
@@ -22,6 +22,7 @@ Download [latest version from Releases page](https://github.com/ValdikSS/Goodbye
|
||||
```
|
||||
Usage: goodbyedpi.exe [OPTION...]
|
||||
-p block passive DPI
|
||||
-q block QUIC/HTTP3
|
||||
-r replace Host with hoSt
|
||||
-s remove space between host header and its value
|
||||
-m mix Host header case (test.com -> tEsT.cOm)
|
||||
@@ -43,6 +44,7 @@ Usage: goodbyedpi.exe [OPTION...]
|
||||
supplied text file (HTTP Host/TLS SNI).
|
||||
This option can be supplied multiple times.
|
||||
--allow-no-sni perform circumvention if TLS SNI can't be detected with --blacklist enabled.
|
||||
--frag-by-sni if SNI is detected in TLS packet, fragment the packet right before SNI value.
|
||||
--set-ttl <value> activate Fake Request Mode and send it with supplied TTL value.
|
||||
DANGEROUS! May break websites in unexpected ways. Use with care (or --blacklist).
|
||||
--auto-ttl [a1-a2-m] activate Fake Request Mode, automatically detect TTL and decrease
|
||||
@@ -76,8 +78,13 @@ LEGACY modesets:
|
||||
-4 -p -r -s (best speed)
|
||||
|
||||
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
|
||||
-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.
|
||||
@@ -140,12 +147,15 @@ Modify them according to your own needs.
|
||||
|
||||
# Similar projects
|
||||
|
||||
- **[zapret](https://github.com/bol-van/zapret)** by @bol-van (for Linux).
|
||||
- **[Green Tunnel](https://github.com/SadeghHayeri/GreenTunnel)** by @SadeghHayeri (for MacOS, Linux and Windows).
|
||||
- **[DPITunnel](https://github.com/zhenyolka/DPITunnel)** by @zhenyolka (for Android).
|
||||
- **[PowerTunnel](https://github.com/krlvm/PowerTunnel)** by @krlvm (for Windows, MacOS and Linux).
|
||||
- **[PowerTunnel for Android](https://github.com/krlvm/PowerTunnel-Android)** by @krlvm (for Android).
|
||||
- **[zapret](https://github.com/bol-van/zapret)** by @bol-van (for Linux)
|
||||
- **[Green Tunnel](https://github.com/SadeghHayeri/GreenTunnel)** by @SadeghHayeri (for MacOS, Linux and Windows)
|
||||
- **[DPI Tunnel CLI](https://github.com/zhenyolka/DPITunnel-cli)** by @zhenyolka (for Linux and routers)
|
||||
- **[DPI Tunnel for Android](https://github.com/zhenyolka/DPITunnel-android)** by @zhenyolka (for Android)
|
||||
- **[PowerTunnel](https://github.com/krlvm/PowerTunnel)** by @krlvm (for Windows, MacOS and Linux)
|
||||
- **[PowerTunnel for Android](https://github.com/krlvm/PowerTunnel-Android)** by @krlvm (for Android)
|
||||
- **[SpoofDPI](https://github.com/xvzc/SpoofDPI)** by @xvzc (for macOS and Linux)
|
||||
- **[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)
|
||||
|
||||
# Kudos
|
||||
|
||||
|
||||
@@ -11,7 +11,12 @@ TARGET = goodbyedpi.exe
|
||||
#LIBS = -L$(WINDIVERTLIBS) -Wl,-Bstatic -lssp -Wl,-Bdynamic -lWinDivert -lws2_32
|
||||
LIBS = -L$(WINDIVERTLIBS) -lWinDivert -lws2_32 -l:libssp.a
|
||||
CC = $(CPREFIX)gcc
|
||||
|
||||
CCWINDRES = $(CPREFIX)windres
|
||||
ifeq (, $(shell which $(CPREFIX)windres))
|
||||
CCWINDRES = windres
|
||||
endif
|
||||
|
||||
CFLAGS = -std=c99 -pie -fPIE -pipe -I$(WINDIVERTHEADERS) -L$(WINDIVERTLIBS) \
|
||||
-O2 -D_FORTIFY_SOURCE=2 -fstack-protector \
|
||||
-Wall -Wextra -Wpedantic -Wformat=2 -Wformat-overflow=2 -Wformat-truncation=2 \
|
||||
@@ -19,7 +24,7 @@ CFLAGS = -std=c99 -pie -fPIE -pipe -I$(WINDIVERTHEADERS) -L$(WINDIVERTLIBS) \
|
||||
-Wnull-dereference -Warray-bounds=2 -Wimplicit-fallthrough=3 \
|
||||
-Wstringop-overflow=4 \
|
||||
-Wformat-signedness -Wstrict-overflow=2 -Wcast-align=strict \
|
||||
-Wfloat-equal -Wcast-align -Wsign-conversion -Wno-stringop-overflow -Wno-stringop-overread \
|
||||
-Wfloat-equal -Wcast-align -Wsign-conversion \
|
||||
#-fstack-protector-strong
|
||||
LDFLAGS = -fstack-protector -Wl,-O1,-pie,--dynamicbase,--nxcompat,--sort-common,--as-needed \
|
||||
-Wl,--image-base,0x140000000 -Wl,--disable-auto-image-base
|
||||
|
||||
@@ -11,41 +11,74 @@ static const unsigned char fake_http_request[] = "GET / HTTP/1.1\r\nHost: www.w3
|
||||
"User-Agent: curl/7.65.3\r\nAccept: */*\r\n"
|
||||
"Accept-Encoding: deflate, gzip, br\r\n\r\n";
|
||||
static const unsigned char fake_https_request[] = {
|
||||
0x16, 0x03, 0x01, 0x02, 0x00, 0x01, 0x00, 0x01, 0xfc, 0x03, 0x03, 0x9a, 0x8f, 0xa7, 0x6a, 0x5d,
|
||||
0x57, 0xf3, 0x62, 0x19, 0xbe, 0x46, 0x82, 0x45, 0xe2, 0x59, 0x5c, 0xb4, 0x48, 0x31, 0x12, 0x15,
|
||||
0x14, 0x79, 0x2c, 0xaa, 0xcd, 0xea, 0xda, 0xf0, 0xe1, 0xfd, 0xbb, 0x20, 0xf4, 0x83, 0x2a, 0x94,
|
||||
0xf1, 0x48, 0x3b, 0x9d, 0xb6, 0x74, 0xba, 0x3c, 0x81, 0x63, 0xbc, 0x18, 0xcc, 0x14, 0x45, 0x57,
|
||||
0x6c, 0x80, 0xf9, 0x25, 0xcf, 0x9c, 0x86, 0x60, 0x50, 0x31, 0x2e, 0xe9, 0x00, 0x22, 0x13, 0x01,
|
||||
0x13, 0x03, 0x13, 0x02, 0xc0, 0x2b, 0xc0, 0x2f, 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0x2c, 0xc0, 0x30,
|
||||
0xc0, 0x0a, 0xc0, 0x09, 0xc0, 0x13, 0xc0, 0x14, 0x00, 0x33, 0x00, 0x39, 0x00, 0x2f, 0x00, 0x35,
|
||||
0x01, 0x00, 0x01, 0x91, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x0d, 0x00, 0x00, 0x0a, 0x77, 0x77, 0x77,
|
||||
0x2e, 0x77, 0x33, 0x2e, 0x6f, 0x72, 0x67, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00,
|
||||
0x00, 0x0a, 0x00, 0x0e, 0x00, 0x0c, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x19, 0x01, 0x00,
|
||||
0x01, 0x01, 0x00, 0x0b, 0x00, 0x02, 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0e,
|
||||
0x00, 0x0c, 0x02, 0x68, 0x32, 0x08, 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31, 0x00, 0x05,
|
||||
0x00, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00, 0x6b, 0x00, 0x69, 0x00, 0x1d, 0x00,
|
||||
0x20, 0xb0, 0xe4, 0xda, 0x34, 0xb4, 0x29, 0x8d, 0xd3, 0x5c, 0x70, 0xd3, 0xbe, 0xe8, 0xa7, 0x2a,
|
||||
0x6b, 0xe4, 0x11, 0x19, 0x8b, 0x18, 0x9d, 0x83, 0x9a, 0x49, 0x7c, 0x83, 0x7f, 0xa9, 0x03, 0x8c,
|
||||
0x3c, 0x00, 0x17, 0x00, 0x41, 0x04, 0x4c, 0x04, 0xa4, 0x71, 0x4c, 0x49, 0x75, 0x55, 0xd1, 0x18,
|
||||
0x1e, 0x22, 0x62, 0x19, 0x53, 0x00, 0xde, 0x74, 0x2f, 0xb3, 0xde, 0x13, 0x54, 0xe6, 0x78, 0x07,
|
||||
0x94, 0x55, 0x0e, 0xb2, 0x6c, 0xb0, 0x03, 0xee, 0x79, 0xa9, 0x96, 0x1e, 0x0e, 0x98, 0x17, 0x78,
|
||||
0x24, 0x44, 0x0c, 0x88, 0x80, 0x06, 0x8b, 0xd4, 0x80, 0xbf, 0x67, 0x7c, 0x37, 0x6a, 0x5b, 0x46,
|
||||
0x4c, 0xa7, 0x98, 0x6f, 0xb9, 0x22, 0x00, 0x2b, 0x00, 0x09, 0x08, 0x03, 0x04, 0x03, 0x03, 0x03,
|
||||
0x02, 0x03, 0x01, 0x00, 0x0d, 0x00, 0x18, 0x00, 0x16, 0x04, 0x03, 0x05, 0x03, 0x06, 0x03, 0x08,
|
||||
0x04, 0x08, 0x05, 0x08, 0x06, 0x04, 0x01, 0x05, 0x01, 0x06, 0x01, 0x02, 0x03, 0x02, 0x01, 0x00,
|
||||
0x2d, 0x00, 0x02, 0x01, 0x01, 0x00, 0x1c, 0x00, 0x02, 0x40, 0x01, 0x00, 0x15, 0x00, 0x96, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00
|
||||
0x16, 0x03, 0x01, 0x02, 0x00, 0x01, 0x00, 0x01, /* ........ */
|
||||
0xfc, 0x03, 0x03, 0xe4, 0x5d, 0x79, 0x60, 0xec, /* ....]y`. */
|
||||
0x73, 0xa8, 0xaf, 0xc0, 0x1b, 0x6e, 0xba, 0x51, /* s....n.Q */
|
||||
0xd4, 0x2f, 0x0c, 0xa9, 0xa3, 0xdf, 0xb0, 0xf4, /* ./...... */
|
||||
0x1e, 0x60, 0x1b, 0x71, 0x09, 0xfd, 0xd4, 0x6a, /* .`.q...j */
|
||||
0xca, 0x9f, 0xf6, 0x20, 0x3c, 0x6a, 0x0f, 0xfa, /* ... <j.. */
|
||||
0x0b, 0x25, 0xda, 0x8f, 0x29, 0x1e, 0x93, 0xfa, /* .%..)... */
|
||||
0x7c, 0x78, 0xf3, 0x3f, 0x5c, 0xbb, 0x16, 0x6e, /* |x.?\..n */
|
||||
0xfa, 0xd0, 0x90, 0xdd, 0xac, 0x54, 0x39, 0x75, /* .....T9u */
|
||||
0x10, 0xd6, 0xd7, 0xc5, 0x00, 0x48, 0x13, 0x02, /* .....H.. */
|
||||
0x13, 0x03, 0x13, 0x01, 0x13, 0x04, 0xc0, 0x2c, /* ......., */
|
||||
0xc0, 0x30, 0xcc, 0xa9, 0xcc, 0xa8, 0xc0, 0xad, /* .0...... */
|
||||
0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0xac, 0xc0, 0x23, /* .+./...# */
|
||||
0xc0, 0x27, 0xc0, 0x0a, 0xc0, 0x14, 0xc0, 0x09, /* .'...... */
|
||||
0xc0, 0x13, 0x00, 0x9d, 0xc0, 0x9d, 0x00, 0x9c, /* ........ */
|
||||
0xc0, 0x9c, 0x00, 0x3d, 0x00, 0x3c, 0x00, 0x35, /* ...=.<.5 */
|
||||
0x00, 0x2f, 0x00, 0x9f, 0xcc, 0xaa, 0xc0, 0x9f, /* ./...... */
|
||||
0x00, 0x9e, 0xc0, 0x9e, 0x00, 0x6b, 0x00, 0x67, /* .....k.g */
|
||||
0x00, 0x39, 0x00, 0x33, 0x00, 0xff, 0x01, 0x00, /* .9.3.... */
|
||||
0x01, 0x6b, 0x00, 0x00, 0x00, 0x12, 0x00, 0x10, /* .k...... */
|
||||
0x00, 0x00, 0x0d, 0x77, 0x69, 0x6b, 0x69, 0x70, /* ...wikip */
|
||||
0x65, 0x64, 0x69, 0x61, 0x2e, 0x6f, 0x72, 0x67, /* edia.org */
|
||||
0x00, 0x0b, 0x00, 0x04, 0x03, 0x00, 0x01, 0x02, /* ........ */
|
||||
0x00, 0x0a, 0x00, 0x16, 0x00, 0x14, 0x00, 0x1d, /* ........ */
|
||||
0x00, 0x17, 0x00, 0x1e, 0x00, 0x19, 0x00, 0x18, /* ........ */
|
||||
0x01, 0x00, 0x01, 0x01, 0x01, 0x02, 0x01, 0x03, /* ........ */
|
||||
0x01, 0x04, 0x00, 0x10, 0x00, 0x0e, 0x00, 0x0c, /* ........ */
|
||||
0x02, 0x68, 0x32, 0x08, 0x68, 0x74, 0x74, 0x70, /* .h2.http */
|
||||
0x2f, 0x31, 0x2e, 0x31, 0x00, 0x16, 0x00, 0x00, /* /1.1.... */
|
||||
0x00, 0x17, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, /* .....1.. */
|
||||
0x00, 0x0d, 0x00, 0x22, 0x00, 0x20, 0x04, 0x03, /* ...". .. */
|
||||
0x05, 0x03, 0x06, 0x03, 0x08, 0x07, 0x08, 0x08, /* ........ */
|
||||
0x08, 0x09, 0x08, 0x0a, 0x08, 0x0b, 0x08, 0x04, /* ........ */
|
||||
0x08, 0x05, 0x08, 0x06, 0x04, 0x01, 0x05, 0x01, /* ........ */
|
||||
0x06, 0x01, 0x03, 0x03, 0x03, 0x01, 0x00, 0x2b, /* .......+ */
|
||||
0x00, 0x05, 0x04, 0x03, 0x04, 0x03, 0x03, 0x00, /* ........ */
|
||||
0x2d, 0x00, 0x02, 0x01, 0x01, 0x00, 0x33, 0x00, /* -.....3. */
|
||||
0x26, 0x00, 0x24, 0x00, 0x1d, 0x00, 0x20, 0x86, /* &.$... . */
|
||||
0x81, 0xce, 0x35, 0x01, 0x85, 0x6b, 0x1e, 0x0d, /* ..5..k.. */
|
||||
0xbd, 0x92, 0xac, 0xf4, 0x9d, 0xcd, 0x5b, 0x1e, /* ......[. */
|
||||
0x12, 0x57, 0x21, 0xc0, 0x0c, 0x59, 0xe9, 0x62, /* .W!..Y.b */
|
||||
0xe3, 0xe2, 0xa4, 0x8d, 0xfa, 0x1b, 0x2e, 0x00, /* ........ */
|
||||
0x15, 0x00, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
|
||||
0x00, 0x00, 0x00, 0x00, 0x00 /* ..... */
|
||||
};
|
||||
|
||||
|
||||
static int send_fake_data(const HANDLE w_filter,
|
||||
const PWINDIVERT_ADDRESS addr,
|
||||
const char *pkt,
|
||||
|
||||
142
src/goodbyedpi.c
142
src/goodbyedpi.c
@@ -23,7 +23,7 @@
|
||||
// My mingw installation does not load inet_pton definition for some reason
|
||||
WINSOCK_API_LINKAGE INT WSAAPI inet_pton(INT Family, LPCSTR pStringBuf, PVOID pAddr);
|
||||
|
||||
#define GOODBYEDPI_VERSION "v0.2.2"
|
||||
#define GOODBYEDPI_VERSION "v0.2.3"
|
||||
|
||||
#define die() do { sleep(20); exit(EXIT_FAILURE); } while (0)
|
||||
|
||||
@@ -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 " \
|
||||
"(" 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 " \
|
||||
"!impostor and !loopback and " \
|
||||
"((ip.Id <= 0xF and ip.Id >= 0x0) " IPID_TEMPLATE ") and " \
|
||||
@@ -162,6 +165,7 @@ static struct option long_options[] = {
|
||||
{"dns-verb", no_argument, 0, 'v' },
|
||||
{"blacklist", required_argument, 0, 'b' },
|
||||
{"allow-no-sni",no_argument, 0, ']' },
|
||||
{"frag-by-sni", no_argument, 0, '>' },
|
||||
{"ip-id", required_argument, 0, 'i' },
|
||||
{"set-ttl", required_argument, 0, '$' },
|
||||
{"min-ttl", required_argument, 0, '[' },
|
||||
@@ -171,7 +175,6 @@ static struct option long_options[] = {
|
||||
{"native-frag", no_argument, 0, '*' },
|
||||
{"reverse-frag",no_argument, 0, '(' },
|
||||
{"max-payload", optional_argument, 0, '|' },
|
||||
{"openvpn", no_argument, 0, '#' },
|
||||
{0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
@@ -218,7 +221,10 @@ static void add_ip_id_str(int id) {
|
||||
static void add_maxpayloadsize_str(unsigned short maxpayload) {
|
||||
char *newstr;
|
||||
/* 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);
|
||||
|
||||
sprintf(addfilter, maxpayloadsize_str, maxpayload);
|
||||
@@ -434,16 +440,6 @@ static int extract_sni(const char *pktdata, unsigned int pktlen,
|
||||
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) {
|
||||
if (size >= 1 && size <= 0xFFFFu) {
|
||||
ppTcpHdr->Window = htons((u_short)size);
|
||||
@@ -485,7 +481,7 @@ static void send_native_fragment(HANDLE w_filter, WINDIVERT_ADDRESS addr,
|
||||
PWINDIVERT_TCPHDR ppTcpHdr,
|
||||
unsigned int fragment_size, int step) {
|
||||
char packet_bak[MAX_PACKET_SIZE];
|
||||
memcpy(&packet_bak, packet, packetLen);
|
||||
memcpy(packet_bak, packet, packetLen);
|
||||
UINT orig_packetLen = packetLen;
|
||||
|
||||
if (fragment_size >= packet_dataLen) {
|
||||
@@ -542,7 +538,7 @@ static void send_native_fragment(HANDLE w_filter, WINDIVERT_ADDRESS addr,
|
||||
packetLen,
|
||||
NULL, &addr
|
||||
);
|
||||
memcpy(packet, &packet_bak, orig_packetLen);
|
||||
memcpy(packet, packet_bak, orig_packetLen);
|
||||
//printf("Sent native fragment of %d size (step%d)\n", packetLen, step);
|
||||
}
|
||||
|
||||
@@ -554,7 +550,6 @@ int main(int argc, char *argv[]) {
|
||||
} packet_type;
|
||||
int i, should_reinject, should_recalc_checksum = 0;
|
||||
int sni_ok = 0;
|
||||
int openvpn_handshake = 0;
|
||||
int opt;
|
||||
int packet_v4, packet_v6;
|
||||
HANDLE w_filter = NULL;
|
||||
@@ -570,7 +565,8 @@ int main(int argc, char *argv[]) {
|
||||
conntrack_info_t dns_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_nowait = 0,
|
||||
do_fragment_https = 0, do_host = 0,
|
||||
@@ -580,8 +576,8 @@ int main(int argc, char *argv[]) {
|
||||
do_dnsv4_redirect = 0, do_dnsv6_redirect = 0,
|
||||
do_dns_verb = 0, do_tcp_verb = 0, do_blacklist = 0,
|
||||
do_allow_no_sni = 0,
|
||||
do_fragment_by_sni = 0,
|
||||
do_fake_packet = 0,
|
||||
do_openvpn = 0,
|
||||
do_auto_ttl = 0,
|
||||
do_wrong_chksum = 0,
|
||||
do_wrong_seq = 0,
|
||||
@@ -642,17 +638,19 @@ int main(int argc, char *argv[]) {
|
||||
);
|
||||
|
||||
if (argc == 1) {
|
||||
/* enable mode -5 by default */
|
||||
/* enable mode -9 by default */
|
||||
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_auto_ttl = 1;
|
||||
do_wrong_chksum = 1;
|
||||
do_wrong_seq = 1;
|
||||
do_block_quic = 1;
|
||||
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) {
|
||||
case '1':
|
||||
do_passivedpi = do_host = do_host_removespace \
|
||||
@@ -693,9 +691,27 @@ int main(int argc, char *argv[]) {
|
||||
do_wrong_seq = 1;
|
||||
max_payload_size = 1200;
|
||||
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':
|
||||
do_passivedpi = 1;
|
||||
break;
|
||||
case 'q':
|
||||
do_block_quic = 1;
|
||||
break;
|
||||
case 'r':
|
||||
do_host = 1;
|
||||
break;
|
||||
@@ -819,6 +835,9 @@ int main(int argc, char *argv[]) {
|
||||
case ']': // --allow-no-sni
|
||||
do_allow_no_sni = 1;
|
||||
break;
|
||||
case '>': // --frag-by-sni
|
||||
do_fragment_by_sni = 1;
|
||||
break;
|
||||
case '$': // --set-ttl
|
||||
do_auto_ttl = auto_ttl_1 = auto_ttl_2 = auto_ttl_max = 0;
|
||||
do_fake_packet = 1;
|
||||
@@ -862,9 +881,6 @@ int main(int argc, char *argv[]) {
|
||||
free(autottl_copy);
|
||||
}
|
||||
break;
|
||||
case '#': // --openvpn
|
||||
do_openvpn = 1;
|
||||
break;
|
||||
case '%': // --wrong-chksum
|
||||
do_fake_packet = 1;
|
||||
do_wrong_chksum = 1;
|
||||
@@ -895,6 +911,7 @@ int main(int argc, char *argv[]) {
|
||||
default:
|
||||
puts("Usage: goodbyedpi.exe [OPTION...]\n"
|
||||
" -p block passive DPI\n"
|
||||
" -q block QUIC/HTTP3\n"
|
||||
" -r replace Host with hoSt\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"
|
||||
@@ -915,6 +932,7 @@ int main(int argc, char *argv[]) {
|
||||
" supplied text file (HTTP Host/TLS SNI).\n"
|
||||
" This option can be supplied multiple times.\n"
|
||||
" --allow-no-sni perform circumvention if TLS SNI can't be detected with --blacklist enabled.\n"
|
||||
" --frag-by-sni if SNI is detected in TLS packet, fragment the packet right before SNI value.\n"
|
||||
" --set-ttl <value> activate Fake Request Mode and send it with supplied TTL value.\n"
|
||||
" DANGEROUS! May break websites in unexpected ways. Use with care (or --blacklist).\n"
|
||||
" --auto-ttl [a1-a2-m] activate Fake Request Mode, automatically detect TTL and decrease\n"
|
||||
@@ -940,7 +958,6 @@ int main(int argc, char *argv[]) {
|
||||
" (like file transfers) in already established sessions.\n"
|
||||
" May skip some huge HTTP requests from being processed.\n"
|
||||
" Default (if set): --max-payload 1200.\n"
|
||||
" --openvpn Detect OpenVPN TCP and fragment/send fake packet.\n"
|
||||
"\n");
|
||||
puts("LEGACY modesets:\n"
|
||||
" -1 -p -r -s -f 2 -k 2 -n -e 2 (most compatible mode)\n"
|
||||
@@ -949,8 +966,13 @@ int main(int argc, char *argv[]) {
|
||||
" -4 -p -r -s (best speed)"
|
||||
"\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"
|
||||
" -6 -f 2 -e 2 --wrong-seq --reverse-frag --max-payload\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"
|
||||
" -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);
|
||||
}
|
||||
}
|
||||
@@ -971,9 +993,11 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
printf("Block passive: %d\n" /* 1 */
|
||||
"Block QUIC/HTTP3: %d\n" /* 1 */
|
||||
"Fragment HTTP: %u\n" /* 2 */
|
||||
"Fragment persistent HTTP: %u\n" /* 3 */
|
||||
"Fragment HTTPS: %u\n" /* 4 */
|
||||
"Fragment by SNI: %u\n" /* 5 */
|
||||
"Native fragmentation (splitting): %d\n" /* 5 */
|
||||
"Fragments sending in reverse: %d\n" /* 6 */
|
||||
"hoSt: %d\n" /* 7 */
|
||||
@@ -988,30 +1012,29 @@ int main(int argc, char *argv[]) {
|
||||
"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 SEQ/ACK: %d\n" /* 18 */
|
||||
"Max payload size: %hu\n" /* 19 */
|
||||
"OpenVPN: %d\n", /* 20 */
|
||||
do_passivedpi, /* 1 */
|
||||
"Max payload size: %hu\n", /* 19 */
|
||||
do_passivedpi, do_block_quic, /* 1 */
|
||||
(do_fragment_http ? http_fragment_size : 0), /* 2 */
|
||||
(do_fragment_http_persistent ? http_fragment_size : 0),/* 3 */
|
||||
(do_fragment_https ? https_fragment_size : 0), /* 4 */
|
||||
do_native_frag, /* 5 */
|
||||
do_reverse_frag, /* 6 */
|
||||
do_host, /* 7 */
|
||||
do_host_removespace, /* 8 */
|
||||
do_additional_space, /* 9 */
|
||||
do_host_mixedcase, /* 10 */
|
||||
do_http_allports, /* 11 */
|
||||
do_fragment_http_persistent_nowait, /* 12 */
|
||||
do_dnsv4_redirect, /* 13 */
|
||||
do_dnsv6_redirect, /* 14 */
|
||||
do_allow_no_sni, /* 15 */
|
||||
do_auto_ttl ? "auto" : (do_fake_packet ? "fixed" : "disabled"), /* 16 */
|
||||
do_fragment_by_sni, /* 5 */
|
||||
do_native_frag, /* 6 */
|
||||
do_reverse_frag, /* 7 */
|
||||
do_host, /* 8 */
|
||||
do_host_removespace, /* 9 */
|
||||
do_additional_space, /* 10 */
|
||||
do_host_mixedcase, /* 11 */
|
||||
do_http_allports, /* 12 */
|
||||
do_fragment_http_persistent_nowait, /* 13 */
|
||||
do_dnsv4_redirect, /* 14 */
|
||||
do_dnsv6_redirect, /* 15 */
|
||||
do_allow_no_sni, /* 16 */
|
||||
do_auto_ttl ? "auto" : (do_fake_packet ? "fixed" : "disabled"), /* 17 */
|
||||
ttl_of_fake_packet, do_auto_ttl ? auto_ttl_1 : 0, do_auto_ttl ? auto_ttl_2 : 0,
|
||||
do_auto_ttl ? auto_ttl_max : 0, ttl_min_nhops,
|
||||
do_wrong_chksum, /* 17 */
|
||||
do_wrong_seq, /* 18 */
|
||||
max_payload_size, /* 19 */
|
||||
do_openvpn /* 20 */
|
||||
do_wrong_chksum, /* 18 */
|
||||
do_wrong_seq, /* 19 */
|
||||
max_payload_size /* 20 */
|
||||
);
|
||||
|
||||
if (do_fragment_http && http_fragment_size > 2 && !do_native_frag) {
|
||||
@@ -1042,6 +1065,15 @@ int main(int argc, char *argv[]) {
|
||||
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
|
||||
* active DPI circumvention
|
||||
@@ -1065,6 +1097,7 @@ int main(int argc, char *argv[]) {
|
||||
packetLen);
|
||||
should_reinject = 1;
|
||||
should_recalc_checksum = 0;
|
||||
sni_ok = 0;
|
||||
|
||||
ppIpHdr = (PWINDIVERT_IPHDR)NULL;
|
||||
ppIpV6Hdr = (PWINDIVERT_IPV6HDR)NULL;
|
||||
@@ -1138,7 +1171,7 @@ int main(int argc, char *argv[]) {
|
||||
*/
|
||||
else if (addr.Outbound &&
|
||||
((do_fragment_https ? packet_dataLen == https_fragment_size : 0) ||
|
||||
packet_dataLen >= 16) &&
|
||||
packet_dataLen > 16) &&
|
||||
ppTcpHdr->DstPort != htons(80) &&
|
||||
(do_fake_packet || do_native_frag)
|
||||
)
|
||||
@@ -1148,11 +1181,9 @@ int main(int argc, char *argv[]) {
|
||||
* But if the packet is more than 2 bytes, check ClientHello byte.
|
||||
*/
|
||||
if ((packet_dataLen == 2 && memcmp(packet_data, "\x16\x03", 2) == 0) ||
|
||||
(packet_dataLen >= 3 && memcmp(packet_data, "\x16\x03\x01", 3) == 0) ||
|
||||
(do_openvpn && (openvpn_handshake = is_openvpn_handshake(packet_data, packet_dataLen)))
|
||||
)
|
||||
(packet_dataLen >= 3 && ( memcmp(packet_data, "\x16\x03\x01", 3) == 0 || memcmp(packet_data, "\x16\x03\x03", 3) == 0 )))
|
||||
{
|
||||
if (do_blacklist) {
|
||||
if (do_blacklist || do_fragment_by_sni) {
|
||||
sni_ok = extract_sni(packet_data, packet_dataLen,
|
||||
&host_addr, &host_len);
|
||||
}
|
||||
@@ -1161,7 +1192,6 @@ int main(int argc, char *argv[]) {
|
||||
blackwhitelist_check_hostname(host_addr, host_len)
|
||||
) ||
|
||||
(do_blacklist && !sni_ok && do_allow_no_sni) ||
|
||||
(do_openvpn && openvpn_handshake) ||
|
||||
(!do_blacklist)
|
||||
)
|
||||
{
|
||||
@@ -1169,7 +1199,7 @@ int main(int argc, char *argv[]) {
|
||||
char lsni[HOST_MAXLEN + 1] = {0};
|
||||
extract_sni(packet_data, packet_dataLen,
|
||||
&host_addr, &host_len);
|
||||
memcpy(&lsni, host_addr, host_len);
|
||||
memcpy(lsni, host_addr, host_len);
|
||||
printf("Blocked HTTPS website SNI: %s\n", lsni);
|
||||
#endif
|
||||
if (do_fake_packet) {
|
||||
@@ -1204,7 +1234,7 @@ int main(int argc, char *argv[]) {
|
||||
host_len = hdr_value_len;
|
||||
#ifdef DEBUG
|
||||
char lhost[HOST_MAXLEN + 1] = {0};
|
||||
memcpy(&lhost, host_addr, host_len);
|
||||
memcpy(lhost, host_addr, host_len);
|
||||
printf("Blocked HTTP website Host: %s\n", lhost);
|
||||
#endif
|
||||
|
||||
@@ -1306,8 +1336,12 @@ int main(int argc, char *argv[]) {
|
||||
current_fragment_size = http_fragment_size;
|
||||
}
|
||||
else if (do_fragment_https && ppTcpHdr->DstPort != htons(80)) {
|
||||
if (do_fragment_by_sni && sni_ok) {
|
||||
current_fragment_size = (void*)host_addr - packet_data;
|
||||
} else {
|
||||
current_fragment_size = https_fragment_size;
|
||||
}
|
||||
}
|
||||
|
||||
if (current_fragment_size) {
|
||||
send_native_fragment(w_filter, addr, packet, packetLen, packet_data,
|
||||
|
||||
Reference in New Issue
Block a user