aboutsummaryrefslogtreecommitdiff
path: root/src/lib/protocols/ssh.c
diff options
context:
space:
mode:
authorPhilippe Antoine <contact@catenacyber.fr>2020-04-02 16:48:35 +0200
committerPhilippe Antoine <contact@catenacyber.fr>2020-04-02 16:48:35 +0200
commit7ce478a58b4dd29a8d1e6f4e9df2f778613d9202 (patch)
treeb8d50b20716a308817daec0e9cc455184bcb83d0 /src/lib/protocols/ssh.c
parent3bbb0cd3296023f6f922c71d21a1c374d2b0a435 (diff)
ssh: fixing unsigned overflow leading to heap overflow
cf GHSL-2020-051
Diffstat (limited to 'src/lib/protocols/ssh.c')
-rw-r--r--src/lib/protocols/ssh.c64
1 files changed, 33 insertions, 31 deletions
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] */