导语:在本文中,我将向你展示如何在两款趋势科技产品远程执行代码,由于它们都使用了相同的代码库。这些漏洞包括包括认证命令注入、泄露私钥、公开访问Sqlite3、SSRF。
在本文中,我将向你展示如何在两款趋势科技产品远程执行代码,由于它们都使用了相同的代码库。这些漏洞包括包括认证命令注入、泄露私钥、公开访问Sqlite3、SSRF。
框架的安全性一直是研究人员的重点研究对象,还记得2016年Apache Struts2高危远程代码执行漏洞吗?由于Apache Struts 2是世界上最流行的Java Web服务器框架之一,该漏洞几乎影响了所有struts产品。由于趋势科技的不同产品使用的代码库都是相同的,所以在本文中,我将向你展示如何在不同的趋势科技产品上获得远程命令执行漏洞。
一处漏洞便千疮百孔,以趋势科技产品的小部件(widgets)为例
小部件(Widgets)就是指各种千奇百怪的小应用程序。在软件行业代表自包含的代码包,它可以用来建立大部分现代流行的图形用户接口,widgets是任何用SWT建立的程序的基础。SWT被称为所谓的标准窗口部件(Standard Widget Toolkit)。简而言之,Widgets和app的区别就是,app是应用程序,而Widgets是一些桌面的小插件,比如说某些音乐播放应用,放到桌面去得那部分。
大多数趋势科技的产品都有管理员页面的小部件,虽然它们都是使用Java/.NET编写的核心系统,但是目前,这个小部件机制已经用PHP实现了。这意味着,无论管理员何时使用小部件,他们都需要用到PHP解释器(PHP interpreter)。也就是从理论上来说,所有小部件使用的代码库都是相同的,只要在PHP解释器上发现一处漏洞,那这个漏洞即适用于所有的使用该代码库的产品。
基于上面的理论假设,我对趋势科技的Micro OfficeScan(一款防毒软件)的小部件系统执行了代码审核。结果不出意外,我发现6个不同的漏洞,其中2个是零日漏洞。
不过在介绍漏洞之前,我想分享一下这个小部件库的工作原理。
小部件库的工作原理
这个小部件框架有一个代理机制,简而言之,就是利用proxy_controller.php端点接收用户提供的参数,然后根据输入调用相关类。
小部件主要分为两类:用户生成的小部件以及默认的小部件。以下源代码就是来自proxy_controller.php文件。
上述代码块分别会执行以下5个操作:
1.合并GET和POST参数,然后将它们存储在$g_GetPost变量中。 2.验证$ g_GetPost ['module']变量。 3.然后通过查看$g_GetPost[‘userGenerated’]参数来决定所请求的窗口小部件是否由用户生成。 4.包含所需的php类。 5.创建一个WFProxy实例,然后调用proxy_exec()和proxy_output()方法。
实现WFProxy的方法有多种,至于采用哪种,还要取决于客户端的值。
在了解了小部件库的工作原理后,我就可以介绍所发现的漏洞的了。
漏洞1:通过身份验证的命令注入
以下代码从modTMCSS的WFProxy实现中提取的:
很明显,在以上代码中可以看到有命令注入的痕迹。虽然我已经发现了该痕迹,但我还是要确定这些命令是否可以控制$this->cgiArgs数组(array)?经过分析,是可以控制的。如果你回到我以前本文的第一个代码blob,你就会看到$request = new WFProxy($g_GetPost, $wfconf_dbconfig); 是完全可以控制的。
每一个WFProxy类都扩展了ABaseProxy抽象类,下面是基类的__construct方法的前两行。。
这意味着,$this->cgiArgs可以直接由GET和POST参数填充。
PoC
在此我要提醒的是,当exec()函数用于第二和第三个函数参数时,如果要使用pipe trick,则只需要成功执行第一个命令。我使用的命令是php ../php/lwcs_report.php TOP=2>&1|ping 4.4.4.4。由于产品中甚至没有用到lwsc_report.php脚本,所以使用2>&1可以愚弄exec() 函数,这也就意味着我在第一个返回命令中还是没有发现漏洞。
不过,我没有发现并不代表它就没有漏洞,这不漏洞还是由Source Incite的研究员Steven Seeley发现了,就在几周前,供应商已经发布了该漏洞的补丁。根据该网站的描述,攻击者需要进行身份验证才能利用此漏洞。不过目前我已找到了一种方法来绕过身份验证,具体办法我会在下面的第6个漏洞中讲到。
漏洞2至漏洞4:泄露私钥以及可以公开访问的Sqlite3和SSRF
这些漏洞也是被另一位研究人员发现(John Page又名hyp3rlinx)。不过这些漏洞与本文的论述无关,我只给一个链接,如果感兴趣你可以仔细阅读。
漏洞5:服务器端请求伪造漏洞(零日漏洞)
小部件主要分为两类:用户生成的小部件以及默认的小部件,趋势科技在代码库中有一个默认用户生成的小部件实现,并把它命名为” modSimple”。我相信趋势科技的开发者会在项目中留下它,以便展示自定义小部件实现的方法。
以下是这个小部件的proxy_exec()函数实现:
它直接使用url参数,无需验证。由上面代码看出,$this->cgiArgs['url']是用户控制的变量。
PoC
漏洞6:绕过认证旁路(零日漏洞)
上面我提到过核心系统是用Java/.NET编写的,但是这个小部件系统是用PHP实现的。所以最大的问题是:当请求发送至小部件时,它们是如何知道知道用户是经过身份验证的?
要回答这个问题,最简单的方法是跟踪从登录到使用小部件的视图仪表板的Burp日志。特别是下面的HTTP POST请求,引起了我的注意。
下面的代码就是从该文件中截取的:
首先,我会进行CSRF验证,请看17-23行之间的进程状态。$wfuser->standalone_user_init() and $wfuser->product_user_init()负责使用小部件框架对用户进行身份验证。我会从第一个调用开始。
下面会有4个内部函数调用序列:
上述代码块会分别执行以下4个操作:
1.获取cookie值。 2.调用loaduser_byuid()并将cookie值发送给此函数。 3.用获取的值调用get_users()函数,如果此函数返回为true,则它本身就为true,,这将帮助前面的函数继续调用recover_session()函数。 4.get_users()函数只使用给定的id执行sql查询。
$wfuser-> product_user_init()函数序列几乎相同,$wfuser->standalone_user_init()和$wfuser->product_user_init()之间的区别就是$wfuser->product_user_init()首先使用了使用user_id用户名。
不过我并没有在以上代码中看到认证,甚至连hash参数没有看到,因此可以猜测所有的身份验证都是使用的相同的变量来调用该端点。这意味着,只需一个漏洞便可将整个验证过程摧毁。
截至目前,我总共发现了两个漏洞。第一个是最近修补过的命令注入漏洞,第二个是绕过身份验证的漏洞,该漏洞只存在于小部件系统且属于零日漏洞。这样,我便可以利用该漏洞在没有任何凭证的情况下执行操作系统命令,点此查看metasploit的模块演示。
相同的代码或漏洞也存在于趋势科技的InterScan Messaging Security产品中,这也就意味着InterScan Messaging Security也存在远程命令执行漏洞。
不过Micro InterScan Messaging Security和Micro OfficeScan在小部件框架方面还是有区别的,区别之一就是路径。
OfficeScan小部件的框架路径如下:
https://TARGET/officescan/console/html/widget/proxy_controller.php
InterScan Messaging Security小部件的框架路径如下:
https://TARGET:8445/widget/proxy_controller.php
另一个主要区别就是关于小部件的验证,InterScan Messaging Security是通过talker.php进行验证的。
可以看到,它需要用户的JSESSIONID值,并使用它将HTTP请求发送到WFSessionCheck,从而使用核心Java应用程序对用户身份进行验证。这看起来像是阻止我进行认证绕过,但实际上不是。仔细看看上面的代码。如果JSESSIONID存在于请求中,那你一定能看到mydebug_log()函数调用JSESSIONID。
该日志文件可公开访问,访问地址如下:
https://12.0.0.201:8445/widget/repository/log/diagnostic.log
接下来我只需读取这个日志文件的内容,以提取有效的JSESSIONID值,然后使用它进行身份验证,点此查看metasploit的模块演示。
总结
首先,我要强调的是,这个命令注入漏洞已被趋势科技进行了修复,目前相关的补丁已经发布,如果你是趋势科技用户建议尽快升级修复漏洞。
客观的讲,在不同的产品上拥有相同的代码并不是什么坏事。我只是想通过本文指出,这种做法的弊端就是如果出现一个漏洞,便会让全部使用该框架的产品都受到威胁。
那除了这两个产品之外,是否还有其它产品也受到这个漏洞的威胁?如果有我会及时进行公开,请大家持续关注后续分析。