Big Binary Files Upload (PostgreSQL)

Support HackTricks

PostgreSQL Large Objects

Το PostgreSQL προσφέρει μια δομή γνωστή ως large objects, προσβάσιμη μέσω του πίνακα pg_largeobject, σχεδιασμένη για την αποθήκευση μεγάλων τύπων δεδομένων, όπως εικόνες ή έγγραφα PDF. Αυτή η προσέγγιση είναι πλεονεκτική σε σχέση με τη λειτουργία COPY TO, καθώς επιτρέπει την εξαγωγή δεδομένων πίσω στο σύστημα αρχείων, διασφαλίζοντας ότι διατηρείται μια ακριβής αναπαράσταση του αρχικού αρχείου.

Για να αποθηκεύσετε ένα πλήρες αρχείο μέσα σε αυτόν τον πίνακα, πρέπει να δημιουργηθεί ένα αντικείμενο στον πίνακα pg_largeobject (αναγνωριζόμενο από ένα LOID), ακολουθούμενο από την εισαγωγή κομματιών δεδομένων, το καθένα 2KB σε μέγεθος, σε αυτό το αντικείμενο. Είναι κρίσιμο αυτά τα κομμάτια να είναι ακριβώς 2KB σε μέγεθος (με την πιθανή εξαίρεση του τελευταίου κομματιού) για να διασφαλιστεί ότι η λειτουργία εξαγωγής εκτελείται σωστά.

Για να διαιρέσετε τα δυαδικά σας δεδομένα σε κομμάτια των 2KB, μπορούν να εκτελούνται οι εξής εντολές:

split -b 2048 your_file # Creates 2KB sized files

Για την κωδικοποίηση κάθε αρχείου σε Base64 ή Hex, μπορούν να χρησιμοποιηθούν οι παρακάτω εντολές:

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

Σημαντικό: Όταν αυτοματοποιείτε αυτή τη διαδικασία, βεβαιωθείτε ότι στέλνετε κομμάτια 2KB καθαρών byte. Τα αρχεία που είναι κωδικοποιημένα σε Hex θα απαιτούν 4KB δεδομένων ανά κομμάτι λόγω διπλασιασμού του μεγέθους, ενώ τα αρχεία που είναι κωδικοποιημένα σε Base64 ακολουθούν τον τύπο ceil(n / 3) * 4.

Τα περιεχόμενα των μεγάλων αντικειμένων μπορούν να προβληθούν για σκοπούς αποσφαλμάτωσης χρησιμοποιώντας:

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

Using lo_creat & Base64

Για να αποθηκεύσετε δυαδικά δεδομένα, πρώτα δημιουργείται ένα 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

Σε καταστάσεις που απαιτούν ακριβή έλεγχο, όπως η εκμετάλλευση ενός Blind SQL Injection, προτιμάται το lo_create για τον καθορισμό ενός σταθερού LOID.

Τα κομμάτια δεδομένων μπορούν στη συνέχεια να εισαχθούν ως εξής:

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'));

Για να εξάγετε και ενδεχομένως να διαγράψετε το μεγάλο αντικείμενο μετά τη χρήση:

SELECT lo_export(173454, '/tmp/your_file');
SELECT lo_unlink(173454);  -- Deletes the specified large object

Χρησιμοποιώντας lo_import & Hex

Η συνάρτηση lo_import μπορεί να χρησιμοποιηθεί για να δημιουργήσει και να καθορίσει ένα LOID για ένα μεγάλο αντικείμενο:

select lo_import('/path/to/file');
select lo_import('/path/to/file', 173454);

Μετά τη δημιουργία του αντικειμένου, τα δεδομένα εισάγονται ανά σελίδα, διασφαλίζοντας ότι κάθε κομμάτι δεν υπερβαίνει τα 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;

Για να ολοκληρωθεί η διαδικασία, τα δεδομένα εξάγονται και το μεγάλο αντικείμενο διαγράφεται:

select lo_export(173454, '/path/to/your_file');
select lo_unlink(173454);  -- Deletes the specified large object

Περιορισμοί

Σημειώνεται ότι τα μεγάλα αντικείμενα μπορεί να έχουν ACLs (Λίστες Ελέγχου Πρόσβασης), περιορίζοντας ενδεχομένως την πρόσβαση ακόμη και σε αντικείμενα που δημιουργήθηκαν από τον χρήστη σας. Ωστόσο, παλαιότερα αντικείμενα με επιτρεπτικές ACLs μπορεί να είναι ακόμη προσβάσιμα για εξαγωγή περιεχομένου.

Support HackTricks

Last updated