From c22d3d3cae8fc6d5fcf1b7320a7602426a9b9ca2 Mon Sep 17 00:00:00 2001
From: theirix <theirix@gmail.com>
Date: Tue, 12 Apr 2016 22:14:13 +0300
Subject: Fixed more buffer overflows with small packets

---
 src/lib/protocols/ssl.c | 87 +++++++++++++++++++++++++------------------------
 1 file changed, 45 insertions(+), 42 deletions(-)

(limited to 'src/lib/protocols/ssl.c')

diff --git a/src/lib/protocols/ssl.c b/src/lib/protocols/ssl.c
index 2269ae782..14deff7f9 100644
--- a/src/lib/protocols/ssl.c
+++ b/src/lib/protocols/ssl.c
@@ -223,64 +223,67 @@ int getSSLcertificate(struct ndpi_detection_module_struct *ndpi_struct,
 	}
       } else if(handshake_protocol == 0x01 /* Client Hello */) {
 	u_int offset, base_offset = 43;
-	u_int16_t session_id_len = packet->payload[base_offset];
+	if (base_offset + 2 <= packet->payload_packet_len)
+	{
+	  u_int16_t session_id_len = packet->payload[base_offset];
 
-	if((session_id_len+base_offset+2) <= total_len) {
-	  u_int16_t cypher_len =  packet->payload[session_id_len+base_offset+2] + (packet->payload[session_id_len+base_offset+1] << 8);
-	  offset = base_offset + session_id_len + cypher_len + 2;
+	  if((session_id_len+base_offset+2) <= total_len) {
+	    u_int16_t cypher_len =  packet->payload[session_id_len+base_offset+2] + (packet->payload[session_id_len+base_offset+1] << 8);
+	    offset = base_offset + session_id_len + cypher_len + 2;
 
-	  flow->l4.tcp.ssl_seen_client_cert = 1;
+	    flow->l4.tcp.ssl_seen_client_cert = 1;
 
-	  if(offset < total_len) {
-	    u_int16_t compression_len;
-	    u_int16_t extensions_len;
+	    if(offset < total_len) {
+	      u_int16_t compression_len;
+	      u_int16_t extensions_len;
 
-	    compression_len = packet->payload[offset+1];
-	    offset += compression_len + 3;
+	      compression_len = packet->payload[offset+1];
+	      offset += compression_len + 3;
 
-	    if(offset < total_len) {
-	      extensions_len = packet->payload[offset];
+	      if(offset < total_len) {
+		extensions_len = packet->payload[offset];
 
-	      if((extensions_len+offset) < total_len) {
-		u_int16_t extension_offset = 1; /* Move to the first extension */
+		if((extensions_len+offset) < total_len) {
+		  u_int16_t extension_offset = 1; /* Move to the first extension */
 
-		while(extension_offset < extensions_len) {
-		  u_int16_t extension_id, extension_len;
+		  while(extension_offset < extensions_len) {
+		    u_int16_t extension_id, extension_len;
 
-		  memcpy(&extension_id, &packet->payload[offset+extension_offset], 2);
-		  extension_offset += 2;
+		    memcpy(&extension_id, &packet->payload[offset+extension_offset], 2);
+		    extension_offset += 2;
 
-		  memcpy(&extension_len, &packet->payload[offset+extension_offset], 2);
-		  extension_offset += 2;
+		    memcpy(&extension_len, &packet->payload[offset+extension_offset], 2);
+		    extension_offset += 2;
 
-		  extension_id = ntohs(extension_id), extension_len = ntohs(extension_len);
+		    extension_id = ntohs(extension_id), extension_len = ntohs(extension_len);
 
-		  if(extension_id == 0) {
-		    u_int begin = 0,len;
-		    char *server_name = (char*)&packet->payload[offset+extension_offset];
+		    if(extension_id == 0) {
+		      u_int begin = 0,len;
+		      char *server_name = (char*)&packet->payload[offset+extension_offset];
 
-		    while(begin < extension_len) {
-		      if((!ndpi_isprint(server_name[begin]))
-			 || ndpi_ispunct(server_name[begin])
-			 || ndpi_isspace(server_name[begin]))
-			begin++;
-		      else
-			break;
-		    }
+		      while(begin < extension_len) {
+			if((!ndpi_isprint(server_name[begin]))
+			   || ndpi_ispunct(server_name[begin])
+			   || ndpi_isspace(server_name[begin]))
+			  begin++;
+			else
+			  break;
+		      }
 
-		    len = (u_int)ndpi_min(extension_len-begin, buffer_len-1);
-		    strncpy(buffer, &server_name[begin], len);
-		    buffer[len] = '\0';
-		    stripCertificateTrailer(buffer, buffer_len);
+		      len = (u_int)ndpi_min(extension_len-begin, buffer_len-1);
+		      strncpy(buffer, &server_name[begin], len);
+		      buffer[len] = '\0';
+		      stripCertificateTrailer(buffer, buffer_len);
 
-		    snprintf(flow->protos.ssl.client_certificate,
-			     sizeof(flow->protos.ssl.client_certificate), "%s", buffer);
+		      snprintf(flow->protos.ssl.client_certificate,
+			       sizeof(flow->protos.ssl.client_certificate), "%s", buffer);
 
-		    /* We're happy now */
-		    return(2 /* Client Certificate */);
-		  }
+		      /* We're happy now */
+		      return(2 /* Client Certificate */);
+		    }
 
-		  extension_offset += extension_len;
+		    extension_offset += extension_len;
+		  }
 		}
 	      }
 	    }
-- 
cgit v1.2.3