diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/include/ndpi_typedefs.h | 17 | ||||
-rw-r--r-- | src/lib/ndpi_main.c | 180 | ||||
-rw-r--r-- | src/lib/ndpi_utils.c | 3 |
3 files changed, 127 insertions, 73 deletions
diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index 8c1b1823a..67f76473b 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -121,9 +121,10 @@ typedef enum { your app will clear this risk if future packets (not sent to nDPI) are received in the opposite direction */ NDPI_HTTP_OBSOLETE_SERVER, - NDPI_PERIODIC_FLOW, /* Set in case a flow repeats at a specific pace [used by apps on top of nDPI] */ - NDPI_MINOR_ISSUES, /* Generic packet issues (e.g. DNS with 0 TTL) */ - + NDPI_PERIODIC_FLOW, /* Set in case a flow repeats at a specific pace [used by apps on top of nDPI] */ + NDPI_MINOR_ISSUES, /* Generic packet issues (e.g. DNS with 0 TTL) */ + NDPI_TCP_ISSUES, /* TCP issues such as connection failed, probing or scan */ + /* Leave this as last member */ NDPI_MAX_RISK /* must be <= 63 due to (**) */ } ndpi_risk_enum; @@ -724,10 +725,9 @@ struct ndpi_flow_tcp_struct { u_int32_t postgres_stage:3; /* Part of the TCP header. */ - u_int32_t seen_syn:1; - u_int32_t seen_syn_ack:1; - u_int32_t seen_ack:1; - + u_int32_t seen_syn:1, seen_syn_ack:1, seen_ack:1, __notused:29; + u_int8_t cli2srv_tcp_flags, srv2cli_tcp_flags; + /* NDPI_PROTOCOL_ICECAST */ u_int32_t icecast_stage:1; @@ -1525,7 +1525,8 @@ struct ndpi_flow_struct { /* Only packets with L5 data (ie no TCP SYN, pure ACKs, ...) */ u_int16_t packet_counter; // can be 0 - 65000 u_int16_t packet_direction_counter[2]; - + u_int16_t all_packets_counter; /* All packets even those without payload */ + /* Every packets */ u_int16_t packet_direction_complete_counter[2]; // can be 0 - 65000 diff --git a/src/lib/ndpi_main.c b/src/lib/ndpi_main.c index 81eb5e277..b2dd8f7d2 100644 --- a/src/lib/ndpi_main.c +++ b/src/lib/ndpi_main.c @@ -168,6 +168,7 @@ static ndpi_risk_info ndpi_known_risks[] = { { NDPI_HTTP_OBSOLETE_SERVER, NDPI_RISK_MEDIUM, CLIENT_LOW_RISK_PERCENTAGE, NDPI_SERVER_ACCOUNTABLE }, { NDPI_PERIODIC_FLOW, NDPI_RISK_LOW, CLIENT_LOW_RISK_PERCENTAGE, NDPI_CLIENT_ACCOUNTABLE }, { NDPI_MINOR_ISSUES, NDPI_RISK_LOW, CLIENT_LOW_RISK_PERCENTAGE, NDPI_BOTH_ACCOUNTABLE }, + { NDPI_TCP_ISSUES, NDPI_RISK_MEDIUM, CLIENT_FAIR_RISK_PERCENTAGE, NDPI_CLIENT_ACCOUNTABLE }, /* Leave this as last member */ { NDPI_MAX_RISK, NDPI_RISK_LOW, CLIENT_FAIR_RISK_PERCENTAGE, NDPI_NO_ACCOUNTABILITY } @@ -5460,25 +5461,42 @@ void ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_str, packet->packet_lines_parsed_complete = 0; if(tcph != NULL) { + u_int8_t flags = ((u_int8_t*)tcph)[13]; + + if(flags == 0) + ndpi_set_risk(ndpi_str, flow, NDPI_TCP_ISSUES, "TCP NULL scan"); + else if(flags == (TH_FIN | TH_PUSH | TH_URG)) + ndpi_set_risk(ndpi_str, flow, NDPI_TCP_ISSUES, "TCP XMAS scan"); + if(!ndpi_str->direction_detect_disable) packet->packet_direction = (ntohs(tcph->source) < ntohs(tcph->dest)) ? 1 : 0; - if(ndpi_str->input_info == NULL || - ndpi_str->input_info->seen_flow_beginning == NDPI_FLOW_BEGINNING_UNKNOWN) { - if(tcph->syn != 0 && tcph->ack == 0 && flow->l4.tcp.seen_syn == 0 && flow->l4.tcp.seen_syn_ack == 0 && - flow->l4.tcp.seen_ack == 0) { - flow->l4.tcp.seen_syn = 1; - } else { - if(tcph->syn != 0 && tcph->ack != 0 && flow->l4.tcp.seen_syn == 1 && flow->l4.tcp.seen_syn_ack == 0 && - flow->l4.tcp.seen_ack == 0) { - flow->l4.tcp.seen_syn_ack = 1; - } else { - if(tcph->syn == 0 && tcph->ack == 1 && flow->l4.tcp.seen_syn == 1 && flow->l4.tcp.seen_syn_ack == 1 && - flow->l4.tcp.seen_ack == 0) { - flow->l4.tcp.seen_ack = 1; - } - } - } + if(packet->packet_direction == 0 /* cli -> srv */) { + if(flags == TH_FIN) + ndpi_set_risk(ndpi_str, flow, NDPI_TCP_ISSUES, "TCP FIN scan"); + + flow->l4.tcp.cli2srv_tcp_flags |= flags; + } else + flow->l4.tcp.srv2cli_tcp_flags |= flags; + + if((ndpi_str->input_info == NULL) + || ndpi_str->input_info->seen_flow_beginning == NDPI_FLOW_BEGINNING_UNKNOWN) { + if(tcph->syn != 0 && tcph->ack == 0 && flow->l4.tcp.seen_syn == 0 + && flow->l4.tcp.seen_syn_ack == 0 && + flow->l4.tcp.seen_ack == 0) { + flow->l4.tcp.seen_syn = 1; + } else { + if(tcph->syn != 0 && tcph->ack != 0 && flow->l4.tcp.seen_syn == 1 + && flow->l4.tcp.seen_syn_ack == 0 && + flow->l4.tcp.seen_ack == 0) { + flow->l4.tcp.seen_syn_ack = 1; + } else { + if(tcph->syn == 0 && tcph->ack == 1 && flow->l4.tcp.seen_syn == 1 && flow->l4.tcp.seen_syn_ack == 1 && + flow->l4.tcp.seen_ack == 0) { + flow->l4.tcp.seen_ack = 1; + } + } + } } if(flow->next_tcp_seq_nr[0] == 0 || flow->next_tcp_seq_nr[1] == 0 || @@ -5525,7 +5543,7 @@ void ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_str, if(tcph->rst) { flow->next_tcp_seq_nr[0] = 0; flow->next_tcp_seq_nr[1] = 0; - } + } } else if(udph != NULL) { if(!ndpi_str->direction_detect_disable) packet->packet_direction = (htons(udph->source) < htons(udph->dest)) ? 1 : 0; @@ -5537,11 +5555,11 @@ void ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_str, flow->init_finished = 1; if(tcph != NULL && - ndpi_str->input_info && - ndpi_str->input_info->seen_flow_beginning == NDPI_FLOW_BEGINNING_SEEN) { - flow->l4.tcp.seen_syn = 1; - flow->l4.tcp.seen_syn_ack = 1; - flow->l4.tcp.seen_ack = 1; + ndpi_str->input_info && + ndpi_str->input_info->seen_flow_beginning == NDPI_FLOW_BEGINNING_SEEN) { + flow->l4.tcp.seen_syn = 1; + flow->l4.tcp.seen_syn_ack = 1; + flow->l4.tcp.seen_ack = 1; } /* Client/Server direction */ @@ -5549,70 +5567,74 @@ void ndpi_connection_tracking(struct ndpi_detection_module_struct *ndpi_str, s_port = 0; d_port = 0; if(tcph != NULL) { - s_port = tcph->source; - d_port = tcph->dest; + s_port = tcph->source; + d_port = tcph->dest; } else if(udph != NULL) { - s_port = udph->source; - d_port = udph->dest; + s_port = udph->source; + d_port = udph->dest; } if(ndpi_str->input_info && - ndpi_str->input_info->in_pkt_dir != NDPI_IN_PKT_DIR_UNKNOWN) { - if(ndpi_str->input_info->in_pkt_dir == NDPI_IN_PKT_DIR_C_TO_S) - flow->client_packet_direction = packet->packet_direction; - else - flow->client_packet_direction = !packet->packet_direction; + ndpi_str->input_info->in_pkt_dir != NDPI_IN_PKT_DIR_UNKNOWN) { + if(ndpi_str->input_info->in_pkt_dir == NDPI_IN_PKT_DIR_C_TO_S) + flow->client_packet_direction = packet->packet_direction; + else + flow->client_packet_direction = !packet->packet_direction; } else { - if(tcph && tcph->syn) { - if(tcph->ack == 0) { - flow->client_packet_direction = packet->packet_direction; - } else { - flow->client_packet_direction = !packet->packet_direction; - } - } else if(ntohs(s_port) > 1024 && ntohs(d_port) < 1024) { - flow->client_packet_direction = packet->packet_direction; - } else if(ntohs(s_port) < 1024 && ntohs(d_port) > 1024) { - flow->client_packet_direction = !packet->packet_direction; - } else { - flow->client_packet_direction = packet->packet_direction; - } + if(tcph && tcph->syn) { + if(tcph->ack == 0) { + flow->client_packet_direction = packet->packet_direction; + } else { + flow->client_packet_direction = !packet->packet_direction; + } + } else if(ntohs(s_port) > 1024 && ntohs(d_port) < 1024) { + flow->client_packet_direction = packet->packet_direction; + } else if(ntohs(s_port) < 1024 && ntohs(d_port) > 1024) { + flow->client_packet_direction = !packet->packet_direction; + } else { + flow->client_packet_direction = packet->packet_direction; + } } if(ndpi_current_pkt_from_client_to_server(packet, flow)) { - if(flow->is_ipv6 == 0) { - flow->c_address.v4 = packet->iph->saddr; - flow->s_address.v4 = packet->iph->daddr; - } else { - memcpy(flow->c_address.v6, &packet->iphv6->ip6_src, 16); - memcpy(flow->s_address.v6, &packet->iphv6->ip6_dst, 16); - } - flow->c_port = s_port; - flow->s_port = d_port; + if(flow->is_ipv6 == 0) { + flow->c_address.v4 = packet->iph->saddr; + flow->s_address.v4 = packet->iph->daddr; + } else { + memcpy(flow->c_address.v6, &packet->iphv6->ip6_src, 16); + memcpy(flow->s_address.v6, &packet->iphv6->ip6_dst, 16); + } + flow->c_port = s_port; + flow->s_port = d_port; } else { - if(flow->is_ipv6 == 0) { - flow->c_address.v4 = packet->iph->daddr; - flow->s_address.v4 = packet->iph->saddr; - } else { - memcpy(flow->c_address.v6, &packet->iphv6->ip6_dst, 16); - memcpy(flow->s_address.v6, &packet->iphv6->ip6_src, 16); - } - flow->c_port = d_port; - flow->s_port = s_port; + if(flow->is_ipv6 == 0) { + flow->c_address.v4 = packet->iph->daddr; + flow->s_address.v4 = packet->iph->saddr; + } else { + memcpy(flow->c_address.v6, &packet->iphv6->ip6_dst, 16); + memcpy(flow->s_address.v6, &packet->iphv6->ip6_src, 16); + } + flow->c_port = d_port; + flow->s_port = s_port; } } if(flow->packet_counter < MAX_PACKET_COUNTER && packet->payload_packet_len) { flow->packet_counter++; } - if(flow->packet_direction_counter[packet->packet_direction] < MAX_PACKET_COUNTER && - packet->payload_packet_len) { + + if(flow->all_packets_counter < MAX_PACKET_COUNTER) + flow->all_packets_counter++; + + if((flow->packet_direction_counter[packet->packet_direction] < MAX_PACKET_COUNTER) + /* && packet->payload_packet_len */) { flow->packet_direction_counter[packet->packet_direction]++; } if(flow->packet_direction_complete_counter[packet->packet_direction] < MAX_PACKET_COUNTER) { flow->packet_direction_complete_counter[packet->packet_direction]++; } - + if(ndpi_is_multi_or_broadcast(packet)) ; /* multicast or broadcast */ else { @@ -6030,6 +6052,31 @@ static void ndpi_add_connection_as_zoom(struct ndpi_detection_module_struct *ndp /* ********************************************************************************* */ +/* + NOTE: + + This function is called only by ndpi_detection_giveup() as it checks + flows that have anomalous conditions such as SYN+RST ACK+RST.... + As these conditions won't happen with nDPI protocol-detected protocols + it is not necessary to call this function elsewhere + */ +static void ndpi_check_tcp_flags(struct ndpi_detection_module_struct *ndpi_str, + struct ndpi_flow_struct *flow) { +#if 0 + printf("[TOTAL] %u / %u [tot: %u]\n", flow->packet_direction_counter[0], flow->packet_direction_counter[1], flow->all_packets_counter); +#endif + + if((flow->l4.tcp.cli2srv_tcp_flags & TH_SYN) + && (flow->l4.tcp.srv2cli_tcp_flags & TH_RST) + && (flow->all_packets_counter < 5 /* Ignore connections terminated by RST but that exchanged data */) + ) + ndpi_set_risk(ndpi_str, flow, NDPI_TCP_ISSUES, "Connection refused"); + else if((flow->l4.tcp.srv2cli_tcp_flags & TH_RST) && (flow->packet_direction_counter[1 /* server -> client */] == 1)) + ndpi_set_risk(ndpi_str, flow, NDPI_TCP_ISSUES, "TCP probing attempt"); +} + +/* ********************************************************************************* */ + ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_str, struct ndpi_flow_struct *flow, u_int8_t enable_guess, u_int8_t *protocol_was_guessed) { ndpi_protocol ret = NDPI_PROTOCOL_NULL; @@ -6042,6 +6089,9 @@ ndpi_protocol ndpi_detection_giveup(struct ndpi_detection_module_struct *ndpi_st if(!ndpi_str || !flow) return(ret); + if(flow->l4_proto == IPPROTO_TCP) + ndpi_check_tcp_flags(ndpi_str, flow); + /* Init defaults */ ret.master_protocol = flow->detected_protocol_stack[1]; ret.app_protocol = flow->detected_protocol_stack[0]; diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c index d39eed818..0e86314a0 100644 --- a/src/lib/ndpi_utils.c +++ b/src/lib/ndpi_utils.c @@ -2051,6 +2051,9 @@ const char* ndpi_risk2str(ndpi_risk_enum risk) { case NDPI_MINOR_ISSUES: return("Minor Issues"); + case NDPI_TCP_ISSUES: + return("TCP Connection Issues"); + default: ndpi_snprintf(buf, sizeof(buf), "%d", (int)risk); return(buf); |