Логотип exploitDog
Консоль
Логотип exploitDog

exploitDog

github логотип

GHSA-76gg-c692-v2mw

Опубликовано: 12 июн. 2023
Источник: github
Github: Не прошло ревью

Описание

Missing error check and insufficient random bytes in HTTP Digest authentication for SOAP

This report was co-authored by @timwolla

Summary

The random byte generation function used in the SOAP HTTP Digest authentication code is not checked for failure. This can result in a stack information leak. Furthermore, there's an insufficient number of random bytes used.

Details

Context: https://github.com/php/php-src/blob/af809ef028e1e3ed59284e2506cab0f275b55d8e/ext/soap/php_http.c#L664-L671

If php_random_bytes_throw fails, the nonce will be uninitialized, but still sent to the server. The client nonce is intended to protect against a malicious server. See section 5.10 and 5.12 of RFC 7616, and bullet point 2 below.

Tim pointed out that even though it's the MD5 of the nonce that gets sent, enumerating 31 bits is trivial. So we have still a stack information leak of 31 bits.

Furthermore, Tim found the following issues:

  • The small size of cnonce might cause the server to erroneously reject a request due to a repeated (cnonce, nc) pair. As per the birthday problem 31 bits of randomness will return a duplication with 50% chance after less than 55000 requests and nc always starts counting at 1.

  • The cnonce is intended to protect the client and password against a malicious server that returns a constant server nonce where the server precomputed a rainbow table between passwords and correct client response. As storage is fairly cheap, a server could precompute the client responses for (a subset of) client nonces and still have a chance of reversing the client response with the same probability as the cnonce duplication.

    Precomputing the rainbow table for all 2^31 cnonces increases the rainbow table size by factor 2 billion, which is infeasible. But precomputing it for 2^14 cnonces only increases the table size by factor 16k and the server would still have a 10% chance of successfully reversing a password with a single client request.

PoC

We do not have a proof-of-concept.

Impact

The weak randomness affects applications that use SOAP with HTTP Digest authentication against a possibly malicious server over HTTP. The stack information leak applies to both HTTP and HTTPS, but is only a few bytes.

Proposed patch

This patch fixes the issues by increasing the nonce size, and checking the return value of php_random_bytes_throw(). In the process we also get rid of the MD5 hashing of the nonce.

From f26fcd3a152a5c6b2d140cb35a5040671696f6e1 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Sun, 16 Apr 2023 15:05:03 +0200 Subject: [PATCH] Fix missing randomness check and insufficient random bytes for SOAP HTTP Digest MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If php_random_bytes_throw fails, the nonce will be uninitialized, but still sent to the server. The client nonce is intended to protect against a malicious server. See section 5.10 and 5.12 of RFC 7616 [1], and bullet point 2 below. Tim pointed out that even though it's the MD5 of the nonce that gets sent, enumerating 31 bits is trivial. So we have still a stack information leak of 31 bits. Furthermore, Tim found the following issues: * The small size of cnonce might cause the server to erroneously reject a request due to a repeated (cnonce, nc) pair. As per the birthday problem 31 bits of randomness will return a duplication with 50% chance after less than 55000 requests and nc always starts counting at 1. * The cnonce is intended to protect the client and password against a malicious server that returns a constant server nonce where the server precomputed a rainbow table between passwords and correct client response. As storage is fairly cheap, a server could precompute the client responses for (a subset of) client nonces and still have a chance of reversing the client response with the same probability as the cnonce duplication. Precomputing the rainbow table for all 2^31 cnonces increases the rainbow table size by factor 2 billion, which is infeasible. But precomputing it for 2^14 cnonces only increases the table size by factor 16k and the server would still have a 10% chance of successfully reversing a password with a single client request. This patch fixes the issues by increasing the nonce size, and checking the return value of php_random_bytes_throw(). In the process we also get rid of the MD5 hashing of the nonce. [1] RFC 7616: https://www.rfc-editor.org/rfc/rfc7616 Co-authored-by: Tim Düsterhus <timwolla@php.net> --- ext/soap/php_http.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index db3c97b647..a619949c69 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -657,18 +657,23 @@ try_again: has_authorization = 1; if (Z_TYPE_P(digest) == IS_ARRAY) { char HA1[33], HA2[33], response[33], cnonce[33], nc[9]; - zend_long nonce; + unsigned char nonce[16]; PHP_MD5_CTX md5ctx; unsigned char hash[16]; - php_random_bytes_throw(&nonce, sizeof(nonce)); - nonce &= 0x7fffffff; + if (UNEXPECTED(php_random_bytes_throw(&nonce, sizeof(nonce)) != SUCCESS)) { + ZEND_ASSERT(EG(exception)); + php_stream_close(stream); + convert_to_null(Z_CLIENT_HTTPURL_P(this_ptr)); + convert_to_null(Z_CLIENT_HTTPSOCKET_P(this_ptr)); + convert_to_null(Z_CLIENT_USE_PROXY_P(this_ptr)); + smart_str_free(&soap_headers_z); + smart_str_free(&soap_headers); + return FALSE; + } - PHP_MD5Init(&md5ctx); - snprintf(cnonce, sizeof(cnonce), ZEND_LONG_FMT, nonce); - PHP_MD5Update(&md5ctx, (unsigned char*)cnonce, strlen(cnonce)); - PHP_MD5Final(hash, &md5ctx); - make_digest(cnonce, hash); + php_hash_bin2hex(cnonce, nonce, sizeof(nonce)); + cnonce[32] = 0; if ((tmp = zend_hash_str_find(Z_ARRVAL_P(digest), "nc", sizeof("nc")-1)) != NULL && Z_TYPE_P(tmp) == IS_LONG) { -- 2.40.0

Пакеты

Наименование
Отсутствует
Затронутые версииВерсия исправления

< 8.0.29

8.0.29

Наименование
Отсутствует
Затронутые версииВерсия исправления

< 8.1.20

8.1.20

Наименование
Отсутствует
Затронутые версииВерсия исправления

< 8.2.7

8.2.7

EPSS

Процентиль: 48%
0.00247
Низкий

Дефекты

CWE-252
CWE-334

Связанные уязвимости

CVSS3: 2.6
ubuntu
около 2 лет назад

In PHP versions 8.0.* before 8.0.29, 8.1.* before 8.1.20, 8.2.* before 8.2.7 when using SOAP HTTP Digest Authentication, random value generator was not checked for failure, and was using narrower range of values than it should have. In case of random generator failure, it could lead to a disclosure of 31 bits of uninitialized memory from the client to the server, and it also made easier to a malicious server to guess the client's nonce.

CVSS3: 4.3
redhat
около 2 лет назад

In PHP versions 8.0.* before 8.0.29, 8.1.* before 8.1.20, 8.2.* before 8.2.7 when using SOAP HTTP Digest Authentication, random value generator was not checked for failure, and was using narrower range of values than it should have. In case of random generator failure, it could lead to a disclosure of 31 bits of uninitialized memory from the client to the server, and it also made easier to a malicious server to guess the client's nonce. 

CVSS3: 2.6
nvd
около 2 лет назад

In PHP versions 8.0.* before 8.0.29, 8.1.* before 8.1.20, 8.2.* before 8.2.7 when using SOAP HTTP Digest Authentication, random value generator was not checked for failure, and was using narrower range of values than it should have. In case of random generator failure, it could lead to a disclosure of 31 bits of uninitialized memory from the client to the server, and it also made easier to a malicious server to guess the client's nonce. 

CVSS3: 2.6
debian
около 2 лет назад

In PHP versions 8.0.* before 8.0.29, 8.1.* before 8.1.20, 8.2.* before ...

suse-cvrf
около 2 лет назад

Security update for php7

EPSS

Процентиль: 48%
0.00247
Низкий

Дефекты

CWE-252
CWE-334