Loading HuntDB...

CVE-2022-32208: FTP-KRB bad message verification

Low
C
curl
Submitted None
Reported by nyymi

Vulnerability Details

Technical details and impact analysis

Business Logic Errors
## Summary: libcurl handles `gss_unwrap` `GSS_S_BAD_SIG` error incorrectly. This enables malicious attacker to inject arbitrary FTP server responses to GSSAPI protected FTP control connection and/or make the client consume unrelated heap memory as a FTP command response. The defective `krb5_decode` function is as follows: ``` static int krb5_decode(void *app_data, void *buf, int len, int level UNUSED_PARAM, struct connectdata *conn UNUSED_PARAM) { gss_ctx_id_t *context = app_data; OM_uint32 maj, min; gss_buffer_desc enc, dec; (void)level; (void)conn; enc.value = buf; enc.length = len; maj = gss_unwrap(&min, *context, &enc, &dec, NULL, NULL); if(maj != GSS_S_COMPLETE) { if(len >= 4) strcpy(buf, "599 "); return -1; } memcpy(buf, dec.value, dec.length); len = curlx_uztosi(dec.length); gss_release_buffer(&min, &dec); return len; } ``` Note how `read_data` function will set the `buf->size` to result of the decode operation as-is without considering possible `-1` return code and that size `buf->size` is of type `size_t`: ``` /* Types needed for krb5-ftp connections */ struct krb5buffer { void *data; size_t size; size_t index; BIT(eof_flag); }; ``` ``` static CURLcode read_data(struct connectdata *conn, curl_socket_t fd, struct krb5buffer *buf) { int len; CURLcode result; result = socket_read(fd, &len, sizeof(len)); if(result) return result; if(len) { /* only realloc if there was a length */ len = ntohl(len); buf->data = Curl_saferealloc(buf->data, len); } if(!len || !buf->data) return CURLE_OUT_OF_MEMORY; result = socket_read(fd, buf->data, len); if(result) return result; buf->size = conn->mech->decode(conn->app_data, buf->data, len, conn->data_prot, conn); buf->index = 0; return CURLE_OK; } ``` When `gss_unwrap` returns an error the `krb5_decode` code attempts to erase the buffer by prefixing the buffer with `599 \0`. However, this doesn't take into account the case that arbitrary number of bytes can be read by `read_data` function. Hence the buffer may contain multiple lines not just one. The attacker merely needs to find a position in the FTP protocol where ftpcode `599` doesn't lead to connection termination to take over the GSSAPI protected FTP session control channel. From that point onwards the server responses can be forged by the attacker (but need to be predicted, as the attacker has no direct knowledge of the actual commands sent to the server). It's also notable that the any `gss_unwrap` error leading to `-1` size will lead to `sec_recv` consuming unallocated heap buffer via `buffer_read` if the reading application keeps reading more blocked: ``` static size_t buffer_read(struct krb5buffer *buf, void *data, size_t len) { if(buf->size - buf->index < len) len = buf->size - buf->index; memcpy(data, (char *)buf->data + buf->index, len); buf->index += len; return len; } ``` This can lead to disclosure of confidential information from the heap - depending on application this may reveal application secrets to the user (for example via verbose error messages). This is a local leak however, so this impact is only meaningful if the information in heap is normally hidden from the user. ## Impact - Injection of arbitrary FTP control channel server responses to supposedly GSSAPI protected FTP session. - Potential leak of local heap memory to client. The practical impact of this vulnerability is rather low, considering the rarity of Kerberos FTP and requirement of either man in the middle or victim connecting to malicious server.

Report Details

Additional information and metadata

State

Closed

Substate

Resolved

Submitted

Weakness

Business Logic Errors