看我如何再一次骇进Facebook,一个在MobileIron MDM 上的远端程式码执行漏洞!

  • A+
所属分类:安全新闻

本文转载自https://devco.re/blog/2020/09/12/how-I-hacked-Facebook-again-unauthenticated-RCE-on-MobileIron-MDM/

原文作者:orange

看我如何再一次骇进FACEBOOK,一个在MOBILEIRON MDM 上的远端程式码执行漏洞!

嗨! 好久不见,这是我在今年年初的研究,讲述如何寻找一款知名行动装置管理产品的漏洞,并绕过层层保护取得远端程式码执行的故事! 其中的漏洞经回报后在六月由官方释出修补程式并紧急通知他们的客户,而我们也在修补程式释出15 天后发现Facebook 并未及时更新,因此透过漏洞取得伺服器权限并回报给Facebook!

此份研究同时发表于HITCON 2020,你可以从这里取得这次演讲的投影片!


身为一个专业的红队,我们一直在寻找着更快速可以从外部进入企业内网的最佳途径!如同我们去年在Black Hat USA发表的研究,SSL VPN理所当然会放在外部网路,成为保护着网路安全、使员工进入内部网路的基础设施,而当你所信任、并且用来保护你安全的设备不再安全了,你该怎么办?


什么是MDM/UEM ?

Mobile Device Management,简称MDM,约是在2012年间,个人手机、平板装置开始兴起时,为了使企业更好的管理员工的BYOD装置,应运而生的资产盘点系统,企业可以透过MDM产品,管理员工的行动装置,确保装置只在信任的环境、政策下运行,也可以从中心的端点伺服器,针对所控制的手机,部署应用程式、安装凭证甚至远端操控以管理企业资产,更可以在装置遗失时,透过MDM远端上锁,或是抹除整台装置资料达到企业隐私不外漏的目的!

UEM (Unified Endpoint Management) 则为近几年来更新的一个术语,其核心皆为行动装置的管理,只是UEM 一词包含更广的装置定义! 我们以下皆用MDM 一词来代指同类产品。

我们的目标

MDM 作为一个中心化的端点控制系统,可以控制、并管理旗下所有员工个人装置! 对日益壮大的企业来说,绝对是一个最佳的资产盘点产品,相对的,对骇客来说也是!而为了管理来自世界各地的员工装置连线,MDM 又势必得曝露在外网。一个可以「管理员工装置」又「放置在外网」的设备,这对我们的红队演练来说无疑是最棒的渗透管道!

另外,从这几年的安全趋势也不难发现MDM逐渐成为骇客、APT组织的首选目标!诱使受害者同意恶意的MDM成为你装置的C&C伺服器,或是干脆入侵企业放置在外网的MDM设备,在批次地派送行动装置木马感染所有企业员工手机、电脑,以达到进一步的攻击!这些都已成真,详细的报告可参阅Cisco Talos团队所发表的Malicious MDM: Let's Hide This App以及CheckPoint CPR团队所发表的First seen in the wild - Malware uses Corporate MDM as attack vector !

从前面的几个案例我们得知MDM 对于企业安全来说,是一个很好的切入点,因此我们开始研究相关的攻击面! 而市面上MDM 厂商有非常多,各个大厂如Microsoft、IBM 甚至Apple 都有推出自己的MDM 产品,我们要挑选哪个开始成为我们的研究对象呢?

因此我们透过公开情报列举了市面上常见的MDM产品,并配合各家特征对全世界进行了一次扫描,发现最多企业使用的MDM为VMware AirWatch与MobileIron这两套产品!至于要挑哪一家研究呢?我们选择了后者,除了考量到大部分的客户都是使用MobileIron外,另外一个吸引我的点则是Facebook也是他们的客户!从我们在2016年发表的How I Hacked Facebook, and Found Someone's Backdoor Script研究中,就已发现Facebook使用MobileIron作为他们的MDM解决方案!

根据MobileIron官方网站描述,至少有20000+的企业使用MobileIron当成他们的MDM解决方案,而根据我们实际对全世界的扫描,也至少有15%以上的财富世界500大企业使用MobileIron且曝露在外网 (实际上一定更多),因此,寻找MobileIron的漏洞也就变成我们的首要目标!

如何开始研究

过往出现过的漏洞可以得知MobileIron并没有受到太多安全人员研究,其中原因除了MDM这个攻击向量尚未广为人知外,另一个可能是因为关于MobileIron的相关韧体太难取得,研究一款设备最大的问题是如何从纯粹的黑箱,到可以分析的灰箱、甚至白箱!由于无法从官网下载韧体,我们花费了好几天尝试着各种关键字在网路上寻找可利用的公开资讯,最后才在Goolge Search索引到的其中一个公开网站根目录上发现疑似是开发商测试用的RPM包。

看我如何再一次骇进Facebook,一个在MobileIron MDM 上的远端程式码执行漏洞!

下载回的为2018 年初的版本,离现在也有很长一段时间,也许核心程式码也大改过,不过总比什么都没有好,因此我们就从这份档案开始研究起。

备注: 经通知MobileIron 官方后,此开发商网站已关闭。

如何寻找漏洞

整个MobileIron 使用Java 作为主要开发语言,对外开放的连接埠为443, 8443, 9997,各个连接埠对应功能如下:

  • 443 为使用者装置注册介面

  • 8443 为设备管理介面

  • 9997 为一个MobileIron 私有的装置同步协定(MI Protocol)

三个连接埠皆透过TLS 保护连线的安全性及完整性,网页部分则是透过Apache 的Reverse Proxy 架构将连线导至后方,由Tomcat 部署的网页应用处理,网页应用则由Spring MVC 开发。

看我如何再一次骇进Facebook,一个在MobileIron MDM 上的远端程式码执行漏洞!

由于使用的技术架构相对新,传统类型的漏洞如SQL Injection 也较难从单一的点来发现,因此理解程式逻辑并配合架构层面的攻击就变成我们这次寻找漏洞的主要目标!

这次的漏洞也很简单,主要是Web Service 使用了Hessian 格式处理资料进而产生了反序列化的弱点! 虽然漏洞一句话就可以解释完了,但懂的人才知道反序列化并不代表你可以做任何事,接下来的利用才是精彩的地方!

现在已知MobileIron 在处理Web Service 的地方存在Hessian 反序列化漏洞! 但漏洞存在,并不代表我们碰得到漏洞,可以触发Hessian 反序列化的路径分别在:

  • 一般使用者介面 - https://mobileiron/mifs/services/

  • 管理介面 - https://mobileiron:8443/mifs/services/

    管理介面基本上没有任何阻挡,可以轻松的碰到Web Service,而一般使用者介面的Web Service 则无法存取,这对我们来说是一个致命性的打击,由于大部分企业的网路架构并不会将管理介面的连接埠开放在外部网路,因此只能攻击管理介面对于的利用程度并不大,因此我们必须寻找其他的方式去触发这个漏洞!

    仔细观察MobileIron 的阻挡方式,发现它是透过在Apache 上使用Rewrite Rules 去阻挡对一般使用者介面Web Service 的存取:

    RewriteRule ^/mifs/services/(.*)$ https://%{SERVER_NAME}:8443/mifs/services/$1 [R=307,L]
    RewriteRule ^/mifs/services [F]

嗯,很棒! 使用Reverse Proxy 架构而且是在前面那层做阻挡,你是否想到什么呢?

没错!就是我们在2015年发现,并且在Black Hat USA 2018上所发表的针对Reverse Proxy架构的新攻击面Breaking Parser Logic !这个优秀的技巧最近也被很好的利用在CVE-2020-5902,F5 BIG-IP TMUI的远端程式码执行上!

https://mobileiron/mifs/.;/services/someService


如何利用漏洞

现在让我们回到Hessian反序列化的利用上!针对Hessian反序列化,Moritz Bechler已经在他的Java Unmarshaller Security中做了一个很详细的研究报告!从他所开源的marshalsec原始码中,我们也学习到Hessian在反序列化过程中除了透过HashMap触发equals()以及hashcode()等触发点外,也可透过XString串出toString(),而目前关于Hessian反序列化已存在的利用链有四条:

  • Apache XBean

  • Caucho Resin

  • Spring AOP

  • ROME EqualsBean/ToStringBean

而根据我们的目标环境,可以触发的只有Spring AOP 这条利用链!

看我如何再一次骇进Facebook,一个在MobileIron MDM 上的远端程式码执行漏洞!

无论如何,我们现在有了JNDI注入后,接下来只要透过Alvaro MuñozOleksandr Mirosh在Black Hat USA 2016上所发表的A Journey From JNDI/LDAP to Remote Code Execution Dream Land就可以取得远端程式码执行了…甘安内?

看我如何再一次骇进Facebook,一个在MobileIron MDM 上的远端程式码执行漏洞!


自从Alvaro MuñozOleksandr Mirosh在Black Hat发表了这个新的攻击向量后,不知道帮助了多少大大小小的骇客,甚至会有人认为「遇到反序列化就用JNDI送就对了!」,但自从2018年十月,Java终于把关于JNDI注入的最后一块拼图给修复,这个修复被记载在CVE-2018-3149中,自此之后,所有Java高于8u181, 7u191, 6u201的版本皆无法透过JNDI/LDAP的方式执行程式码,因此若要在最新版本的MobileIron上实现攻击,我们势必得面对这个问题!


关于CVE-2018-3149,是透过将com.sun.jndi.ldap.object.trustURLCodebase的预设值改为False的方式以达到禁止攻击者下载远端Bytecode取得执行程式码。

但幸运的是,我们依然可以透过JNDI的Naming Reference到本机既有的Class Factory上!透过类似Return-Oriented Programming的概念,寻找本机ClassPath中可利用的类别去做更进一步的利用,详细的手法可参考由Michael Stepankin在2019年年初所发表的Exploiting JNDI Injections in Java,里面详细叙述了如何透过Tomcat的BeanFactory去载入ELProcessor达成任意程式码执行!

这条路看似通畅,但实际上却差那么一点,由于ELProcessor在Tomcat 8后才被引入,因此上面的绕过方式只能在Tomcat版本大于8后的某个版本才能成功,而我们的目标则是Tomcat 7.x,因此得为BeanFactory寻找一个新的利用链!而经过搜寻,发现在Welkin文章中所提到:

除了javax.el.ELProcessor,当然也还有很多其他的类符合条件可以作为beanClass注入到BeanFactory中实现利用。举个例子,如果目标机器classpath中有groovy的库,则可以结合之前Orange师傅发过的Jenkins的漏洞实现利用

目标的ClassPath 上刚好有Groovy 存在! 于是我们又让Meta Programming 伟大了一次:D

然而事实上,目标伺服器上Groovy版本为1.5.6,是一个距今十年前老旧到不支援Meta Programming的版本,所以我们最后还是基于Groovy的程式码,重新寻找了一个在GroovyShell上的利用链!详细的利用链可参考我送给JNDI-Injection-Bypass的这个Pull Request !

攻击FACEBOOK

现在我们已经有了一个基于JNDI+ BeanFactory+ GroovyShell的完美远端程式码执行漏洞,接下来就开始攻击Facebook吧!从前文提到,我们在2016年时就已知Facebook使用MobileIron当作他们的MDM解决方案,虽然现在再检查一次发现首页直接变成403 Forbidden了,不过幸运的是Web Service层并无阻挡!

看我如何再一次骇进Facebook,一个在MobileIron MDM 上的远端程式码执行漏洞!

万事俱备,只欠东风!正当要攻击Facebook的前几天,我们突然想到,从上次进入Facebook伺服器的经验,由于安全上的考量,Facebook似乎会禁止所有对外部非法的连线,这点对我们JNDI注入攻击有着至关重要的影响!首先,JNDI注入的核心就是透过受害者连线至攻击者控制的恶意伺服器,并接收回传的恶意Naming Reference后所导致的一系列利用,但现在连最开始的连线到攻击者的恶意伺服器都无法,更别谈后续的利用。

看我如何再一次骇进Facebook,一个在MobileIron MDM 上的远端程式码执行漏洞!

自此,我们关于JNDI 注入的路已全被封杀,只能回到Hessian 反序列化重新思考! 而现有的利用链皆无法达到远端程式码执行,所以我们势必得抛弃JNDI 注入,寻找一个新的利用链!

看我如何再一次骇进Facebook,一个在MobileIron MDM 上的远端程式码执行漏洞!


为了寻找新的利用链,必须先深入理解已存在利用链的原理及成因,在重读Java Unmarshaller Security的论文后,我对其中一句话感到了好奇:

Cannot restore Groovy's MethodClosure as readResolve() is called which throws an exception.

哦,为什么作者要特地补上这句话呢? 我开始有个猜想:

作者评估过把Groovy 当成利用链的可行性,虽然被限制住了,但一定觉得有机会才会写进论文中!


从这个猜想出发,虽然Groovy的利用链被readResolve()限制住了,但刚好我们目标版本的Groovy很旧,说不定尚未把这个限制加入程式库!

我们比较了一下Groovy-1.5.6与最新版本位于groovy/runtime/MethodClosure.java中的readSolve()实现:

$ diff 1_5_6/MethodClosure.java 3_0_4/MethodClosure.java

>     private Object readResolve() {
>         if (ALLOW_RESOLVE) {
>             return this;
>         }
>         throw new UnsupportedOperationException();
>     }

可以看到的确在旧版是没有ALLOW_RESOLVE限制的,而后来经过考古后也发现,这个限制其实Groovy自己为了因应2015年所出现Java反序列化漏洞的减缓措施,因此也被分配了CVE-2015-3253这个漏洞编号!由于Groovy只是一个只在内部使用、不会对外的小配角,因此在没有特别需求下开发者也不会特地去更新它,因此成为了我们攻击链的一环!这也再一次验证了「任何看似举无轻重的小元件,都有可能成为你被攻击的主因」!



最后,当然! 我们成功的取得在Facebook 伺服器上的Shell,以下是影片:

漏洞通报与修复

我们约在三月时完成整个漏洞研究,并在4/3日将研究成果写成报告,透过[email protected]回报给MobileIron!官方收到后着手开始修复,在6/15释出修补程式并记录了三个CVE编号,详细的修复方式请参阅MobileIron官方网站 !

  • CVE-2020-15505 - Remote Code Execution

  • CVE-2020-15506 - Authentication Bypass

  • CVE-2020-15507 - Arbitrary File Reading

当官方释出修补程式后,我们也开始监控世界上所有有使用MobileIron企业的修复状况,这里只单纯检查静态档案的Last-ModifiedHeader,结果仅供参考不完全代表实际情况(Unknown代表未开443/8443无法利用):

看我如何再一次骇进Facebook,一个在MobileIron MDM 上的远端程式码执行漏洞!

与此同时,我们也持续监控着Facebook,并在15 天确认都未修补后于7/2 日成功进入Facebook 伺服器后回报Facebook Bug Bounty Program!

结语

到此,我们已经成功示范了如何寻找一个MDM 伺服器的漏洞! 从绕过Java 语言层级的保护、网路限制,到写出攻击程式并成功的利用在Bug Bounty Program 上! 因为文长,还有许多来不及分享的故事,这里仅条列一下供有兴趣继续研究的人参考!

  • 如何从MDM 伺服器,控制回员工的手机装置

  • 如何分析MobileIron 的私有MI Protocol

  • CVE-2020-15506 本质上其实是一个很有趣的认证绕过漏洞

希望这篇文章能够唤起大众对于MDM 攻击面的注意,以及企业安全的重要性! 感谢收看:D

I am Orange : )



发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: