Commit graph

88 commits

Author SHA1 Message Date
Luca Deri
04ee0bb48b nDPI fingerprint calculation
- Added the ability to exclude TCP fingerprint via metadata.ndpi_fingerprint_ignore_tcp_fp configuration
- TLS blocks not include the block lenght only for Client and Server hello, ignored for all other blocks
2026-01-09 12:00:10 +01:00
Luca Deri
d3206230bb TLS blocks timing is not hidden by default.
Use --cfg "tls,tls_blocks_show_timing,1" to show it
2026-01-09 09:24:35 +01:00
Luca Deri
901e317422
Added --cfg "tls,max_num_blocks_to_analyze,X" for dynamically setting TLS blocks number (#3073)
* Added --cfg "tls,max_num_blocks_to_analyze,X" where if X > 0 TLS blocks are analyzed

Example --cfg "tls,max_num_blocks_to_analyze,8"

* TLS blocks now include a time-delta (msec) with respect to the previous TLS block.
The format is @<msec delta>. Example:

 "tls_blocks": [
         "22:1=232@191",
         "22:2=-122@5,20=-1@5,21=-23@5,21=-905@5,21=-281@5",
         "21=-53@0",
         "20=1@3,21=53@3",
         "21=-218@119,21=-218@119",
 ]
2026-01-08 23:36:13 +01:00
Luca Deri
8aaff75ede
Fixes protocol inconsistencies (#3069)
* Added code to address inconsistencies
* Added check for discarding dig errors
* Temporarily disabled whatsapp script: an update is required. See https://developers.facebook.com/docs/whatsapp/on-premises/sunset
2025-12-31 20:54:35 +01:00
Ivan Nardi
87440c59bb
fuzz: extend fuzzing coverage and fix loading of TCP fingerprints from file (#3059) 2025-12-09 14:03:46 +01:00
Ivan Nardi
5cae544a40
s7comm: small fixes and extend tests (#3046) 2025-11-30 15:52:22 +01:00
Ivan Nardi
6bb0585a27
fuzz: minor improvements. Be sure the right configuration is always loaded (#3031) 2025-11-18 14:11:16 +01:00
Ivan Nardi
c37937a211
fuzz: improve fuzzing coverage (#3020)
We should pay attention to tell ndpiReader configuration files and
libnDPI configuration files!! Better solution?

Be sure that configuration files are located where they are expected.
In oss-fuzz enviroment we can't make any assumptions about the current
working directory of your fuzz target.
2025-11-04 21:04:29 +01:00
Ivan Nardi
83d85775a8
Provide an explicit state for the flow classification process (#2942)
Application should keep calling nDPI until flow state became
`NDPI_STATE_CLASSIFIED`.

The main loop in the application is simplified to something like:
```
res = ndpi_detection_process_packet(...);
if(res->state == NDPI_STATE_CLASSIFIED) {
  /* Done: you can get finale classification and all metadata.
     nDPI doesn't need more packets for this flow */
} else {
  /* nDPI needs more packets for this flow. The provided
     classification is not final and more metadata might be
     extracted.
     If `res->state` is `NDPI_STATE_PARTIAL`, partial/initial
     classification is available in `res->proto`
     as usual but it can be updated later.
  */
}

/*
    Example A (QUIC flow):
     pkt 1: proto QUIC state NDPI_STATE_PARTIAL
     pkt 2: proto QUIC/Youtube  state NDPI_STATE_CLASSIFIED
    Example B (GoogleMeet call):
     pkt 1:   proto STUN state NDPI_STATE_PARTIAL
     pkt N:   proto DTLS state NDPI_STATE_PARTIAL
     pkt N+M: proto DTLS/GoogleCall state NDPI_STATE_CLASSIFIED
    Example C (standard TLS flow):
     pkt 1:   proto Unknown state NDPI_STATE_INSPECTING
     pkt 2:   proto Unknown state NDPI_STATE_INSPECTING
     pkt 3:   proto Unknown state NDPI_STATE_INSPECTING
     pkt 4:   proto TLS/Facebook state NDPI_STATE_PARTIAL
     pkt N:   proto TLS/Facebook state NDPI_STATE_CLASSIFIED
 */
}
```
You can take a look at `ndpiReader` for a slightly more complex example.

API changes:
* remove the third parameter from `ndpi_detection_giveup()`. If you need
to know if the classification flow has been guessed, you can access
`flow->protocol_was_guessed`
* remove `ndpi_extra_dissection_possible()`
* change some prototypes from accepting `ndpi_protocol foo` to
`ndpi_master_app_protocol bar`. The update is trivial: from `foo` to
`foo.proto`
2025-11-03 12:08:15 +01:00
Ivan Nardi
a07d55005d
fuzz: try to improve fuzzing coverage (#2981) 2025-10-06 20:44:31 +02:00
Ivan Nardi
3a06d2037f
ndpiReader: create a wrapper to configure nDPI (local) context (#2979)
Use it to better test domains, too
2025-10-05 11:39:46 +02:00
Ivan Nardi
2619729661
fuzz: improve per-fuzzer introspector statistics (#2970)
See: f2bccee04
This is clearly a workaround for a introspector bug/limittaions. It
seems that we need separate files for every fuzzers to get per-fuzzer
coverage stats
2025-09-21 17:20:45 +02:00
Ivan Nardi
44c94e924f
fuzz: extend fuzzing coverage (#2951) 2025-08-31 20:12:53 +02:00
Ivan Nardi
b7cb6cf408
Follow-up of 8e1b17215: NDPI_UNRESOLVED_HOSTNAME (#2933)
Add fuzzing, documentation and unit tests
2025-08-05 11:32:29 +02:00
Ivan Nardi
978ca1ba1a
New API to enable/disable protocols. Removed NDPI_LAST_IMPLEMENTED_PROTOCOL (#2894)
Change the API to enable/disable protocols: you can set that via the
standard `ndpi_set_config()` function, as every configuration
parameters. By default, all protocols are enabled.

Split the (local) context initialization into two phases:
* `ndpi_init_detection_module()`: generic part. It does not depend on the
configuration and on the protocols being enabled or not. It also
calculates the real number of internal protocols
* `ndpi_finalize_initialization()`: apply the configuration. All the
initialization stuff that depend on protocols being enabled or not
must be put here

This is the last step to have the protocols number fully calculated at
runtime

Remove a (now) useless fuzzer.

Important API changes:
* remove `NDPI_LAST_IMPLEMENTED_PROTOCOL` define
* remove `ndpi_get_num_internal_protocols()`. To get the number of
configured protocols (internal and custom) you must use
`ndpi_get_num_protocols()` after having called `ndpi_finalize_initialization()`
2025-06-23 11:24:18 +02:00
Ivan Nardi
6cbc8d1471
fuzz: fuzz loading of external protocols lists (#2897) 2025-06-22 20:43:16 +02:00
Ivan Nardi
e07fc3dfb8
fuzz: improve coverage (#2878) 2025-06-10 13:51:57 +02:00
Ivan Nardi
70a72f1638
New API to enable/disable protocols; remove ndpi_set_protocol_detection_bitmask2() (#2853)
The main goal is not to have the bitmask depending on the total number
of protocols anymore: `NDPI_INTERNAL_PROTOCOL_BITMASK` depends only on
internal protocols, i.e. on `NDPI_MAX_INTERNAL_PROTOCOLS`, i.e.
custom-defined protocols are not counted.
See #2136

Keep the old data structure `NDPI_PROTOCOL_BITMASK` with the old
semantic.

Since we need to change the API (and all the application code...)
anyway, simplify the API: by default all the protocols are enabled.
If you need otherwise, please use `ndpi_init_detection_module_ext()`
instead of `ndpi_init_detection_module()` (you can find an example in
the `ndpiReader` code).

To update the application code you likely only need to remove these 3
lines from your code:
```
- NDPI_PROTOCOL_BITMASK all;
- NDPI_BITMASK_SET_ALL(all);
- ndpi_set_protocol_detection_bitmask2(ndpi_str, &all);
```

Removed an unused field and struct definition.
2025-06-03 09:45:46 +02:00
Ivan Nardi
f4691c518a
fuzz: extend coverage (#2786) 2025-03-31 17:54:14 +02:00
Ivan Nardi
8bb3a9faf7 fuzz: fix configuration 2025-03-26 11:38:24 +01:00
Ivan Nardi
4a66f95808 fuzz: fix configuration after latest updates 2025-03-26 10:02:50 +01:00
Ivan Nardi
0cf735b12a
fuzz: try to run one (ndpiReader-) fuzzer with a slight different cfg (#2771) 2025-03-18 17:26:23 +01:00
Ivan Nardi
8ee59bb9b9
fuzz: extend fuzzing coverage (#2750) 2025-02-28 12:38:15 +01:00
Ivan Nardi
73d1856525
DNS: disable subclassification by default (#2715)
Prelimary change to start supporting multiple DNS transactions on the
same flow
2025-02-11 13:50:00 +01:00
Ivan Nardi
d4fb7b0aa1
fuzz: extend fuzzing coverage (#2696) 2025-01-23 15:23:01 +01:00
Ivan Nardi
63a3547f99
Add (kind of) support for loading a list of JA4C malicious fingerprints (#2678)
It might be usefull to be able to match traffic against a list of
suspicious JA4C fingerprints

Use the same code/logic/infrastructure used for JA3C (note that we are
going to remove JA3C...)

See: #2551
2025-01-14 12:05:03 +01:00
Ivan Nardi
f20cec4985
fuzz: improve fuzzing coverage (#2642)
Updtae pl7m code (Fix swap-direction mutation)
2024-12-11 16:41:35 +01:00
Ivan Nardi
43f7dc9ba0
fuzz: extend fuzzing coverage (#2626) 2024-11-20 13:36:41 +01:00
Ivan Nardi
819291b7e4
Add configuration of TCP fingerprint computation (#2598)
Extend configuration of raw format of JA4C fingerprint
2024-10-18 16:58:06 +02:00
Ivan Nardi
521d0ca7a0
Add monitoring capability (#2588)
Allow nDPI to process the entire flows and not only the first N packets.
Usefull when the application is interested in some metadata spanning the
entire life of the session.

As initial step, only STUN flows can be put in monitoring.

See `doc/monitoring.md` for further details.

This feature is disabled by default.

Close #2583
2024-10-14 18:05:35 +02:00
Luca Deri
7bdb2796c3 Added addr_dump_path definition 2024-10-10 18:18:04 +02:00
Ivan Nardi
ddd08f913c
Add some heuristics to detect encrypted/obfuscated/proxied TLS flows (#2553)
Based on the paper: "Fingerprinting Obfuscated Proxy Traffic with
Encapsulated TLS Handshakes".
See: https://www.usenix.org/conference/usenixsecurity24/presentation/xue-fingerprinting

Basic idea:
* the packets/bytes distribution of a TLS handshake is quite unique
* this fingerprint is still detectable if the handshake is
encrypted/proxied/obfuscated

All heuristics are disabled by default.
2024-09-24 14:20:31 +02:00
Nardi Ivan
b6f187dffb fuzz: fix compilation 2024-09-17 20:17:35 +02:00
Ivan Nardi
0ddbda1f82
Add an heuristic to detect encrypted/obfuscated OpenVPN flows (#2547)
Based on the paper: "OpenVPN is Open to VPN Fingerprinting"
See: https://www.usenix.org/conference/usenixsecurity22/presentation/xue-diwen

Basic idea:
* the distribution of the first byte of the messages (i.e. the distribution
of the op-codes) is quite unique
* this fingerprint might be still detectable even if the OpenVPN packets are
somehow fully encrypted/obfuscated

The heuristic is disabled by default.
2024-09-16 18:38:26 +02:00
Nardi Ivan
f310424037 fuzz: fix compilation 2024-09-16 10:10:49 +02:00
Ivan Nardi
83e6e753af
fuzz: pl7m: add a custom mutator for better fuzzing of pcap files (#2483)
Pl7m is a custom mutator (used for structure aware fuzzing) for network
traffic packet captures (i.e. pcap files).

The output of the mutator is always a valid pcap file, containing the
same flows/sessions of the input file. That's it: the mutator only
changes the packet payload after the TCP/UDP header, keeping all the
original L2/L3 information (IP addresses and L4 ports).

See: https://github.com/IvanNardi/pl7m
2024-06-27 18:07:43 +02:00
Nardi Ivan
556f892a56 wireshark: lua: export some metadata
Export some metadata (for the moment, SNI and TLS fingerprints) to
Wireshark/tshark via extcap.
Note that:
* metadata are exported only once per flow
* metadata are exported (all together) when nDPI stopped processing
the flow

Still room for a lot of improvements!
In particular:
* we need to add some boundary checks (if we are going to export other
attributes)
* we should try to have a variable length trailer
2024-06-25 16:39:45 +02:00
Ivan Nardi
26cc1f131f
fuzz: improve fuzzing coverage (#2474)
Remove some code never triggered

AFP: the removed check is included in the following one
MQTT: fix flags extraction
2024-06-17 13:45:47 +02:00
Ivan Nardi
b90d39c4ac
RTP/STUN: look for STUN packets after RTP/RTCP classification (#2465)
After a flow has been classified as RTP or RTCP, nDPI might analyse more
packets to look for STUN/DTLS packets, i.e. to try to tell if this flow
is a "pure" RTP/RTCP flow or if the RTP/RTCP packets are multiplexed with
STUN/DTLS.
Useful for proper (sub)classification when the beginning of the flows
are not captured or if there are lost packets in the the captured traffic.

Disabled by default
2024-06-07 13:12:04 +02:00
Ivan Nardi
700637a162
fuzzing: extend fuzzing coverage (#2371) 2024-04-05 21:02:54 +02:00
Ivan Nardi
400cd516b5
Allow multiple struct ndpi_detection_module_struct to share some state (#2271)
Add the concept of "global context".

Right now every instance of `struct ndpi_detection_module_struct` (we
will call it "local context" in this description) is completely
independent from each other. This provide optimal performances in
multithreaded environment, where we pin each local context to a thread,
and each thread to a specific CPU core: we don't have any data shared
across the cores.

Each local context has, internally, also some information correlating
**different** flows; something like:
```
if flow1 (PeerA <-> Peer B) is PROTOCOL_X; then
  flow2 (PeerC <-> PeerD) will be PROTOCOL_Y
```
To get optimal classification results, both flow1 and flow2 must be
processed by the same local context. This is not an issue at all in the far
most common scenario where there is only one local context, but it might
be impractical in some more complex scenarios.

Create the concept of "global context": multiple local contexts can use
the same global context and share some data (structures) using it.
This way the data correlating multiple flows can be read/write from
different local contexts.
This is an optional feature, disabled by default.

Obviously data structures shared in a global context must be thread safe.
This PR updates the code of the LRU implementation to be, optionally,
thread safe.

Right now, only the LRU caches can be shared; the other main structures
(trees and automas) are basically read-only: there is little sense in
sharing them. Furthermore, these structures don't have any information
correlating multiple flows.

Every LRU cache can be shared, independently from the others, via
`ndpi_set_config(ndpi_struct, NULL, "lru.$CACHE_NAME.scope", "1")`.

It's up to the user to find the right trade-off between performances
(i.e. without shared data) and classification results (i.e. with some
shared data among the local contexts), depending on the specific traffic
patterns and on the algorithms used to balance the flows across the
threads/cores/local contexts.

Add some basic examples of library initialization in
`doc/library_initialization.md`.

This code needs libpthread as external dependency. It shouldn't be a big
issue; however a configure flag has been added to disable global context
support. A new CI job has been added to test it.

TODO: we should need to find a proper way to add some tests on
multithreaded enviroment... not an easy task...

*** API changes ***

If you are not interested in this feature, simply add a NULL parameter to
any `ndpi_init_detection_module()` calls.
2024-02-01 15:33:11 +01:00
Ivan Nardi
9b26e74bb7
example: rework code between ndpiReader.c and reader_util.c (#2273) 2024-01-22 18:12:06 +01:00
Ivan Nardi
42d23cff6a
config: follow-up (#2268)
Some changes in the parameters names.
Add a fuzzer to fuzz the configuration file format.
Add the infrastructure to configuratin callbacks.
Add an helper to map LRU cache indexes to names.
2024-01-20 16:14:41 +01:00
Nardi Ivan
0712d496fe config: allow configuration of guessing algorithms 2024-01-18 10:21:24 +01:00
Nardi Ivan
6c85f10cd5 config: move debug/log configuration to the new API 2024-01-18 10:21:24 +01:00
Nardi Ivan
88720331ae config: remove enum ndpi_prefs 2024-01-18 10:21:24 +01:00
Nardi Ivan
1289951b32 config: remove ndpi_set_detection_preferences() 2024-01-18 10:21:24 +01:00
Ivan Nardi
b3f2b1bb7f
STUN: rework extra dissection (#2202)
Keep looking for RTP packets but remove the monitoring concept.
We will re-introduce a more general concept of "flow in monitoring
state" later.
The function was disabled by default.
Some configuration knobs will be provided when/if #2190 is merged.
2023-12-11 14:53:12 +01:00
Ivan Nardi
adf8982d8e
fuzz: extend fuzzing coverage (#2205) 2023-12-11 12:48:50 +01:00
Ivan Nardi
7b0c16a70d
TLS: remove JA3+ fingerprints. (#2192)
See: #2191
2023-12-05 08:05:44 +01:00