删除附加到每个帖子的恶意软件

时间:2020-01-29 作者:Elkrat

我在每篇文章的末尾都添加了一个恶意软件java脚本。我尝试在phpMyAdmin中使用SQL语句。以下是其简略版本:

SET @virus = "<script>var _0x2cf4=[\'MSIE"+CHAR(59)+"\',\'OPR\',\'Chromium\',\'Chrome\',\'ppkcookie\',\'location\',\'https://www.wow-robotics.xyz\',\'onload\',\'getElementById\'...(and a lot more obfuscated script)...;
UPDATE
  wp_posts
SET
  post_content =
REPLACE
  (
    post_content,
    @virus COLLATE utf8mb4_unicode_520_ci,
    \'\'
  );
这最初并不成功,因为许多错误匹配导致整个网站被删除。我没有时间找出原因,所以我将搜索文本缩短为脚本的开头,这破坏了恶意软件,使其变得丑陋。这让我摆脱了麻烦,但显然这不是最好的解决方案。

我应该怎么做?我尝试将帖子内容标记化,使用恶意软件脚本的文本作为标记:

<?php

ignore_user_abort(true);
set_time_limit(30);

$path = $_SERVER[\'DOCUMENT_ROOT\'];
require( $path.\'/wp-load.php\' );
$post_table = $wpdb->prefix . \'posts\';
$meta_table = $wpdb->prefix . \'postmeta\';
$starting_virus_text = "<script>[\'MSIE;\',\'OPR\',\'Chromium\',\'Chrome\',\'ppkcookie\',\'location\',\'https://www.wow-robotics.xy";

$args = array(
        \'post_type\' => \'page\',
        \'post_status\' => \'publish\',
        \'posts_per_page\' => -1,
    );

$posts = get_posts($args);

echo \'Post count is \'.count($posts).\'<br>\';

foreach($posts as $post){
    $new_content = strtok($post->post_content, $starting_virus_text);
    if ($post->ID == 192) { // my home page, just for example
        echo \'POST 192<br><pre>\';
        var_dump($post->post_content);
    }
    if (strlen($new_content) > 20){
        echo $new_content;
        die;
    }
}

echo \'<br>Done.\';

?>
这也是不成功的。在帖子内容中从未找到标记,即使它在那里。我是否应该执行字符ny字符类型检查并将post\\U内容存储在中间变量中?如有任何建议,我们将不胜感激。

3 个回复
SO网友:Rick Hellewell

数据库中每个帖子中是否都有恶意软件?如果是这样的话,有东西插入了它,所以您需要首先修复它。关于如何从WP网站上删除恶意软件,很多Google/Bing/ducks都在讨论。(我在这里有自己的程序供客户使用:https://www.securitydawg.com/recovering-from-a-hacked-wordpress-site/ ; 还有其他人。)

我会彻底清理现场;更改凭据(无处不在,而不仅仅是WP),在整个过程中更改强密码;查找未经授权的文件;检查wp配置。php和其他用于插入代码的文件;从已知良好来源(通过FTP)重新安装插件/主题;更新所有内容;更新PHP版本;还有更多。

然后查看wp posts表中插入的内容。每个帖子的脚本代码可能不同,因此您可能需要手动修复。

当然,还有在任何重大更改之前备份数据库。

SO网友:Elkrat

我的朋友,答案是在str\\u repl()的正则表达式中吹出的-使用开始和结束标记从post\\u内容中删除恶意软件脚本

首先,我在数据库中找到一些特定帖子,其中包含恶意软件的示例,以获取其开头字符串,在我的情况下:

<script>;\',\'OPR\'
然后,我编写了以下脚本,以提供字符串的精确长度,并查看它在数据库中的样本行上是否稳定:

ignore_user_abort(true);
set_time_limit(30);

$path = $_SERVER[\'DOCUMENT_ROOT\'];
require( $path.\'/wp-load.php\' );

$test_posts = array(1,15002,9664,3342);

foreach ($test_posts as $post){ 
    $post = get_post($post);
    $content = $post->post_content;
    $strlen = strlen($content);
    // to delete a script tag... preg_replace(\'/(<script>.+?)+(<\\/script>)/i\', \'\', $string);
    // starting virus text is <script>;\',\'OPR\'  must use backslash to escape the folling characters: \\ ^ . $ | ( ) [ ] * + ? { } ,
    $new_content = preg_replace(\'/(<script>;\\\'\\,\\\'OPR\\\'.+?)+(<\\/script>)/i\', \'\', $content);
    $new_strlen = strlen($new_content);
    $difference = $strlen - $new_strlen;
    echo \'Post \'.$post->ID.\': \'.$strlen.\'-\'.$new_strlen.\'=<b>\'.($difference).\'</b><br>\';
}

echo \'<br>Done.\';
我在所有条目中都看到了相同的数字:2409。因此,我将2409插入到第二个脚本中,该脚本实际执行后期更新:

ignore_user_abort(true);
set_time_limit(90);

$path = $_SERVER[\'DOCUMENT_ROOT\'];
require( $path.\'/wp-load.php\' );

$args = array(
        \'post_type\' => array(
                            \'post\',
                            \'page\',
                            \'revision\',
                            \'item\',
                            \'wpsl_stores\',
                            \'nav_menu_item\',
                            \'accordion_menu\',
                            \'et_pb_layout\',
                            \'scheduled-action\',
                            \'wpsl_stores\',
                            \'popup_theme\',
            ),
        \'post_status\' => array(\'publish\', \'draft\', \'inherit\'),
        \'posts_per_page\' => -1,
    );

$posts = get_posts($args);

echo \'Post count is \'.count($posts).\'<br>\';

$post_of_interest = 1;

foreach($posts as $post){
    $content = $post->post_content;
    $strlen = strlen($content);
    // starting virus text is <script>;\',\'OPR\'
    $new_content = preg_replace(\'/(<script>;\\\'\\,\\\'OPR\\\'.+?)+(<\\/script>)/i\', \'\', $content);
    $new_strlen = strlen($new_content);
    if (($strlen - $new_strlen) == 2409){ // I know my target string has a specific number of characters
        echo \'<br><b>*** HIT \'.$post->ID.\' ***</b><br>\';
    } else {
        echo \'-\';
    }

    if($post->ID == $post_of_interest){
        echo \'<br>\'.$post_of_interest.\' original strlen=\'.$strlen.\' New strlen=\'.$new_strlen.\' Difference=\'.($strlen - $new_strlen).\'<br>\';
    }
    $args = array(
            \'ID\' => $post->ID,
            \'post_content\' => $new_content,
        );
    wp_update_post( $args ); 
}

echo \'<br>Done.\';
希望这对别人有帮助。

SO网友:Elkrat

清理Wordpress帖子的更好方法是删除所有脚本标记及其内容。我碰巧知道我的帖子内容中不应该有脚本,所以这对我来说是安全的。首先快速备份数据库,这样你就不会哭了。

此外,如果您注意函数作者所做的工作,您可以使用它从html中去除任何标记。或者,通过将最后一个参数保留为false,可以去除除指定标记以外的所有标记。我将其设置为true,这使得它只剥离指定的标记。

函数来自https://gist.github.com/marcanuy/7651298

顺便说一句,如果有人能插话告诉我这些人是如何注入这些脚本的,我将非常感激。我在一个经过强化的网站上遇到过这种情况——将wp config移到了公共html目录之上,更改了权限,移动了登录地址,等等。这让人感到不安,因为虽然垃圾邮件让我看起来很糟糕,但真正的问题是它显示了一个安全漏洞。

<?php
ignore_user_abort(true);
set_time_limit(90);

$path = $_SERVER[\'DOCUMENT_ROOT\'];
require( $path.\'/wp-load.php\' );

$args = array(
        \'post_type\' => array( // add all your post types here, but be careful: it will strip all scripts from their content
                            \'post\',
                            \'page\',
                            \'revision\',
                            \'item\',
                            \'wpsl_stores\',
                            \'nav_menu_item\',
                            \'accordion_menu\',
                            \'et_pb_layout\',
                            \'scheduled-action\',
                            \'wpsl_stores\',
                            \'popup_theme\',
            ),
        \'post_status\' => array(\'publish\', \'draft\', \'inherit\'),
        \'posts_per_page\' => -1,
    );

$posts = get_posts($args);

echo \'Post count is \'.count($posts).\'<br>\';

foreach($posts as $post){

    $content = $post->post_content;
    $new_content = strip_tags_content($content, \'<script>\', true);

    $args = array(
            \'ID\' => $post->ID,
            \'post_content\' => $new_content,
        );
    wp_update_post( $args );    
}

echo \'<br>Done.\';

function strip_tags_content($text, $tags = \'\', $invert = FALSE) {

  preg_match_all(\'/<(.+?)[\\s]*\\/?[\\s]*>/si\', trim($tags), $tags);
  $tags = array_unique($tags[1]);

  if(is_array($tags) AND count($tags) > 0) {
    if($invert == FALSE) {
      return preg_replace(\'@<(?!(?:\'. implode(\'|\', $tags) .\')\\b)(\\w+)\\b.*?>.*?</\\1>@si\', \'\', $text);
    }
    else {
      return preg_replace(\'@<(\'. implode(\'|\', $tags) .\')\\b.*?>.*?</\\1>@si\', \'\', $text);
    }
  }
  elseif($invert == FALSE) {
    return preg_replace(\'@<(\\w+)\\b.*?>.*?</\\1>@si\', \'\', $text);
  }
  return $text;
} 

?>

相关推荐