Coordinated Disclosure Timeline
- 2023-03-01: Issues reported to maintainer
- 2023-03-09: Report acknowledged
- 2023-03-21: GitHub Security Lab review proposed fixes
- 2023-05-04: libssh 0.10.5 and 0.9.7 released
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
- CVE-2023-1667
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.