diff --git a/binaries/aarch64/nfqws b/binaries/aarch64/nfqws index 966b1688..6fedd57d 100755 Binary files a/binaries/aarch64/nfqws and b/binaries/aarch64/nfqws differ diff --git a/binaries/armhf/nfqws b/binaries/armhf/nfqws index 7c6b3469..88944d55 100755 Binary files a/binaries/armhf/nfqws and b/binaries/armhf/nfqws differ diff --git a/binaries/mips32r1-lsb/nfqws b/binaries/mips32r1-lsb/nfqws index c969d1cf..e16d325c 100755 Binary files a/binaries/mips32r1-lsb/nfqws and b/binaries/mips32r1-lsb/nfqws differ diff --git a/binaries/mips32r1-msb/nfqws b/binaries/mips32r1-msb/nfqws index 9e370301..a5b15e42 100755 Binary files a/binaries/mips32r1-msb/nfqws and b/binaries/mips32r1-msb/nfqws differ diff --git a/binaries/mips64r2-msb/nfqws b/binaries/mips64r2-msb/nfqws index 6970582a..d9340a3a 100755 Binary files a/binaries/mips64r2-msb/nfqws and b/binaries/mips64r2-msb/nfqws differ diff --git a/binaries/ppc/nfqws b/binaries/ppc/nfqws index 59617696..5b347df2 100755 Binary files a/binaries/ppc/nfqws and b/binaries/ppc/nfqws differ diff --git a/binaries/x86/nfqws b/binaries/x86/nfqws index d0a54c60..9743f20c 100755 Binary files a/binaries/x86/nfqws and b/binaries/x86/nfqws differ diff --git a/binaries/x86_64/nfqws b/binaries/x86_64/nfqws index f58bd86a..5690c1ed 100755 Binary files a/binaries/x86_64/nfqws and b/binaries/x86_64/nfqws differ diff --git a/docs/readme.eng.txt b/docs/readme.eng.txt index dcdbb388..90773147 100644 --- a/docs/readme.eng.txt +++ b/docs/readme.eng.txt @@ -139,7 +139,7 @@ It takes the following parameters: --pidfile= ; write pid to file --user= ; drop root privs --uid=uid[:gid] ; drop root privs - --dpi-desync[=fake|rst|rstack|disorder] ; try to desync dpi state + --dpi-desync[=] ; try to desync dpi state. modes : fake rst rstack disorder disorder2 --dpi-desync-fwmark= ; override fwmark for desync packet. default = 0x40000000 --dpi-desync-ttl= ; set ttl for desync packet --dpi-desync-fooling=none|md5sig|badsum @@ -192,6 +192,7 @@ If position is higher than packet length, pos=1 is used. This sequence is designed to make reconstruction of critical message as difficult as possible. Fake segments may not be required to bypass some DPIs, but can potentially help if more sophisticated reconstruction algorithms are used. +Mode 'disorder2' disables sending of fake segments. It can be used as a faster alternative to --wsize. Hostlist is applicable only to desync attack. It does not work for other options. Hosts are extracted from plain http request Host: header and SNI of ClientHelllo TLS message. diff --git a/docs/readme.txt b/docs/readme.txt index f3c4134b..8a0d0988 100644 --- a/docs/readme.txt +++ b/docs/readme.txt @@ -167,7 +167,7 @@ nfqws --hostcase ; менять регистр заголовка "Host:" по умолчанию на "host:". --hostnospace ; убрать пробел после "Host:" и переместить его в конец значения "User-Agent:" для сохранения длины пакета --hostspell=HoST ; точное написание заголовка Host (можно "HOST" или "HoSt"). автоматом включает --hostcase - --dpi-desync[=fake|rst|rstack|disorder ; атака по десинхронизации DPI + --dpi-desync[=] ; атака по десинхронизации DPI. mode : fake rst rstack disorder disorder2 --dpi-desync-fwmark= ; бит fwmark для пометки десинхронизирующих пакетов, чтобы они повторно не падали в очередь. default = 0x40000000 --dpi-desync-ttl= ; установить ttl для десинхронизирующих пакетов --dpi-desync-fooling=none|md5sig|badsum ; дополнительные методики как сделать, чтобы десинхронизирующий пакет не дошел до сервера @@ -222,6 +222,7 @@ nfqws Этой последовательностью для DPI максимально усложняется задача реконструкции начального сообщения, по которому принимается решение о блокировке. Некоторым DPI хватит и tcp сегментов в неправильном порядке, поддельные части сделаны для дополнительной надежности и более сложных алгоритмов реконструкции. +Режим disorder2 отключает отправку поддельных частей. Он может быть использован как более быстрая альтернатива --wsize. hostlist относится только к атаке desync. он не работает для других параметров. при попытке запустить nfqws с hostlist и без dpi-desync будет ошибка. Хосты извлекаются из Host: хедера обычных http запросов и из SNI в TLS ClientHello. diff --git a/nfq/nfqws.c b/nfq/nfqws.c index 11bceb17..b591cde2 100644 --- a/nfq/nfqws.c +++ b/nfq/nfqws.c @@ -75,7 +75,8 @@ enum dpi_desync_mode { DESYNC_FAKE, DESYNC_RST, DESYNC_RSTACK, - DESYNC_DISORDER + DESYNC_DISORDER, + DESYNC_DISORDER2 }; @@ -550,6 +551,7 @@ static bool dpi_desync_packet(const uint8_t *data_pkt, size_t len_pkt, const str } break; case DESYNC_DISORDER: + case DESYNC_DISORDER2: { size_t split_pos=len_payload>params.desync_split_pos ? params.desync_split_pos : 1; uint8_t fakeseg[1600]; @@ -568,14 +570,17 @@ static bool dpi_desync_packet(const uint8_t *data_pkt, size_t len_pkt, const str } - DLOG("sending fake(1) 1st out-of-order tcp segment 0-%zu len=%zu\n",split_pos-1, split_pos) - fakeseg_len = sizeof(fakeseg); - if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->seq, tcphdr->ack_seq, - ttl_fake,params.desync_tcp_fooling_mode, - zeropkt, split_pos, fakeseg, &fakeseg_len) || - !rawsend((struct sockaddr *)&dst, params.desync_fwmark, fakeseg, fakeseg_len)) + if (params.desync_mode==DESYNC_DISORDER) { - return false; + DLOG("sending fake(1) 1st out-of-order tcp segment 0-%zu len=%zu\n",split_pos-1, split_pos) + fakeseg_len = sizeof(fakeseg); + if (!prepare_tcp_segment((struct sockaddr *)&src, (struct sockaddr *)&dst, flags_orig, tcphdr->seq, tcphdr->ack_seq, + ttl_fake,params.desync_tcp_fooling_mode, + zeropkt, split_pos, fakeseg, &fakeseg_len) || + !rawsend((struct sockaddr *)&dst, params.desync_fwmark, fakeseg, fakeseg_len)) + { + return false; + } } @@ -589,9 +594,12 @@ static bool dpi_desync_packet(const uint8_t *data_pkt, size_t len_pkt, const str return false; } - DLOG("sending fake(2) 1st out-of-order tcp segment 0-%zu len=%zu\n",split_pos-1, split_pos) - if (!rawsend((struct sockaddr *)&dst, params.desync_fwmark, fakeseg, fakeseg_len)) - return false; + if (params.desync_mode==DESYNC_DISORDER) + { + DLOG("sending fake(2) 1st out-of-order tcp segment 0-%zu len=%zu\n",split_pos-1, split_pos) + if (!rawsend((struct sockaddr *)&dst, params.desync_fwmark, fakeseg, fakeseg_len)) + return false; + } return true; } @@ -718,7 +726,7 @@ static void exithelp() " --hostcase\t\t\t\t; change Host: => host:\n" " --hostspell\t\t\t\t; exact spelling of \"Host\" header. must be 4 chars. default is \"host\"\n" " --hostnospace\t\t\t\t; remove space after Host: and add it to User-Agent: to preserve packet size\n" - " --dpi-desync[=]\t\t\t; try to desync dpi state. modes : fake rst rstack disorder\n" + " --dpi-desync[=]\t\t\t; try to desync dpi state. modes : fake rst rstack disorder disorder2\n" " --dpi-desync-fwmark=\t; override fwmark for desync packet. default = 0x%08X\n" " --dpi-desync-ttl=\t\t\t; set ttl for desync packet\n" " --dpi-desync-fooling=none|md5sig|badsum\n" @@ -875,6 +883,8 @@ int main(int argc, char **argv) params.desync_mode = DESYNC_RSTACK; else if (!strcmp(optarg,"disorder")) params.desync_mode = DESYNC_DISORDER; + else if (!strcmp(optarg,"disorder2")) + params.desync_mode = DESYNC_DISORDER2; else { fprintf(stderr, "invalid dpi-desync mode\n");