Palo Alto防火墙远程代码执行漏洞分析

近期,Palo Alto Networks多个防火墙产品被曝存在未授权远程代码执行漏洞(CVE-2017-15944 ),该漏洞基于其它三个单独漏洞的综合利用,可以通过Web管理端对Palo Alto Networks防火墙实现root身份的未授权远程代码执行攻击。本文中,我们来简单分析一下该漏洞的具体成因。

该漏洞影响范围

受影响的Palo Alto 防火墙版本如下:

目前,Palo Alto Networks已经修复了该漏洞,请及时到Palo Alto 官网下载PAN-OS6.1.19、PAN-OS 7.0.19 PAN-OS 7.1.14、PAN-OS 8.0.6 的更新版本。Palo Alto Networks建议客户采取隔离或其它安全措施,限制Web管理接口网络访问权限,避免攻击者通过Project Sonar 或 Shodan探测到防火墙WAN端口实施攻击。

漏洞分析

漏洞 #1:部分授权验证功能可绕过

文件`/etc/appweb3/conf/common.conf`中包含了Web管理控制接口的配置内容,它针对大多子目录利用以下方式设置了一个验证过滤器:

也就是说,所有对/php/*相关目录的请求都会被检查其中的授权会话cookie,具体检查动作由`libpanApiWgetFilter.so`库文件执行。

其中,函数`openAuthFilter()` 将对PHPSESSID cookie执行检查,然后调用会话文件中的`readSessionVarsFromFile()`函数以提取其中的 `dloc`和 `user`值。问题在于`readSessionVarsFromFile()`函数并不是使用正式的PHP功能去读取序列化的会话数据,而是使用了内置存在运行问题的`strtok()`方法解析器来读取。

`readSessionVarsFromFile()`尝试解析的PHP会话格式看起来像这样的字符串值:

ocale|s:2:”en”;

语法注释:

var_name|s:str_length:”string value”; var_name|s:str_length:”another string”;…

如果我们向包含`”;`字符的会话文件中注入一个数值,就能截断解析器从而执行我们自己设置的 `user`变量值。另外,文件`panmodule.so`会把`dloc` GET参数用”:”进行分割,并把`dloc` 和 `loc`会话变量赋第二个值,因此,我们可以通过调用不需任何验证授权的脚本`/esp/cms_changeDeviceContext.esp` ,然后利用它去请求文件`panmodule.so`中的 `panUserSetDeviceLocation()函数。

我们由此可利用以下请求方式来混淆破坏会话文件:

`/esp/cms_changeDeviceContext.esp?device=aaaaa:a%27″;user|s.”1337″;`

之后,它会在 `/tmp/sess_`中产生以下内容:

`dloc|s:20:”8:a’”;user|s.”1337″;”;loc|s:27:”16:a’”;user|s.”1337″;:vsys1″;`

当`readSessionVarsFromFile()`对其进行解析时,会把`16:a’`当成`user`变量值处理。由于这种方式会被后端XML请求应用去检查用户是否被验证授权,但在检查过程中会产生一个XML注入,从而导致一种无效的XML文件,如:

额外的单引号字符被注入到cookie值中后,由于解析错误会引起请求失败,然后有意思的是,文件`libpanApiWgetFilter.so`中的`panCheckSessionExpired()`函数却不会发现这种状态,并错误地认为验证授权已成功通过。由此,我们可以控制会话cookie对panAuthCheck指令保护的任意PHP文件实现访问控制,POC:

需要注意的是,这样之后我们并未获取到一个有效可登录的会话session,而且大多PHP脚本请求也会失败,但却能绕过Web服务器端的验证授权功能。

漏洞 #2:任意目录创建

`/php/utils/router.php`文件负责对Web管理接口的后端通信API请求进行处理,在该文件中泄露了多个PHP类,这些类中包含了利用HTTP POST/JSON方式请求Web管理接口的一种简单远程调用。

`/php/device/Administrator.php`文件声明了`Administrator`类,其中还包含了名为`get`且可从`router.php`中调用的方法函数。在该`get`方法对`Direct::getConfigByXpath`的调用中,存在一处XML注入,即附加到请求中的参数 `jsonArgs->id`不会被执行任何过滤检查,这就能使我们对发送到后端的XML请求进行操纵控制。

正常请求是这样的:

在此基础上,我们能向 `obj` 属性注入我们自设的数值, 从而实现控制其它所有的XML请求。

另外,文件`libpanmp_mp.so` 中的`pan_cfg_req_ctxt_construct()` 函数负责对后端的XML请求进行解析,如果我们发送一个具有`async-mode =’yes’`属性集的请求标签,后端会在请求输出的文件`/opt/pancfg/session/pan/user_tmp//.xml`中,创建一个临时文件和父目录。由此,我们可以控制创建部分目录结构的 ``值, 结合目录遍历攻击在系统中任意地方创建任意名称目录。

例如,通过发送以下特定的POST请求来创建目录:

当服务器后端接收到以下XML请求后,就会执行`/tmp/hacked`目录创建操作:

漏洞 #3:Cron脚本中的命令注入

文件`/usr/local/bin/genindex_batch.sh`为每隔15分钟定时执行的Cron脚本,该脚本功能为转而执行`/usr/local/bin/genindex.sh`,生成对数据库文件 `/opt/pancfg/mgmt/logdb/`的索引。在该脚本执行文件名称的处理过程中,存在一处命令注入漏洞:

由于我们能在 `$PAN_BASE_DIR/logdb/$dir/1`中创建目录,所以能更改第一次 `find`命令的输出内容,该输出内容会作为第二次 `find`命令执行时的一个参数,但却没有闭合引号,因此,我们可以在该调用中注入任意参数,在`-exec`选项值传递到`find`命令中时,可以在其中执行任意系统命令。

Exploit执行示例

我的exploit创建目录为:

`* -print -exec python -c exec(“[base64 code..]“.decode(“base64″)) ;`

其中,base64编码的python代码会被以root权限执行,在`/var/appweb/htdocs/api/c.php`中创建一个小马,同时能在‘usr/bin/x’目录下以root权限隐蔽执行。

  • 发表于:
  • 原文链接:http://kuaibao.qq.com/s/20171225B0KU4Z00?refer=cp_1026

同媒体快讯

相关快讯

扫码关注云+社区