Big Binary Files Upload (PostgreSQL)

Aprende hacking en AWS desde cero hasta experto con htARTE (Experto en Red Team de AWS de HackTricks)!

Otras formas de apoyar a HackTricks:

Objetos Grandes de PostgreSQL

PostgreSQL ofrece una estructura conocida como objetos grandes, accesibles a través de la tabla pg_largeobject, diseñada para almacenar tipos de datos grandes, como imágenes o documentos PDF. Este enfoque es ventajoso sobre la función COPY TO ya que permite la exportación de datos de vuelta al sistema de archivos, asegurando que se mantenga una réplica exacta del archivo original.

Para almacenar un archivo completo dentro de esta tabla, se debe crear un objeto en la tabla pg_largeobject (identificado por un LOID), seguido de la inserción de fragmentos de datos, cada uno de 2KB de tamaño, en este objeto. Es crucial que estos fragmentos tengan exactamente 2KB de tamaño (con la posible excepción del último fragmento) para garantizar que la función de exportación se realice correctamente.

Para dividir tus datos binarios en fragmentos de 2KB, se pueden ejecutar los siguientes comandos:

split -b 2048 your_file # Creates 2KB sized files

Para codificar cada archivo en Base64 o Hex, se pueden utilizar los siguientes comandos:

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

Importante: Al automatizar este proceso, asegúrate de enviar fragmentos de 2KB de bytes de texto claro. Los archivos codificados en hexadecimal requerirán 4KB de datos por fragmento debido al doble en tamaño, mientras que los archivos codificados en Base64 siguen la fórmula ceil(n / 3) * 4.

El contenido de los objetos grandes se puede ver con fines de depuración utilizando:

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

Usando lo_creat & Base64

Para almacenar datos binarios, primero se crea un 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

En situaciones que requieran un control preciso, como explotar una Inyección SQL a ciegas, se prefiere lo_create para especificar un LOID fijo.

Los fragmentos de datos pueden ser insertados de la siguiente manera:

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 y potencialmente eliminar el objeto grande después de su uso:

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

Utilizando lo_import & Hex

La función lo_import se puede utilizar para crear y especificar un LOID para un objeto grande:

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

Después de la creación del objeto, se insertan datos por página, asegurando que cada fragmento no exceda los 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 el proceso, los datos se exportan y el objeto grande se elimina:

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

Limitaciones

Se señala que los objetos grandes pueden tener ACL (Listas de Control de Acceso), lo que potencialmente restringe el acceso incluso a objetos creados por tu usuario. Sin embargo, objetos antiguos con ACL permisivas aún pueden ser accesibles para la exfiltración de contenido.

Aprende hacking en AWS desde cero hasta experto con htARTE (HackTricks AWS Red Team Expert)!

Otras formas de apoyar a HackTricks:

Última actualización