尝试访问

http://mdsec.net/addressbook/32/

首先,我们需要确定请求的列数。对单一列进行测试导致了以下错误消息:

img247b

我们添加另一个NULL,并得到同样的错误。于是我们继续添加NULL,直到查询被执行,并在结果表中生成另一个数据项,如下所示:

img247c

人 名 电子邮件地址
Matthew Adamson handytrick@gmail.com
[空] [空]

现在我们验证查询的第一列是否包含字符串数据:

img247d

人 名 电子邮件地址
Matthew Adamson handytrick@gmail.com
[a]

接下来,需要查明可能包含有用信息的数据库表和列的名称。为此,我们需要查询元数据表information_schema.columns,其中包含数据库中的所有表和列名称的详细资料。使用以下请求可以检索上述信息:

img248a

人 名 电子邮件地址
Matthew Adamson handytrick@gmail.com
shop_items Price
shop_items Prodid
shop_items Prodname
addr_book Contactemail
addr_book Contactname
Users Username
Users Password

从以上结果可以确定,很明显,我们可以从用户表开始提取数据。这时使用以下查询:

img248b

人 名 电子邮件地址
Matthew Adamson handytrick@gmail.com
administrator fme69
dev uber
marcus 8pinto
smith twosixty
jlo 6kdown

img004  提示  MS-SQL、MySQL和许多其他数据库(包括SQLite 和Postgresql)均支持information_schema。它主要用于保存数据库元数据,这也使它成为探查数据库的攻击者的主要目标。需要注意的是,Oracle并不支持该方案。对Oracle数据库实施攻击时,攻击方法在其他各方面可能完全相同。但是,需要使用查询SELECTtable_name,column_name FROM all_tab_columns来检索有关数据库表和列的信息。(使用user_tab_columns表以仅针对当前数据库。)通常,在分析大型数据库以探查攻击目标时,最好是查找有用的列名称,而不是表。例如:

img248c

img004  提示  如果目标表返回了多个列,则可以将这些列串连到单独一个列中,这样检索起来会更加方便,因为这时只需要在原始查询中确定一个varchar字段:

img002 Oracle: SELECT table_name||’:’||column_name FROM all_tab_columns

img002 MS-SQL: SELECT table_name+’:’+column_name from information_schema.columns

img002 MySQL: SELECT CONCAT(table_name,’:’,column_name) from information_schema.columns

9.2.8 避开过滤

有时,易受SQL 注入攻击的应用程序可能会执行各种输入过滤以防止攻击者无限制地利用其中存在的缺陷。例如,应用程序可能会删除或净化某些字符,或阻止常用的SQL关键字。这种过滤通常非常容易避开,这时可尝试使用各种技巧。

1.避免使用被阻止的字符

如果应用程序删除或编码某些在SQL注入攻击中经常用到的字符,不使用这些字符仍然能够实施攻击。

img002 如果要注入数字数据字段或列名称,不一定必须使用单引号。要在攻击有效载荷中插入字符串,不使用引号仍可以做到这一点。这时,可以通过各种字符串函数,使用每个字符的ASCII代码动态构建一个字符串。例如,下面两个查询分别用于Oracle和MS-SQL,它们等同于select ename,sal from emp where ename=‘marcus’:

img249a

img002 如果注释符号被阻止,通常可以设计注入的数据,使其不会破坏周围查询的语法。例如,不用注入

img249b

可以注入

img249c

img002 在MS-SQL数据库中注入批量查询时,不必使用分号分隔符。只要纠正所有批量查询的语法,无论你是否使用分号,查询解析器都会正确解释它们。