记一次oracle数据库SQL注入bypass

前言

在帮电信的客户测试项目的过程中,发现一处 SQL 注入漏洞。

数据库类型是 oracle,该处功能点是用来查询用户的。

查询 1 时,输出无结果。

image

查询 a 时,输出有结果

image

测试过程

第一次测试

第一次测试是毫无过滤手法的。

image

通过 sqlmap 可以正常的获取数据。

image

第二次测试

这次复测,正确来说是第三次复测,通过项目经理得知,该项目,客户已经找了另外一个公司帮助复测。

因此我这次复测是第三次,但实际上是我的第二次测试。

image

使用第一次测试的 payload 可以发现,该 payload 已经无法正常使用了。开始想办法让它 SQL 语句报错,看看 SQL 语句是怎么写的。

测试后发现使用可以使语句报错。

image

familyName 参数的值,是在 instr 函数中,这是一个字符串查找函数。

image

大概看了一下相关概念和使用案例,明白了这个函数怎么使用。

这里使用在线的 oracle 运行工具进行语句和 payload 调试。

https://livesql.oracle.com/apex/f?p=590:1000

通过报错语句、构造一个类似的伪查询 SQL 语句

select user from dual where instr(user,'A')>0

image

这里的 A 也就可以是我们通过发包传入的 payload

那么通过闭合,在使用逻辑运算符就可以去进行SQL注入了。

假设 payload 是 A')>0 OR instr(user,'A

image

此时在数据包中构造一个类似的 payload,并且尝试注入。

image

当我的值都是 1 时,查询结果应该是为空的,但是正常回显了数据。说明插入的字符串中有字符串被过滤了。

此时尝试寻找是哪个关键字被过滤了。

最后确定是逻辑运算符 andor 被过滤。

image

image

此时把 or 删掉,看看 instr 有没有被过滤

image

可以发现 instr 没有过滤

ByPass过程

尝试编码绕过

测试 payload 是 1')>0 or instr(cscp_user.username,'1

当插入语句被成功执行时,预期应该是返回数据是空。

image

并且其他可被识别的编码绕过均失败。

尝试大小写绕过

image

大小写失败

尝试双写绕过

image

绕过失败,OrRr 被没有按预期变成 or

在网上查了很多相关资料,也并未找到能够代替逻辑运算符的方法。

此时想到了字符拼接

即将 or 拆分成 or,然后通过||符号连接。

image

但是实际上经过测试后发现,这个返回的是一条记录,而不是一个简单的字符串,因此没办法拼接。

峰回路转,成功 bypass

难受啊、正在迷茫的时候。

突然发现了一个有意思的东西。

image

当我把 0OR 中间的空格删除后发现,OR 的颜色没变,说明 SQL 还是把它当作了一个逻辑运算符。

这里我尝试执行一下这个语句。

image

发现结果被正常的输出,所以大胆猜测 0or0 or 的执行效果是一样的,这应该是 oracle 的啥特性
,可以忽略空格。

这里我来在数据包中尝试注入。

image

测试发现,结果已经达到了预期值

image

查询 a 时,返回也有记录

注:这里被测站点使用的查询语句中 instr 实际上有多个,我要考虑完美闭合,即闭合左边的 instr,还不能忽略掉右边的),所以 payload 里面才会有一个 instr。为什么这么操作,是因为测试发现,通过注释,是无法闭合语句的。

这里尝试获取数据。

但是这里有几个概念要清楚。

oracle数据库中,查询用户是可以直接用 user 来查的,andor 的优先级高,因此and 先执行。

构造一个这样的 payload

1')>0or length(user)=10and instr(cscp_user.username,'a

通过前面分析可知,a 代表有数据,因此 instrlength(user)两个是先执行的,这里是判断当前用户长度是否是 10,如果是 10,并且 instr 中的 string2a,回显有数据即and 左右两边都是 true,因此查询有数据。

开始发包

image

回显有数据,说明当前用户长度是 10

接下来可以通过 leftsubstr 这类关键字去截取字符串,既可以成功注入到当前的用户名称了。

如果 leftsubstr 被过滤,可以使用 like 进行绕过。

user like ‘%’ 通过通配符去匹配。

这里也就 bypass 成功,这里开发只是做了黑名单校验,因此开发祭天,法力无边。哈哈哈,开发要挨打了。

总结

SQL注入绕过没技巧,主要得通过页面回显去判断拦截类型,并且要需要本地调试自己的payload能否正常运行。

后续就是,由于第二天是国庆,下午是和甲方开发玩了一下午,她边修我边绕,最后下班了,我就没绕了,也算是一次比较有趣的bypass经历,毕竟是真实的实战对抗。

Author: jdr
Link: https://jdr2021.github.io/2021/09/29/记一次oracle数据库SQL注入bypass/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.