浅谈json参数解析对waf绕过的影响

2019-04-04 约 2774 字 预计阅读 6 分钟

声明:本文 【浅谈json参数解析对waf绕过的影响】 由作者 doggy 于 2016-12-15 07:27:00 首发 先知社区 曾经 浏览数 5905 次

感谢 doggy 的辛苦付出!

0x00介绍

编码问题一直以来是WAF防御体系中的薄弱环节,由于HTTP(S)协议支持多种格式数据传输,当网站存在SQL注入漏洞时,黑客往往会利用编码绕过WAF的防御。本文将简单介绍利用Fuzz技术探测对于json格式编码的数据中一些特殊字符的编码规律,提高WAF对于json格式数据的兼容性。
为了便于理解,我们先来看一个在URL中进行SQL注入的例子。
假设服务器上的article.php是这样一段代码:

<?php
$id=$_GET['id'];
$sql="select * from article where id=$id";
mysql_query($sql,$conn);
?>

那么当我们请求 article.php?id=1 and 1=1 时,mysql会执行

select * from article where id=1 and 1=1

这样就可以通过修改and后面的语句进行查询,最终甚至可以拖下整个数据库数据。WAF(Web Application Firewall),中文名称网站应用防火墙,可以对用户提交的请求进行判断,拦截并阻断恶意的HTTP(S)请求,以达到保护网站安全的目的。对于部署了WAF的网站我们可以通过匹配关键字来阻断攻击。例如检测到HTTP(S)请求中含有and 1=1,我们可以将该请求阻断,当然这里仅仅是举个例子,真实情况下需要阻断请求的规则匹配十分复杂。黑客可以通过变形:”and/**/1=1”、”and%0a1=1”、”and+1=1”来绕过防御,这时就要求WAF能够加载这些变形的规则将有可能绕过WAF的请求全部拦截。

在json格式的数据中,由于服务器会对json数据进行一次json解析,导致有些字符可能会漏防,所以本文主要研究有哪些字符在php+mysql执行环境中的json格式解码后容易出现遗漏。

这张图描述了json格式传输的数据会被转义的几种情况,例如\”会被转义成”,\会被转义成\,\n会被转义成换行,\u(四位十六进制字符)会被转义成unicode解码后对应的字符。
测试环境:php5.4.39 mysql 5.1.73。
测试用例: 这里我们使用开源系统phpaacms中的show.php ,修改php标签内的内容为:

<?php
include_once 'global.php';
$id = json_decode($_GET['id'])->id;
for($i = 0; $i < strlen($id); $i ++)
{
printf("%x",ord($id[$i]));
echo ",";
}
$arc = getArticleInfo($id);
?>

测试URL:

http://127.0.0.1/phpaacms/show.php?id={"id":"31 and 1=1"}

测试说明:这里以\n为例,我们跟踪一下从提交请求到mysql后端的执行流程。

http://127.0.0.1/phpaacms/show.php?id={"id":"31 and\n1=1"}

首先使用php代码跟踪php json_decode函数的执行结果,可以看到\n这里已经变为了0x0a也就是linefeed(换行符)。然后带入mysql执行,我们从mysqllog 跟踪:

这里的 “and”和“1=1”之间确实多了一个换行符,说明\n被解析成0x0a后带入mysql中,为了验证mysql的执行我们在mysql中进行模拟:

这里的换行符对于mysql语句来说仅仅是and和1=1之间的分隔符,对于执行没有影响。可见在json环境下传入的\n 字符会带入到mysql执行。

0x01 URL编码探测

由于-%FF是经过url编码后的字符,对于%09、%0A、%0B、%0C、%0D这些字符都是在普通url中绕过waf常见的单词分隔符,所以我们想看一下这些特殊字符在json格式下是否能够被正常解析。
利用工具:Burpsuite 中的Intruder模块。该模块可以通过加载字典将http请求包指定位置的内容进行替换,从而实现类似“暴力破解”的效果。

测试用例:

http://127.0.0.1/phpaacms/show.php?id={"id":"31 and%(00-FF)1=1"}

我们这里将url中 and与1=1之间的空格依次替换为~%FF。
测试结果:

测试结果中,我们可以看出不同的payload发送的请求http响应也不同,我们可以依据长度(Length)来进行筛选,按长度排序以后,返回长度2743的为”and 1=1”执行成功的请求,也就是说sql注入可以执行,而返回长度2664或小于2664的payload说明无法sql注入成功,这里我们看到仅有%20(space)和%2B(+) 可以在json格式中存活,在常见注入的url中的%0A %0B……这些字符并不能被php的json_decode所解析。

0x02转义探测

这一次我们想探测经过’\’转义过的字符是否会被json decode并在mysql中执行。

测试用例:

http://127.0.0.1/phpaacms/show.php?id={"id":"31 and\%(00-FF)1=1"}

测试结果:

%66(f)、%6E(n)、 %72(r)、%74(t)。也就是说 \f \n \r \t 这四个字符经过json_decode后,可以被当作mysql分隔符进行解析。
测试用例:

http://127.0.0.1/phpaacms/show.php?id={"id":"31 and\u00(00-FF)1=1"}

这一次主要测试\u0000-\u00ff 经过unicode编码的类型是否能够通过json_decode。
测试结果:

可以看出,\u0009、\u000A、\u000B、\u000C、\u000D、\u0020、\u002B均可以被json_decode并带入mysql作为mysql单词分隔符。

0x03单词中的探测

为了探测\x这类字符是否会被json_decode解析后替换为空,这里我们采用单词间的探测,即在mysql单词中插入该用例进行探测这里采用的是”an\xd”。

测试用例:

http://127.0.0.1/phpaacms/show.php?id={"id":"31 an\%(00-FF)d 1=1"}

测试结果:

无一幸免,可见在单词中插入这些转义字符并不会在json解析的时候丢失,多于的转义字符是破坏mysql语法的。

0x04十六进制探测

对于常用的十六进制编码,有可能会采用\00-\ff和\x00-\xff。两种形式,这里我们分别fuzz一下。

1) \00-\FF

测试用例:

http://127.0.0.1/phpaacms/show.php?id={"id":"31 and(00-FF) 1=1"}

测试结果:

可见\00-\FF 并不能如我们所愿被当作-%FF之类的解析。

2) \x00-\xFF

测试用例:

http://127.0.0.1/phpaacms/show.php?id={"id":"31 and\x(00-FF)1=1"}

测试结果:

可以看出,\x00-FF与 \00-FF一样都不能被json直接解析。

0x05 小结

经过以上几次fuzz,可以看出在json环境下:
%20 %2B \f \n \r \t \u0009 \u000A \u000B \u000C \u000D \u0020 \u002B

这些字符会作为mysql分隔符。下面我们来进行实战。

0x06 实战

经过对目前国内主流的几大WAF产品测试,我们目前还没有发现能够防御该漏洞的产品。

以国内某知名云安全厂商的waf产品为例:

正常情况下:
我们请求 http://www.xx.com/xx?id=1 会下图:

而当我们请求http://www.xx.com/xx?id=1%20and%201=1
被WAF阻断以后,会返回下图:

1)使用url编码用例进行探测

测试结果:

可以发现对于%20进行了防护,而对于%2b没有防护。

2)使用\f \n \r \t编码用例进行探测

使用\r \f \n \t 测试结果均没有防护:

3)使用\/**\/代替注释符进行探测

正常情况下,对于json格式数据的注入我们可以类似这样构造:

http://www.xx.com/xx?id={%22id%22:%221%20and/**/1=1%22}

对于常用的绕过waf手段:替换空格为/**/,可能大多数网站都会有所防范。

但是对于 json格式来说\/\/ 同样可以decode成为 //带入mysql成为分隔符。

http://www.xx.com/xx?id={%22id%22:%221%20and\/**\/1=1%22}

0x07总结

在waf对抗技术中,针对编码(json、base64……)中的特殊字符处理上仍然是受到挑战的风险点,在设计和完善waf产品时应当充分考虑业务系统的数据交互流程,从而进一步将黑客对于漏洞的恶意利用遏制在萌芽中。

关键词:[‘技术文章’, ‘技术文章’]


author

旭达网络

旭达网络技术博客,曾记录各种技术问题,一贴搞定.
本文采用知识共享署名 4.0 国际许可协议进行许可。

We notice you're using an adblocker. If you like our webite please keep us running by whitelisting this site in your ad blocker. We’re serving quality, related ads only. Thank you!

I've whitelisted your website.

Not now