Ejemplo n.º 1
0
void ndpi_search_ssl_tcp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow)
{
  struct ndpi_packet_struct *packet = &flow->packet;

  //      struct ndpi_id_struct         *src=flow->src;
  //      struct ndpi_id_struct         *dst=flow->dst;

  u_int8_t ret;

  if(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL) {
    if(flow->l4.tcp.ssl_stage == 3 && packet->payload_packet_len > 20 && flow->packet_counter < 5) {
      /* this should only happen, when we detected SSL with a packet that had parts of the certificate in subsequent packets
       * so go on checking for certificate patterns for a couple more packets
       */
      NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG,
	       "ssl flow but check another packet for patterns\n");
      ssl_mark_and_payload_search_for_other_protocols(ndpi_struct, flow);
      if(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL) {
	/* still ssl so check another packet */
	return;
      } else {
	/* protocol has changed so we are done */
	return;
      }
    }
    return;
  }

  NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "search ssl\n");

  {
    /* Check if this is whatsapp first (this proto runs over port 443) */
    if((packet->payload_packet_len > 5)
       && ((packet->payload[0] == 'W')
	   && (packet->payload[1] == 'A')
	   && (packet->payload[4] == 0)
	   && (packet->payload[2] <= 9)
	   && (packet->payload[3] <= 9))) {
      ndpi_int_add_connection(ndpi_struct, flow, NDPI_SERVICE_WHATSAPP, NDPI_REAL_PROTOCOL);
      return;
    } else {
      /* No whatsapp, let's try SSL */
      if(sslDetectProtocolFromCertificate(ndpi_struct, flow) > 0)
	return;
    }
  }

  if(packet->payload_packet_len > 40 && flow->l4.tcp.ssl_stage == 0) {
    NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "first ssl packet\n");
    // SSLv2 Record
    if(packet->payload[2] == 0x01 && packet->payload[3] == 0x03
	&& (packet->payload[4] == 0x00 || packet->payload[4] == 0x01 || packet->payload[4] == 0x02)
	&& (packet->payload_packet_len - packet->payload[1] == 2)) {
      NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv2 len match\n");
      flow->l4.tcp.ssl_stage = 1 + packet->packet_direction;
      return;
    }

    if(packet->payload[0] == 0x16 && packet->payload[1] == 0x03
	&& (packet->payload[2] == 0x00 || packet->payload[2] == 0x01 || packet->payload[2] == 0x02)
	&& (packet->payload_packet_len - ntohs(get_u_int16_t(packet->payload, 3)) == 5)) {
      // SSLv3 Record
      NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv3 len match\n");
      flow->l4.tcp.ssl_stage = 1 + packet->packet_direction;
      return;
    }
  }

  if(packet->payload_packet_len > 40 &&
      flow->l4.tcp.ssl_stage == 1 + packet->packet_direction
      && flow->packet_direction_counter[packet->packet_direction] < 5) {
    return;
  }

  if(packet->payload_packet_len > 40 && flow->l4.tcp.ssl_stage == 2 - packet->packet_direction) {
    NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "second ssl packet\n");
    // SSLv2 Record
    if(packet->payload[2] == 0x01 && packet->payload[3] == 0x03
	&& (packet->payload[4] == 0x00 || packet->payload[4] == 0x01 || packet->payload[4] == 0x02)
	&& (packet->payload_packet_len - 2) >= packet->payload[1]) {
      NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv2 server len match\n");
      ssl_mark_and_payload_search_for_other_protocols(ndpi_struct, flow);
      return;
    }

    ret = ndpi_search_sslv3_direction1(ndpi_struct, flow);
    if(ret == 1) {
      NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "sslv3 server len match\n");
      ssl_mark_and_payload_search_for_other_protocols(ndpi_struct, flow);
      return;
    } else if(ret == 2) {
      NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG,
	       "sslv3 server len match with split packet -> check some more packets for SSL patterns\n");
      ssl_mark_and_payload_search_for_other_protocols(ndpi_struct, flow);
      if(packet->detected_protocol_stack[0] == NDPI_PROTOCOL_SSL) {
	flow->l4.tcp.ssl_stage = 3;
      }
      return;
    }

    if(packet->payload_packet_len > 40 && flow->packet_direction_counter[packet->packet_direction] < 5) {
      NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "need next packet\n");
      return;
    }
  }

  NDPI_LOG(NDPI_PROTOCOL_SSL, ndpi_struct, NDPI_LOG_DEBUG, "exclude ssl\n");
  NDPI_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, NDPI_PROTOCOL_SSL);
  return;
}
Ejemplo n.º 2
0
void ipoque_search_ssl_tcp(struct ipoque_detection_module_struct *ipoque_struct)
{
	struct ipoque_packet_struct *packet = &ipoque_struct->packet;
	struct ipoque_flow_struct *flow = ipoque_struct->flow;
//      struct ipoque_id_struct         *src=ipoque_struct->src;
//      struct ipoque_id_struct         *dst=ipoque_struct->dst;

	u8 ret;

	if (packet->detected_protocol_stack[0] == IPOQUE_PROTOCOL_SSL) {
		if (flow->l4.tcp.ssl_stage == 3 && packet->payload_packet_len > 20 && flow->packet_counter < 5) {
			/* this should only happen, when we detected SSL with a packet that had parts of the certificate in subsequent packets
			 * so go on checking for certificate patterns for a couple more packets
			 */
			IPQ_LOG(IPOQUE_PROTOCOL_SSL, ipoque_struct, IPQ_LOG_DEBUG,
					"ssl flow but check another packet for patterns\n");
			ssl_mark_and_payload_search_for_other_protocols(ipoque_struct);
			if (packet->detected_protocol_stack[0] == IPOQUE_PROTOCOL_SSL) {
				/* still ssl so check another packet */
				return;
			} else {
				/* protocol has changed so we are done */
				return;
			}
		}
		return;
	}

	IPQ_LOG(IPOQUE_PROTOCOL_SSL, ipoque_struct, IPQ_LOG_DEBUG, "search ssl\n");

	if (packet->payload_packet_len > 40 && flow->l4.tcp.ssl_stage == 0) {
		IPQ_LOG(IPOQUE_PROTOCOL_SSL, ipoque_struct, IPQ_LOG_DEBUG, "first ssl packet\n");
		// SSLv2 Record
		if (packet->payload[2] == 0x01 && packet->payload[3] == 0x03
			&& (packet->payload[4] == 0x00 || packet->payload[4] == 0x01 || packet->payload[4] == 0x02)
			&& (packet->payload_packet_len - packet->payload[1] == 2)) {
			IPQ_LOG(IPOQUE_PROTOCOL_SSL, ipoque_struct, IPQ_LOG_DEBUG, "sslv2 len match\n");
			flow->l4.tcp.ssl_stage = 1 + packet->packet_direction;
			return;
		}

		if (packet->payload[0] == 0x16 && packet->payload[1] == 0x03
			&& (packet->payload[2] == 0x00 || packet->payload[2] == 0x01 || packet->payload[2] == 0x02)
			&& (packet->payload_packet_len - ntohs(get_u16(packet->payload, 3)) == 5)) {
			// SSLv3 Record
			IPQ_LOG(IPOQUE_PROTOCOL_SSL, ipoque_struct, IPQ_LOG_DEBUG, "sslv3 len match\n");
			flow->l4.tcp.ssl_stage = 1 + packet->packet_direction;
			return;
		}
	}

	if (packet->payload_packet_len > 40 &&
		flow->l4.tcp.ssl_stage == 1 + packet->packet_direction
		&& flow->packet_direction_counter[packet->packet_direction] < 5) {
		return;
	}

	if (packet->payload_packet_len > 40 && flow->l4.tcp.ssl_stage == 2 - packet->packet_direction) {
		IPQ_LOG(IPOQUE_PROTOCOL_SSL, ipoque_struct, IPQ_LOG_DEBUG, "second ssl packet\n");
		// SSLv2 Record
		if (packet->payload[2] == 0x01 && packet->payload[3] == 0x03
			&& (packet->payload[4] == 0x00 || packet->payload[4] == 0x01 || packet->payload[4] == 0x02)
			&& (packet->payload_packet_len - 2) >= packet->payload[1]) {
			IPQ_LOG(IPOQUE_PROTOCOL_SSL, ipoque_struct, IPQ_LOG_DEBUG, "sslv2 server len match\n");
			ssl_mark_and_payload_search_for_other_protocols(ipoque_struct);
			return;
		}

		ret = ipoque_search_sslv3_direction1(ipoque_struct);
		if (ret == 1) {
			IPQ_LOG(IPOQUE_PROTOCOL_SSL, ipoque_struct, IPQ_LOG_DEBUG, "sslv3 server len match\n");
			ssl_mark_and_payload_search_for_other_protocols(ipoque_struct);
			return;
		} else if (ret == 2) {
			IPQ_LOG(IPOQUE_PROTOCOL_SSL, ipoque_struct, IPQ_LOG_DEBUG,
					"sslv3 server len match with split packet -> check some more packets for SSL patterns\n");
			ssl_mark_and_payload_search_for_other_protocols(ipoque_struct);
			if (packet->detected_protocol_stack[0] == IPOQUE_PROTOCOL_SSL) {
				flow->l4.tcp.ssl_stage = 3;
			}
			return;
		}

		if (packet->payload_packet_len > 40 && flow->packet_direction_counter[packet->packet_direction] < 5) {
			IPQ_LOG(IPOQUE_PROTOCOL_SSL, ipoque_struct, IPQ_LOG_DEBUG, "need next packet\n");
			return;
		}
	}

	IPQ_LOG(IPOQUE_PROTOCOL_SSL, ipoque_struct, IPQ_LOG_DEBUG, "exclude ssl\n");
	IPOQUE_ADD_PROTOCOL_TO_BITMASK(flow->excluded_protocol_bitmask, IPOQUE_PROTOCOL_SSL);
	return;
}