Lucene search

K
hackeroneNyymiH1:1180380
HistoryApr 29, 2021 - 8:31 p.m.

curl: CVE-2021-22901: TLS session caching disaster

2021-04-2920:31:01
nyymi
hackerone.com
$2000
38
tls session caching
remote code execution
libcurl backend
use after free
webkit browser
sony playstation
attacker control

EPSS

0.1

Percentile

94.9%

Summary:

lib/vtls/openssl.c ossl_connect_step1 sets up the ossl_new_session_cb sessionid callback with SSL_CTX_sess_set_new_cb, and adds association from data_idx and connectdata_idx to current conn and data respectively:

  SSL_CTX_set_session_cache_mode(backend->ctx,
      SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_NO_INTERNAL);
  SSL_CTX_sess_set_new_cb(backend->ctx, ossl_new_session_cb);

      SSL_set_ex_data(backend->handle, data_idx, data);
      SSL_set_ex_data(backend->handle, connectdata_idx, conn);

Whenever the ossl_new_session_cb callback is called the code fetches the conn and data associated via:

  conn = (struct connectdata*) SSL_get_ex_data(ssl, connectdata_idx);
  if(!conn)
    return 0;

  data = (struct Curl_easy *) SSL_get_ex_data(ssl, data_idx);

However, it is possible that the connection is disassociated from these pointers via Curl_detach_connnection, and reassociated to a different connection via Curl_attach_connnection. Yet, Curl_detach_connnection doesn’t SSL_set_ex_data the data_idx / connectdata_idx/ to NULL, nor does Curl_attach_connnection update the pointers with new ones. I am not absolutely certain but this appears to lead to a situation where a stale pointer(s) can exists when the session callback is called.

Steps To Reproduce:

Unfortunately I currently have no easy to way reproduce this issue. I might attempt to do this later.

Notes

This issue is currently lacking information but includes what I believe is the potential root cause of the issue. This information might be wrong or lacking necessary details to make full determination of the validity of this issue at this time.

This issue seems to be occurring somewhat periodically when webkit browser is built with the libcurl backend. Typically this is a rare use case, I know of only Sony Playstation devices that use in larger scale.

Impact

Use after free, with potential for (remote(*)) code execution as ossl_new_session_cb calls Curl_ssl_sessionid_lock(data); with potentially repurposed memory. Attacker would need to control data->share pointer to attacker controller memory. This fake struct Curl_share would need to be crafted in a way that if(share->specifier & (1<<type)) is taken. share->lockfunc would then get called by the function, resulting in code execution.

*) caveat here, as it is unknown if external attacker can trigger this situation. It would be difficult, but cannot be completely ruled out.