aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib/protocols/tls.c86
-rw-r--r--tests/pcap/tls_invalid_reads.pcapbin0 -> 2436 bytes
-rw-r--r--tests/result/tls_invalid_reads.pcap.out8
3 files changed, 55 insertions, 39 deletions
diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c
index 3a09f444b..035142f00 100644
--- a/src/lib/protocols/tls.c
+++ b/src/lib/protocols/tls.c
@@ -1074,8 +1074,12 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
u_int16_t version_offset = (!is_dtls) ? 4 : 12;
u_int16_t offset = (!is_dtls) ? 38 : 46, extension_len, j;
u_int8_t session_id_len = 0;
- if (base_offset < total_len)
- session_id_len = packet->payload[base_offset];
+
+ if((base_offset >= total_len) ||
+ (version_offset + 1) >= total_len)
+ return 0; /* Not found */
+
+ session_id_len = packet->payload[base_offset];
#ifdef DEBUG_TLS
printf("TLS [len: %u][handshake_type: %02X]\n", packet->payload_packet_len, handshake_type);
@@ -1352,12 +1356,12 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
}
offset = base_offset + session_id_len + cookie_len + cipher_len + 2;
+ offset += (!is_dtls) ? 1 : 2;
if(offset < total_len) {
u_int16_t compression_len;
u_int16_t extensions_len;
- offset += (!is_dtls) ? 1 : 2;
compression_len = packet->payload[offset];
offset++;
@@ -1368,7 +1372,7 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
// offset += compression_len + 3;
offset += compression_len;
- if(offset < total_len) {
+ if(offset+1 < total_len) {
extensions_len = ntohs(*((u_int16_t*)&packet->payload[offset]));
offset += 2;
@@ -1382,9 +1386,11 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
u_int extension_offset = 0;
u_int32_t j;
- while(extension_offset < extensions_len) {
+ while(extension_offset < extensions_len &&
+ offset+extension_offset+4 <= total_len) {
u_int16_t extension_id, extension_len, extn_off = offset+extension_offset;
+
extension_id = ntohs(*((u_int16_t*)&packet->payload[offset+extension_offset]));
extension_offset += 2;
@@ -1414,55 +1420,57 @@ int processClientServerHello(struct ndpi_detection_module_struct *ndpi_struct,
#ifdef DEBUG_TLS
printf("[TLS] Extensions: found server name\n");
#endif
+ if((offset+extension_offset+4) < packet->payload_packet_len) {
- len = (packet->payload[offset+extension_offset+3] << 8) + packet->payload[offset+extension_offset+4];
- len = (u_int)ndpi_min(len, sizeof(buffer)-1);
+ len = (packet->payload[offset+extension_offset+3] << 8) + packet->payload[offset+extension_offset+4];
+ len = (u_int)ndpi_min(len, sizeof(buffer)-1);
- if((offset+extension_offset+5+len) <= packet->payload_packet_len) {
- strncpy(buffer, (char*)&packet->payload[offset+extension_offset+5], len);
- buffer[len] = '\0';
+ if((offset+extension_offset+5+len) <= packet->payload_packet_len) {
+ strncpy(buffer, (char*)&packet->payload[offset+extension_offset+5], len);
+ buffer[len] = '\0';
- cleanupServerName(buffer, sizeof(buffer));
+ cleanupServerName(buffer, sizeof(buffer));
- snprintf(flow->protos.tls_quic_stun.tls_quic.client_requested_server_name,
- sizeof(flow->protos.tls_quic_stun.tls_quic.client_requested_server_name),
- "%s", buffer);
+ snprintf(flow->protos.tls_quic_stun.tls_quic.client_requested_server_name,
+ sizeof(flow->protos.tls_quic_stun.tls_quic.client_requested_server_name),
+ "%s", buffer);
#ifdef DEBUG_TLS
- printf("[TLS] SNI: [%s]\n", buffer);
+ printf("[TLS] SNI: [%s]\n", buffer);
#endif
- if(!is_quic) {
- if(ndpi_match_hostname_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TLS, buffer, strlen(buffer)))
- flow->l4.tcp.tls.subprotocol_detected = 1;
- } else {
- if(ndpi_match_hostname_protocol(ndpi_struct, flow, NDPI_PROTOCOL_QUIC, buffer, strlen(buffer)))
- flow->l4.tcp.tls.subprotocol_detected = 1;
- }
+ if(!is_quic) {
+ if(ndpi_match_hostname_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TLS, buffer, strlen(buffer)))
+ flow->l4.tcp.tls.subprotocol_detected = 1;
+ } else {
+ if(ndpi_match_hostname_protocol(ndpi_struct, flow, NDPI_PROTOCOL_QUIC, buffer, strlen(buffer)))
+ flow->l4.tcp.tls.subprotocol_detected = 1;
+ }
- if(ndpi_check_dga_name(ndpi_struct, flow,
- flow->protos.tls_quic_stun.tls_quic.client_requested_server_name, 1)) {
- char *sni = flow->protos.tls_quic_stun.tls_quic.client_requested_server_name;
- int len = strlen(sni);
+ if(ndpi_check_dga_name(ndpi_struct, flow,
+ flow->protos.tls_quic_stun.tls_quic.client_requested_server_name, 1)) {
+ char *sni = flow->protos.tls_quic_stun.tls_quic.client_requested_server_name;
+ int len = strlen(sni);
#ifdef DEBUG_TLS
- printf("[TLS] SNI: (DGA) [%s]\n", flow->protos.tls_quic_stun.tls_quic.client_requested_server_name);
+ printf("[TLS] SNI: (DGA) [%s]\n", flow->protos.tls_quic_stun.tls_quic.client_requested_server_name);
#endif
- if((len >= 4)
- /* Check if it ends in .com or .net */
- && ((strcmp(&sni[len-4], ".com") == 0) || (strcmp(&sni[len-4], ".net") == 0))
- && (strncmp(sni, "www.", 4) == 0)) /* Not starting with www.... */
- ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TOR, NDPI_PROTOCOL_TLS);
- } else {
+ if((len >= 4)
+ /* Check if it ends in .com or .net */
+ && ((strcmp(&sni[len-4], ".com") == 0) || (strcmp(&sni[len-4], ".net") == 0))
+ && (strncmp(sni, "www.", 4) == 0)) /* Not starting with www.... */
+ ndpi_set_detected_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TOR, NDPI_PROTOCOL_TLS);
+ } else {
#ifdef DEBUG_TLS
- printf("[TLS] SNI: (NO DGA) [%s]\n", flow->protos.tls_quic_stun.tls_quic.client_requested_server_name);
+ printf("[TLS] SNI: (NO DGA) [%s]\n", flow->protos.tls_quic_stun.tls_quic.client_requested_server_name);
#endif
- }
- } else {
+ }
+ } else {
#ifdef DEBUG_TLS
- printf("[TLS] Extensions server len too short: %u vs %u\n",
- offset+extension_offset+5+len,
- packet->payload_packet_len);
+ printf("[TLS] Extensions server len too short: %u vs %u\n",
+ offset+extension_offset+5+len,
+ packet->payload_packet_len);
#endif
+ }
}
} else if(extension_id == 10 /* supported groups */) {
u_int16_t s_offset = offset+extension_offset + 2;
diff --git a/tests/pcap/tls_invalid_reads.pcap b/tests/pcap/tls_invalid_reads.pcap
new file mode 100644
index 000000000..4979428be
--- /dev/null
+++ b/tests/pcap/tls_invalid_reads.pcap
Binary files differ
diff --git a/tests/result/tls_invalid_reads.pcap.out b/tests/result/tls_invalid_reads.pcap.out
new file mode 100644
index 000000000..ecfed29e5
--- /dev/null
+++ b/tests/result/tls_invalid_reads.pcap.out
@@ -0,0 +1,8 @@
+TLS 8 1891 2
+
+JA3 Host Stats:
+ IP Address # JA3C
+
+
+ 1 TCP 192.168.10.101:3967 <-> 206.33.61.113:443 [proto: 91/TLS][cat: Web/5][4 pkts/330 bytes <-> 3 pkts/1497 bytes][Goodput ratio: 31/89][0.08 sec][bytes ratio: -0.639 (Download)][IAT c2s/s2c min/avg/max/stddev: 0/38 25/19 58/38 24/19][Pkt Len c2s/s2c min/avg/max/stddev: 54/60 82/499 156/905 43/346][Risk: ** Obsolete TLS version (< 1.1) **][TLSv1][JA3S: 53611273a714cb4789c8222932efd5a7 (INSECURE)][Cipher: TLS_RSA_WITH_RC4_128_MD5][Plen Bins: 0,0,0,33,0,0,0,0,0,0,0,0,0,0,33,0,0,0,0,0,0,0,0,0,0,0,33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
+ 2 TCP 74.80.160.99:3258 -> 67.217.77.28:443 [proto: 91/TLS][cat: Web/5][1 pkts/64 bytes -> 0 pkts/0 bytes][Goodput ratio: 15/0][< 1 sec][Plen Bins: 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,0]