mirror of
https://github.com/vel21ripn/nDPI.git
synced 2026-05-19 07:54:24 +00:00
Add support for Snapchat voip calls (#1147)
* Add support for Snapchat voip calls Snapchat multiplexes some of its audio/video real time traffic with QUIC sessions. The peculiarity of these sessions is that they are Q046 and don't have any SNI. * Fix tests with libgcrypt disabled
This commit is contained in:
parent
73e4348570
commit
c50a8d4808
8 changed files with 84 additions and 3 deletions
|
|
@ -81,7 +81,7 @@ u_int8_t verbose = 0, enable_joy_stats = 0;
|
|||
int nDPI_LogLevel = 0;
|
||||
char *_debug_protocols = NULL;
|
||||
u_int8_t human_readeable_string_len = 5;
|
||||
u_int8_t max_num_udp_dissected_pkts = 16 /* 8 is enough for most protocols, Signal requires more */, max_num_tcp_dissected_pkts = 80 /* due to telnet */;
|
||||
u_int8_t max_num_udp_dissected_pkts = 24 /* 8 is enough for most protocols, Signal and SnapchatCall require more */, max_num_tcp_dissected_pkts = 80 /* due to telnet */;
|
||||
static u_int32_t pcap_analysis_duration = (u_int32_t)-1;
|
||||
static u_int16_t decode_tunnels = 0;
|
||||
static u_int16_t num_loops = 1;
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@
|
|||
|
||||
extern u_int8_t enable_protocol_guess, enable_joy_stats, enable_payload_analyzer;
|
||||
extern u_int8_t verbose, human_readeable_string_len;
|
||||
extern u_int8_t max_num_udp_dissected_pkts /* 8 */, max_num_tcp_dissected_pkts /* 10 */;
|
||||
extern u_int8_t max_num_udp_dissected_pkts /* 24 */, max_num_tcp_dissected_pkts /* 80 */;
|
||||
static u_int32_t flow_id = 0;
|
||||
|
||||
u_int8_t enable_doh_dot_detection = 0;
|
||||
|
|
|
|||
|
|
@ -283,6 +283,7 @@ typedef enum {
|
|||
NDPI_PROTOCOL_ANYDESK = 252, /* Toni Uhlig <matzeton@googlemail.com> */
|
||||
NDPI_PROTOCOL_SOAP = 253, /* Toni Uhlig <matzeton@googlemail.com> */
|
||||
NDPI_PROTOCOL_APPLE_SIRI = 254, /* Zied Aouini <aouinizied@gmail.com> */
|
||||
NDPI_PROTOCOL_SNAPCHAT_CALL = 255,
|
||||
|
||||
|
||||
#ifdef CUSTOM_NDPI_PROTOCOLS
|
||||
|
|
|
|||
|
|
@ -1576,6 +1576,10 @@ static void ndpi_init_protocol_defaults(struct ndpi_detection_module_struct *ndp
|
|||
1 /* can_have_a_subprotocol */, no_master, no_master, "AppleSiri",
|
||||
NDPI_PROTOCOL_CATEGORY_VIRTUAL_ASSISTANT, ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
|
||||
ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
|
||||
ndpi_set_proto_defaults(ndpi_str, NDPI_PROTOCOL_ACCEPTABLE, NDPI_PROTOCOL_SNAPCHAT_CALL,
|
||||
0 /* can_have_a_subprotocol */, no_master, no_master, "SnapchatCall",
|
||||
NDPI_PROTOCOL_CATEGORY_VOIP, ndpi_build_default_ports(ports_a, 0, 0, 0, 0, 0) /* TCP */,
|
||||
ndpi_build_default_ports(ports_b, 0, 0, 0, 0, 0) /* UDP */);
|
||||
|
||||
#ifdef CUSTOM_NDPI_PROTOCOLS
|
||||
#include "../../../nDPI-custom/custom_ndpi_main.c"
|
||||
|
|
@ -7069,6 +7073,11 @@ uint8_t ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_str,
|
|||
if(flow->extra_packets_func)
|
||||
return(1);
|
||||
break;
|
||||
|
||||
case NDPI_PROTOCOL_QUIC:
|
||||
if(flow->extra_packets_func)
|
||||
return(1);
|
||||
break;
|
||||
}
|
||||
|
||||
return(0);
|
||||
|
|
|
|||
|
|
@ -1382,6 +1382,65 @@ static int may_be_initial_pkt(struct ndpi_detection_module_struct *ndpi_struct,
|
|||
|
||||
/* ***************************************************************** */
|
||||
|
||||
static int eval_extra_processing(struct ndpi_detection_module_struct *ndpi_struct,
|
||||
struct ndpi_flow_struct *flow, u_int32_t version)
|
||||
{
|
||||
/* For the time being we need extra processing only to detect Snapchat calls,
|
||||
i.e. RTP/RTCP multiplxed with QUIC.
|
||||
We noticed that Snapchat uses Q046, without any SNI */
|
||||
|
||||
if(version == V_Q046 &&
|
||||
flow->protos.tls_quic_stun.tls_quic.client_requested_server_name[0] == '\0') {
|
||||
NDPI_LOG_DBG2(ndpi_struct, "We have further work to do\n");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int is_valid_rtp_payload_type(uint8_t type)
|
||||
{
|
||||
/* https://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml */
|
||||
return type <= 34 || (type >= 96 && type <= 127);
|
||||
}
|
||||
|
||||
static int ndpi_search_quic_extra(struct ndpi_detection_module_struct *ndpi_struct,
|
||||
struct ndpi_flow_struct *flow)
|
||||
{
|
||||
struct ndpi_packet_struct *packet = &flow->packet;
|
||||
|
||||
/* We are elaborating a packet following the initial CHLO/ClientHello.
|
||||
Mutiplexing QUIC with RTP/RTCP should be quite generic, but
|
||||
for the time being, we known only NDPI_PROTOCOL_SNAPCHAT_CALL having such behaviour */
|
||||
|
||||
NDPI_LOG_DBG(ndpi_struct, "search QUIC extra func\n");
|
||||
|
||||
/* If this packet is still a Q046 one we need to keep going */
|
||||
if(packet->payload[0] & 0x40) {
|
||||
NDPI_LOG_DBG(ndpi_struct, "Still QUIC\n");
|
||||
return 1; /* Keep going */
|
||||
}
|
||||
|
||||
NDPI_LOG_DBG2(ndpi_struct, "No more QUIC: nothing to do on QUIC side\n");
|
||||
flow->extra_packets_func = NULL;
|
||||
|
||||
/* This might be a RTP/RTCP stream: let's check it */
|
||||
/* TODO: the cleanest solution should be triggering the rtp/rtcp dissector, but
|
||||
I have not been able to that that so I reimplemented a basic RTP/RTCP detection.*/
|
||||
if((packet->payload[0] >> 6) == 2 && /* Version 2 */
|
||||
packet->payload_packet_len > 1 &&
|
||||
(packet->payload[1] == 201 || /* RTCP, Receiver Report */
|
||||
packet->payload[1] == 200 || /* RTCP, Sender Report */
|
||||
is_valid_rtp_payload_type(packet->payload[1] & 0x7F)) /* RTP */) {
|
||||
NDPI_LOG_DBG(ndpi_struct, "Found RTP/RTCP over QUIC\n");
|
||||
ndpi_int_change_protocol(ndpi_struct, flow, NDPI_PROTOCOL_SNAPCHAT_CALL, NDPI_PROTOCOL_QUIC);
|
||||
} else {
|
||||
/* Unexpected traffic pattern: we should investigate it... */
|
||||
NDPI_LOG_INFO(ndpi_struct, "To investigate...\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct,
|
||||
struct ndpi_flow_struct *flow)
|
||||
{
|
||||
|
|
@ -1465,6 +1524,15 @@ void ndpi_search_quic(struct ndpi_detection_module_struct *ndpi_struct,
|
|||
if(is_version_with_encrypted_header(version)) {
|
||||
ndpi_free(clear_payload);
|
||||
}
|
||||
|
||||
/*
|
||||
* 7) We need to process other packets than ClientHello/CHLO?
|
||||
*/
|
||||
if(eval_extra_processing(ndpi_struct, flow, version)) {
|
||||
flow->check_extra_packets = 1;
|
||||
flow->max_extra_packets_to_check = 24; /* TODO */
|
||||
flow->extra_packets_func = ndpi_search_quic_extra;
|
||||
}
|
||||
}
|
||||
|
||||
/* ***************************************************************** */
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ cd "$(dirname "${0}")"
|
|||
FUZZY_TESTING_ENABLED=@BUILD_FUZZTARGETS@
|
||||
|
||||
GCRYPT_ENABLED=@GCRYPT_ENABLED@
|
||||
GCRYPT_PCAPS="gquic.pcap quic-23.pcap quic-24.pcap quic-27.pcap quic-28.pcap quic-29.pcap quic-mvfst-22.pcap quic-mvfst-27.pcap quic-mvfst-exp.pcap quic_q50.pcap quic_t50.pcap quic_t51.pcap quic_0RTT.pcap quic_interop_V.pcapng quic-33.pcapng doq.pcapng doq_adguard.pcapng dlt_ppp.pcap os_detected.pcapng"
|
||||
GCRYPT_PCAPS="gquic.pcap quic-23.pcap quic-24.pcap quic-27.pcap quic-28.pcap quic-29.pcap quic-mvfst-22.pcap quic-mvfst-27.pcapng quic-mvfst-exp.pcap quic_q50.pcap quic_t50.pcap quic_t51.pcap quic_0RTT.pcap quic_interop_V.pcapng quic-33.pcapng doq.pcapng doq_adguard.pcapng dlt_ppp.pcap os_detected.pcapng"
|
||||
READER="../example/ndpiReader -p ../example/protos.txt -c ../example/categories.txt -r ../example/risky_domains.txt -j ../example/ja3_fingerprints.csv -S ../example/sha1_fingerprints.csv"
|
||||
|
||||
RC=0
|
||||
|
|
|
|||
BIN
tests/pcap/snapchat_call.pcapng
Normal file
BIN
tests/pcap/snapchat_call.pcapng
Normal file
Binary file not shown.
3
tests/result/snapchat_call.pcapng.out
Normal file
3
tests/result/snapchat_call.pcapng.out
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
SnapchatCall 50 12772 1
|
||||
|
||||
1 UDP 192.168.12.169:42083 <-> 18.184.138.142:443 [proto: 188.255/QUIC.SnapchatCall][cat: Web/5][25 pkts/5295 bytes <-> 25 pkts/7477 bytes][Goodput ratio: 80/86][8.29 sec][bytes ratio: -0.171 (Mixed)][IAT c2s/s2c min/avg/max/stddev: 0/0 288/246 1313/1315 376/342][Pkt Len c2s/s2c min/avg/max/stddev: 65/62 212/299 1392/1392 365/419][Risk: ** SNI TLS extension was missing **][PLAIN TEXT (AESGCC20)][Plen Bins: 28,44,0,2,2,0,0,2,4,4,0,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,10,0,0,0,0,0]
|
||||
Loading…
Add table
Add a link
Reference in a new issue