aboutsummaryrefslogtreecommitdiff
path: root/src/lib/protocols/ssh.c
diff options
context:
space:
mode:
authoremanuele-f <black.silver@hotmail.it>2019-08-23 11:36:35 +0200
committeremanuele-f <black.silver@hotmail.it>2019-08-23 11:36:35 +0200
commit1231b8183978fd9f2a64ffd1d3f8069f7774f435 (patch)
treef4c7219e836fccceab00a6846204f3eeeced8a26 /src/lib/protocols/ssh.c
parentd2fe21ddffbbae12880b9d5ece1eb2c7d13a09ca (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.c181
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);
}
/* ************************************************************************ */