skip to content
Back to GitHub.com
Home Bounties Research Advisories CodeQL Wall of Fame Get Involved Events
May 9, 2023

GHSL-2023-032_GHSL-2023-042: Denial of Service in libssh - CVE-2023-1667

Phil Turnbull

Coordinated Disclosure Timeline

Summary

The libssh server logic does not correctly handle SSH_MSG_KEXINIT packets sent after a client authenticates which can allow an attacker to trigger a NULL pointer dereference, causing a denial-of-service.

In addition, there are a number of memory leaks in the GSSAPI integration which may allow an attacker to trigger memory exhaustion, causing a denial-of-service.

Product

libssh

Tested Version

Details

Issue 1: cmp_first_kex_algo NULL pointer dereference (GHSL-2023-032)

The ssh_packet_kexinit function handles SSH_MSG_KEXINIT packets:

SSH_PACKET_CALLBACK(ssh_packet_kexinit)
{
    int i, ok;
    int server_kex = session->server;        // (1)
    ssh_string str = NULL;
    char *strings[SSH_KEX_METHODS] = {0};
    char *rsa_sig_ext = NULL;
    int rc = SSH_ERROR;
    size_t len;

    uint8_t first_kex_packet_follows = 0;
    uint32_t kexinit_reserved = 0;

    ...

    /* copy the server kex info into an array of strings */
    if (server_kex) {
        for (i = 0; i < SSH_KEX_METHODS; i++) {
            session->next_crypto->client_kex.methods[i] = strings[i];        // (2)
        }
    } else { /* client */
        ...
    }

    ...

    /*
     * Handle the two final fields for the KEXINIT message (RFC 4253 7.1):
     *
     *      boolean      first_kex_packet_follows
     *      uint32       0 (reserved for future extension)
     *
     * Notably if clients set 'first_kex_packet_follows', it is expected
     * that its value is included when computing the session ID (see
     * 'make_sessionid').
     */
    if (server_kex) {
        rc = ssh_buffer_get_u8(packet, &first_kex_packet_follows);
        ...
        /*
         * Remember whether 'first_kex_packet_follows' was set and the client
         * guess was wrong: in this case the next SSH_MSG_KEXDH_INIT message
         * must be ignored.
         */
        if (first_kex_packet_follows) {        // (3)
          session->first_kex_follows_guess_wrong =        // (4)
            cmp_first_kex_algo(session->next_crypto->client_kex.methods[SSH_KEX],
                               session->next_crypto->server_kex.methods[SSH_KEX]) ||
            cmp_first_kex_algo(session->next_crypto->client_kex.methods[SSH_HOSTKEYS],
                               session->next_crypto->server_kex.methods[SSH_HOSTKEYS]);
        }
    }
    ...
}

The key-exchange algorithms are then compared with cmp_first_kex_algo:

static int cmp_first_kex_algo(const char *client_str,
                              const char *server_str) {
    size_t client_kex_len;
    size_t server_kex_len;

    char *colon;

    int is_wrong = 1;

    colon = strchr(client_str, ',');
    if (colon == NULL) {
        client_kex_len = strlen(client_str);
    } else {
        client_kex_len = colon - client_str;
    }

    colon = strchr(server_str, ',');        // (5)
    ...
}

The logic of the function differs depending on if the process is a server or client, which is determined at (1). In the server case, the list of methods is copied from the client packet into client_kex.methods at (2). If the SSH_MSG_KEXINIT packet has the first_kex_packet_follows flag set, at (3), then the code determines if the following packet should be ignored or not by calling cmp_first_kex_algo at (4).

SSH_MSG_KEXINIT packets can be sent both pre- and post-authentication. In the pre-authentication case, both the client_kex.methods and server_kex.methods arrays will be initialized with a list of non-NULL algorithms. However, in the post-authentication case the server_kex.methods array will be initialized with NULL pointers. This then triggers a NULL-pointer deference at (5) in cmp_first_kex_algo.

Impact

An attacker can use this issue to trigger a NULL pointer deference and cause a post-authentication denial-of-service.

Issue 2: both_supported not released in ssh_gssapi_handle_userauth (GHSL-2023-033)

The ssh_gssapi_handle_userauth function handles SSH_MSG_USERAUTH_REQUEST packets specifying gssapi-with-mic authentication. The OID set stored in both_supported is not released on all codepaths, triggering a memory leak.

Impact

Repeated exploitation of this issue could allow an attacker to cause excessive memory use and trigger a denial-of-service.

Issue 3: selected not released in ssh_gssapi_handle_userauth (GHSL-2023-034)

Similar to the previous issue, the ssh_gssapi_handle_userauth function does not release the data stored in the selected OID set on all codepaths, triggering a memory leak.

Impact

Repeated exploitation of this issue could allow an attacker to cause excessive memory use and trigger a denial-of-service.

Issue 4: buffer not released in ssh_gssapi_name_to_char (GHSL-2023-035)

The ssh_gssapi_name_to_char does not release the string stored in buffer if the preceding malloc fails, triggering a memory leak.

Impact

Repeated exploitation of this issue could allow an attacker to cause excessive memory use and trigger a denial-of-service.

Issue 5: selected not released in ssh_gssapi_auth_mic (GHSL-2023-036)

The ssh_gssapi_auth_mic function handles authenticating with the gssapi-with-mic authentication method. The OID set stored in selected is not released on all codepaths, triggering a memory leak.

Impact

Repeated exploitation of this issue could allow an attacker to cause excessive memory use and trigger a denial-of-service.

Issue 6: output_token not released in ssh_packet_userauth_gssapi_response (GHSL-2023-037)

The ssh_packet_userauth_gssapi_response function handles SSH_USERAUTH_GSSAPI_RESPONSE packets. The token stored in output_token is not released on all codepaths, triggering a memory leak.

Impact

Repeated exploitation of this issue could allow an attacker to cause excessive memory use and trigger a denial-of-service.

Issue 7: mic_token_buf not released in ssh_gssapi_send_mic (GHSL-2023-038)

The ssh_gssapi_send_mic function generates a message integrity check (MIC) to be sent to the server after authentication succeeds. The data stored in mic_token_buf is not released, triggering a memory leak.

Impact

Repeated exploitation of this issue could allow an attacker to cause excessive memory use and trigger a denial-of-service.

Issue 8: output_token not released in ssh_packet_userauth_gssapi_token_client (GHSL-2023-039)

The ssh_packet_userauth_gssapi_token_client function handles SSH2_MSG_USERAUTH_INFO_RESPONSE packets when operating in client mode. The buffer stored in output_token is not released on all codepaths, triggering a memory leak.

Impact

Repeated exploitation of this issue could allow an attacker to cause excessive memory use and trigger a denial-of-service.

Issue 9: actual_mechs not released in ssh_gssapi_match (GHSL-2023-040)

The ssh_gssapi_match function generates a list of GSSAPI mechanisms that are usable for authentication. The OID set stored in actual_mechs, either by acquiring a credential or using a delegated credential, is not released on all codepaths, triggering a memory leak.

Impact

Repeated exploitation of this issue could allow an attacker to cause excessive memory use and trigger a denial-of-service.

Issue 10: output_token not released in ssh_packet_userauth_gssapi_token_server (GHSL-2023-041)

The ssh_packet_userauth_gssapi_token_server function handles SSH2_MSG_USERAUTH_INFO_RESPONSE packets when operating in server mode. The buffer stored in output_token is not released on all codepaths, triggering a memory leak.

Impact

Repeated exploitation of this issue could allow an attacker to cause excessive memory use and trigger a denial-of-service.

Issue 11: mic_buffer not freed in ssh_gssapi_send_mic (GHSL-2023-042)

The ssh_gssapi_send_mic function generates a message integrity check (MIC) to be sent to the server after authentication succeeds. The data stored in mic_buffer is not freed on all codepaths after generating the MIC, triggering a memory leak.

Impact

Repeated exploitation of this issue could allow an attacker to cause excessive memory use and trigger a denial-of-service.

CVE

Credit

These issues were discovered and reported by GHSL team member @philipturnbull (Phil Turnbull).

Contact

You can contact the GHSL team at securitylab@github.com, please include a reference to GHSL-2023-032, GHSL-2023-033, GHSL-2023-034, GHSL-2023-035, GHSL-2023-036, GHSL-2023-037, GHSL-2023-038, GHSL-2023-039, GHSL-2023-040, GHSL-2023-041, or GHSL-2023-042 in any communication regarding these issues.