diff options
author | emanuele-f <black.silver@hotmail.it> | 2019-08-23 11:36:35 +0200 |
---|---|---|
committer | emanuele-f <black.silver@hotmail.it> | 2019-08-23 11:36:35 +0200 |
commit | 1231b8183978fd9f2a64ffd1d3f8069f7774f435 (patch) | |
tree | f4c7219e836fccceab00a6846204f3eeeced8a26 /src/lib/protocols/ssh.c | |
parent | d2fe21ddffbbae12880b9d5ece1eb2c7d13a09ca (diff) |
Add more length checks in HASSH
This to prevent possible crashes on invalid packets
Diffstat (limited to 'src/lib/protocols/ssh.c')
-rw-r--r-- | src/lib/protocols/ssh.c | 181 |
1 files changed, 110 insertions, 71 deletions
diff --git a/src/lib/protocols/ssh.c b/src/lib/protocols/ssh.c index 7e5ca5e62..4b2296411 100644 --- a/src/lib/protocols/ssh.c +++ b/src/lib/protocols/ssh.c @@ -64,93 +64,132 @@ 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 len = ntohl(*(u_int32_t*)&packet->payload[offset]); + offset += 4; - if(len < (packet->payload_packet_len-offset)) { - /* ssh.kex_algorithms [C/S] */ + /* -1 for ';' */ + if((offset >= packet->payload_packet_len) || (len >= packet->payload_packet_len-offset-1)) + goto invalid_payload; + + /* ssh.kex_algorithms [C/S] */ + strncpy(buf, (const char *)&packet->payload[offset], buf_out_len = len); + buf[buf_out_len++] = ';'; + offset += len; + + /* ssh.server_host_key_algorithms [None] */ + len = ntohl(*(u_int32_t*)&packet->payload[offset]); + offset += 4 + len; + + /* ssh.encryption_algorithms_client_to_server [C] */ + len = ntohl(*(u_int32_t*)&packet->payload[offset]); + + if(client_hash) { offset += 4; - strncpy(buf, (const char *)&packet->payload[offset], buf_out_len = len); + + 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; - /* ssh.server_host_key_algorithms [None] */ - len = ntohl(*(u_int32_t*)&packet->payload[offset]); + /* ssh.encryption_algorithms_server_to_client [S] */ + len = ntohl(*(u_int32_t*)&packet->payload[offset]); + + 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; - /* ssh.encryption_algorithms_client_to_server [C] */ - len = ntohl(*(u_int32_t*)&packet->payload[offset]); + /* ssh.mac_algorithms_client_to_server [C] */ + len = ntohl(*(u_int32_t*)&packet->payload[offset]); - if(client_hash) { - offset += 4; - 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; - - /* ssh.encryption_algorithms_server_to_client [S] */ - len = ntohl(*(u_int32_t*)&packet->payload[offset]); - if(!client_hash) { - offset += 4; - 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; - - /* ssh.mac_algorithms_client_to_server [C] */ - len = ntohl(*(u_int32_t*)&packet->payload[offset]); - if(client_hash) { - offset += 4; - 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; - - /* ssh.mac_algorithms_server_to_client [S] */ - len = ntohl(*(u_int32_t*)&packet->payload[offset]); - if(!client_hash) { - offset += 4; - 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; - - /* ssh.compression_algorithms_client_to_server [C] */ - len = ntohl(*(u_int32_t*)&packet->payload[offset]); - if(client_hash) { - offset += 4; - strncpy(&buf[buf_out_len], (const char *)&packet->payload[offset], len); - buf_out_len += len; - offset += len; - } else - offset += 4 + len; - - /* ssh.compression_algorithms_server_to_client [S] */ - len = ntohl(*(u_int32_t*)&packet->payload[offset]); - if(!client_hash) { - offset += 4; - strncpy(&buf[buf_out_len], (const char *)&packet->payload[offset], len); - buf_out_len += len; - offset += len; - } else - offset += 4 + len; + if(client_hash) { + offset += 4; - /* ssh.languages_client_to_server [None] */ + if((offset >= packet->payload_packet_len) || (len >= packet->payload_packet_len-offset-1)) + goto invalid_payload; - /* ssh.languages_server_to_client [None] */ - } + 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; + + /* ssh.mac_algorithms_server_to_client [S] */ + len = ntohl(*(u_int32_t*)&packet->payload[offset]); + + 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; + + /* ssh.compression_algorithms_client_to_server [C] */ + len = ntohl(*(u_int32_t*)&packet->payload[offset]); + + 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; + + /* ssh.compression_algorithms_server_to_client [S] */ + len = ntohl(*(u_int32_t*)&packet->payload[offset]); + + 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; + + /* ssh.languages_client_to_server [None] */ + + /* ssh.languages_server_to_client [None] */ #ifdef SSH_DEBUG printf("\n[SSH] %s\n", buf); #endif return(buf_out_len); + +invalid_payload: + +#ifdef SSH_DEBUG + printf("\n[SSH] Invalid packet payload\n"); +#endif + + return(0); } /* ************************************************************************ */ |