特定sql注入的说明

时间:2010-10-28 12:19:16

标签: sql security

浏览网页中较为可疑的部分,我碰巧遇到了这种特殊的SQL注入:

http://server/path/page.php?id=1+union+select+0,1,concat_ws(user(),0x3a,database(),0x3a,version()),3,4,5,6--

我对SQL的了解 - 我认为这是一个不错的 - 在我读到这篇文章时似乎非常有限。

自从我为网络广泛开发以来,我很想知道这段代码实际上做了什么,更重要的是 它是如何工作的。

4 个答案:

答案 0 :(得分:8)

它取代了不正确编写的参数化查询,如下所示:

$sql = '
SELECT  *
FROM    products
WHERE   id = ' . $_GET['id'];

使用此查询:

SELECT  *
FROM    products
WHERE   id = 1
UNION ALL
select 0,1,concat_ws(user(),0x3A,database(),0x3A,version()),3,4,5,6

,它为您提供有关数据库名称,版本和用户名的信息。

答案 1 :(得分:4)

注入结果依赖于对基础查询语法的一些假设。

这里假设的是代码中的某个地方有一个查询,它将采用“id”参数并将其直接替换为查询,而无需对其进行清理。

它假定了一个简单的查询语法:

select * from records where id = {id param}

这样做会导致替换查询(在上面的示例中):

select * from records where id = 1 union select 0, 1 , concat_ws(user(),0x3a,database(),0x3a,version()), 3, 4, 5, 6 --

现在,这有用的是,它不仅设法抓住程序感兴趣的记录,而且还设置了一个伪造的数据集UNIONs告诉攻击者(这些值在冒号中以冒号分隔)第三栏):

  • 我们所使用的用户名 连接到数据库
  • 数据库的名称
  • db软件的版本

只需运行即可获得相同的信息:

select concat_ws(user(),0x3a,database(),0x3a,version())

直接在sql提示符下,你会得到类似的东西:

joe:production_db:mysql v. whatever

此外,由于UNION进行了隐式排序,并且伪造数据集中的第一列以0开头,因此您的虚假结果可能位于列表的顶部。这很重要,因为程序可能只使用了第一个结果,或者我在上面给出的基本表达式中有一些额外的SQL,它将结果集限制为一条记录。

存在上述噪音的原因(例如选择0,1,...等)是为了使其起作用,您调用UNION的语句必须具有与第一个结果集。因此,只有相应的记录表有7列时,上述注入攻击才有效。否则你会得到语法错误,这种攻击不会真正给你你想要的。双破折号( - )只是为了确保忽略替换后可能发生的任何事情,并得到我想要的结果。 0x3a垃圾只是说“用冒号分隔我的值”。

现在,使这个查询作为攻击向量有用的原因是,如果表有多于或少于7列,则可以手动重写它。

例如,如果上述查询不起作用,并且该表有5列,经过一些实验后,我会点击以下查询URL作为注入向量:

http://server/path/page.php?id=1+union+select+0,1,concat_ws(user(),0x3a,database(),0x3a,version()),3,4--

攻击者猜测的列数可能基于对页面的有根据的看法。例如,如果您正在查看列出商店中所有Doodads的页面,它看起来像:

Name        |        Type        |        Manufacturer
Doodad Foo   Shiny                Shiny Co.
Doodad Bar   Flat                 Simple Doodads, Inc.

这是一个非常好的猜测,你正在查看的表有4列(如果我们通过'id'参数搜索,请记住最有可能隐藏在某处的主键)。

对于文字墙感到抱歉,但希望能回答你的问题。

答案 2 :(得分:1)

此代码向page.php上正在执行的select语句添加了一个额外的联合查询。注入器已确定原始查询有6个字段,因此选择数值(列计数必须与联合匹配)。 concat_ws只创建一个字段,其中包含数据库用户,数据库和版本的值,以冒号分隔。

答案 3 :(得分:0)

它似乎检索用于连接数据库的用户,数据库地址和端口,它的版本。它将由错误消息放置。