nDPI icon indicating copy to clipboard operation
nDPI copied to clipboard

TLS: out-of-order fragmented Client Hello

Open IvanNardi opened this issue 3 years ago • 5 comments

nDPI doesn't always handle out-of-order fragments of Client Hello messages in TLS sessions (see #1195 for some details about why this scenario is interesting)

The case which is not handled happens when the first received fragment is not the first fragment of the CH; all others scenarios should be fine.

Example attached: tls_frags_client_hello_out_of_order.pcapng.gz

IvanNardi avatar Jun 23 '21 16:06 IvanNardi

I thought that nDPI does not support any TCP segment reassembly at all? There was a PR some time ago. But the code was somehow broken and hard to understand.

utoni avatar Jun 29 '21 09:06 utoni

I thought that nDPI does not support any TCP segment reassembly at all? There was a PR some time ago. But the code was somehow broken and hard to understand.

You are right: nDPI lacks a generic (TCP) reassembler, like the one proposed some months ago.

Nonetheless, some specific dissectors support some kind of specific "reassembly" feature: for example TLS code is able to reassemble (most of) ClientHello or certificate fragments, or Kerberos code is able to reassemble (some cases of) messages split across multiple packets.

IvanNardi avatar Jun 29 '21 10:06 IvanNardi

But would it not better to write a generic TCP reassembler as other protocols may profit as well? I know that writing a reassmbler is not a trivial task and it will also increase nDPI's memory usage. But if it can increase the detection ratio it could be worth a(nother) try.

What do you think?

utoni avatar Jun 29 '21 11:06 utoni

I think that a generic reassembler code might be beneficial to nDPI: it could be used for TCP (obviously), for IP reassembler (IP fragments are rarely an issue on home/enterprise networks but they can cause troubles on networks where tunnels are involved) and even on some UDP scenarios (QUIC Client Hello or DTLS Certificate fragments). It could be also used to replace all the existing specific code I cited in the previous post.

From a development perspective, a generic reassembler (for a DPI engine, not for a network device!) shouldn't be too hard to code; you can always start handling the most common cases first and then add the hardest/uncommon cases later, in an incremental way. The real issue is the performance: with some naive implementations you end up copying the data multiple times or wasting a lot of memory.

A critical point I see is deciding when that code will be triggered. Let's take the TCP example: do we reassemble all the flows before trying to classify them, or do we reassemble only "some" flows, only in some "specific" cases? I strongly believe the former is the best option, but I know that opinions may differ on this topic. There is even the option to left TCP reassembler responsibility to the application, not to the library itself (like the flow management). The application might pass a reassembled flow to nDPI (or not) depending on external factors. A bit extreme as a solution to me, but I mention it for the sake of completeness.

IvanNardi avatar Jul 03 '21 15:07 IvanNardi

#1134, #1122 may be helpful for implementation

utoni avatar Oct 06 '21 14:10 utoni