F5 BIG-IP 未授权 RCE(CVE-2022-1388)分析

 

作者:知道创宇404实验室 kuipla、Billion

2022/5/4日F5官方发布一个关于BIG-IP的未授权RCE(CVE-2022-1388)安全公告,官方对该漏洞的描述是Undisclosed requests may bypass iControl REST authentication.,修复方式中提到了低版本可以将非Connection:keep-aliveConnection:close的请求全部关闭。

 

0x00 补丁分析

由于BIG-IP的框架依旧有大佬分析过了,因此我们直接根据去寻找apache的认证服务mod_pam_auth.so以及mgmt转发的8100端口对应的认证/usr/share/java/rest/目录下发生改变的jar包上。

mod_pam_auth.so

在ida中使用bindiff插件对比新旧两个so文件,能够发现只有sub_5EF0和5AF0改动比较大

接下来用ida把这两个函数反编译出来进行对比,主要修改位置有以下两处

此处是将非Connection:keep-aliveConnection:close的请求头清除。

此处是对X-F5-Auth-Token进行了验证,而不是之前简单判断了下是否赋值。

测试发现确实可以bypass apache认证

添加xf5头

icrd.jar&f5.rest.jar

通过对icrd/com/f5/mgmt/tm/common/WellKnownPorts.class的路由分析以及鉴权的com/f5/rest/app/RestServerServlet.class进行前后对比,我们发现一个很奇怪的事情,鉴权部分的代码并未进行大的更改,也就是说apache的请求走私可以bypass掉jetty的认证。

总结

猜测Connection头请求走私可以bypass jetty的认证。

根据官方的描述和推特上的讨论,我们一开始是认为这个洞是由CVE-2021-22986的SSRF带出cookie的bypass。因为一般的请求走私是CL-CL,CL-TE,TE-CL,TE-TE,但因为BIG-IP使用的apache不支持 Transfer-Encoding,因此我们猜测走私的原因放到了Content-Length上走私请求到一个未授权的接口获取SSRF。

后面卡了很久也没找到这个”不存在的接口”,最后才发现是hop-by-hop导致的问题。

关于hop-by-hop是在这里导致的权限bypass我们放到下面细讲。

 

0x01 漏洞分析

首先我们先来看如果要Bypass掉Apache的认证怎么做,根据官方的补丁,只要符合X-F5-Auth-Token不为空即可,并且mod_pam_auth.so是先判断X-F5-Auth-Token后再判断Authorization的值,这给了hop-by-hop一个很大的操作空间。

那么剩下的就是jetty的认证,jetty的认证只要由组成X-F5-Auth-Token和Authorization组成。由于鉴权部分并未做太大改动,因此我们简单描述下两者是如何进行检验的。

X-F5-Auth-Token

com/f5/rest/workers/EvaluatePermissions.class#evaluatePermission

请求最后会被送到/shared/authz/tokens/进行验证,由于跟CVE-2022-1388关系不大就不继续跟下去了。

Authorization

Authorization的鉴权非常奇怪,Authorization是由authn进行的验证,之前了解过CVE-2021-22986肯定知道这里之前只鉴权了用户名是否存在,因为admin一定存在,只要将Auth设置为YWRtaW46就行。

补丁的是检测了X-Forwarded-Host不为本地的Basic Auth header的账号密码,但X-Forwarded-Host为本地IP依旧只检测了账户名是否正确。

com/f5/rest/common/RestOperationIdentifier.class#setIdentityFromBasicAuth

那么这个X-Forwarded-Host是怎么赋值的呢,很明显已公开的poc中并没有直接在header中添加X-Forwarded-Host,其实这个字段是由apache整出来的,后面提到的变形poc中会讲解怎么利用,这里由于逆向能力不强就不献丑了。

在最新版测试发现这个问题依旧存在,猜测可能是环境内部的一些其他认证需求导致的这个问题。

hop-by-hop

hop-by-hop简单的说就是将可以在Connection: Keep-Alive后面再加一个字段,这个字段在经过代理服务器转发后会被删除。理论上东西的危害非常有限,甚至于说不能算漏洞。

但是在BIG-IP的环境下,有一个非常罕见的系统流程路径可以经过hop-by-hop产生RCE。

让我们回顾一下整个系统的认证流程,apache是检查Authorization的正确性,但只检测X-F5-Auth-Token是否为空,并且优先检查X-F5-Auth-Token。Jetty同样优先检查X-F5-Auth-Token的正确性,但只检查Authorization是否是合法用户名。

那么只要我们设置Host为localhost,X-F5-Auth-Token不为空,Authorization设置为YWRtaW46Connection: Keep-Alive, X-F5-Auth-Token就可以绕过apache的检查,同时apache还会贴心的帮我们删去X-F5-Auth-Token,把请求直接送到Authorization的验证,从而实现bypass。

 

0x02 一些poc的变种

经过我们的测试发现两种poc变种

  1. 写两个X-F5-Auth-Token:也能绕过apache的检测
  2. 同时由于hop-by-hop的原因,即使apache删除了header中的X-Forwarded-Host,但如果我们用Connection: Keep-Alive, X-F5-Auth-Token, X-Forwarded-Host,那么我们设置的X-Forwarded-Host依旧生效,这样Host就不必必须为localhost了

 

参考链接

https://book.hacktricks.xyz/pentesting-web/abusing-hop-by-hop-headers

https://blog.riskivy.com/f5%E4%BB%8E%E8%AE%A4%E8%AF%81%E7%BB%95%E8%BF%87%E5%88%B0%E8%BF%9C%E7%A8%8B%E4%BB%A3%E7%A0%81%E6%89%A7%E8%A1%8C%E6%BC%8F%E6%B4%9E%E5%88%86%E6%9E%90

https://support.f5.com/csp/article/K23605346

(完)