Catching Zencart Hack Attempts

Credit Card Theft

So, one morning I noticed quite a lot of 404 errors recording on a client’s web server logs and decided to take a look at them. Turns out that between 12:00am to 4:00am we would get about 4 requests a minute to different paths in the admin folder of our Zencart installation.

Keep in mind that we don’t have an admin folder, as any one from the Zencart community would tell you, ALWAYS RENAME THE ADMIN FOLDER AFTER INSTALLATION!.

So, what did the requests look like? They were calls to known old security issues that have been patched for a while now in the vanilla Zencart installation. They looked like this:

  • /admin/sqlpatch.php/password_forgotten.php
  • /admin/record_company.php <-- this was fun(scarry?) to see. They were attempting code injection

So what can we do with the knowledge that we are getting hack attempts on the old(non existant) admin folder?

Simple, record their IP addresses. Then block them at the firewall level(if you like). Here is a simple setup of a php file that will record the requests attempts in the admin folder, then you can review those records and figure out if you want to ban any IPs or not. We’ll use a .htaccess file with mod_rewrite module to redirect all requests in the admin folder to a single php script.

This is the script that will record all the request attempts: /admin/hackthis.php

<?php
//error_reporting(E_ALL & ~E_NOTICE);

$toEmail = false;
$fromEmail = 'noreply@mydomain.com';
$sendEmailAlert = false;

function getClientIP() {
	// taken from: http://www.kavoir.com/2010/03/php-how-to-detect-get-the-real-client-ip-address-of-website-visitors.html
	$test = array(
                'HTTP_CLIENT_IP',
                'HTTP_X_FORWARDED_FOR',
                'HTTP_X_FORWARDED',
                'HTTP_X_CLUSTER_CLIENT_IP',
                'HTTP_FORWARDED_FOR',
                'HTTP_FORWARDED',
                'REMOTE_ADDR');

	foreach ($test as $key) {
            if (array_key_exists($key, $_SERVER)) {
                foreach (explode(',', $_SERVER[$key]) as $ip) {
                    if (filter_var($ip, FILTER_VALIDATE_IP) !== false) {
                        return $ip;
                    }
                }
            }
        }

	return "";
}

// move dir to root, so we can include zencart include files
$root = realpath(dirname(__FILE__) . "/../") . '/';
chdir($root);
require($root . 'includes/application_top.php');

// get the attempted url
$url = $_SERVER['HTTP_HOST'] . '/admin/' . $_GET['__url'];

// the ip of the request
$ip = getClientIP();

// lets record the request variables into a json string so we can fit it in a text column
$request_data = json_encode(
    array(
        'REQUEST' => $_REQUEST,
        'GET' => $_GET,
        'POST' => $_POST,
        'RAW_POST' => file_get_contents('php://input')
    )
);

// reverse dns look up of the ip
$host = ($ip?gethostbyaddr($ip):'');

// the request referer, can't really trust it... but we'll record it anyways
$referer = $_SERVER['HTTP_REFERER'];

// quietly record this attempt at retrieving this file. It's probably a hack attempt
$query = "
    INSERT INTO hack_attempt
        (url, ip, referer, request, host)
    VALUES
        (:url, :ip, :referer, :request, :host)";

$query = $db->bindVars($query, ':url', $url, 'string');
$query = $db->bindVars($query, ':ip', $ip, 'string');
$query = $db->bindVars($query, ':referer', $referer, 'string');
$query = $db->bindVars($query, ':request', $request_data, 'string');
$query = $db->bindVars($query, ':host', $host, 'string');

$db->Execute($query);

if ( $toEmail ) {
    $emailBody = "[$host]$ip Attempted to access admin files!";
    $header = 'FROM: ' . $fromEmail . "\r\n" .
		  'X-Mailer: PHP/' . phpversion();

    @mail($toEmail, "[HACK ATTEMPT] $url", $emailBody, $headers);
}

// send out a 404
header("HTTP/1.0 404 Not Found");

// you can modify the rest as you like from here
?>
<!DOCTYPE html>
<html>
	<head>
		<title>File Not found!</title>
	</head>
	<body>
		<p>File Not Found!</p>
	</body>
</html>

You can optionally set $toEmail to your email address to get an alert on every request attempt, but that may get out of hand if you are getting bombarded by requests

The sql table looks like this:


CREATE TABLE  `hack_attempt` (
  `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP,
  `url` varchar(512) NOT NULL,
  `ip` varchar(64) default NULL,
  `referer` varchar(512) default NULL,
  `request` text,
  `host` varchar(64) default NULL,
  PRIMARY KEY  (`timestamp`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

and the /admin/.htaccess file looks like this:


RewriteEngine On
RewriteRule (.*) hackthis.php?__url=$1 [QSA]

So, from now on you’ll get a record of all IPs trying to access anything in the admin folder. But do remember that this will only work if you had renamed your admin folder to something else. So, the idea here is to catch bots trying to access admin files that don’t exists and block them from ever visiting the site again. You do need to add:


Disallow: /admin/

in your robots.txt file to keep google bot, or other search engine bots from going in that directory. So you should only get misbehaving or malicious bots recorded in your hack_attempt table.

So, where to go from here? Well, you can take those IP addresses and add them to your firewall filters so they can never attempt anything on your server ever again. Some people will argue that IP blocking is harsh and easy to circumvent by using proxies, but what can you really do when seeing blatant hacking attempts from those IPs?

Leave a Reply

Your email address will not be published. Required fields are marked *

*

* Copy this password:

* Type or paste password here:

168 Spam Comments Blocked so far by Spam Free Wordpress