aboutsummaryrefslogtreecommitdiff
path: root/src/lib/protocols/dns.c
diff options
context:
space:
mode:
authorLuca Deri <deri@ntop.org>2016-01-06 17:38:41 +0100
committerLuca Deri <deri@ntop.org>2016-01-06 17:38:41 +0100
commita08a0077e6dcb193efe97b71f26c3bc82769a6ac (patch)
tree9fa9241961612a5425b8cd2d175b838cdcfdba75 /src/lib/protocols/dns.c
parent5336aecde7e6f40e22810538dba9dd6601291145 (diff)
Hardened DNS dissector
Diffstat (limited to 'src/lib/protocols/dns.c')
-rw-r--r--src/lib/protocols/dns.c35
1 files changed, 29 insertions, 6 deletions
diff --git a/src/lib/protocols/dns.c b/src/lib/protocols/dns.c
index ea136f453..f0ae86ea4 100644
--- a/src/lib/protocols/dns.c
+++ b/src/lib/protocols/dns.c
@@ -60,7 +60,9 @@ void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct nd
if((s_port == 53 || d_port == 53 || d_port == 5355)
&& (flow->packet.payload_packet_len > sizeof(struct ndpi_dns_packet_header)))
{
- struct ndpi_dns_packet_header * dns_header = (struct ndpi_dns_packet_header*) &flow->packet.payload[x];
+ struct ndpi_dns_packet_header *dns_header = (struct ndpi_dns_packet_header*) &flow->packet.payload[x];
+ int invalid = 0;
+
dns_header->tr_id = ntohs(dns_header->tr_id);
dns_header->flags = ntohs(dns_header->flags);
dns_header->num_queries = ntohs(dns_header->num_queries);
@@ -75,11 +77,34 @@ void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct nd
else if(dns_header->flags & FLAGS_MASK != 0x8000)
is_query = 1;
else
- {
+ invalid = 1
+
+ if(is_query) {
+ /* DNS Request */
+ if((header.num_queries > 0) && (header.num_queries <= NDPI_MAX_DNS_REQUESTS)
+ && (((header.flags & 0x2800) == 0x2800 /* Dynamic DNS Update */)
+ || ((header.answer_rrs == 0) && (header.authority_rrs == 0)))) {
+ /* This is a good query */
+ } else
+ invalid = 1;
+ } else {
+ /* DNS Reply */
+ if((header.num_queries <= NDPI_MAX_DNS_REQUESTS) /* Don't assume that num_queries must be zero */
+ && (((header.answer_rrs > 0) && (header.answer_rrs <= NDPI_MAX_DNS_REQUESTS))
+ || ((header.authority_rrs > 0) && (header.authority_rrs <= NDPI_MAX_DNS_REQUESTS))
+ || ((header.additional_rrs > 0) && (header.additional_rrs <= NDPI_MAX_DNS_REQUESTS)))
+ ) {
+ /* This is a good reply */
+ } else
+ invalid = 1;
+ }
+
+ if(invalid) {
NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "exclude DNS.\n");
NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DNS);
+ return;
}
-
+
/* extract host name server */
ret_code = (is_query == 0) ? 0 : (dns_header->flags & 0x0F);
int j = 0;
@@ -111,9 +136,7 @@ void ndpi_search_dns(struct ndpi_detection_module_struct *ndpi_struct, struct nd
**/
NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "found DNS.\n");
ndpi_set_detected_protocol(ndpi_struct, flow, (d_port == 5355) ? NDPI_PROTOCOL_LLMNR : NDPI_PROTOCOL_DNS, NDPI_PROTOCOL_UNKNOWN);
- }
- else
- {
+ } else {
NDPI_LOG(NDPI_PROTOCOL_DNS, ndpi_struct, NDPI_LOG_DEBUG, "exclude DNS.\n");
NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_DNS);
}