diff options
author | Luca Deri <deri@ntop.org> | 2020-05-31 08:28:02 +0200 |
---|---|---|
committer | Luca Deri <deri@ntop.org> | 2020-05-31 08:28:02 +0200 |
commit | c793e16050df1de377e400eec6e2b34ccff6ca85 (patch) | |
tree | eae00620f08c260404999b7382470430a9178ec9 /src | |
parent | b6eef17e54999586b6aef8f545c87de4d3ec0ab3 (diff) |
Added extra TLS memory boundary checks
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/protocols/tls.c | 124 |
1 files changed, 65 insertions, 59 deletions
diff --git a/src/lib/protocols/tls.c b/src/lib/protocols/tls.c index 816a08adc..e2d1a572e 100644 --- a/src/lib/protocols/tls.c +++ b/src/lib/protocols/tls.c @@ -390,77 +390,83 @@ static void processCertificateElements(struct ndpi_detection_module_struct *ndpi i += 3 /* skip the initial patten 55 1D 11 */; i++; /* skip the first type, 0x04 == BIT STRING, and jump to it's length */ - i += (packet->payload[i] & 0x80) ? (packet->payload[i] & 0x7F) : 0; /* skip BIT STRING length */ - i += 2; /* skip the second type, 0x30 == SEQUENCE, and jump to it's length */ - i += (packet->payload[i] & 0x80) ? (packet->payload[i] & 0x7F) : 0; /* skip SEQUENCE length */ - i++; - - while(i < packet->payload_packet_len) { - if(packet->payload[i] == 0x82) { - if((i < (packet->payload_packet_len - 1)) - && ((i + packet->payload[i + 1] + 2) < packet->payload_packet_len)) { - u_int8_t len = packet->payload[i + 1]; - char dNSName[256]; - - i += 2; - - /* The check "len > sizeof(dNSName) - 1" will be always false. If we add it, - the compiler is smart enough to detect it and throws a warning */ - if(len == 0 /* Looks something went wrong */) - break; + if(i < packet->payload_packet_len) { + i += (packet->payload[i] & 0x80) ? (packet->payload[i] & 0x7F) : 0; /* skip BIT STRING length */ + if(i < packet->payload_packet_len) { + i += 2; /* skip the second type, 0x30 == SEQUENCE, and jump to it's length */ + if(i < packet->payload_packet_len) { + i += (packet->payload[i] & 0x80) ? (packet->payload[i] & 0x7F) : 0; /* skip SEQUENCE length */ + i++; + + while(i < packet->payload_packet_len) { + if(packet->payload[i] == 0x82) { + if((i < (packet->payload_packet_len - 1)) + && ((i + packet->payload[i + 1] + 2) < packet->payload_packet_len)) { + u_int8_t len = packet->payload[i + 1]; + char dNSName[256]; + + i += 2; + + /* The check "len > sizeof(dNSName) - 1" will be always false. If we add it, + the compiler is smart enough to detect it and throws a warning */ + if(len == 0 /* Looks something went wrong */) + break; - strncpy(dNSName, (const char*)&packet->payload[i], len); - dNSName[len] = '\0'; + strncpy(dNSName, (const char*)&packet->payload[i], len); + dNSName[len] = '\0'; - cleanupServerName(dNSName, len); + cleanupServerName(dNSName, len); #if DEBUG_TLS - printf("[TLS] dNSName %s [%s]\n", dNSName, flow->protos.stun_ssl.ssl.client_requested_server_name); + printf("[TLS] dNSName %s [%s]\n", dNSName, flow->protos.stun_ssl.ssl.client_requested_server_name); #endif - if(matched_name == 0) { - if((dNSName[0] == '*') && strstr(flow->protos.stun_ssl.ssl.client_requested_server_name, &dNSName[1])) - matched_name = 1; - else if(strcmp(flow->protos.stun_ssl.ssl.client_requested_server_name, dNSName) == 0) - matched_name = 1; - } + if(matched_name == 0) { + if((dNSName[0] == '*') && strstr(flow->protos.stun_ssl.ssl.client_requested_server_name, &dNSName[1])) + matched_name = 1; + else if(strcmp(flow->protos.stun_ssl.ssl.client_requested_server_name, dNSName) == 0) + matched_name = 1; + } - if(flow->protos.stun_ssl.ssl.server_names == NULL) - flow->protos.stun_ssl.ssl.server_names = ndpi_strdup(dNSName), - flow->protos.stun_ssl.ssl.server_names_len = strlen(dNSName); - else { - u_int16_t dNSName_len = strlen(dNSName); - u_int16_t newstr_len = flow->protos.stun_ssl.ssl.server_names_len + dNSName_len + 1; - char *newstr = (char*)ndpi_realloc(flow->protos.stun_ssl.ssl.server_names, - flow->protos.stun_ssl.ssl.server_names_len+1, newstr_len+1); - - if(newstr) { - flow->protos.stun_ssl.ssl.server_names = newstr; - flow->protos.stun_ssl.ssl.server_names[flow->protos.stun_ssl.ssl.server_names_len] = ','; - strncpy(&flow->protos.stun_ssl.ssl.server_names[flow->protos.stun_ssl.ssl.server_names_len+1], - dNSName, dNSName_len+1); - flow->protos.stun_ssl.ssl.server_names[newstr_len] = '\0'; - flow->protos.stun_ssl.ssl.server_names_len = newstr_len; - } - } + if(flow->protos.stun_ssl.ssl.server_names == NULL) + flow->protos.stun_ssl.ssl.server_names = ndpi_strdup(dNSName), + flow->protos.stun_ssl.ssl.server_names_len = strlen(dNSName); + else { + u_int16_t dNSName_len = strlen(dNSName); + u_int16_t newstr_len = flow->protos.stun_ssl.ssl.server_names_len + dNSName_len + 1; + char *newstr = (char*)ndpi_realloc(flow->protos.stun_ssl.ssl.server_names, + flow->protos.stun_ssl.ssl.server_names_len+1, newstr_len+1); + + if(newstr) { + flow->protos.stun_ssl.ssl.server_names = newstr; + flow->protos.stun_ssl.ssl.server_names[flow->protos.stun_ssl.ssl.server_names_len] = ','; + strncpy(&flow->protos.stun_ssl.ssl.server_names[flow->protos.stun_ssl.ssl.server_names_len+1], + dNSName, dNSName_len+1); + flow->protos.stun_ssl.ssl.server_names[newstr_len] = '\0'; + flow->protos.stun_ssl.ssl.server_names_len = newstr_len; + } + } - if(!flow->l4.tcp.tls.subprotocol_detected) - if(ndpi_match_hostname_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TLS, dNSName, len)) - flow->l4.tcp.tls.subprotocol_detected = 1; + if(!flow->l4.tcp.tls.subprotocol_detected) + if(ndpi_match_hostname_protocol(ndpi_struct, flow, NDPI_PROTOCOL_TLS, dNSName, len)) + flow->l4.tcp.tls.subprotocol_detected = 1; - i += len; - } else { + i += len; + } else { #if DEBUG_TLS - printf("[TLS] Leftover %u bytes", packet->payload_packet_len - i); + printf("[TLS] Leftover %u bytes", packet->payload_packet_len - i); #endif - break; + break; + } + } else { + break; + } + } /* while */ + + if(!matched_name) + NDPI_SET_BIT(flow->risk, NDPI_TLS_CERTIFICATE_MISMATCH); /* Certificate mismatch */ } - } else { - break; } - } /* while */ - - if(!matched_name) - NDPI_SET_BIT(flow->risk, NDPI_TLS_CERTIFICATE_MISMATCH); /* Certificate mismatch */ + } } } |