nfqws: handle QUIC decrypt failed case during desync

This commit is contained in:
bol-van 2022-03-25 22:34:37 +03:00
parent 7df1be9d3e
commit f7c0c35670
12 changed files with 26 additions and 5 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

@ -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")

View File

@ -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;

View File

@ -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);