$con = new mysqli($hostname,$username,$password,$database)
$con->query(“select username, password from users where username=’$username’ and password=’$password'”);
if ($con->error) {
die(“ERROR”)
} else die(“查询完成”);
可以发现这是一个符合延时盲注条件的题目,因为题目没有根据查询结果的真假进行不同的布尔输出。但是题目同时ban掉了所有延时盲注所需的关键字,这时怎么办呢?
我们注意到,它会根据MySQL的query是否出错来选择是否输出ERROR,这其实就是布尔回显,因此报错盲注依然是布尔盲注的一种,但是他又和传统布尔盲注有显著的不同。
为了解决这个问题,如果我们能做到如下的操作就可以进行布尔盲注了:
if( condition, 报错, 不报错)
case when (condition) then 报错 else 不报错 end
问题就是,这个我们手工构造的报错应该如何来搞呢?
手工报错的方法
exp(99999)
exp(x)
返回e^x
也就是e的x次方。所以exp(x)
实际上就是f(x)=e^x^
既然是指数函数,增长率是很大的,那么就很容易变得很大,大到MySQL无法承受就报错了。
cot(0)
余切三角函数
pow(99999,999999)
和C语言一样,是用来求平方的,我们依然利用数太大导致报错这个思路。
优化
我们可以发现,报错盲注和延时盲注很像,延时盲注是“条件满足就sleep”,报错盲注是“条件满足就error”,那么如果if
和case
被ban了,如何进行报错盲注呢?
exp
我们发现exp(1) exp(2)
这些是ok的,而exp(9999)
就报错了,不免会问:exp
的临界值是多少?是709
基于此我们可以让709加上一个condition,或者710减去一个condition。也可以利用sleep()
用的乘法思想。
condition真则报错:
exp((1=1)*9999)
exp(709+(1=1))
condition假则报错:
exp(710-(1=2))
cot
思路参考exp
的,不详细说了。
condition真则报错
cot(1-(1=1))
condition假则报错:
cot(1=0) # 直接把条件放cot()函数里
pow
condition真则报错:
pow(1+(1=1),99999)
condition假则报错:
pow(2-(1=1),99999)