diff --git a/binaries/aarch64/nfqws b/binaries/aarch64/nfqws index 97c696b..6142018 100755 Binary files a/binaries/aarch64/nfqws and b/binaries/aarch64/nfqws differ diff --git a/binaries/arm/nfqws b/binaries/arm/nfqws index dbef358..cec02a6 100755 Binary files a/binaries/arm/nfqws and b/binaries/arm/nfqws differ diff --git a/binaries/freebsd-x64/dvtws b/binaries/freebsd-x64/dvtws index f41049e..efa078c 100755 Binary files a/binaries/freebsd-x64/dvtws and b/binaries/freebsd-x64/dvtws differ diff --git a/binaries/mips32r1-lsb/nfqws b/binaries/mips32r1-lsb/nfqws index 7906184..178ce12 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 90a93b1..a380be7 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 13f9d62..38187f2 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 b854c11..b5857db 100755 Binary files a/binaries/ppc/nfqws and b/binaries/ppc/nfqws differ diff --git a/binaries/x86/nfqws b/binaries/x86/nfqws index 863088a..8b55881 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 15fc996..8c1dfa8 100755 Binary files a/binaries/x86_64/nfqws and b/binaries/x86_64/nfqws differ diff --git a/nfq/desync.c b/nfq/desync.c index 1ec451d..add328e 100644 --- a/nfq/desync.c +++ b/nfq/desync.c @@ -664,18 +664,32 @@ packet_process_result dpi_desync_udp_packet(uint8_t *data_pkt, size_t len_pkt, s fake = params.fake_quic; fake_size = params.fake_quic_size; - bool bIsCryptoHello; - bHaveHost=QUICExtractHostFromInitial(data_payload,len_payload,host,sizeof(host),&bIsCryptoHello); + bool bIsCryptoHello, bDecryptOK; + bHaveHost=QUICExtractHostFromInitial(data_payload,len_payload,host,sizeof(host), &bDecryptOK,&bIsCryptoHello); if (bIsCryptoHello) { + // decrypted and payload is ClientHello if (params.desync_skip_nosni && !bHaveHost) { DLOG("not applying tampering to QUIC ClientHello without hostname in the SNI\n") return res; } } + else if (!bDecryptOK) + { + // could not decrypt + if (params.desync_skip_nosni) + { + DLOG("not applying tampering to QUIC initial that could not be decrypted\n") + return res; + } + else + // consider this case the same way as absence of the SNI. DPI also might not be able to decrypt this and get SNI + DLOG("QUIC initial decryption failed. still applying tampering because desync_skip_nosni is not set\n") + } else { + // decrypted and payload is not ClientHello if (params.desync_any_proto) { DLOG("QUIC initial without CRYPTO frame. applying tampering because desync_any_proto is set\n") diff --git a/nfq/protocol.c b/nfq/protocol.c index 26baea9..c6586d4 100644 --- a/nfq/protocol.c +++ b/nfq/protocol.c @@ -444,6 +444,10 @@ bool QUICDecryptInitial(const uint8_t *data, size_t data_len, uint8_t *clean, si bool QUICDefragCrypto(const uint8_t *clean,size_t clean_len, uint8_t *defrag,size_t *defrag_len) { + // Crypto frame can be split into multiple chunks + // quiche (chromium) randomly splits it and pads with zero/one bytes to force support the standard + // mozilla does not split + if (*defrag_len<10) return false; uint8_t *defrag_data = defrag+10; size_t defrag_data_len = *defrag_len-10; @@ -477,8 +481,8 @@ bool QUICDefragCrypto(const uint8_t *clean,size_t clean_len, uint8_t *defrag,siz zeropos=offset+sz; memcpy(defrag_data+offset,clean+pos,sz); if ((offset+sz) > szmax) szmax = offset+sz; - found=true; + found=true; pos+=sz; } } @@ -496,14 +500,17 @@ bool QUICDefragCrypto(const uint8_t *clean,size_t clean_len, uint8_t *defrag,siz } -bool QUICExtractHostFromInitial(const uint8_t *data, size_t data_len, char *host, size_t len_host, bool *bIsCryptoHello) +bool QUICExtractHostFromInitial(const uint8_t *data, size_t data_len, char *host, size_t len_host, bool *bDecryptOK, bool *bIsCryptoHello) { if (bIsCryptoHello) *bIsCryptoHello=false; + if (bDecryptOK) *bDecryptOK=false; uint8_t clean[1500]; size_t clean_len = sizeof(clean); if (!QUICDecryptInitial(data,data_len,clean,&clean_len)) return false; + if (bDecryptOK) *bDecryptOK=true; + uint8_t defrag[1500]; size_t defrag_len = sizeof(defrag); if (!QUICDefragCrypto(clean,clean_len,defrag,&defrag_len)) return false; diff --git a/nfq/protocol.h b/nfq/protocol.h index 98a72d9..08605b4 100644 --- a/nfq/protocol.h +++ b/nfq/protocol.h @@ -30,4 +30,4 @@ bool QUICExtractDCID(const uint8_t *data, size_t len, quic_cid_t *cid); bool QUICDecryptInitial(const uint8_t *data, size_t data_len, uint8_t *clean, size_t *clean_len); bool QUICDefragCrypto(const uint8_t *clean,size_t clean_len, uint8_t *defrag,size_t *defrag_len); -bool QUICExtractHostFromInitial(const uint8_t *data, size_t data_len, char *host, size_t len_host, bool *bIsCryptoHello); +bool QUICExtractHostFromInitial(const uint8_t *data, size_t data_len, char *host, size_t len_host, bool *bDecryptOK, bool *bIsCryptoHello); \ No newline at end of file