首页 应用实战正文

通过ModSecurity检测XML格式数据

王子 应用实战 2021-03-05 3472 0

本文主要介绍,如何通过编写规则,对提交到WEB服务器的XML格式的数据进行检测。


以WordPress历史上的一个漏洞为例:xmlrpc.php暴力破解漏洞,黑客可POST以下数据到xmlrpc.php对网站后台的账号密码进行暴力破解:

<?xml version="1.0" encoding="utf-8"?>
<methodCall>
    <methodName>wp.getUsersBlogs</methodName>
    <params>
        <param>
            <value>username</value>
        </param>
        <param>
            <value>password</value>
        </param>
    </params>
</methodCall>


本地搭建测试环境,利用以上方法进行一次攻击模拟后,通过ModSecurity的审计日志功能,可记录此次的请求数据包:

--63034d57-A--
[05/Mar/2021:16:49:05 +0800] YEHwgexiyecp5T00SgL3FwAAAIE 192.168.142.1 61967 192.168.142.131 80
--63034d57-B--
POST /wordpress/xmlrpc.php HTTP/1.1
accept: */*
user-agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)
Content-Type: text/xml
Host: wp.modsecurity.cn
Connection: keep-alive
Content-Length: 192
--63034d57-C--
<?xml version="1.0" encoding="utf-8"?><methodCall><methodName>wp.getUsersBlogs</methodName><params><param><value>admin</value></param><param><value>123456</value></param></params></methodCall>

从审计日志中可以看出,数据的确是存放在请求体当中,但如果直接通过REQUEST_BODY去检测请求体当中的数据(如下方规则),将无法匹配成功:

SecRule REQUEST_BODY "wp.getusersblogs" "phase:2,id:105,log,deny,t:lowercase"

造成无法匹配的原因是,仅当Content-Type为application/x-www-form-urlencoded,或者强制使用URLENCODED请求体解析器时,REQUEST_BODY这一变量才有效,而我们模拟攻击时提交的Content-Type为text/xml,因此REQUEST_BODY变量无效,进而导致上述规则无法起到防御作用。


针对上述原因,我们可以对规则进行改进,即当检测到Content-Type为text/xml,临时更改请求体的解析器,如下方规则所示:

SecRule REQUEST_HEADERS:Content-Type "^text/xml$" "chain,phase:2,id:106,log,t:lowercase,deny,ctl:requestBodyProcessor=XML"
SecRule XML:/methodCall/methodName/text() "wp.getusersblogs" "t:lowercase"

上述规则表示,当检测到Content-Type为text/xml,临时更改请求体的解析器,同时判断/methodCall/methodName的节点数据是否为wp.getusersblogs,如果是的话,则拦截此次访问。请注意,lowercase只是将要判断的目标数据转化为小写,XML节点的名称应跟源数据保持一致,即区分大小写。


如果要判断XML数据中是否包含指定的节点,可使用以下规则:

SecRule REQUEST_HEADERS:Content-Type "^text/xml$" "chain,phase:2,id:107,log,t:lowercase,deny,ctl:requestBodyProcessor=XML"
SecRule &XML:/methodCall/methodName "@gt 0"

上述规则表示,当检测到Content-Type为text/xml,临时更改请求体的解析器,同时判断methodCall节点下是否存在methodName节点,如果存在,则拦截此次访问。

版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。