nfqws: wireguard protocol recognition

This commit is contained in:
bol-van 2023-08-12 09:56:19 +03:00
parent b80c501eb9
commit bc6b683009
14 changed files with 38 additions and 16 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -727,6 +727,13 @@ packet_process_result dpi_desync_udp_packet(uint32_t fwmark, const char *ifout,
} }
bKnownProtocol = true; bKnownProtocol = true;
} }
else if (IsWireguardHandshakeInitiation(data_payload,len_payload))
{
DLOG("packet contains wireguard handshake initiation\n")
fake = params.fake_wg;
fake_size = params.fake_wg_size;
bKnownProtocol = true;
}
else else
{ {
if (!params.desync_any_proto) return res; if (!params.desync_any_proto) return res;

View File

@ -546,6 +546,7 @@ static void exithelp()
" --dpi-desync-fake-tls=<filename>\t; file containing fake TLS ClientHello (for https)\n" " --dpi-desync-fake-tls=<filename>\t; file containing fake TLS ClientHello (for https)\n"
" --dpi-desync-fake-unknown=<filename>\t; file containing unknown protocol fake payload\n" " --dpi-desync-fake-unknown=<filename>\t; file containing unknown protocol fake payload\n"
" --dpi-desync-fake-quic=<filename>\t; file containing fake QUIC Initial\n" " --dpi-desync-fake-quic=<filename>\t; file containing fake QUIC Initial\n"
" --dpi-desync-fake-wireguard=<filename>\t; file containing fake wireguard handshake initiation\n"
" --dpi-desync-fake-unknown-udp=<filename> ; file containing unknown udp protocol fake payload\n" " --dpi-desync-fake-unknown-udp=<filename> ; file containing unknown udp protocol fake payload\n"
" --dpi-desync-udplen-increment=<int>\t; increase or decrease udp packet length by N bytes (default %u). negative values decrease length.\n" " --dpi-desync-udplen-increment=<int>\t; increase or decrease udp packet length by N bytes (default %u). negative values decrease length.\n"
" --dpi-desync-cutoff=[n|d|s]N\t\t; apply dpi desync only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N\n" " --dpi-desync-cutoff=[n|d|s]N\t\t; apply dpi desync only to packet numbers (n, default), data packet numbers (d), relative sequence (s) less than N\n"
@ -645,6 +646,7 @@ int main(int argc, char **argv)
memcpy(params.fake_http,fake_http_request_default,params.fake_http_size); memcpy(params.fake_http,fake_http_request_default,params.fake_http_size);
params.fake_quic_size = 620; // must be 601+ for TSPU hack params.fake_quic_size = 620; // must be 601+ for TSPU hack
params.fake_quic[0] = 0x40; // russian TSPU QUIC short header fake params.fake_quic[0] = 0x40; // russian TSPU QUIC short header fake
params.fake_wg_size = 64;
params.fake_unknown_size = 256; params.fake_unknown_size = 256;
params.fake_unknown_udp_size = 64; params.fake_unknown_udp_size = 64;
params.wscale=-1; // default - dont change scale factor (client) params.wscale=-1; // default - dont change scale factor (client)
@ -712,14 +714,15 @@ int main(int argc, char **argv)
{"dpi-desync-fake-tls",required_argument,0,0},// optidx=29 {"dpi-desync-fake-tls",required_argument,0,0},// optidx=29
{"dpi-desync-fake-unknown",required_argument,0,0},// optidx=30 {"dpi-desync-fake-unknown",required_argument,0,0},// optidx=30
{"dpi-desync-fake-quic",required_argument,0,0},// optidx=31 {"dpi-desync-fake-quic",required_argument,0,0},// optidx=31
{"dpi-desync-fake-unknown-udp",required_argument,0,0},// optidx=32 {"dpi-desync-fake-wireguard",required_argument,0,0},// optidx=32
{"dpi-desync-udplen-increment",required_argument,0,0},// optidx=33 {"dpi-desync-fake-unknown-udp",required_argument,0,0},// optidx=33
{"dpi-desync-cutoff",required_argument,0,0},// optidx=34 {"dpi-desync-udplen-increment",required_argument,0,0},// optidx=34
{"hostlist",required_argument,0,0}, // optidx=35 {"dpi-desync-cutoff",required_argument,0,0},// optidx=35
{"hostlist-exclude",required_argument,0,0}, // optidx=36 {"hostlist",required_argument,0,0}, // optidx=36
{"hostlist-exclude",required_argument,0,0}, // optidx=37
#ifdef __linux__ #ifdef __linux__
{"bind-fix4",no_argument,0,0}, // optidx=37 {"bind-fix4",no_argument,0,0}, // optidx=38
{"bind-fix6",no_argument,0,0}, // optidx=38 {"bind-fix6",no_argument,0,0}, // optidx=39
#endif #endif
{NULL,0,NULL,0} {NULL,0,NULL,0}
}; };
@ -1001,32 +1004,36 @@ int main(int argc, char **argv)
params.fake_quic_size = sizeof(params.fake_quic); params.fake_quic_size = sizeof(params.fake_quic);
load_file_or_exit(optarg,params.fake_quic,&params.fake_quic_size); load_file_or_exit(optarg,params.fake_quic,&params.fake_quic_size);
break; break;
case 32: /* dpi-desync-fake-unknown-udp */ case 32: /* dpi-desync-fake-wireguard */
params.fake_wg_size = sizeof(params.fake_wg);
load_file_or_exit(optarg,params.fake_wg,&params.fake_wg_size);
break;
case 33: /* dpi-desync-fake-unknown-udp */
params.fake_unknown_udp_size = sizeof(params.fake_unknown_udp); params.fake_unknown_udp_size = sizeof(params.fake_unknown_udp);
load_file_or_exit(optarg,params.fake_unknown_udp,&params.fake_unknown_udp_size); load_file_or_exit(optarg,params.fake_unknown_udp,&params.fake_unknown_udp_size);
break; break;
case 33: /* dpi-desync-udplen-increment */ case 34: /* dpi-desync-udplen-increment */
if (sscanf(optarg,"%d",&params.udplen_increment)<1 || params.udplen_increment>0x7FFF || params.udplen_increment<-0x8000) if (sscanf(optarg,"%d",&params.udplen_increment)<1 || params.udplen_increment>0x7FFF || params.udplen_increment<-0x8000)
{ {
fprintf(stderr, "dpi-desync-udplen-increment must be integer within -32768..32767 range\n"); fprintf(stderr, "dpi-desync-udplen-increment must be integer within -32768..32767 range\n");
exit_clean(1); exit_clean(1);
} }
break; break;
case 34: /* desync-cutoff */ case 35: /* desync-cutoff */
if (!parse_cutoff(optarg, &params.desync_cutoff, &params.desync_cutoff_mode)) if (!parse_cutoff(optarg, &params.desync_cutoff, &params.desync_cutoff_mode))
{ {
fprintf(stderr, "invalid desync-cutoff value\n"); fprintf(stderr, "invalid desync-cutoff value\n");
exit_clean(1); exit_clean(1);
} }
break; break;
case 35: /* hostlist */ case 36: /* hostlist */
if (!strlist_add(&params.hostlist_files, optarg)) if (!strlist_add(&params.hostlist_files, optarg))
{ {
fprintf(stderr, "strlist_add failed\n"); fprintf(stderr, "strlist_add failed\n");
exit_clean(1); exit_clean(1);
} }
break; break;
case 36: /* hostlist-exclude */ case 37: /* hostlist-exclude */
if (!strlist_add(&params.hostlist_exclude_files, optarg)) if (!strlist_add(&params.hostlist_exclude_files, optarg))
{ {
fprintf(stderr, "strlist_add failed\n"); fprintf(stderr, "strlist_add failed\n");
@ -1034,10 +1041,10 @@ int main(int argc, char **argv)
} }
break; break;
#ifdef __linux__ #ifdef __linux__
case 37: /* bind-fix4 */ case 38: /* bind-fix4 */
params.bind_fix4 = true; params.bind_fix4 = true;
break; break;
case 38: /* bind-fix6 */ case 39: /* bind-fix6 */
params.bind_fix6 = true; params.bind_fix6 = true;
break; break;
#endif #endif

View File

@ -50,8 +50,8 @@ struct params_s
uint8_t desync_fooling_mode; uint8_t desync_fooling_mode;
uint32_t desync_fwmark; // unused in BSD uint32_t desync_fwmark; // unused in BSD
uint32_t desync_badseq_increment, desync_badseq_ack_increment; uint32_t desync_badseq_increment, desync_badseq_ack_increment;
uint8_t fake_http[1432],fake_tls[1432],fake_unknown[1432],fake_unknown_udp[1472],fake_quic[1472]; uint8_t fake_http[1432],fake_tls[1432],fake_quic[1472],fake_wg[1472],fake_unknown[1432],fake_unknown_udp[1472];
size_t fake_http_size,fake_tls_size,fake_unknown_size,fake_unknown_udp_size,fake_quic_size; size_t fake_http_size,fake_tls_size,fake_quic_size,fake_wg_size,fake_unknown_size,fake_unknown_udp_size;
int udplen_increment; int udplen_increment;
bool droproot; bool droproot;
uid_t uid; uid_t uid;

View File

@ -188,6 +188,12 @@ bool TLSHelloExtractHostFromHandshake(const uint8_t *data, size_t len, char *hos
} }
bool IsWireguardHandshakeInitiation(const uint8_t *data, size_t len)
{
return len==148 && data[0]==1 && data[1]==0 && data[2]==0 && data[3]==0;
}
/* Returns the QUIC draft version or 0 if not applicable. */ /* Returns the QUIC draft version or 0 if not applicable. */
uint8_t QUICDraftVersion(uint32_t version) uint8_t QUICDraftVersion(uint32_t version)
{ {

View File

@ -15,6 +15,8 @@ bool TLSFindExtInHandshake(const uint8_t *data, size_t len, uint16_t type, const
bool TLSHelloExtractHost(const uint8_t *data, size_t len, char *host, size_t len_host); bool TLSHelloExtractHost(const uint8_t *data, size_t len, char *host, size_t len_host);
bool TLSHelloExtractHostFromHandshake(const uint8_t *data, size_t len, char *host, size_t len_host); bool TLSHelloExtractHostFromHandshake(const uint8_t *data, size_t len, char *host, size_t len_host);
bool IsWireguardHandshakeInitiation(const uint8_t *data, size_t len);
#define QUIC_MAX_CID_LENGTH 20 #define QUIC_MAX_CID_LENGTH 20
typedef struct quic_cid { typedef struct quic_cid {
uint8_t len; uint8_t len;