From f0e68527ba794d161fbaa08f87faa01419ffa0e2 Mon Sep 17 00:00:00 2001 From: bol-van Date: Sat, 9 Nov 2024 15:53:28 +0300 Subject: [PATCH 1/6] nfqws,tpws: snisld split --- nfq/desync.c | 2 +- nfq/nfqws.c | 4 ++- nfq/protocol.c | 82 ++++++++++++++++++++++++++++++++++++------------- nfq/protocol.h | 2 +- tpws/protocol.c | 81 +++++++++++++++++++++++++++++++++++------------- tpws/protocol.h | 2 +- tpws/tpws.c | 6 ++-- 7 files changed, 131 insertions(+), 48 deletions(-) diff --git a/nfq/desync.c b/nfq/desync.c index 7251e49..cf942e1 100644 --- a/nfq/desync.c +++ b/nfq/desync.c @@ -1270,7 +1270,7 @@ static uint8_t dpi_desync_tcp_packet_play(bool replay, size_t reasm_offset, uint seg_len = dis->len_payload-split_pos; } - if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, net32_add(net32_add(dis->tcp->th_seq,split_pos),-dp->desync_seqovl), dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps, + if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, net32_add(dis->tcp->th_seq , split_pos - dp->desync_seqovl), dis->tcp->th_ack, dis->tcp->th_win, scale_factor, timestamps, ttl_orig,IP4_TOS(dis->ip),IP6_FLOW(dis->ip6), fooling_orig,dp->desync_badseq_increment,dp->desync_badseq_ack_increment, seg, seg_len, pkt1, &pkt1_len)) diff --git a/nfq/nfqws.c b/nfq/nfqws.c index a27ffcf..e07054f 100644 --- a/nfq/nfqws.c +++ b/nfq/nfqws.c @@ -927,7 +927,7 @@ static void exithelp(void) " --dpi-desync-skip-nosni=0|1\t\t\t; 1(default)=do not act on ClientHello without SNI (ESNI ?)\n" " --dpi-desync-split-pos=<1..%u>\t\t; data payload split position\n" " --dpi-desync-split-http-req=method|host\t; split at specified logical part of plain http request\n" - " --dpi-desync-split-tls=sni|sniext\t\t; split at specified logical part of TLS ClientHello\n" + " --dpi-desync-split-tls=sni|sniext|snisld\t; split at specified logical part of TLS ClientHello\n" " --dpi-desync-split-seqovl=\t\t; use sequence overlap before first sent original split segment\n" " --dpi-desync-split-seqovl-pattern=|0xHEX ; pattern for the fake part of overlap\n" " --dpi-desync-ipfrag-pos-tcp=<8..%u>\t\t; ip frag position starting from the transport header. multiple of 8, default %u.\n" @@ -983,6 +983,8 @@ bool parse_tlspos(const char *s, enum tlspos *pos) *pos = tlspos_sni; else if (!strcmp(s, "sniext")) *pos = tlspos_sniext; + else if (!strcmp(s, "snisld")) + *pos = tlspos_snisld; else return false; return true; diff --git a/nfq/protocol.c b/nfq/protocol.c index b83607e..bec8362 100644 --- a/nfq/protocol.c +++ b/nfq/protocol.c @@ -7,6 +7,23 @@ #include #include +// find N level domain +static bool FindNLD(const uint8_t *dom, size_t dlen, int level, const uint8_t **p, size_t *len) +{ + int i; + const uint8_t *p1,*p2; + for (i=1,p2=dom+dlen;idom && *p2!='.'; p2--); + if (p2<=dom) return false; + } + for (p1=p2-1 ; p1>dom && *p1!='.'; p1--); + if (*p1=='.') p1++; + if (p) *p = p1; + if (len) *len = p2-p1; + return true; +} + const char *http_methods[] = { "GET /","POST /","HEAD /","OPTIONS /","PUT /","DELETE /","CONNECT /","TRACE /",NULL }; const char *HttpMethod(const uint8_t *data, size_t len) { @@ -116,17 +133,6 @@ bool HttpExtractHost(const uint8_t *data, size_t len, char *host, size_t len_hos { return HttpExtractHeader(data, len, "\nHost:", host, len_host); } -const char *HttpFind2ndLevelDomain(const char *host) -{ - const char *p=NULL; - if (*host) - { - for (p = host + strlen(host)-1; p>host && *p!='.'; p--); - if (*p=='.') for (p--; p>host && *p!='.'; p--); - if (*p=='.') p++; - } - return p; -} // DPI redirects are global redirects to another domain bool HttpReplyLooksLikeDPIRedirect(const uint8_t *data, size_t len, const char *host) { @@ -157,10 +163,11 @@ bool HttpReplyLooksLikeDPIRedirect(const uint8_t *data, size_t len, const char * // somethinkg like : censor.net // extract 2nd level domains + const char *dhost, *drhost; + if (!FindNLD((uint8_t*)host,strlen(host),2,(const uint8_t**)&dhost,NULL) || !FindNLD((uint8_t*)redirect_host,strlen(redirect_host),2,(const uint8_t**)&drhost,NULL)) + return false; - const char *dhost = HttpFind2ndLevelDomain(host); - const char *drhost = HttpFind2ndLevelDomain(redirect_host); - + // compare 2nd level domains return strcasecmp(dhost, drhost)!=0; } size_t HttpPos(enum httpreqpos tpos_type, size_t hpos_pos, const uint8_t *http, size_t sz) @@ -305,15 +312,24 @@ bool TLSFindExt(const uint8_t *data, size_t len, uint16_t type, const uint8_t ** if (reclen= len_host) slen = len_host - 1; @@ -338,22 +354,46 @@ bool TLSHelloExtractHostFromHandshake(const uint8_t *data, size_t len, char *hos if (!TLSFindExtInHandshake(data, len, 0, &ext, &elen, bPartialIsOK)) return false; return TLSExtractHostFromExt(ext, elen, host, len_host); } + +// find N level domain in SNI +static bool TLSHelloFindNLDInSNI(const uint8_t *ext, size_t elen, int level, const uint8_t **p, size_t *len) +{ + size_t slen; + return TLSAdvanceToHostInSNI(&ext,&elen,&slen) && FindNLD(ext,slen,level,p,len); +} +// find the middle of second level domain (SLD) in SNI ext : www.sobaka.ru => aka.ru +// return false if SNI ext is bad or SLD is not found +static bool TLSHelloFindMiddleOfSLDInSNI(const uint8_t *ext, size_t elen, const uint8_t **p) +{ + size_t len; + if (!TLSHelloFindNLDInSNI(ext,elen,2,p,&len)) + return false; + // in case of one letter SLD (x.com) we split at '.' to prevent appearance of the whole SLD + *p = (len==1) ? *p+1 : *p+len/2; + return true; +} size_t TLSPos(enum tlspos tpos_type, size_t tpos_pos, const uint8_t *tls, size_t sz, uint8_t type) { size_t elen; - const uint8_t *ext; + const uint8_t *ext, *p; switch(tpos_type) { case tlspos_sni: case tlspos_sniext: if (TLSFindExt(tls,sz,0,&ext,&elen,false)) return (tpos_type==tlspos_sni) ? ext-tls+6 : ext-tls+1; - // fall through + break; + case tlspos_snisld: + if (TLSFindExt(tls,sz,0,&ext,&elen,false)) + if (TLSHelloFindMiddleOfSLDInSNI(ext,elen,&p)) + return p-tls; + break; case tlspos_pos: - return tpos_pos #include +// find N level domain +static bool FindNLD(const uint8_t *dom, size_t dlen, int level, const uint8_t **p, size_t *len) +{ + int i; + const uint8_t *p1,*p2; + for (i=1,p2=dom+dlen;idom && *p2!='.'; p2--); + if (p2<=dom) return false; + } + for (p1=p2-1 ; p1>dom && *p1!='.'; p1--); + if (*p1=='.') p1++; + if (p) *p = p1; + if (len) *len = p2-p1; + return true; +} const char *http_methods[] = { "GET /","POST /","HEAD /","OPTIONS /","PUT /","DELETE /","CONNECT /","TRACE /",NULL }; const char *HttpMethod(const uint8_t *data, size_t len) @@ -116,17 +132,6 @@ bool HttpExtractHost(const uint8_t *data, size_t len, char *host, size_t len_hos { return HttpExtractHeader(data, len, "\nHost:", host, len_host); } -const char *HttpFind2ndLevelDomain(const char *host) -{ - const char *p=NULL; - if (*host) - { - for (p = host + strlen(host)-1; p>host && *p!='.'; p--); - if (*p=='.') for (p--; p>host && *p!='.'; p--); - if (*p=='.') p++; - } - return p; -} // DPI redirects are global redirects to another domain bool HttpReplyLooksLikeDPIRedirect(const uint8_t *data, size_t len, const char *host) { @@ -157,10 +162,11 @@ bool HttpReplyLooksLikeDPIRedirect(const uint8_t *data, size_t len, const char * // somethinkg like : censor.net // extract 2nd level domains + const char *dhost, *drhost; + if (!FindNLD((uint8_t*)host,strlen(host),2,(const uint8_t**)&dhost,NULL) || !FindNLD((uint8_t*)redirect_host,strlen(redirect_host),2,(const uint8_t**)&drhost,NULL)) + return false; - const char *dhost = HttpFind2ndLevelDomain(host); - const char *drhost = HttpFind2ndLevelDomain(redirect_host); - + // compare 2nd level domains return strcasecmp(dhost, drhost)!=0; } size_t HttpPos(enum httpreqpos tpos_type, size_t hpos_pos, const uint8_t *http, size_t sz) @@ -295,15 +301,24 @@ bool TLSFindExt(const uint8_t *data, size_t len, uint16_t type, const uint8_t ** if (reclen= len_host) slen = len_host - 1; @@ -328,20 +343,44 @@ bool TLSHelloExtractHostFromHandshake(const uint8_t *data, size_t len, char *hos if (!TLSFindExtInHandshake(data, len, 0, &ext, &elen, bPartialIsOK)) return false; return TLSExtractHostFromExt(ext, elen, host, len_host); } + +// find N level domain in SNI +static bool TLSHelloFindNLDInSNI(const uint8_t *ext, size_t elen, int level, const uint8_t **p, size_t *len) +{ + size_t slen; + return TLSAdvanceToHostInSNI(&ext,&elen,&slen) && FindNLD(ext,slen,level,p,len); +} +// find the middle of second level domain (SLD) in SNI ext : www.sobaka.ru => aka.ru +// return false if SNI ext is bad or SLD is not found +static bool TLSHelloFindMiddleOfSLDInSNI(const uint8_t *ext, size_t elen, const uint8_t **p) +{ + size_t len; + if (!TLSHelloFindNLDInSNI(ext,elen,2,p,&len)) + return false; + // in case of one letter SLD (x.com) we split at '.' to prevent appearance of the whole SLD + *p = (len==1) ? *p+1 : *p+len/2; + return true; +} size_t TLSPos(enum tlspos tpos_type, size_t tpos_pos, const uint8_t *tls, size_t sz, uint8_t type) { size_t elen; - const uint8_t *ext; + const uint8_t *ext, *p; switch(tpos_type) { case tlspos_sni: case tlspos_sniext: if (TLSFindExt(tls,sz,0,&ext,&elen,false)) return (tpos_type==tlspos_sni) ? ext-tls+6 : ext-tls+1; - // fall through + break; + case tlspos_snisld: + if (TLSFindExt(tls,sz,0,&ext,&elen,false)) + if (TLSHelloFindMiddleOfSLDInSNI(ext,elen,&p)) + return p-tls; + break; case tlspos_pos: - return tpos_pos\t; debug auto hostlist positives\n" "\nTAMPER:\n" " --split-http-req=method|host\t\t; split at specified logical part of plain http request\n" - " --split-tls=sni|sniext\t\t\t; split at specified logical part of TLS ClientHello\n" + " --split-tls=sni|sniext|snisld\t\t; split at specified logical part of TLS ClientHello\n" " --split-pos=\t\t; split at specified pos. split-http-req or split-tls take precedence for http.\n" " --split-any-protocol\t\t\t; split not only http and https\n" #if defined(BSD) && !defined(__APPLE__) @@ -203,7 +203,7 @@ static void exithelp(void) " --methodspace\t\t\t\t; add extra space after method\n" " --methodeol\t\t\t\t; add end-of-line before method\n" " --unixeol\t\t\t\t; replace 0D0A to 0A\n" - " --tlsrec=sni|sniext\t\t\t; make 2 TLS records. split at specified logical part. don't split if SNI is not present\n" + " --tlsrec=sni|sniext|snisld\t\t; make 2 TLS records. split at specified logical part. don't split if SNI is not present\n" " --tlsrec-pos=\t\t\t; make 2 TLS records. split at specified pos\n" #ifdef __linux__ " --mss=\t\t\t\t; set client MSS. forces server to split messages but significantly decreases speed !\n" @@ -292,6 +292,8 @@ bool parse_tlspos(const char *s, enum tlspos *pos) *pos = tlspos_sni; else if (!strcmp(s, "sniext")) *pos = tlspos_sniext; + else if (!strcmp(s, "snisld")) + *pos = tlspos_snisld; else return false; return true; From 07b8567bebceafe4dc4472d26853b70558cd0b2f Mon Sep 17 00:00:00 2001 From: bol-van Date: Sat, 9 Nov 2024 16:46:23 +0300 Subject: [PATCH 2/6] readme: scammers notice --- docs/readme.en.md | 7 ++++++- docs/readme.md | 5 +++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/docs/readme.en.md b/docs/readme.en.md index ccd2640..612ea9e 100644 --- a/docs/readme.en.md +++ b/docs/readme.en.md @@ -1,4 +1,9 @@ -# zapret v.67 +# zapret v.68 + +# SCAMMER WARNING + +This software is free and open source under [MIT license](./LICENSE.txt). +If anyone demands you to download this software only from their webpage, telegram channel, forces you to delete links, videos, makes copyright claims, you are dealing with scammers. # Multilanguage/Мультиязычный README ___ diff --git a/docs/readme.md b/docs/readme.md index bd3c226..e714636 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -1,5 +1,10 @@ # zapret v.68 +# ВНИМАНИЕ, остерегайтесь мошенников + +zapret является свободным и open source. +Всякий, кто понуждает вас скачивать zapret только с его ресурса, требует удалить ссылки, видео, файлы, обосновывая эти требования авторскими правами, сам нарушает [лицензию](./LICENSE.txt). + # Multilanguage README [![en](https://img.shields.io/badge/lang-en-red.svg)](./readme.en.md) From 591b246ed69006b20a27fd08b405ea29943b6ed0 Mon Sep 17 00:00:00 2001 From: bol-van Date: Sat, 9 Nov 2024 23:33:33 +0300 Subject: [PATCH 3/6] mdig: fix text mode std io in windows --- mdig/mdig.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/mdig/mdig.c b/mdig/mdig.c index d50c1cc..6521f5f 100644 --- a/mdig/mdig.c +++ b/mdig/mdig.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #include #ifdef _WIN32 @@ -21,7 +20,9 @@ #include #include #include +#include #else +#include #include #include #include @@ -364,6 +365,9 @@ int dns_make_query(const char *dom, char family) fprintf(stderr, "could not make DNS query\n"); return 1; } +#ifdef _WIN32 + _setmode(_fileno(stdout), _O_BINARY); +#endif if (fwrite(q,l,1,stdout)!=1) { fprintf(stderr, "could not write DNS query blob to stdout\n"); @@ -422,6 +426,9 @@ int dns_parse_query() { uint8_t a[1500]; size_t l; +#ifdef _WIN32 + _setmode(_fileno(stdin), _O_BINARY); +#endif l = fread(a,1,sizeof(a),stdin); if (!l || !feof(stdin)) { From c16b125a555102a20d6b9f3208262204b5f43a03 Mon Sep 17 00:00:00 2001 From: bol-van Date: Sun, 10 Nov 2024 14:20:14 +0300 Subject: [PATCH 4/6] makefiles: -Os --- ip2net/Makefile | 2 +- mdig/Makefile | 2 +- nfq/BSDmakefile | 2 +- nfq/Makefile | 2 +- tpws/BSDmakefile | 2 +- tpws/Makefile | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ip2net/Makefile b/ip2net/Makefile index 97a53d7..56f6b17 100644 --- a/ip2net/Makefile +++ b/ip2net/Makefile @@ -1,5 +1,5 @@ CC ?= gcc -CFLAGS += -std=gnu99 -O3 +CFLAGS += -std=gnu99 -Os CFLAGS_BSD = -Wno-address-of-packed-member CFLAGS_WIN = -static LIBS = diff --git a/mdig/Makefile b/mdig/Makefile index 58bc4b4..0100b5b 100644 --- a/mdig/Makefile +++ b/mdig/Makefile @@ -1,5 +1,5 @@ CC ?= gcc -CFLAGS += -std=gnu99 -O3 +CFLAGS += -std=gnu99 -Os CFLAGS_BSD = -Wno-address-of-packed-member CFLAGS_WIN = -static LIBS = -lpthread diff --git a/nfq/BSDmakefile b/nfq/BSDmakefile index 1717340..ff5475e 100644 --- a/nfq/BSDmakefile +++ b/nfq/BSDmakefile @@ -1,5 +1,5 @@ CC ?= cc -CFLAGS += -std=gnu99 -s -O3 -Wno-address-of-packed-member +CFLAGS += -std=gnu99 -s -Os -Wno-address-of-packed-member LIBS = -lz SRC_FILES = *.c crypto/*.c diff --git a/nfq/Makefile b/nfq/Makefile index fb8c900..e2a1779 100644 --- a/nfq/Makefile +++ b/nfq/Makefile @@ -1,5 +1,5 @@ CC ?= gcc -CFLAGS += -std=gnu99 -O3 +CFLAGS += -std=gnu99 -Os CFLAGS_BSD = -Wno-address-of-packed-member CFLAGS_MAC = -mmacosx-version-min=10.8 CFLAGS_CYGWIN = -Wno-address-of-packed-member -static diff --git a/tpws/BSDmakefile b/tpws/BSDmakefile index 568f67b..e9ad901 100644 --- a/tpws/BSDmakefile +++ b/tpws/BSDmakefile @@ -1,5 +1,5 @@ CC ?= cc -CFLAGS += -std=gnu99 -s -O3 +CFLAGS += -std=gnu99 -s -Os LIBS = -lz -lpthread SRC_FILES = *.c diff --git a/tpws/Makefile b/tpws/Makefile index 52b72f7..b2b00ea 100644 --- a/tpws/Makefile +++ b/tpws/Makefile @@ -1,5 +1,5 @@ CC ?= gcc -CFLAGS += -std=gnu99 -O3 +CFLAGS += -std=gnu99 -Os CFLAGS_BSD = -Wno-address-of-packed-member LIBS = -lz -lpthread SRC_FILES = *.c From 925fdd633a48c7522bc791c981a244cd2585c8ad Mon Sep 17 00:00:00 2001 From: bol-van Date: Sun, 10 Nov 2024 17:26:13 +0300 Subject: [PATCH 5/6] docs works --- docs/readme.md | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/readme.md b/docs/readme.md index e714636..2abf35e 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -1318,9 +1318,9 @@ linux, но через раз приобретает статус INVALID в con она стабильна, на третьих полный хаос, и проще отказаться. `Blockcheck` имеет 3 уровня сканирования. -Цель режима quick - максимально быстро найти хоть что-то работающее.\ -`standard` дает возможность провести исследование как и на что реагирует DPI в плане методов обхода.\ -`force` дает максимум проверок даже в случаях, когда ресурс работает без обхода или с более простыми стратегиями. +* `quick` - максимально быстро найти хоть что-то работающее. +* `standard` дает возможность провести исследование как и на что реагирует DPI в плане методов обхода. +* `force` дает максимум проверок даже в случаях, когда ресурс работает без обхода или с более простыми стратегиями. Есть ряд других параметров, которые не будут спрашиваться в диалоге, но которые можно переопределить через переменные. @@ -1338,9 +1338,10 @@ PKTWS_EXTRA_1 .. PKTWS_EXTRA_9, TPWS_EXTRA_1 .. TPWS_EXTRA_9 - отдельно SECURE_DNS=0|1 - принудительно выключить или включить DoH DOH_SERVERS - список URL DoH через пробел для автоматического выбора работающего сервера DOH_SERVER - конкретный DoH URL, отказ от поиска +CURL - замена программы curl ``` -Пример запуска с переменными: `SECURE_DNS=1 SKIP_TPWS=1 CURL_MAX_TIME=1 ./blockcheck.sh` +Пример запуска с переменными: `SECURE_DNS=1 SKIP_TPWS=1 CURL_MAX_TIME=1 CURL=/tmp/curl ./blockcheck.sh` **СКАН ПОРТОВ**\ Если в системе присутствует совместимый `netcat` (ncat от nmap или openbsd ncat. в openwrt по умолчанию нет), From 41b4c6650b13707654066b5af007d531dd348286 Mon Sep 17 00:00:00 2001 From: bol-van Date: Sun, 10 Nov 2024 17:27:25 +0300 Subject: [PATCH 6/6] docs works --- docs/readme.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/readme.md b/docs/readme.md index 2abf35e..e93b529 100644 --- a/docs/readme.md +++ b/docs/readme.md @@ -1341,7 +1341,8 @@ DOH_SERVER - конкретный DoH URL, отказ от поиска CURL - замена программы curl ``` -Пример запуска с переменными: `SECURE_DNS=1 SKIP_TPWS=1 CURL_MAX_TIME=1 CURL=/tmp/curl ./blockcheck.sh` +Пример запуска с переменными:\ +`SECURE_DNS=1 SKIP_TPWS=1 CURL_MAX_TIME=1 CURL=/tmp/curl ./blockcheck.sh` **СКАН ПОРТОВ**\ Если в системе присутствует совместимый `netcat` (ncat от nmap или openbsd ncat. в openwrt по умолчанию нет),