From 3bbb0cd3296023f6f922c71d21a1c374d2b0a435 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Thu, 2 Apr 2020 16:35:10 +0200 Subject: ssh: adds systematic bounds checks in concat_hash_string cf GHSL-2020-052 --- src/lib/protocols/ssh.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/lib/protocols/ssh.c') diff --git a/src/lib/protocols/ssh.c b/src/lib/protocols/ssh.c index 853fbb24b..292433e55 100644 --- a/src/lib/protocols/ssh.c +++ b/src/lib/protocols/ssh.c @@ -110,10 +110,14 @@ static u_int16_t concat_hash_string(struct ndpi_packet_struct *packet, buf[buf_out_len++] = ';'; offset += len; + if(offset+sizeof(u_int32_t) >= packet->payload_packet_len) + goto invalid_payload; /* ssh.server_host_key_algorithms [None] */ len = ntohl(*(u_int32_t*)&packet->payload[offset]); offset += 4 + len; + if(offset+sizeof(u_int32_t) >= packet->payload_packet_len) + goto invalid_payload; /* ssh.encryption_algorithms_client_to_server [C] */ len = ntohl(*(u_int32_t*)&packet->payload[offset]); @@ -130,6 +134,8 @@ static u_int16_t concat_hash_string(struct ndpi_packet_struct *packet, } else offset += 4 + len; + if(offset+sizeof(u_int32_t) >= packet->payload_packet_len) + goto invalid_payload; /* ssh.encryption_algorithms_server_to_client [S] */ len = ntohl(*(u_int32_t*)&packet->payload[offset]); @@ -146,6 +152,8 @@ static u_int16_t concat_hash_string(struct ndpi_packet_struct *packet, } else offset += 4 + len; + if(offset+sizeof(u_int32_t) >= packet->payload_packet_len) + goto invalid_payload; /* ssh.mac_algorithms_client_to_server [C] */ len = ntohl(*(u_int32_t*)&packet->payload[offset]); @@ -162,6 +170,8 @@ static u_int16_t concat_hash_string(struct ndpi_packet_struct *packet, } else offset += 4 + len; + if(offset+sizeof(u_int32_t) >= packet->payload_packet_len) + goto invalid_payload; /* ssh.mac_algorithms_server_to_client [S] */ len = ntohl(*(u_int32_t*)&packet->payload[offset]); @@ -195,6 +205,8 @@ static u_int16_t concat_hash_string(struct ndpi_packet_struct *packet, } else offset += 4 + len; + if(offset+sizeof(u_int32_t) >= packet->payload_packet_len) + goto invalid_payload; /* ssh.compression_algorithms_server_to_client [S] */ len = ntohl(*(u_int32_t*)&packet->payload[offset]); -- cgit v1.2.3 From 7ce478a58b4dd29a8d1e6f4e9df2f778613d9202 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Thu, 2 Apr 2020 16:48:35 +0200 Subject: ssh: fixing unsigned overflow leading to heap overflow cf GHSL-2020-051 --- src/lib/protocols/ssh.c | 64 +++++++++++++++++++++++++------------------------ 1 file changed, 33 insertions(+), 31 deletions(-) (limited to 'src/lib/protocols/ssh.c') diff --git a/src/lib/protocols/ssh.c b/src/lib/protocols/ssh.c index 292433e55..849dbeed4 100644 --- a/src/lib/protocols/ssh.c +++ b/src/lib/protocols/ssh.c @@ -95,7 +95,7 @@ static void ndpi_int_ssh_add_connection(struct ndpi_detection_module_struct static u_int16_t concat_hash_string(struct ndpi_packet_struct *packet, char *buf, u_int8_t client_hash) { - u_int16_t offset = 22, buf_out_len = 0; + u_int32_t offset = 22, buf_out_len = 0; if(offset+sizeof(u_int32_t) >= packet->payload_packet_len) goto invalid_payload; u_int32_t len = ntohl(*(u_int32_t*)&packet->payload[offset]); @@ -114,6 +114,8 @@ static u_int16_t concat_hash_string(struct ndpi_packet_struct *packet, goto invalid_payload; /* ssh.server_host_key_algorithms [None] */ len = ntohl(*(u_int32_t*)&packet->payload[offset]); + if (len > UINT32_MAX - 4 - offset) + goto invalid_payload; offset += 4 + len; if(offset+sizeof(u_int32_t) >= packet->payload_packet_len) @@ -121,106 +123,106 @@ static u_int16_t concat_hash_string(struct ndpi_packet_struct *packet, /* ssh.encryption_algorithms_client_to_server [C] */ len = ntohl(*(u_int32_t*)&packet->payload[offset]); + offset += 4; if(client_hash) { - offset += 4; - if((offset >= packet->payload_packet_len) || (len >= packet->payload_packet_len-offset-1)) goto invalid_payload; strncpy(&buf[buf_out_len], (const char *)&packet->payload[offset], len); buf_out_len += len; buf[buf_out_len++] = ';'; - offset += len; - } else - offset += 4 + len; + } + if (len > UINT32_MAX - offset) + goto invalid_payload; + offset += len; if(offset+sizeof(u_int32_t) >= packet->payload_packet_len) goto invalid_payload; /* ssh.encryption_algorithms_server_to_client [S] */ len = ntohl(*(u_int32_t*)&packet->payload[offset]); + offset += 4; if(!client_hash) { - offset += 4; - if((offset >= packet->payload_packet_len) || (len >= packet->payload_packet_len-offset-1)) goto invalid_payload; strncpy(&buf[buf_out_len], (const char *)&packet->payload[offset], len); buf_out_len += len; buf[buf_out_len++] = ';'; - offset += len; - } else - offset += 4 + len; + } + if (len > UINT32_MAX - offset) + goto invalid_payload; + offset += len; if(offset+sizeof(u_int32_t) >= packet->payload_packet_len) goto invalid_payload; /* ssh.mac_algorithms_client_to_server [C] */ len = ntohl(*(u_int32_t*)&packet->payload[offset]); + offset += 4; if(client_hash) { - offset += 4; - if((offset >= packet->payload_packet_len) || (len >= packet->payload_packet_len-offset-1)) goto invalid_payload; strncpy(&buf[buf_out_len], (const char *)&packet->payload[offset], len); buf_out_len += len; buf[buf_out_len++] = ';'; - offset += len; - } else - offset += 4 + len; + } + if (len > UINT32_MAX - offset) + goto invalid_payload; + offset += len; if(offset+sizeof(u_int32_t) >= packet->payload_packet_len) goto invalid_payload; /* ssh.mac_algorithms_server_to_client [S] */ len = ntohl(*(u_int32_t*)&packet->payload[offset]); + offset += 4; if(!client_hash) { - offset += 4; - if((offset >= packet->payload_packet_len) || (len >= packet->payload_packet_len-offset-1)) goto invalid_payload; strncpy(&buf[buf_out_len], (const char *)&packet->payload[offset], len); buf_out_len += len; buf[buf_out_len++] = ';'; - offset += len; - } else - offset += 4 + len; + } + if (len > UINT32_MAX - offset) + goto invalid_payload; + offset += len; /* ssh.compression_algorithms_client_to_server [C] */ if(offset+sizeof(u_int32_t) >= packet->payload_packet_len) goto invalid_payload; len = ntohl(*(u_int32_t*)&packet->payload[offset]); + offset += 4; if(client_hash) { - offset += 4; - if((offset >= packet->payload_packet_len) || (len >= packet->payload_packet_len-offset-1)) goto invalid_payload; strncpy(&buf[buf_out_len], (const char *)&packet->payload[offset], len); buf_out_len += len; - offset += len; - } else - offset += 4 + len; + } + if (len > UINT32_MAX - offset) + goto invalid_payload; + offset += len; if(offset+sizeof(u_int32_t) >= packet->payload_packet_len) goto invalid_payload; /* ssh.compression_algorithms_server_to_client [S] */ len = ntohl(*(u_int32_t*)&packet->payload[offset]); + offset += 4; if(!client_hash) { - offset += 4; - if((offset >= packet->payload_packet_len) || (len >= packet->payload_packet_len-offset-1)) goto invalid_payload; strncpy(&buf[buf_out_len], (const char *)&packet->payload[offset], len); buf_out_len += len; - offset += len; - } else - offset += 4 + len; + } + if (len > UINT32_MAX - offset) + goto invalid_payload; + offset += len; /* ssh.languages_client_to_server [None] */ -- cgit v1.2.3