In 2021 I discovered several high and critical vulnerabilities in the Kaseya Unitrends backup appliance. This research was conducted and published as part of my day job. Part one details a chain of vulnerabilities by leveraging an insecure PostgreSQL database to ultimately gain shell access to the remote server. Visit https://www.cyberonesecurity.com/blog/exploiting-kaseya-unitrends-backup-appliance-part-1 for the the full write-up. Stay tuned for part two.
The pg_ctlcluster script in the postgresql-common package in Debian and Ubuntu is vulnerable to a local privilege escalation attack. pg_ctlcluster is a script used to manage PostgreSQL instances. A malicious actor with access to the postgres account can create arbitrary directories during startup or reload when called via systemd. This vulnerability can be leveraged to escalate privileges to root.
It’s important to note this is not a vulnerability in PostgreSQL and is specific to Debian, Ubuntu, or any system that consumes the Debian postgresql-common package.
The vulnerability appears to have existed since 2013 based on the Debian Git history (9dc97b, e97d16). I attempted to reproduce it on Wheezy but was unable to verify it due to unrelated technical issues standing up a test environment.
This proof of concept will show the ability to gain root privileges using the default
installation of postgresql-common v200+deb10u2 along with postgresql-11 on Debian Buster. I have also verified the vulnerability on Ubuntu 19.04 with version 199 of the postgresql-common package.
The postgresql init script(/etc/init.d/postgresql) sources init.d-functions which contain functions that call the pg_ctlcluster script. pg_ctlcluster loads the following configuration files determined by the Pgcommon module.
These files are owned by the postgres user. The postgresql.auto.conf file will override the settings from /etc/postgresql. This file is created when the alter system command is executed.
pg_ctlcluster contains logic to create directories for socketdir(defined in pg_ctl.conf) and stats_temp_directory(defined in postgresql.conf). During a start or reload, if the directories defined in either of these variables do not exist, pg_ctlcluster will create it and set the owner to the postgres user.