我一直在互联网上四处寻找关于二阶 SQLi 的演示,但我还没有找到一个。许多网站并没有真正彻底解释它是如何工作的。我需要做一个简短的演示,我一直在练习使用 Mutillidae。任何人都可以引导我朝着正确的方向前进吗?
1 回答
谷歌搜索“二阶 sql 注入”会出现一些或多或少相关的解释,说明二阶 SQL 注入是什么,具有不同程度的详细信息(如您所说)。
基本思想是数据库存储一些来自用户的文本,这些文本随后被合并到 SQL 语句中——但在重用之前文本没有得到充分的净化。
考虑一个允许用户针对数据库创建用户定义查询的应用程序。一个简单的示例可能是错误跟踪系统。一些用户定义的查询属性可能是简单的条件,例如“错误状态为“关闭””。这可以通过查看存储的查询定义来编码:
CREATE TABLE UserDefinedQuery
(
...user info...,
bug_status VARCHAR(20),
...other info...
);
SELECT ..., bug_status, ...
INTO ..., hv_bug_status, ...
FROM UserDefinedQuery
WHERE bug_status IS NOT NULL
AND ...other criteria...
wherehv_bug_status
是保存错误状态标准的主变量(PHP,C,您使用的任何语言)。
如果此值为= 'closed'
,则生成的 SQL 可能包含:
SELECT *
FROM Bugs
WHERE status = 'closed'
AND ...other criteria...
现在假设当用户定义他们的查询时,他们改为写:
= 'open' or 1=1
这意味着生成的查询现在看起来像:
SELECT *
FROM Bugs
WHERE status = 'open' or 1=1
AND ...other criteria...
查询的存在OR
极大地改变了查询的含义,并且将显示用户不希望看到的各种其他记录。这是错误查询应用程序中的错误。如果此修改意味着 CustomerX 可以看到其他客户 CustomerY 和 CustomerZ 报告的他们不应该看到的错误,那么 CustomerX 已经设法创建了二阶 SQL 注入攻击。(如果注入仅仅意味着他们可以看到比他们应该看到的更多的记录,包括那些与他们无关的记录,那么他们只是创建了一个错误的查询。)
显然,在 VARCHAR(20) 字段中,您注入致命 SQL 的选项是有限的,因为 SQL 是一种冗长的语言。但是,如果标准存储在更长的字段中,“小 Bobby Tables”可能会出现问题。
='';DELETE Bugs;--
(对 DELETE 语句使用非标准的缩写;在 18 个字符时发出吱吱声。)
你怎么能避免这种情况?不允许用户编写包含在生成的 SQL 中的原始 SQL 片段。将 UserDefinedQuery.Bug_Status 中的值视为空格/逗号分隔的字符串值列表,并相应地构建查询:
SELECT *
FROM Bugs
WHERE status IN ('=', '''open''', 'or', '1=1')
AND ...other criteria...
该查询可能没有用,但它的结构不会因 UserDefinedQuery 表中的数据而改变。