Lucene search

K
hackeroneSybrH1:1555441
HistoryApr 30, 2022 - 7:24 p.m.

curl: CVE-2022-27781: CERTINFO never-ending busy-loop

2022-04-3019:24:14
sybr
hackerone.com
40

Summary:

Curl is prone to a DoS attack in case the NSS TLS library is used and the CERTINFO option is enabled. Using maliciously crafted certificates on a server, an attacker can make curl run into an endless loop when connecting to the server. The bug is located in the following code segment (https://github.com/curl/curl/blob/master/lib/vtls/nss.c#L1014):

/* Count certificates in chain. */
int i = 1;
now = PR_Now();
if(!cert->isRoot) {
  cert2 = CERT_FindCertIssuer(cert, now, certUsageSSLCA);
  while(cert2) {
    i++;
    if(cert2->isRoot) {
      CERT_DestroyCertificate(cert2);
      break;
    }
    cert3 = CERT_FindCertIssuer(cert2, now, certUsageSSLCA);
    CERT_DestroyCertificate(cert2);
    cert2 = cert3;
  }
}

When CERTINFO is set, display_conn_info() executes the above shown code, which tries to count the certificates in the chain received from servers via TLS. To this end, display_conn_info() starts with the leaf certificate and attempts to find its issuer certificate in the chain. The issuer certificate then becomes the origin for the next iteration. This step is repeated until there either is no issuer certificate or a root (= self-signed) certificate is found. However, if the received certificate chain contains a loop, this exit condition is never reached and display_conn_info() runs into an endless loop. To craft a loop, it is sufficient to have two CA certificates that mutually list each other as issuers (see attached PoC).

Steps To Reproduce:

I have implemented a small PoC where a Webserver uses a maliciously crafted certificate chain that contains a loop. To this end, the end-entity certificate for localhost is issued by CA2, whose certificate is issued by CA1, whose certificate in turn is issued by CA2 (-> loop). The Python script for the Webserver and the certificate chain are attached to this report. To trigger the DoS in curl, the following steps need to be executed:

  1. Modify URL in certinfo example (https://github.com/curl/curl/blob/master/docs/examples/certinfo.c#L46) to point to https://localhost:4443/ instead of https://www.example.com/ (url_easy_setopt(curl, CURLOPT_URL, "https://localhost:4443/"))
  2. Build curl with NSS TLS library (./configure --with-nss) and with examples (make examples)
  3. Execute python script attached to this report to start the attackerโ€™s Webserver
  4. Execute certinfo (doc/examples/certinfo)

Supporting Material/References:

[list any additional material (e.g. screenshots, logs, etc.)]

  • https_server.py (poc webserver)
  • key.pem (poc webserver key)
  • combined_loop.pem (poc webserver certificate chain)

Impact

An attacker who controls a server that a libcurl-using application (with NSS and enabled CERTINFO) connects to, can trigger a DoS. In this case, the application runs into an infinite loop and consumes nearly 100% CPU.

Using the CVSS calculator, I initially came up with medium severity (5.3). However, because the vulnerabilities relies on CERTINFO being enabled and NSS being used, which is not that popular and will soon be deprecated (https://curl.se/dev/deprecate.html), I eventually estimate the severity to be low.