CVE-2024-53376 CyberPanel Authenticated RCE
1
Introduction⌗
This article shows the research, development, exploitation and responsible disclosure of a zero-day vulnerability in the CyberPanel software solution. CyberPanel is a web hosting control panel for OpenLiteSpeed and LiteSpeed Enterprise. It is alternative to cPanel or Plesk (cyberpanel.net). This vulnerability lives in version prior to 2.3.8 of CyberPanel.
2
Terminology⌗
This chapter gives some insight into the terms used throughout this article.
Term | Description |
---|---|
Burpsuite | BurpSuite is a tool used to test and fix security problems in websites. It helps find weaknesses that hackers could exploit. |
Cloud | Cloud is a service that lets you store and access data or run applications over the internet instead of on your computer’s hard drive. |
Opensource | Open source is software with code that is made freely available for anyone to use, modify, and share. |
Python | Python is a popular programming language used to write software. It’s easy to learn and is used for building websites, analyzing data, automating tasks, and more. |
Server | A server is a powerful computer that stores data or runs services, which can be accessed by other computers over a network. |
Vulnerability | A vulnerability is a weakness or flaw in a system, software, or device that can be exploited by someone. |
3
Obtaining the platform code⌗
CyberPanel is an opensource software solution for managing cloud servers, which is hosted on Github. Github is a hosting service for software projects. The github link for CyberPanel is: https://github.com/usmannasir/cyberpanel. CyberPanel provides the user with an easy-to-use installer sh <(curl https://cyberpanel.net/install.sh || wget -O - https://cyberpanel.net/install.sh)
which also allows to select the version to install.
Even when using the installer for version 2.3.9
we can choose to install another version, like the vulnerable version 2.3.7
. To execute this installer root
user is required to be used, thus CyberPanel also runs as the root
user. The machine will restart once, when logging back into the root user the user will be greeted with the following message:
I had to hide the Log in
as this exposes my public IP :)
Once we now go to localhost:8090
we see the following:
The admin password is funky, so I change it to something that can be easily remembered using the following command adminPass Welkom01
Now we can log into our CyberPanel instance using the credentials admin:Welkom01
. We can check the current version that is running by selecting Version management
and looking at the Current version
and Build
Here we can see that we’re running on version 2.3.7
.
4
Identifying vulnerabilities⌗
Since we know that the CyberPanel is written using the Python language, which can be seen from the file extensions that are used within the files.
Knowing that it is Python, I started hunting for any way that CyberPanel executes code on the underlying operating system. This is a way that Remote Code Execution can be achieved. A way to do this is to open a random file and searching for any indication of functions that can execute code:
Here we can see that execPath
is being parsed to the function ProcessUtilities.executioner
, without making an assumption lets take a look at this executioner
.
The executioner
function checks the current logged-in user using the getpass.getuser()
function. Remember that it was required to run as root? Yeah.. spoiler alert it runs everything as root.
Since we know this we need to look at the ProcessUtilities.normalExecutioner
function:
Funnily enough, if we were running as a different user that is not None
and not root
CyberPanel would still try and run it using sudo
permissions! Regardless, it runs as root already :)
CyberPanel uses the following functions that can all execute code on the underlying operating system:
- ProcessUtilities.executioner
- ProcessUtilities.normalExecutioner
- ProcessUtilities.sendCommand
- ProcessUtilities.outputExecutioner
- ProcessUtilities.customPoen
- ProcessUtilities.BuildCommand
- ProcessUtilities.popenExecutioner
Why would you need 7 different functions that can all execute code?? I probably missed some too!
Time to actually hunt vulnerable functions.
CyberPanel contains 807
Python files, ain’t no way looking through each and every one looking for a specific function.. that would take ages!
Luckily we can use grep
to look quickly for us, for example with the command grep -rni "ProcessUtilities.popenExecutioner"
(Normally you would go through all the functions, for this writeup the vulnerable function uses the popenExecutioner which is why I demo it here).
After reading, theorizing and trying functions I found an interesting candidate within the websiteFunctions\website.py
file. The function submitWebsiteCreation
used user controlled variables that were directly parsed to the exectioner without firstly being sanitized or checked.
The submitWebsiteCreation
function uses the following user defined variables:
- domain
- adminEmail
- phpSelection
- packageName
- websiteOwner
Now not every variable is ideal for injection, the reasoning for this are validators
. Validators is the worst nightmare for a hacker as this checks if the input given by a user is actually valid.
The domain
variable has a validator.
The adminEmail
variable also has a validator.
The phpSelection
variable however does not have a validator, added bonus is that it gets parsed directly to the executor:
Now we know we have a possible executor we need to actually prove that it is vulnerable.
5
Proof-of-Concept⌗
It is possible to make a Python exploit script to test the vulnerability, however a quicker way (that also shows a lot more) is BurpSuite. BurpSuite allows us to see what is normally hidden from view, thus also improving the time required to write an exploit script.
We see a couple of interesting things, namely that the login is being made using a POST
request to the /verifyLogin
endpoint. It also encodes the login credentials using JSON as shown below.
{
"username":"admin",
"password":"Welkom01",
"languageSelection":"english"
}
Furthermore CyberPanel uses a csrftoken
embedded in the Cookie, aswell as a X-Csrftoken
in the header. Once we forward the requests within BurpSuite we can see we’ve now obtained a sessionid
which indicates that we’re authenticated with our CyberPanel instance.
We can now move to the vulnerable page that calls our vulnerable function. This can be found under the Websites
tab and Create Website
Intercepting this request using BurpSuite we get to see the following:
We know the vulnerability lies within the phpSelection
variable, so lets see what happends when we send our exploit by adding '; touch /tmp/PoC; #
to the end of phpSelection
.
We see that our exploit attempt is stopped, because it filters characters like $ & ( ) [ ] { } ; :
. Lets see how the function that is responsible for this actually works. We can find this function by using grep -rni "Data supplied is not accepted"
:
We can see that the file CyberCP\secMiddleWare.py
is responsible for stopping our exploit attempt, lets see if we can bypass this filter.
The filter looks to be filtering every character that is used for Command Injection. There is one HUGE mistake tho.. and that is the assumption that only POST
can be used to submit data. OPTIONS
can do exactly the same.. So changing the method from POST
to OPTIONS
we get the following result:
When looking at /tmp/
location using ls -la
we see the following:
The owner of the file is root
which proves that the command is being executed as the root user. We can further prove this by issuing a whoami
and id
and outputting it to this file. Instead of PHP 8.0'; touch /tmp/PoC; #
we use PHP 8.0'; whoami > /tmp/PoC && id >> /tmp/PoC; #
To do the exploit, we need the csrftoken
and sessionid
. The csrftoken
is the same as the X-Csrftoken
.
Lastly we need the headers and payload to actually exploit the vulnerability:
The full PoC code is available on: https://github.com/ThottySploity/CVE-2024-53376
6
Mitigation⌗
To mitigate this vulnerability, the core problem needs to be handles which is the only sanitization of POST
requests. Ideally any method is sanitized.
7
Responsible Disclosure⌗
- 30.10.2024 - Identified vulnerability
- 31.10.2024 - Contacted Usman Nasir, owner of CyberPanel
- 02.11.2024 - Usman fixed the issue and published a fix
- 03.11.2024 - Requested CVE-ID from MITRE
- 23.11.2024 - MITRE reserved CVE-ID 2024-53376
- 15.12.2024 - CVE-2024-53376 published to the public