背景
从乌云平台公开的案例来看,大部分的SQL注入漏洞均发生在单个HTTP请求和响应中,也就是说要触发漏洞,需经过以下步骤:
- 客户端请求构造payload并发起请求
- 服务端执行了payload
- 客户端收到响应结果
而二阶(Second Order)SQL注入相对来说更隐晦一些,需经过以下步骤:
- 客户端构造payload并发起请求
- 服务端存储payload
- 客户端发起另一请求
- 服务端执行了存储的payload
- 客户端收到响应结果
可以对比看到,二阶注入很隐蔽,很难被黑盒测试检测到,这也是现在各大漏洞平台二阶注入案例少的原因之一吧。
分析
二阶可以理解为两步吧,当将用户的输入存储在某个地方,然后在另一处功能的SQL语句中使用它的时候,既没有进行正确的过滤也没有使用参数化查询,这就造成了二阶注入。至于它的影响的话和普通SQL注入没什么差别。
下面代码来自于sqli-labs
|
|
代码里的$id
被直接保存到了result.txt
文件,为了更形象的表示出二阶注入,我新写了一个页面。
|
|
second.php
从result.txt
文件里读取记录,获取$id
的值并代入SQL查询。具体攻击步骤如下:
访问
index.php
,构造参数id
值为1' and (select 1 from (select count(*),concat(version(),0x7e,floor(rand()*2))a from information_schema.tables group by a)b)#
,完整URL如下http://localhost:8888/sqli-labs/Less-5/?id=1' and (select 1 from (select count(*),concat(version(),0x7e,floor(rand()*2))a from information_schema.tables group by a)b)#
id
的值被写入了result.txt
- 发起另一请求,访问
second.php
SQL语句报错,回显出了数据库版本信息
检测方式
就其本身来说就是个SQL注入,只不过触发方式相对隐晦了一些。一般情况下很难用自动化工具扫出来,最好可以白盒审计源代码,我一般在审计源码的时候会对所有数据库执行的语句做日志记录,对可能出现注入的点输入对应payload,然后查看日志来分析是否有注入问题。当然黑盒情况下也是可能找到二阶注入的,可以利用cloudeye等平台构造合适的payload(cloudeye支持callback哦)来发现这些隐晦的注入问题。
总结
二阶注入比普通的SQL注入更难检测,因为漏洞触发点并不在攻击者提交请求的页面。其防御方式和普通SQL注入没差别,使用参数化查询语句,分离数据和代码。