Skip to content

Commit

Permalink
Add more length checks in HASSH
Browse files Browse the repository at this point in the history
This to prevent possible crashes on invalid packets
  • Loading branch information
emanuele-f committed Aug 23, 2019
1 parent d2fe21d commit 1231b81
Showing 1 changed file with 110 additions and 71 deletions.
181 changes: 110 additions & 71 deletions src/lib/protocols/ssh.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

/* ************************************************************************ */
Expand Down

0 comments on commit 1231b81

Please sign in to comment.