Lucene search

K
hackeroneFullmetal5H1:2410774
HistoryMar 10, 2024 - 9:32 p.m.

curl: CVE-2024-2379: QUIC certificate check bypass with wolfSSL

2024-03-1021:32:06
fullmetal5
hackerone.com
31
cve-2024-2379
quic
certificate verification
wolfssl
curl
vulnerability
security document

6.9 Medium

AI Score

Confidence

High

0.0004 Low

EPSS

Percentile

15.3%

Summary:

In vquic-tls.c curl_wssl_init_ctx errors are handled by goto out and having result be set to an error code to be returned. At the beginning of the function result is correctly set to CURLE_FAILED_INIT which allows for goto out to work correctly without having to set result however, result’s value is overridden at a certain point if ctx_setup is passed to the function. If ctx_setup returns 0 (the expected result) then it’s assigned to result and any attempt after that to goto out without setting result to an error code will make the function skip the rest of its initialization and return with an error code indicating success.

Unfortunately the last thing curl_wssl_init_ctx is supposed to setup for the ssl context is the certificate verification requirements. There are 4 places goto out is used without setting result, of those 3 can result from bad user input (bad tls13-ciphers, curves, or cafile/capath) and 1 is from trying to setup ssl key logging when having a WolfSSL build that doesn’t have wolfSSL_CTX_set_keylog_callback.

Luckily this does require the user to have passed in bogus values for one of the above parameters which I find very unlikely. Also very fortunately WolfSSL attempts to default to verify a cert rather than OpenSSL’s default of not verifying. There is an option to make WolfSSL have OpenSSL compatible defaults but I don’t know how common it is to have WolfSSL configured like that so I’m not sure how likely it is that people could run into this.

Given the unlikely set of configurations required to encounter this I don’t think this is a “high” vulnerability like the CVSS claims but there is no way of manually setting the score, honestly I would have just submitted a patch to fix this but I’m not to sure on how common having WolfSSL in OpenSSL compatible mode is so I’m err’ing on the side of caution and submitting it here.

I checked the other initialization functions in vquic-tls.c and it doesn’t look like the same mistake was made in them. result is assigned before each use of goto out.

Steps To Reproduce:

Build WolfSSL with something that sets OPENSSL_COMPATIBLE_DEFAULTS (I used --enable-nginx) and build curl with the WolfSSL backend.
Setup a QUIC webserver with a self signed cert that matches the domain being spoofed and attempt to make a HTTP/3 connection to it using curl with a bad --curves list. curl connects to the site without having set --insecure, taking out the bad --curves argument curl will complain about the invalid cert.

ex:

./curl -v --http3-only 'https://example.com/' -o /dev/null -s --resolve example.com:443:192.168.1.24 --curves blah
* Added example.com:443:192.168.1.24 to DNS cache
* Hostname example.com was found in DNS cache
*   Trying 192.168.1.24:443...
* wolfSSL failed to set curves
* Verified certificate just fine
* Connected to example.com (192.168.1.24) port 443
* using HTTP/3
* [HTTP/3] [0] OPENED stream for https://example.com/
* [HTTP/3] [0] [:method: GET]
* [HTTP/3] [0] [:scheme: https]
* [HTTP/3] [0] [:authority: example.com]
* [HTTP/3] [0] [:path: /]
* [HTTP/3] [0] [user-agent: curl/8.7.0-DEV]
* [HTTP/3] [0] [accept: */*]
> GET / HTTP/3
> Host: example.com
> User-Agent: curl/8.7.0-DEV
> Accept: */*
> 
* We are completely uploaded and fine
< HTTP/3 200 
< server: nginx/1.25.4
< date: Sun, 10 Mar 2024 21:02:39 GMT
< content-type: text/html
< content-length: 615
< last-modified: Wed, 14 Feb 2024 16:03:00 GMT
< etag: "65cce434-267"
< accept-ranges: bytes
< 
{ [615 bytes data]
* Connection #0 to host example.com left intact

vs

./curl -v --http3-only 'https://example.com/' -o /dev/null -s --resolve example.com:443:192.168.1.24 
* Added example.com:443:192.168.1.24 to DNS cache
* Hostname example.com was found in DNS cache
*   Trying 192.168.1.24:443...
*  CAfile: /etc/ssl/certs/ca-certificates.crt
*  CApath: none
* QUIC connect to 192.168.1.24 port 443 failed: SSL peer certificate or SSH remote key was not OK
* Failed to connect to example.com port 443 after 12 ms: SSL peer certificate or SSH remote key was not OK
* Closing connection

Supporting Material/References:

This was introduced in https://github.com/curl/curl/pull/12678 so the only vulnerable version to be released is 8.6.0

Impact

If the stars align and the user is using such a configuration and passing bad arguments then they would be vulnerable to MITM attacks.