WordPress WP-Statistics插件存储型XSS漏洞分析

2019-09-30 约 150 字 预计阅读 1 分钟

声明:本文 【WordPress WP-Statistics插件存储型XSS漏洞分析】 由作者 熊本熊本熊 于 2019-09-30 09:15:00 首发 先知社区 曾经 浏览数 729 次

感谢 熊本熊本熊 的辛苦付出!

写在翻译稿前面

最近,笔者在研究一些与WordPress漏洞相关内容。Sucuri、RIPS、Fortinet等安全公司对WordPress有着一系列的深入研究,因此笔者计划陆续将一些有意思文章翻译出来,与大家共同学习下,祝君多挖漏洞。

这篇文章是来自Sucuri Labs,本文介绍了强大的 WordPress 统计分析插件 WP Statistics的一个xss漏洞以及与防火墙的组合利用,文中括号加粗的是我自己分析这个原稿的一些见解,大家可以在评论里一起讨论下。

下面翻译稿正文开始

风险评级:次要:可用于有针对性攻击,但需要特定配置后利用。

漏洞名称:存储型XSS漏洞

修复版本: 12.6.7

WordPress插件WP Statistics具有50万用户的活动安装基础,在12.6.7之前的版本上存在未经身份验证的存储XSS漏洞。

此漏洞只能在某些配置下使用 - 默认设置不易受到攻击。

时间线

· 2019/06/26 - 初步与开发人员取得联系。

· 2019/06/27 - 开发人员回应,披露漏洞。

· 2019/06/30 - 拟议审核补丁。

· 2019/07/01 - 版本12.6.7发布,修复漏洞。

通过IP操作存储型XSS漏洞

在该插件某些配置情况下,网站可以使用header来查找访问者的IP。

在使用防火墙的环境中,经常会需要这样的方式(译者注:使用header来查找访问者的IP),否则所有访问者都会拥代理的IP而不是自己的IP。

为什么使用防火墙需要使用Header

默认情况下,网站可以轻松找到访问用户的IP地址。并且找到的一定是发起请求User的IP,如下图所示:

请求访问没有防火墙的网站

当使用网站防火墙时,事情就会变得有些棘手;要么优化我们的性能,要么保护我们自己免受攻击。

由于用户的请求在到达网站前,已经通过了防火墙,因此网站无法利用连接地址来找出实际发起请求的IP。

忽略原始用户IP,使用防火墙代理发起访问请求

为了解决这种情况,防火墙通常会在HTTP header中自动添加用户原始IP。

防火墙会转送请求访问的原始用户IP

这使得网站能够正确识别原始用户以及其相应的IP。

多层防火墙

当攻击者自己构造forwarded IP(即使这个IP并不存在)时,可能会使服务器弄错原始IP。(译者注:这里的意思是,攻击者在自己发出的原始报文中,加入了一个forwarded IP,例如下图中,加入一个Forwarded: 123,当最终website读取用户IP时,会误认为123是原始IP,即使123可能不存在)使用多层防火墙时也会有这种情况出现,因为每一层都会在现有的基础上再添加一个IP地址。

这完全取决于防火墙的配置方式,以及它如何处理现有的转送数据。

用户发送一个forwarded IP,混淆服务器

大多数防火墙都会将用户的真实IP加入HTTP header自定义字段里,例如X_SUCURI_CLIENTIP(译者注:SUCURI是这篇文章的公司的名字,这个字段是他家防火墙header里的存放用户的真实IP的自定义字段)

此HTTP header里始终含有用户原始IP信息,因为它应该永远不会存在于防火墙之外的环境里。因此,即使存在也会被被覆盖(译者注:即使攻击者在自己的报文里构造了X_SUCURI_CLIENTIP,在被SUCURI防火墙转发时,这个值也会被覆盖掉)

在您有多个代理的情况下,您可能希望获取用户真实IP,而不是最后进行连接的IP。在这种情况下,您可以使用可包含多个IP地址的X-forwarded-for

如果X-forwarded-for在连接防火墙之前已具有IP值,则将执行以下某一项操作:

· 将用户的IP附加到任意现有IP列表中。

· 保持原样; 不添加或替换值。

· 清除header; 删除所有值。

· 使用用户的IP覆盖header。

这些结果可能取决于所使用的防火墙和它的配置的不同而不同,最终保证多级防火墙来正确地发送所述用户信息给服务器。

漏洞分析

该插件的漏洞是由于不过滤或验证用户IP所产生的。

只有当插件使用header来识别访问者的IP地址(例如,不是REMOTE_ADDR)时,才能触发利用:

插件的设置页面:使用X_Forwarded_For来获取IP

该漏洞利用触发还必须满足以下两个条件之一:

· 防火墙必须是可绕过的

这意味着必须将网站配置为接受来自于所有人的连接,而不仅仅是接受使用防火墙端口转发的连接。

(译者注:这里作者“防火墙必须是可绕过”的意思是,攻击者的请求,可以不经过防火墙,直接发送至wordpress站点)

或者

· 防火墙必须原样保留header,如果其存在的话。

防火墙转发访问请求时保持forwarded IP不变

以上两个利用条件的共同点是forwarded值完全由攻击者控制。

启用WAF使您不会容轻易遭受攻击(请参阅此处以获取有关如何防止防火墙被绕过的说明),除非攻击者可以绕过WAF;或者防火墙被配置为保持IP不变。

如果您以前使用过WAF,但是在未更新插件设置的情况下停止运行,则可能会受到攻击。

由于header可以包含多个IP地址,具体取决于防火墙的数量及其配置,因此插件将首先取出完整的header IP列表值,然后在提供多个地址的情况下遍历IP列表,依次向右边的寻找并将IP值替换为有效地址(译者注:原理可以看下面那个代码段的图)

在这两种易受攻击的配置中, IP变量完全由攻击者控制。这使得他们可以将恶意JavaScript代码作为自己的IP注入,并将这些代码存储在管理页面上并执行。

技术细节

该插件使用class-wp-statistics.php文件中的get_IP方法。

IP变量的默认值为设置中提供的header,默认情况下为REMOTE_ADDR(译者注:默认配置情况下不存在漏洞,具体配置见上文插件的设置页面)。如果有多个以逗号分隔的IP地址,则该插件将使用最后一个有效的IP地址

由于IP地址的默认值是header的值,并且未使用FILTER_VALIDATE_IP方法进行清理或验证,因此当header中没有多个IP地址时,它将按原样存储。

在top visitor,online users与最近访问者等模块中,访问者IP将作为页面的一部分输出,它是插件渲染页面的一部分。

(译者注:我对于上述的理解是,插件设置页面提供了一个用户自己选择获取ip的方式”the items below return the ip address that is different on each server. Is the best way that you choose”,如果用户选的是X_Forwarded_For方式,$user_ip里获得的是X_Forwarded_For中的值,攻击者在X_Forwarded_For中传入xss payload,由于不是合法的ip格式,在foreach里的filter_var结果为false,因此不会进入if中执行$user_ip=$ip语句,$user_ip中值仍然是xss payload,最终,在代码最后一个else中赋值给$this->ip并return)

结论

某种类型的信息看起来可能是安全的(像是访问者的IP地址),但实际上与预期相悖。由于开发人员的某些臆断,使得攻击者可以在在管理页面上注入恶意代码,从而导致整个网络瘫痪。

为了不受此漏洞影响,我们强烈建议用户尽快将插件更新到12.6.7版。

原文地址https://blog.sucuri.net/2019/07/wordpress-plugin-wp-statistics-unauthenticated-stored-xss-under-certain-configurations.html

写在翻译稿后面

我跟踪了下wp-statistics的修复

使用esc_html对获取到的IP进行过滤

虽然现在仍然可以在header里传payload,但是由于esc_html的转义,到页面渲染的时候,payload已经失效,流程见下图

关键词:[‘安全技术’, ‘漏洞分析’]


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