【技术干货】F5BIG-IPAPIUnauthenticatedRCE(CVE-2022-1388)分析

xxhzz@PortalLab实验室

漏洞描述

F5官网发布安全公告,披露F5 BIG-IP存在一处远程代码执行漏洞(CVE-2022-1388)。漏洞存在于iControl REST组件中,该漏洞允许定义身份验证的攻击者通过 BIG-IP 管理界面和自身IP地址对 iControl REST API 接口进行网络访问,进而导致可以在目标主机上执行任意系统命令、创建或删除文件或禁用BIG-IP上的服务。

利用范围

BIG-IP 16.x: 16.1.0 - 16.1.2

BIG-IP 15.x: 15.1.0 - 15.1.5

BIG-IP 14.x: 14.1.0 - 14.1.4

BIG-IP 13.x: 13.1.0 - 13.1.4

BIG-IP 12.x: 12.1.0 - 12.1.6

BIG-IP 11.x: 11.6.1 - 11.6.5

环境搭建

登录F5 BUG-IP官网下载对应版本的F5 BUG-IP,这里选择的是15.x系列。

选择下载对应版本虚拟机ova包。

导入虚拟机。

在导入虚拟机时,需选择部署,这里根据电脑配置选择越大越好。

导入之后,打开虚拟机,输入默认账号密码root/default登录,默认情况需强制修改密码,修改之后即可登录。

输入ifconfig mgmt查看IP,或者输入config配置IP。

在浏览器中访问即可访问登录界面。

环境搭建成功。

漏洞分析

在CVE-2021-22986中,F5是允许未经身份验证的攻击者,通过BIG-IP管理界面和自身IP地址对iControl REST接口进行网络访问,从而导致了命令执行。

那么此次,我们先在浏览器中访问漏洞接口/mgmt/tm/util/bash,使用用户名为admin,密码为空进行登录。

抓取登陆数据包,重新发包。

可以看到,此时的请求中是不存在X-F5-Auth-Token。

在添加上X-F5-Auth-Token并且使其为空时,从响应结果可以看到server为Apache,状态为401。

添加上X-F5-Auth-Token并且使其不为空时,server变为了Jetty,返回状态为401,返回结果为X-F5-Auth-Token does not exist。

由此可以得出结论,在CVE-2021-22986修复之后,会使用Apache去检查X-F5-Auth-Token是否存在,同时检查是否为空。当X-F5-Auth-Token存在且不为空时,后端才会进行Jetty认证,而在Jetty认证中,还存在一个对X-F5-Auth-Token是否合法的检查,如上图显示的X-F5-Auth-Token does not exist就是在Jetty认证中,我们的X-F5-Auth-Token不为空,但是随便输入的一个值,导致检测不通过,返回401。

回顾一下,在CVE-2021-22986中, Apache(模块为mod_pam_auth.so)进行第一次检查,这里是检查请求中是否存在X-F5-Auth-Token(不检查是否为空)。

那么在检测到X-F5-Auth-Token不为空时,在jetty中 f5.rest.jar中,将获取到basic认证的username和password。

com.f5.rest.workers.authz.AuthzHelper#decodeBasicAuth

此外在com.f5.rest.common.RestOperationIdentifier#setIdentityFromBasicAuth中,我们的basic认证的值不为空时。

进入到com.f5.rest.common.RestOperation#setIdentityData。

由于userName和userReference都不为空时,我们传入的是admin,那username就为admin,userReference的url为/mgmt/shared/authz/users/admin。

随后在com.f5.rest.workers.EvaluatePermissions#completeEvaluatePermission中。

setBasicAuthFromIdentity获取到用户身份。

在com.f5.rest.workers.authz.AuthzHelper#isLocalOrDefaultAdminRequest

当前用户身份匹配默认的匹配,在getDefaultAdminReference中拿到admin用户的身份new一个RestReference,而这个RestReference和之前我们获取的userReference是一样的,此时就完成了身份认证。

那么在进入com.f5.rest.workers.EvaluatePermissions#completeEvaluatePermission之前这里还存在了对X-F5-Auth-Token的值进行了检查。

com.f5.rest.workers.EvaluatePermissions#evaluatePermission

也就是当Apache检查X-F5-Auth-Token存在时,会转发给后端的 Jetty进行的第二次检查(检查X-F5-Auth-Token的值是否合法)。

从如上代码可以判断,Jetty 检查到X-F5-Auth-Token为空时,将直接忽略其提供的信息是否合法从而进入到com.f5.rest.workers.EvaluatePermissions#completeEvaluatePermission完成后面的身份验证,从而绕过权限认证。

那么分析到这里,CVE-2022-1388和CVE-2021-22986不同之处就是,在CVE-2021-22986之后官方进行了修复,让apache对X-F5-Auth-Token是否为空做了一次检查,如果存在且为空,就不会进入到Jetty认证;如果存在且不为空,则进入Jetty认证,并且Jetty会对X-F5-Auth-Token的值做出合法检查。

那么如何使得apache检测时X-F5-Auth-Toke存在不为空,传给Jetty检查时X-F5-Auth-Toke为空呢,这里就利用到了HTTP 的 hop-by-hop滥用漏洞。

参考:

参考文章后我们可以发现,如果请求中带有 HTTP 头Connection: close, X-Foo, X-Bar,Apache 会在请求转发到代理前,将X-Foo和X-Bar逐一删除。

所以CVE-2022-1388的利用,即是构造特殊请求(加上Connection:Keep-Alive,X-F5-Auth-Toke)去通过 Apache 的第一次检查,由于  hop-by-hop 滥用漏洞导致在进入 Jetty 前X-F5-Auth-Token头被删除。

漏洞复现

通过实战,在Connection头加上X-F5-Auth-Token,只有当host为localhost时,才会绕过认证,命令执行。

这是因为在com.f5.rest.common.RestOperationIdentifier#setIdentityFromBasicAuth中。

当host为localhost或者127.0.0.1时,会赋予用户身份。

解决方法就是在Connection再后加上X-Forwarded-Host,绕过认证,从而命令执行。

参考资料

1.

2. https://downloads.f5.com/esd/productlines.jsp

3. ?__biz=Mzg3MTU0MjkwNw==&mid=&idx=1&sn=52811f2a353bf61a756ddf0feb

4.