-
Notifications
You must be signed in to change notification settings - Fork 1
DPI Bypass tool
License
0xffabc/waterfall
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Waterfall
=========
Waterfall's a network traffic modification software written in Rust
The traffic is captured via a SOCKS5 proxy and requires a client that handles direct socket connections
Meaning socks2tun/etc. is not supported yet, however the author is working on it
Build information
-----------------
* build+run: `cargo run`
* build: `cargo build`
First run will generate a config.xml file, unless you specified the exact filename with `--config`
Limitations
-----------
* No schannel support (tokio merges every TLS record from the server to handle backpressuring, and schannel mandates every record to be sent as a separate segment)
You should compile curl with OpenSSL instead. Moreover, OpenSSL is a correct ssl implementation.
You can also consider rustls (if you're on Rust, obviously)
In future, I'll add a configuration flag to disable async socket piping and use the old multi-threaded approach instead.
* No UDP support (fixable)
* No IPv6 support (fixable)
* Inability to inject fabricated TCP packets in the stream (libpcap solves that)
Most of these limitations are eventually fixable and will be patched over time
However, you can make a PR if you're interested
Essential Info
--------------
examples/ are outdated, use /config.xml instead
* bind-options: iface-mtu, iface-ipv4-ip and iface-ipv6-ip are reserved for TUN support
* fake-packet-options: only-oob marks every fake packet as OOB, could be dropped by the DPI
- protocol-http simulates an HTTP connection
- send-reversed would send the fake first
- send-random-garbage generates a random byte stream and sends it (seed=0xDEAD, add configuration option for RNG later)
- send-clienthello sends a fake CH with sni=clienthello-sni
- <send-twice>{bool}</send-twice>, where {bool} decides whether to duplicate the fake or not
* socket-options:
- desync-cutoff-ms is useful for not processing already hanging connections
- disable-sack works ONLY on linux with BPF filters. We'll need functionality to decompose this in a configuration option
(something like <BPF code="..." jt="0" jf="8" k="0x00000036" />), therefore disable-sack might get removed
- oob-hell-data changes what bytes OobStream sends as OOB between separated packets. OobStream CAN and WILL confuse Wireshark's DPI a lot
* http-options:
- Depends on a sequence of 'http' word in the packet (internal DPI will not modify packets with randomized capsulation or any other tweaks)
* desync-options:
- packet-hops-max specifies how much packets the internal DPI must process. BufReader hook would return Ok(size) afterwards
- default-ttl works for disorder packets, currently TSPU checks whether packet-ttl is in range of default-ttl (for disorder),
so you might not want to set it to 4. Use traceroute/tracert to find where the closest loss-hop is
* dns-options: you might not want to have 'integrated_doh_enabled'='true', since it's known to mess with socks2tun (curl chooses the TUN adapter's interface on wintun impl)
- use whitelist-sni-list if you don't want to feed internal DPI with every packet possible
* negative_offset for strategies reverses the effect of offset, offset="3" becomes offset="-3" (pseudoarg)
Current limitations: lack of BPF filter config, lack of mod utils/random's seed customization
You might want to use `bpf_asm` to wrie BPF filters after they get considered by the config
Disabling selective acknowledgment
----------------------------------
This is useful for fake packets, since windows acts weird with them, and resends the whole CH at some index.
Please, DON'T use this with disorder group. Consider using jitter socket option instead
It will prevent windows from holding separated packets in the send buffer, even while NO_DELAY option isn't available (for some reason)
Sometimes it's easier to modify the strategy and put a disorder group strategy before the fake packet.
Use SACK disabler as the last resort.
Note: You can't disable SACK on socket level on windows, so you'll have to edit the registry value `SackOpts` in `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters` and set it to DWORD 0
SACK will be disabled for every connection, and not just the ones the proxy makes.
Router rules
------------
Sometimes you might want to forward a part of traffic to a socks5 proxy (or even block it)
Waterfall's internal DPI tries to retrieve SNI (server name indication), IP and Socks5 DNS requests from what it gets
An example rule would block every visible clienthello to gateway.discord.gg
```
<router-options>
<!-- Prevent discord from connecting to main gateway URL -->
<rules
scope="SNI"
type="Forward"
match="*.discord.gg"
exec="block 127.0.0.1:9050"
/>
</router-options>
```
Available router scopes: SNI, DnsQuery, IP (4, 6)
Router rule types: Forward (socks5, block), FakeDNS
* FakeDNS is useful for forwarding a domain to its correct IP (basically, a userland replacement of hosts file). A common case is resolving ntc.party to <pretend that ntc.party's IPv4 is there>
FakeDNS will run before the DOH resolver and bypass it completely, and can be only used with DnsQuery scope.
Forward is not available on SNI, unless it's a `block` type.
Global strategy whitelist
-------------------------
Denoted as
```
<whitelist-sni-list list="domain" value="googlevideo.com" />
```
Where list is WhiteListedSNI (basically domain, file, path)
File and path aren't considered as for now
Strategy config
---------------
```
<strategies
type="FRAGTLS"
offset="3"
add-sni="true"
add-host="false"
negative_offset="false"
>
<filter-protocol>TCP</filter-protocol>
<filter-port>
<start>442</start>
</filter-port>
<filter-sni>
<WhiteListedSNIWrapper list="domain" value="youtube.com" />
<WhiteListedSNIWrapper list="domain" value="discord.com" />
<WhiteListedSNIWrapper list="domain" value="discordapp.com" />
<WhiteListedSNIWrapper list="domain" value="googlevideo.com" />
</filter-sni>
</strategies>
```
Available types
* NONE - Noop action
* SPLIT - Segments the packet. Corresponds to geneva's `fragment`
* DISORDER - Segments the packet, sends the first with low TTL
* DISORDER2 - The same as DISORDER, but the second is sent with low TTL instead
* FAKEMD - The same as SPLIT, but we get a fake in between
* FAKE - The same as FAKEMD, but DISORDER is used instead of SPLIT
* FAKE2INSERT - The same as FAKEMD, but ignores most fake options
* FAKE2DISORDER - The same as FAKEMD, but DISORDER2 is used
* FAKESURROUND - SPLIT segments are surrounded with fakes
* MELTDOWN - TTL=1 for the whole packet. In other words, duplicates the remaining part from previous operations. Corresponds to geneva's `duplicate`
* OOB - inserts an OOB byte in between of the segments
* OOBSTREAMHELL - inserts A LOT of OOB bytes
* DISOOB - DISORDER + OOB
* OOB2 - DISORDER2 + OOB
* FRAGTLS - Splits TLS header in two parts, used to be a powerful counter-attack against GFW. For more info: https://upb-syssec.github.io/blog/2023/record-fragmentation/. A particular case of geneva's `tamper`
*
Implementation details
----------------------
* Router uses DNS-resolved IP and the SOCKS5 request domain for RouterRuleType::SNI as for now
* IPv6-enabled interfaces aren't handled by the socket binder, if you use one, fall back to `default`
* SNI, IP router scopes are handled before the socket creation, to allow FORWARD router rule
* Fakedns action type makes sense only with the DnsQuery router scope
* Router will use the first rule available for current context and ignore every other one
* Current SOCKS5 proxy is inefficient and uses a BufReader/BufWriter pair, which causes regressed network latencies
Planned features
----------------
- BPF filter config (<BPFilters>, <BPF />)
- Config verification
- Eventually waterfall will become a more advanced traffic inspection and modification tool, rather than just a censorship evasion tool
- Eventually waterfall will become an autonomous censorship evasion tool
- Socks2tun will be supported
- Performance regress (from 31ms to 80ms on krunker.io) will be fixed
Useful sources
--------------
https://geneva.cs.umd.edu/papers/geneva_ccs19.pdf - Waterfall inherits geneva's strategy branching
https://upb-syssec.github.io/blog/2023/record-fragmentation/ - FRAGTLS
https://github.com/hufrea/byedpi - Significantly shaped my views on how a DPI bypass would look like
About
DPI Bypass tool
Resources
License
Stars
Watchers
Forks
Packages 0
No packages published