diff --git a/binaries/aarch64/nfqws b/binaries/aarch64/nfqws index 966b168..6fedd57 100755 Binary files a/binaries/aarch64/nfqws and b/binaries/aarch64/nfqws differ diff --git a/binaries/armhf/nfqws b/binaries/armhf/nfqws index 7c6b346..88944d5 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 c969d1c..e16d325 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 9e37030..a5b15e4 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 6970582..d9340a3 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 5961769..5b347df 100755 Binary files a/binaries/ppc/nfqws and b/binaries/ppc/nfqws differ diff --git a/binaries/x86/nfqws b/binaries/x86/nfqws index d0a54c6..9743f20 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 f58bd86..5690c1e 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 dcdbb38..9077314 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 f3c4134..8a0d098 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 11bceb1..b591cde 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");