# 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 # Open psql console with user psql -h -d # Remote connection psql -h -p -U -W # Remote connection ``` ```sql psql -h localhost -d -U #Password will be prompted \list # List databases \c # 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('','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//main/log/ #or in /var/lib/postgresql//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 ```