Skip to content

Commit

Permalink
STUN: fix detection of DTLS
Browse files Browse the repository at this point in the history
Fix a memory leak
```
==97697==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 16 byte(s) in 1 object(s) allocated from:
    #0 0x55a6967cfa7e in malloc (/home/ivan/svnrepos/nDPI/fuzz/fuzz_ndpi_reader+0x701a7e) (BuildId: c7124999fa1ccc54346fa7bd536d8eab88c3ea01)
    ntop#1 0x55a696972ab5 in ndpi_malloc /home/ivan/svnrepos/nDPI/src/lib/ndpi_memory.c:60:25
    ntop#2 0x55a696972da0 in ndpi_strdup /home/ivan/svnrepos/nDPI/src/lib/ndpi_memory.c:113:13
    ntop#3 0x55a696b7658d in processClientServerHello /home/ivan/svnrepos/nDPI/src/lib/protocols/tls.c:2394:46
    ntop#4 0x55a696b86e81 in processTLSBlock /home/ivan/svnrepos/nDPI/src/lib/protocols/tls.c:897:5
    ntop#5 0x55a696b80649 in ndpi_search_tls_udp /home/ivan/svnrepos/nDPI/src/lib/protocols/tls.c:1262:11
    ntop#6 0x55a696b67a57 in ndpi_search_tls_wrapper /home/ivan/svnrepos/nDPI/src/lib/protocols/tls.c:2751:5
    ntop#7 0x55a696b67758 in switch_to_tls /home/ivan/svnrepos/nDPI/src/lib/protocols/tls.c:1408:3
    ntop#8 0x55a696c47810 in stun_search_again /home/ivan/svnrepos/nDPI/src/lib/protocols/stun.c:422:4
    ntop#9 0x55a6968a22af in ndpi_process_extra_packet /home/ivan/svnrepos/nDPI/src/lib/ndpi_main.c:7247:9
    ntop#10 0x55a6968acd6f in ndpi_internal_detection_process_packet /home/ivan/svnrepos/nDPI/src/lib/ndpi_main.c:7746:5
    ntop#11 0x55a6968aba3f in ndpi_detection_process_packet /home/ivan/svnrepos/nDPI/src/lib/ndpi_main.c:8013:22
    ntop#12 0x55a69683d30e in packet_processing /home/ivan/svnrepos/nDPI/fuzz/../example/reader_util.c:1723:31
    ntop#13 0x55a69683d30e in ndpi_workflow_process_packet /home/ivan/svnrepos/nDPI/fuzz/../example/reader_util.c:2440:10
    ntop#14 0x55a69680f08f in LLVMFuzzerTestOneInput /home/ivan/svnrepos/nDPI/fuzz/fuzz_ndpi_reader.c:135:7
[...]
SUMMARY: AddressSanitizer: 16 byte(s) leaked in 1 allocation(s).
```
Found by oss-fuzzer
See: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=64564
  • Loading branch information
IvanNardi committed Nov 29, 2023
1 parent d85f859 commit 0357b29
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 10 deletions.
5 changes: 5 additions & 0 deletions fuzz/fuzz_ndpi_reader.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
int r;
char errbuf[PCAP_ERRBUF_SIZE];
NDPI_PROTOCOL_BITMASK all;
NDPI_PROTOCOL_BITMASK debug_bitmask;
u_int i;
FILE *fd;

Expand All @@ -60,6 +61,10 @@ int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
NDPI_BITMASK_SET_ALL(all);
ndpi_set_protocol_detection_bitmask2(workflow->ndpi_struct, &all);

NDPI_BITMASK_SET_ALL(debug_bitmask);
ndpi_set_log_level(workflow->ndpi_struct, 4);
ndpi_set_debug_bitmask(workflow->ndpi_struct, debug_bitmask);

ndpi_load_protocols_file(workflow->ndpi_struct, "protos.txt");
ndpi_load_categories_file(workflow->ndpi_struct, "categories.txt", NULL);
ndpi_load_risk_domain_file(workflow->ndpi_struct, "risky_domains.txt");
Expand Down
28 changes: 28 additions & 0 deletions src/lib/protocols/stun.c
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,8 @@ static int stun_search_again(struct ndpi_detection_module_struct *ndpi_struct,
u_int16_t app_proto = NDPI_PROTOCOL_UNKNOWN;
u_int32_t unused;
int first_dtls_pkt = 0;
u_int16_t old_proto_stack[2] = {NDPI_PROTOCOL_UNKNOWN, NDPI_PROTOCOL_UNKNOWN};
ndpi_protocol_category_t old_category = NDPI_PROTOCOL_CATEGORY_UNSPECIFIED;

NDPI_LOG_DBG2(ndpi_struct, "Packet counter %d protos %d/%d\n", flow->packet_counter,
flow->detected_protocol_stack[0], flow->detected_protocol_stack[1]);
Expand Down Expand Up @@ -396,6 +398,10 @@ static int stun_search_again(struct ndpi_detection_module_struct *ndpi_struct,
* the easiest (!?) solution is to remove everything, and let the TLS dissector
to set both master (i.e. DTLS) and subprotocol (if any) */

/* In same rare cases, with malformed/fuzzed traffic, `is_dtls()` might return false
positives. In that case, the TLS dissector doesn't set the master protocol, so we
need to rollback to the current state */

if(packet->tcp) {
/* TODO: TLS code assumes that DTLS is only over UDP */
NDPI_LOG_DBG(ndpi_struct, "Ignoring DTLS over TCP\n");
Expand All @@ -407,6 +413,11 @@ static int stun_search_again(struct ndpi_detection_module_struct *ndpi_struct,
/* First DTLS packet of the flow */
first_dtls_pkt = 1;

/* We might need to rollback this change... */
old_proto_stack[0] = flow->detected_protocol_stack[0];
old_proto_stack[1] = flow->detected_protocol_stack[1];
old_category = flow->category;

/* TODO: right way? It is a bit scary... do we need to reset something else too? */
reset_detected_protocol(ndpi_struct, flow);
change_category(ndpi_struct, flow, NDPI_PROTOCOL_CATEGORY_UNSPECIFIED);
Expand All @@ -423,6 +434,23 @@ static int stun_search_again(struct ndpi_detection_module_struct *ndpi_struct,

NDPI_LOG_DBG(ndpi_struct, "(%d/%d)\n",
flow->detected_protocol_stack[0], flow->detected_protocol_stack[1]);

/* If this is not a real DTLS packet, we need to restore the old state */
if(flow->detected_protocol_stack[0] == NDPI_PROTOCOL_UNKNOWN &&
first_dtls_pkt) {
NDPI_LOG_DBG(ndpi_struct, "Switch to TLS failed. Rollback to old classification\n");

ndpi_set_detected_protocol(ndpi_struct, flow,
old_proto_stack[1], old_proto_stack[0],
NDPI_CONFIDENCE_DPI);
change_category(ndpi_struct, flow, old_category);

flow->stun.maybe_dtls = 0;
flow->max_extra_packets_to_check -= 10;

NDPI_LOG_DBG(ndpi_struct, "(%d/%d)\n",
flow->detected_protocol_stack[0], flow->detected_protocol_stack[1]);
}
}
}
}
Expand Down
Binary file modified tests/cfgs/default/pcap/stun.pcap
Binary file not shown.
27 changes: 17 additions & 10 deletions tests/cfgs/default/result/stun.pcap.out
Original file line number Diff line number Diff line change
@@ -1,40 +1,47 @@
Guessed flow protos: 0
Guessed flow protos: 1

DPI Packets (TCP): 9 (4.50 pkts/flow)
DPI Packets (UDP): 12 (3.00 pkts/flow)
DPI Packets (UDP): 16 (3.20 pkts/flow)
DPI Packets (other): 1 (1.00 pkts/flow)
Confidence DPI : 7 (flows)
Num dissector calls: 22 (3.14 diss/flow)
Confidence DPI : 8 (flows)
Num dissector calls: 28 (3.50 diss/flow)
LRU cache ookla: 0/0/0 (insert/search/found)
LRU cache bittorrent: 0/0/0 (insert/search/found)
LRU cache zoom: 0/0/0 (insert/search/found)
LRU cache stun: 8/28/0 (insert/search/found)
LRU cache tls_cert: 0/0/0 (insert/search/found)
LRU cache stun: 8/32/0 (insert/search/found)
LRU cache tls_cert: 0/1/0 (insert/search/found)
LRU cache mining: 0/0/0 (insert/search/found)
LRU cache msteams: 0/0/0 (insert/search/found)
LRU cache stun_zoom: 0/0/0 (insert/search/found)
Automa host: 0/0 (search/found)
Automa domain: 0/0 (search/found)
Automa tls cert: 0/0 (search/found)
Automa risk mask: 1/0 (search/found)
Automa common alpns: 0/0 (search/found)
Patricia risk mask: 8/0 (search/found)
Automa common alpns: 2/2 (search/found)
Patricia risk mask: 10/0 (search/found)
Patricia risk mask IPv6: 2/0 (search/found)
Patricia risk: 1/0 (search/found)
Patricia risk IPv6: 1/0 (search/found)
Patricia protocols: 8/4 (search/found)
Patricia protocols: 9/5 (search/found)
Patricia protocols IPv6: 2/0 (search/found)

DTLS 4 766 1
Skype_TeamsCall 15 2124 1
STUN 62 7620 2
ICMP 1 122 1
GoogleHangoutDuo 41 7228 2
FacebookVoip 75 10554 1

JA3 Host Stats:
IP Address # JA3C
1 192.168.43.169 1


1 UDP 192.168.12.169:38123 <-> 31.13.86.54:40003 [proto: 78.268/STUN.FacebookVoip][IP: 119/Facebook][ClearText][Confidence: DPI][DPI packets: 2][cat: VoIP/10][40 pkts/6134 bytes <-> 35 pkts/4420 bytes][Goodput ratio: 73/67][10.09 sec][Hostname/SNI: turner.facebook][bytes ratio: 0.162 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 0/0 260/331 6004/5997 1040/1126][Pkt Len c2s/s2c min/avg/max/stddev: 70/68 153/126 190/174 31/39][Risk: ** Known Proto on Non Std Port **][Risk Score: 50][PLAIN TEXT (unauthorized)][Plen Bins: 8,14,9,28,40,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
2 UDP 192.168.12.169:49153 <-> 142.250.82.99:3478 [proto: 78.201/STUN.GoogleHangoutDuo][IP: 126/Google][ClearText][Confidence: DPI][DPI packets: 1][cat: VoIP/10][18 pkts/2856 bytes <-> 15 pkts/3436 bytes][Goodput ratio: 74/82][2.12 sec][bytes ratio: -0.092 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 8/0 88/153 699/625 177/222][Pkt Len c2s/s2c min/avg/max/stddev: 107/76 159/229 588/1240 107/297][PLAIN TEXT (BwlkYDtFJ)][Plen Bins: 0,6,57,21,6,0,0,0,0,0,0,0,0,0,0,0,0,6,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,0,0,0,0,0,0,0,0]
3 UDP [3516:bf0b:fc53:75e7:70af:f67f:8e49:f603]:56880 <-> [2a38:e156:8167:a333:face:b00c::24d9]:3478 [proto: 78/STUN][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 5][cat: Network/14][21 pkts/1722 bytes <-> 21 pkts/2226 bytes][Goodput ratio: 24/41][191.49 sec][bytes ratio: -0.128 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 2/2 9451/9451 10358/10358 2441/2441][Pkt Len c2s/s2c min/avg/max/stddev: 82/106 82/106 82/106 0/0][PLAIN TEXT (WOBTrOXR)][Plen Bins: 50,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
4 TCP 87.47.100.17:3478 <-> 54.1.57.155:37257 [proto: 78/STUN][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 6][cat: Network/14][9 pkts/1494 bytes <-> 11 pkts/2178 bytes][Goodput ratio: 60/67][0.95 sec][Hostname/SNI: apps-host.com][bytes ratio: -0.186 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 0/0 104/96 267/252 102/93][Pkt Len c2s/s2c min/avg/max/stddev: 74/94 166/198 234/354 41/65][PLAIN TEXT (Unauthorized)][Plen Bins: 10,0,15,21,42,5,0,0,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
5 TCP 10.77.110.51:41588 <-> 10.206.50.239:42000 [VLAN: 1611][proto: 78.38/STUN.Skype_TeamsCall][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 3][cat: VoIP/10][7 pkts/1006 bytes <-> 8 pkts/1118 bytes][Goodput ratio: 58/57][1.05 sec][bytes ratio: -0.053 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 0/0 189/134 369/399 144/153][Pkt Len c2s/s2c min/avg/max/stddev: 70/64 144/140 164/172 31/43][Plen Bins: 0,0,25,75,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
6 UDP 192.168.12.169:43016 <-> 74.125.247.128:3478 [proto: 78.201/STUN.GoogleHangoutDuo][IP: 126/Google][ClearText][Confidence: DPI][DPI packets: 4][cat: VoIP/10][4 pkts/528 bytes <-> 4 pkts/408 bytes][Goodput ratio: 68/59][1.25 sec][Hostname/SNI: turn.l.google.com][bytes ratio: 0.128 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 9/23 342/409 974/1177 447/543][Pkt Len c2s/s2c min/avg/max/stddev: 62/74 132/102 198/122 61/19][PLAIN TEXT (BSnLfRxS6)][Plen Bins: 12,37,25,0,25,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
7 ICMP 192.168.12.169:0 -> 74.125.247.128:0 [proto: 81/ICMP][IP: 126/Google][ClearText][Confidence: DPI][DPI packets: 1][cat: Network/14][1 pkts/122 bytes -> 0 pkts/0 bytes][Goodput ratio: 65/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][PLAIN TEXT (62NfUD5)][Plen Bins: 0,0,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
7 UDP 192.168.43.169:48854 <-> 134.224.90.111:8801 [proto: 30/DTLS][IP: 189/Zoom][Encrypted][Confidence: DPI][DPI packets: 4][3 pkts/660 bytes <-> 1 pkts/106 bytes][Goodput ratio: 81/60][0.12 sec][(Advertised) ALPNs: webrtc;c-webrtc][Risk: ** Known Proto on Non Std Port **** Missing SNI TLS Extn **][Risk Score: 100][DTLSv1.2][JA3C: 3e12a43c7535bb32beac3928f8fe905d][Firefox][PLAIN TEXT (DCBD09778680)][Plen Bins: 0,0,25,0,25,50,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
8 ICMP 192.168.12.169:0 -> 74.125.247.128:0 [proto: 81/ICMP][IP: 126/Google][ClearText][Confidence: DPI][DPI packets: 1][cat: Network/14][1 pkts/122 bytes -> 0 pkts/0 bytes][Goodput ratio: 65/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][PLAIN TEXT (62NfUD5)][Plen Bins: 0,0,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

0 comments on commit 0357b29

Please sign in to comment.