mirror of
https://github.com/ValdikSS/GoodbyeDPI.git
synced 2024-12-22 14:26:08 +00:00
New Fake Packet circumvention method: wrong SEQ/ACK numbers
This method sends Fake Packet with the TCP SEQ/ACK numbers "in the past": -66000 is used for ACK (right out of the ACK permissive window in Linux stack), -10000 is used for SEQ (without any reasoning). This method is pretty effective in Russia. It also could be handy in a networks which prohibit changing TTL values (mobile networks with tethering block/premium feature).
This commit is contained in:
parent
b57a204d96
commit
bbb6af89fe
@ -53,7 +53,8 @@ static int send_fake_data(const HANDLE w_filter,
|
|||||||
const BOOL is_ipv6,
|
const BOOL is_ipv6,
|
||||||
const BOOL is_https,
|
const BOOL is_https,
|
||||||
const BYTE set_ttl,
|
const BYTE set_ttl,
|
||||||
const BYTE set_checksum
|
const BYTE set_checksum,
|
||||||
|
const BYTE set_seq
|
||||||
) {
|
) {
|
||||||
char packet_fake[MAX_PACKET_SIZE];
|
char packet_fake[MAX_PACKET_SIZE];
|
||||||
WINDIVERT_ADDRESS addr_new;
|
WINDIVERT_ADDRESS addr_new;
|
||||||
@ -69,6 +70,9 @@ static int send_fake_data(const HANDLE w_filter,
|
|||||||
memcpy(&addr_new, addr, sizeof(WINDIVERT_ADDRESS));
|
memcpy(&addr_new, addr, sizeof(WINDIVERT_ADDRESS));
|
||||||
memcpy(packet_fake, pkt, packetLen);
|
memcpy(packet_fake, pkt, packetLen);
|
||||||
|
|
||||||
|
addr_new.PseudoTCPChecksum = 0;
|
||||||
|
addr_new.PseudoIPChecksum = 0;
|
||||||
|
|
||||||
if (!is_ipv6) {
|
if (!is_ipv6) {
|
||||||
// IPv4 TCP Data packet
|
// IPv4 TCP Data packet
|
||||||
if (!WinDivertHelperParsePacket(packet_fake, packetLen, &ppIpHdr,
|
if (!WinDivertHelperParsePacket(packet_fake, packetLen, &ppIpHdr,
|
||||||
@ -107,8 +111,15 @@ static int send_fake_data(const HANDLE w_filter,
|
|||||||
ppIpV6Hdr->HopLimit = set_ttl;
|
ppIpV6Hdr->HopLimit = set_ttl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (set_seq) {
|
||||||
|
// This is the smallest ACK drift Linux can't handle already, since at least v2.6.18.
|
||||||
|
// https://github.com/torvalds/linux/blob/v2.6.18/net/netfilter/nf_conntrack_proto_tcp.c#L395
|
||||||
|
ppTcpHdr->AckNum = htonl(ntohl(ppTcpHdr->AckNum) - 66000);
|
||||||
|
// This is just random, no specifics about this value.
|
||||||
|
ppTcpHdr->SeqNum = htonl(ntohl(ppTcpHdr->SeqNum) - 10000);
|
||||||
|
}
|
||||||
|
|
||||||
// Recalculate the checksum
|
// Recalculate the checksum
|
||||||
addr_new.PseudoTCPChecksum = 0;
|
|
||||||
WinDivertHelperCalcChecksums(packet_fake, packetLen_new, &addr_new, NULL);
|
WinDivertHelperCalcChecksums(packet_fake, packetLen_new, &addr_new, NULL);
|
||||||
|
|
||||||
if (set_checksum) {
|
if (set_checksum) {
|
||||||
@ -134,17 +145,23 @@ static int send_fake_request(const HANDLE w_filter,
|
|||||||
const BOOL is_ipv6,
|
const BOOL is_ipv6,
|
||||||
const BOOL is_https,
|
const BOOL is_https,
|
||||||
const BYTE set_ttl,
|
const BYTE set_ttl,
|
||||||
const BYTE set_checksum
|
const BYTE set_checksum,
|
||||||
|
const BYTE set_seq
|
||||||
) {
|
) {
|
||||||
if (set_ttl) {
|
if (set_ttl) {
|
||||||
send_fake_data(w_filter, addr, pkt, packetLen,
|
send_fake_data(w_filter, addr, pkt, packetLen,
|
||||||
is_ipv6, is_https,
|
is_ipv6, is_https,
|
||||||
set_ttl, FALSE);
|
set_ttl, FALSE, FALSE);
|
||||||
}
|
}
|
||||||
if (set_checksum) {
|
if (set_checksum) {
|
||||||
send_fake_data(w_filter, addr, pkt, packetLen,
|
send_fake_data(w_filter, addr, pkt, packetLen,
|
||||||
is_ipv6, is_https,
|
is_ipv6, is_https,
|
||||||
FALSE, set_checksum);
|
FALSE, set_checksum, FALSE);
|
||||||
|
}
|
||||||
|
if (set_seq) {
|
||||||
|
send_fake_data(w_filter, addr, pkt, packetLen,
|
||||||
|
is_ipv6, is_https,
|
||||||
|
FALSE, FALSE, set_seq);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -155,11 +172,12 @@ int send_fake_http_request(const HANDLE w_filter,
|
|||||||
const UINT packetLen,
|
const UINT packetLen,
|
||||||
const BOOL is_ipv6,
|
const BOOL is_ipv6,
|
||||||
const BYTE set_ttl,
|
const BYTE set_ttl,
|
||||||
const BYTE set_checksum
|
const BYTE set_checksum,
|
||||||
|
const BYTE set_seq
|
||||||
) {
|
) {
|
||||||
return send_fake_request(w_filter, addr, pkt, packetLen,
|
return send_fake_request(w_filter, addr, pkt, packetLen,
|
||||||
is_ipv6, FALSE,
|
is_ipv6, FALSE,
|
||||||
set_ttl, set_checksum);
|
set_ttl, set_checksum, set_seq);
|
||||||
}
|
}
|
||||||
|
|
||||||
int send_fake_https_request(const HANDLE w_filter,
|
int send_fake_https_request(const HANDLE w_filter,
|
||||||
@ -168,9 +186,10 @@ int send_fake_https_request(const HANDLE w_filter,
|
|||||||
const UINT packetLen,
|
const UINT packetLen,
|
||||||
const BOOL is_ipv6,
|
const BOOL is_ipv6,
|
||||||
const BYTE set_ttl,
|
const BYTE set_ttl,
|
||||||
const BYTE set_checksum
|
const BYTE set_checksum,
|
||||||
|
const BYTE set_seq
|
||||||
) {
|
) {
|
||||||
return send_fake_request(w_filter, addr, pkt, packetLen,
|
return send_fake_request(w_filter, addr, pkt, packetLen,
|
||||||
is_ipv6, TRUE,
|
is_ipv6, TRUE,
|
||||||
set_ttl, set_checksum);
|
set_ttl, set_checksum, set_seq);
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,8 @@ int send_fake_http_request(const HANDLE w_filter,
|
|||||||
const UINT packetLen,
|
const UINT packetLen,
|
||||||
const BOOL is_ipv6,
|
const BOOL is_ipv6,
|
||||||
const BYTE set_ttl,
|
const BYTE set_ttl,
|
||||||
const BYTE set_checksum
|
const BYTE set_checksum,
|
||||||
|
const BYTE set_seq
|
||||||
);
|
);
|
||||||
int send_fake_https_request(const HANDLE w_filter,
|
int send_fake_https_request(const HANDLE w_filter,
|
||||||
const PWINDIVERT_ADDRESS addr,
|
const PWINDIVERT_ADDRESS addr,
|
||||||
@ -12,5 +13,6 @@ int send_fake_https_request(const HANDLE w_filter,
|
|||||||
const UINT packetLen,
|
const UINT packetLen,
|
||||||
const BOOL is_ipv6,
|
const BOOL is_ipv6,
|
||||||
const BYTE set_ttl,
|
const BYTE set_ttl,
|
||||||
const BYTE set_checksum
|
const BYTE set_checksum,
|
||||||
|
const BYTE set_seq
|
||||||
);
|
);
|
||||||
|
@ -125,6 +125,7 @@ static struct option long_options[] = {
|
|||||||
{"ip-id", required_argument, 0, 'i' },
|
{"ip-id", required_argument, 0, 'i' },
|
||||||
{"set-ttl", required_argument, 0, '$' },
|
{"set-ttl", required_argument, 0, '$' },
|
||||||
{"wrong-chksum",no_argument, 0, '%' },
|
{"wrong-chksum",no_argument, 0, '%' },
|
||||||
|
{"wrong-seq", no_argument, 0, ')' },
|
||||||
{"native-frag", no_argument, 0, '*' },
|
{"native-frag", no_argument, 0, '*' },
|
||||||
{"reverse-frag",no_argument, 0, '(' },
|
{"reverse-frag",no_argument, 0, '(' },
|
||||||
{0, 0, 0, 0 }
|
{0, 0, 0, 0 }
|
||||||
@ -453,6 +454,7 @@ int main(int argc, char *argv[]) {
|
|||||||
do_dns_verb = 0, do_blacklist = 0,
|
do_dns_verb = 0, do_blacklist = 0,
|
||||||
do_fake_packet = 0,
|
do_fake_packet = 0,
|
||||||
do_wrong_chksum = 0,
|
do_wrong_chksum = 0,
|
||||||
|
do_wrong_seq = 0,
|
||||||
do_native_frag = 0, do_reverse_frag = 0;
|
do_native_frag = 0, do_reverse_frag = 0;
|
||||||
unsigned int http_fragment_size = 0;
|
unsigned int http_fragment_size = 0;
|
||||||
unsigned int https_fragment_size = 0;
|
unsigned int https_fragment_size = 0;
|
||||||
@ -665,6 +667,10 @@ int main(int argc, char *argv[]) {
|
|||||||
do_fake_packet = 1;
|
do_fake_packet = 1;
|
||||||
do_wrong_chksum = 1;
|
do_wrong_chksum = 1;
|
||||||
break;
|
break;
|
||||||
|
case ')':
|
||||||
|
do_fake_packet = 1;
|
||||||
|
do_wrong_seq = 1;
|
||||||
|
break;
|
||||||
case '*':
|
case '*':
|
||||||
do_native_frag = 1;
|
do_native_frag = 1;
|
||||||
do_fragment_http_persistent = 1;
|
do_fragment_http_persistent = 1;
|
||||||
@ -703,6 +709,7 @@ int main(int argc, char *argv[]) {
|
|||||||
" --wrong-chksum activate Fake Request Mode and send it with incorrect TCP checksum.\n"
|
" --wrong-chksum activate Fake Request Mode and send it with incorrect TCP checksum.\n"
|
||||||
" May not work in a VM or with some routers, but is safer than set-ttl.\n"
|
" May not work in a VM or with some routers, but is safer than set-ttl.\n"
|
||||||
" Could be combined with --set-ttl\n"
|
" Could be combined with --set-ttl\n"
|
||||||
|
" --wrong-seq activate Fake Request Mode and send it with TCP SEQ/ACK in the past.\n"
|
||||||
" --native-frag fragment (split) the packets by sending them in smaller packets, without\n"
|
" --native-frag fragment (split) the packets by sending them in smaller packets, without\n"
|
||||||
" shrinking the Window Size. Works faster (does not slow down the connection)\n"
|
" shrinking the Window Size. Works faster (does not slow down the connection)\n"
|
||||||
" and better.\n"
|
" and better.\n"
|
||||||
@ -730,13 +737,15 @@ int main(int argc, char *argv[]) {
|
|||||||
"Mix Host: %d\nHTTP AllPorts: %d\nHTTP Persistent Nowait: %d\n"
|
"Mix Host: %d\nHTTP AllPorts: %d\nHTTP Persistent Nowait: %d\n"
|
||||||
"DNS redirect: %d\nDNSv6 redirect: %d\n"
|
"DNS redirect: %d\nDNSv6 redirect: %d\n"
|
||||||
"Fake requests, TTL: %hu\nFake requests, wrong checksum: %d\n",
|
"Fake requests, TTL: %hu\nFake requests, wrong checksum: %d\n",
|
||||||
|
"Fake requests, wrong SEQ/ACK: %d\n",
|
||||||
do_passivedpi, (do_fragment_http ? http_fragment_size : 0),
|
do_passivedpi, (do_fragment_http ? http_fragment_size : 0),
|
||||||
(do_fragment_http_persistent ? http_fragment_size : 0),
|
(do_fragment_http_persistent ? http_fragment_size : 0),
|
||||||
(do_fragment_https ? https_fragment_size : 0),
|
(do_fragment_https ? https_fragment_size : 0),
|
||||||
do_native_frag, do_reverse_frag,
|
do_native_frag, do_reverse_frag,
|
||||||
do_host, do_host_removespace, do_additional_space, do_host_mixedcase,
|
do_host, do_host_removespace, do_additional_space, do_host_mixedcase,
|
||||||
do_http_allports, do_fragment_http_persistent_nowait, do_dnsv4_redirect,
|
do_http_allports, do_fragment_http_persistent_nowait, do_dnsv4_redirect,
|
||||||
do_dnsv6_redirect, ttl_of_fake_packet, do_wrong_chksum
|
do_dnsv6_redirect, ttl_of_fake_packet, do_wrong_chksum,
|
||||||
|
do_wrong_seq
|
||||||
);
|
);
|
||||||
|
|
||||||
if (do_fragment_http && http_fragment_size > 2) {
|
if (do_fragment_http && http_fragment_size > 2) {
|
||||||
@ -863,7 +872,7 @@ int main(int argc, char *argv[]) {
|
|||||||
if (packet_dataLen >=2 && memcmp(packet_data, "\x16\x03", 2) == 0) {
|
if (packet_dataLen >=2 && memcmp(packet_data, "\x16\x03", 2) == 0) {
|
||||||
if (do_fake_packet) {
|
if (do_fake_packet) {
|
||||||
send_fake_https_request(w_filter, &addr, packet, packetLen, packet_v6,
|
send_fake_https_request(w_filter, &addr, packet, packetLen, packet_v6,
|
||||||
ttl_of_fake_packet, do_wrong_chksum);
|
ttl_of_fake_packet, do_wrong_chksum, do_wrong_seq);
|
||||||
}
|
}
|
||||||
if (do_native_frag) {
|
if (do_native_frag) {
|
||||||
// Signal for native fragmentation code handler
|
// Signal for native fragmentation code handler
|
||||||
@ -899,7 +908,8 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
if (do_fake_packet)
|
if (do_fake_packet)
|
||||||
send_fake_http_request(w_filter, &addr, packet, packetLen, packet_v6,
|
send_fake_http_request(w_filter, &addr, packet, packetLen, packet_v6,
|
||||||
ttl_of_fake_packet, do_wrong_chksum);
|
ttl_of_fake_packet, do_wrong_chksum, do_wrong_seq);
|
||||||
|
}
|
||||||
|
|
||||||
if (do_host_mixedcase) {
|
if (do_host_mixedcase) {
|
||||||
mix_case(host_addr, host_len);
|
mix_case(host_addr, host_len);
|
||||||
|
Loading…
Reference in New Issue
Block a user