第79篇:记一次Oracle注入漏洞提权的艰难过程

95ce133f9628b2be98dbb0c19f14a5e9.png

 Part1 前言 

大家好,我是ABC_123。前不久遇到一个Oracle注入漏洞,是搜索型的盲注漏洞,只能用折半法一个字符一个字符的猜解数据,使用sqlmap可以直接跑出来,经过判断是DBA权限。接下来就是想办法通过这个注入点获取操作系统的权限,但是遇到了很多问题,于是搭建环境研究了一天,最后终于获取系统权限,本期ABC_123就把这个案例分享给大家。

注:本篇文章中的一些说法可能与其它文章不一样,欢迎批评指正。

 Part2 技术研究过程 

  • 加快sqlmap注入过程

由于这个注入点是盲注的,需要通过折半法一个字符字符的猜解,然后又是搜索型的,所以导致注入速度特别慢,所以ABC_123进行了两方面优化,加快sql注入的速度。

 1   在search=%语句中加一个存在结果很少的搜索值,比search=201922321%,只显示出一条搜索结果,这样减少数据库的检索量和http返回的数据包大小,可以加快sql注入的速度。

如下图所示,%' And 'sdf' LIKE 'sdf变成201922321%' And 'sdf' LIKE 'sdf

fc574dc448c8cfef7a3e6c87e6500f16.png

 2   更改sqlmap的默认10个线程限制。这里需要修改sqlmap的源码,网上有很多教程,这里不过多叙述了。

  • 改造一下网上的提权语句

网上很多文章给出的Oracle注入提权的语句一般是分为以下3个步骤:

30d5073aedc1e40443094216bec03817.png

这里需要注意看第2步骤,这一步骤就是赋予当前Oracle账号相关的JAVA权限,但是这个语句我一直都不太喜欢用,因为有大量的单引号存在,然后还有左右尖括号,有时候会被当做XSS攻击payload被转义掉导致注入失败,而且这个语句异常复杂,很容易出错。

这里ABC_123直接用一个简单的语句替代:效果比上述语句赋予的权限更多,效果更好。其中需要注意的是,BEGIN开头,然后end;结尾,代表一个PL/SQL语句块。

select dbms_xmlquery.newcontext('declare PRAGMA AUTONOMOUS_TRANSACTION; BEGIN EXECUTE IMMEDIATE ''grant javasyspriv to test111''; end;') from dual

  • Sqlmap的sql-shell功能失败

能用工具还是优先使用工具,于是我用sqlmap的--sql-shell命令将上述语句执行。

sqlmap.py -r 111.txt --dbms=”Oracle” --threads 20 --technique B --batch --sql-shell

将上述三条sql语句执行完毕,发现最后执行命令没有成功:

select LinxRunCMD('whoami') from dual

遇到这种情况,一般两种可能,一种可能是执行命令被拦截了,另一种可能是Java代码没有执行成功

于是使用如下sql语句进行判断,

select * from all_objects where object_name like '%LinuxUtil111%'

结果返回0,说明函数没有添加成功。经过后续一系列测试,发现是sqlmap的sql-shell下功能下,上述很复杂的sql语句根本没执行成功。

  • 开始手工注入

Oracle一般都是支持多语句的,我将SQL注入语句进行了如下修改,通过and ( 插入sql语句 ) is not null的方式,在左右括号中可以插入各种Oracle的sql语句,这种形式非常方便,这种方式可以方便我们将oracle的各种复杂语句不加修改直接放置进去。

839bdf8fc90fd96656bb13ab92a0383a.png

如下图所示,将Oracle提取语句放到左右括号中去执行,结果被waf拦截了。

a54caafe295366374ccd3a485b437f9f.png

于是用Oracle特有的编码方式编码一下,变成如下格式成功执行。

2d21e001b44bfa76f0c2386d61461c75.png

再次执行查询LinuxUtil111是否存在的sql语句,发现返回count()不为0,说明Java代码成功添加执行。结果LinxRunCMD('whoami')还是执行不了命令,这是为什么呢?

  • Oracle的java执行权限问题

于是我首先认为是java权限没有添加成功,于是我执行了如下语句:

select granted_role from user_role_privs

发现当前用户有3个权限CONNECT、RESOURCE、JAVASYSPRIV,说明Java相关权限确实是添加成功了,可是为什么就是调用不了LinxRunCMD('whoami')呢?没办法,遇到问题还是搭建环境测试吧。在测试环境中,使用navicat将上述oracle提权语句依次执行之后,发现报了权限错误。

java.security.AccessControlException: the Permission (java.io.FilePermission <<ALL FILES>> execute) has not been granted to TEST111. The PL/SQL to grant this is dbms_java.grant_permission( 'TEST111', 'SYS:java.io.FilePermission', '<<ALL FILES>>', 'execute' )

0de6438e580feea2fad815a215465975.png

使用如下sql语句查询当前Oracle用户的权限,发现是具有JAVASYSPRIV的,但是为啥还是提示没有权限呢?

4bd609a0a723a5ffb8e9a079921271a0.png

然后ABC_123翻看了大量国外的文章终于发现了问题所在,真正判断当前用户是否有java权限,需要查询session_roles表才行,该表用于用于显示当前会话(session)中的角色信息,必须session_roles中有JAVASYSPRIV权限才行。方法之一就是断开Oracle当前账号的连接,重新连接之后session_roles表中就有相应权限了。

9053a1bf618d967e3f70ce494b1e4fc4.png

在测试环境中,断开重连之后,重新查询session_roles表,发现Java权限成功被添加。

be4cc0d38c03f7ac34b62d41419b468a.png

aa6d9ed9cb93bffc98567fc04459dd1f.png

但是我们这里是sql注入点,不可能断开重连,那么有没有办法不断开连接,使java权限立即生效呢?国外文章给出了好几种方法,但是执行之后发现还是不行:

ALTER USER TEST111 DEFAULT ROLE "JAVASYSPRIV";

SET ROLE JAVASYSPRIV;

  • 最终成功获取系统权限

等到第二天之后,惊奇地发现session_roles中存在JAVASYSPRIV角色了,我也不知道为什么,此时可以通过select LinuxExecHanshu('whoami') from dual可以执行命令,但是这个时候盲注就是太麻烦了,我们还是结合sqlmap的sql-shell终端来盲注入吧,因为该sql语句比较简短,sqlmap的sql-shell模式猜解是完全无压力的,最终我们成功获取了系统权限。

036da218aa6c7c7e6a05c95c09bc7f23.png

 Part3 总结 

1.  这个dbms_xmlquery.newcontext函数在高版本的Oracle数据库中已经不能提权成功,甚至是不能使用,这时候需要使用其它的方法提权。

2.  本地搭建的Oracle环境,大多数情况下可以直接提权成功,极少数情况下需要断开重连,具体原因不明。

3.  文章中如果有错误,欢迎批评指正。后续会继续分享Oracle提权的其它方法,敬请期待。

35dbd5720c3fd31453ec3347c79395e0.png

公众号专注于网络安全技术分享,包括APT事件分析、红队攻防、蓝队分析、渗透测试、代码审计等,每周一篇,99%原创,敬请关注。

Contact me: 0day123abc#gmail.com(replace # with @)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

希潭实验室

您的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值