Find out how multiple vulnerabilities in VestaCP allow an authenticated attacker to elevate his access to root privileges.
VestaCP is “an open source hosting control panel, a clean and focused interface without the clutter, and has the latest of very innovative technologies”.
Two security vulnerabilities in VestaCP allow attackers that have access to the VestaCP panel to elevate their privileges from user to admin, and subsequently from admin to root – by chaining these two vulnerabilities together a user can become ‘root’ on the victim machine.
Two independent security researchers, Martí Guasch Jiménez (@0xGsch) and Francisco Andreu Sanz (@kikoas1995), have reported this vulnerability to the SSD Secure Disclosure program.
VestaCP version 0.9.8-24 and prior
We informed the vendor 3 months ago and have initially had communication with the developers – however after a few back and forth emails with them – they have stopped answering our emails and have not released a patch.
We currently recommend you to use forks of VestaCP like, myVestaCP and HestiaCP, has they released patches for the vulnerabilities.
Privilege escalation from user to admin in VestaCP
To show this vulnerability we will be using a standard user account in VestaCP which we previously created called user1.
First of all we will show you how to obtain a reverse shell as the user account in the VestaCP server. This is not completely necessary but facilitates the exploitation by a lot.
In order to obtain the shell we need to create a cron job that executes periodically and sends a reverse shell to a server controlled by the attacker.
In the following image, we get a shell as the user who executed the cronjob.
Go to your users web directory inside your home directory (~) and create a directory with the name of the domain you desire, in our case we are using
Now inside that directory, create another directory called
public_xhtml. And inside
public_xhtml create a symlink
pwn.pwn to the desired file you want to read, in this case we want to takeover the admin account so we are going to point to its
user.conf which contains the RKEY that allows us to change their password, but we can takeover any account with this vulnerability or read any file.
Now again in the directory of our domain,
pwned.pwn, create as many symlinks to the folders which we don’t have permission to access. In our case we need access to
/usr/local/vesta/data/users/admin, so we create two symlinks with any desired name.
Once all the setup is finished we can trigger the vulnerability by creating a domain as the user1 with the name
pwned.pwn in the /add/web URL of VestaCP.
After creating the domain we should see that some directories have been created in our domain folder,
pwned.pwn. If we now try to read the contests of the
user.conf of admin we should be able to do so.
Now that we can read its RKEY, we can simply access
/reset/?action=confirm&user=admin&code=RKEY_VALUE and change the password of the
The vulnerability happens in the shell script v-add-web-domain which is called in
In it, the following commands are used without checking if the directory already exists or has any contents.
$domain is the name of the domain of our website and
$user of our VestaCP user.
In lines 88 to 94 we can see that various chmod commands are used in our
$domain directory. We can abuse the command in line 94 to change the permissions of the file we want to read, and the command in line 92 to change the permissions of the directories we need access to.
Privilege escalation from “admin” to “root” in VestaCP
To exploit this vulnerability we should also create a reverse shell as the admin user as seen in the previous one.
As seen in the following screenshot, VestaCP relies on bash scripts to perform every operation in the web-app, such as adding a user or listing them. The scripts are under the path
These bash scripts are owned by root user and can not be modified. However, sudo -l reveals that admin can run any of these scripts as root without having to insert the password.
Looking at the script v-list-user we see that it uses the environment variable
$VESTA at the beginning of it to import
First, let’s create a bash script under
/tmp/func called main.sh, which is just going to spawn a shell.
As we are able to execute any of the scripts as root without entering the password, we can first overwrite the environment variable $VESTA before executing them.
This way, when running v-list-user, we will instantly have root access to the system: