0, 'infections_found' => 0, 'backdoors_found' => 0, 'injections_found' => 0, 'suspicious_files' => 0, 'cleaned_files' => 0, 'quarantined_files' => 0 ]; // Patterns de détection malware private $malware_patterns = [ // Backdoors 'backdoor_eval' => '/eval\s*\(\s*\$_(GET|POST|REQUEST|COOKIE)\s*\[.*?\]\s*\)/i', 'backdoor_system' => '/system\s*\(\s*\$_(GET|POST|REQUEST)\s*\[.*?\]\s*\)/i', 'backdoor_exec' => '/exec\s*\(\s*\$_(GET|POST|REQUEST)\s*\[.*?\]\s*\)/i', 'backdoor_shell' => '/shell_exec\s*\(\s*\$_(GET|POST|REQUEST)\s*\[.*?\]\s*\)/i', 'backdoor_passthru' => '/passthru\s*\(\s*\$_(GET|POST|REQUEST)\s*\[.*?\]\s*\)/i', 'backdoor_assert' => '/assert\s*\(\s*\$_(GET|POST|REQUEST)\s*\[.*?\]\s*\)/i', 'backdoor_base64' => '/eval\s*\(\s*base64_decode\s*\(/i', 'backdoor_gzinflate' => '/eval\s*\(\s*gzinflate\s*\(\s*base64_decode\s*\(/i', 'backdoor_str_rot13' => '/eval\s*\(\s*str_rot13\s*\(/i', 'backdoor_create_function' => '/create_function\s*\(\s*[\'"][^\'\"]*[\'"]\s*,\s*\$_(GET|POST|REQUEST)/i', 'backdoor_preg_replace' => '/preg_replace\s*\(\s*[\'"].*?e[\'"].*?\$_(GET|POST|REQUEST)/i', // Injections JavaScript malveillantes 'js_injection_eval' => '/]*>.*?eval\s*\(/i', 'js_injection_unescape' => '/]*>.*?unescape\s*\(/i', 'js_injection_fromcharcode' => '/String\.fromCharCode\s*\(/i', 'js_injection_document_write' => '/document\.write\s*\(\s*unescape/i', 'js_injection_iframe_hidden' => '/]*width\s*=\s*[\'"]?1[\'"]?[^>]*>/i', 'js_injection_onclick' => '/onclick\s*=\s*[\'"].*?eval\s*\(/i', // Pharma hack 'pharma_viagra' => '/viagra|cialis|levitra|pharmacy|prescription/i', 'pharma_links' => '/]*href=[\'"][^\'\"]*pharmacy[^\'\"]*[\'"]/i', // Redirections malveillantes 'redirect_meta' => '/]*http-equiv\s*=\s*[\'"]refresh[\'"][^>]*url\s*=/i', 'redirect_javascript' => '/window\.location\.href\s*=|document\.location\.replace/i', 'redirect_header' => '/header\s*\(\s*[\'"]location:/i', // Code obfusqué 'obfuscated_chr' => '/chr\s*\(\s*\d+\s*\)\s*\.\s*chr\s*\(\s*\d+\s*\)/i', 'obfuscated_hex' => '/\\\\x[0-9a-f]{2}/i', 'obfuscated_base64_long' => '/[A-Za-z0-9+\/]{200,}/i', // Fichiers système sensibles 'file_passwd' => '/\/etc\/passwd|\/etc\/shadow/i', 'file_htaccess' => '/RewriteRule.*http:\/\/[^\/]*/i', // Fonctions dangereuses 'dangerous_file_get_contents' => '/file_get_contents\s*\(\s*[\'"]https?:\/\//i', 'dangerous_curl' => '/curl_exec\s*\(\s*\$[^)]*\)/i', 'dangerous_fwrite' => '/fwrite\s*\(\s*fopen\s*\([^)]*\.php/i', 'dangerous_move_uploaded' => '/move_uploaded_file\s*\([^)]*\.php/i', 'dangerous_chmod_777' => '/chmod\s*\(\s*[^,]*,\s*0?777\s*\)/i', ]; // Signatures de backdoors connus private $backdoor_signatures = [ 'c99shell' => 'c99shell|FilesMan|Safe Mode|eval\(gzinflate\(base64_decode', 'r57shell' => 'r57shell|RST\(|\$_REQUEST\[\$_\]|eval\(\$_POST', 'wso_shell' => 'WSO|WSOsetcookie|wso\d+|eval\(\$_\[\$_', 'b374k' => 'b374k|0x62374b|preg_replace.*e.*\$_', 'crystal_shell' => 'Crystal.*Shell|\$_=\$_GET|\$_\[\]=', 'alfa_shell' => 'alfacgiapi|Edited By Alfa', 'mini_shell' => 'mini.*shell|system\(\$_GET\[.*?\]\)', 'idx_shell' => 'IndoXploit|idx_file|eval\(str_rot13', 'adminer_shell' => 'eval\(gzinflate\(base64_decode.*adminer', 'angel_shell' => 'Angel|AngelSecurityTeam', 'fox_wso' => 'FoxWSO|FGS|eval\(\$_POST\[.*?\]\)', 'sadrazam_shell' => 'Sadrazam|configration|eval\(base64_decode\(\$_POST', 'jackal_shell' => 'Jackal.*Shell|eval\(\$_REQUEST\[.*?\]\)', 'jspshell' => 'JspShell|eval\(new\(java\.lang\.String\)', 'dark_security' => 'DarkSecurity.*Team|d4rk.*cr3w', 'gfs_shell' => 'GFS.*shell|eval\(\$_\[\$_\]', 'tryag_shell' => 'tryag.*shell|eval\(stripslashes\(\$_REQUEST', 'w4ck1ng' => 'w4ck1ng|eval\(\$_POST\[.*?chr.*?\]', 'versaf_shell' => 'Versaf|eval\(\$_POST\[".*?"\]\)', 'fx29_shell' => 'Fx29Sh|eval\(\$_POST\[chr\(', ]; // Extensions de fichiers à scanner private $scan_extensions = [ 'php', 'php3', 'php4', 'php5', 'php7', 'php8', 'phtml', 'phar', 'js', 'html', 'htm', 'htaccess', 'txt', 'inc', 'tpl', 'sql' ]; // Dossiers à exclure du scan private $exclude_dirs = [ '.git', '.svn', 'node_modules', 'vendor', 'cache', 'logs' ]; /** * Constructeur */ public function __construct($wp_path = null) { $this->wp_path = $wp_path ?: $this->detectWordPressPath(); $this->initializeDirectories(); $this->startSession(); } /** * Détection automatique du chemin WordPress */ private function detectWordPressPath() { $possible_paths = [ dirname(__FILE__), dirname(dirname(__FILE__)), '/var/www/html', '/var/www/wordpress', $_SERVER['DOCUMENT_ROOT'] ?? '' ]; foreach ($possible_paths as $path) { if (file_exists($path . '/wp-config.php') || file_exists($path . '/wp-settings.php')) { return realpath($path); } } throw new Exception('Installation WordPress non détectée. Veuillez spécifier le chemin.'); } /** * Initialisation des répertoires de travail */ private function initializeDirectories() { $dirs = [self::QUARANTINE_DIR, self::BACKUP_DIR, self::REPORTS_DIR]; foreach ($dirs as $dir) { if (!is_dir($dir)) { mkdir($dir, 0755, true); } } } /** * Démarrage de session pour l'interface web */ private function startSession() { if (session_status() === PHP_SESSION_NONE) { session_start(); } } /** * Logging centralisé */ private function log($level, $message) { $timestamp = date('Y-m-d H:i:s'); $log_entry = "[$timestamp] [$level] $message" . PHP_EOL; file_put_contents(self::LOG_FILE, $log_entry, FILE_APPEND | LOCK_EX); } /** * Validation de l'installation WordPress */ public function validateWordPress() { if (!is_dir($this->wp_path)) { throw new Exception("Chemin WordPress invalide: {$this->wp_path}"); } if (!file_exists($this->wp_path . '/wp-config.php') && !file_exists($this->wp_path . '/wp-settings.php')) { throw new Exception("Installation WordPress non détectée dans: {$this->wp_path}"); } $this->log('INFO', "WordPress validé dans: {$this->wp_path}"); return true; } /** * Obtenir les informations WordPress */ public function getWordPressInfo() { $info = [ 'path' => $this->wp_path, 'version' => 'Non détectée', 'plugins' => [], 'themes' => [], 'users' => [] ]; // Version WordPress $version_file = $this->wp_path . '/wp-includes/version.php'; if (file_exists($version_file)) { $content = file_get_contents($version_file); if (preg_match('/\$wp_version\s*=\s*[\'"]([^\'"]+)[\'"]/', $content, $matches)) { $info['version'] = $matches[1]; } } // Plugins installés $plugins_dir = $this->wp_path . '/wp-content/plugins'; if (is_dir($plugins_dir)) { $info['plugins'] = array_diff(scandir($plugins_dir), ['.', '..']); } // Thèmes installés $themes_dir = $this->wp_path . '/wp-content/themes'; if (is_dir($themes_dir)) { $info['themes'] = array_diff(scandir($themes_dir), ['.', '..']); } return $info; } /** * Création de sauvegarde complète */ public function createBackup() { $this->log('INFO', 'Création de la sauvegarde complète...'); $backup_timestamp = date('Y-m-d_H-i-s'); $backup_file = self::BACKUP_DIR . "/wp_backup_{$backup_timestamp}.tar.gz"; // Sauvegarde des fichiers $exclude_dirs = implode(' --exclude=', $this->exclude_dirs); $command = "tar --exclude={$exclude_dirs} -czf {$backup_file} -C " . dirname($this->wp_path) . " " . basename($this->wp_path); exec($command, $output, $return_code); if ($return_code === 0) { $this->log('SUCCESS', "Sauvegarde créée: {$backup_file}"); return $backup_file; } else { $this->log('ERROR', "Échec de la sauvegarde: " . implode("\n", $output)); return false; } } /** * Calcul de l'entropie d'un fichier (détection code obfusqué) */ private function calculateEntropy($data) { if (empty($data)) return 0; $char_counts = array_count_values(str_split($data)); $data_length = strlen($data); $entropy = 0; foreach ($char_counts as $count) { $p = $count / $data_length; $entropy -= $p * log($p, 2); } return $entropy; } /** * Détection de patterns malware dans un fichier */ private function scanMalwarePatterns($file_path, $content) { $threats = []; foreach ($this->malware_patterns as $pattern_name => $pattern) { if (preg_match($pattern, $content)) { $threats[] = [ 'type' => 'pattern', 'name' => $pattern_name, 'severity' => $this->getPatternSeverity($pattern_name), 'description' => $this->getPatternDescription($pattern_name) ]; } } return $threats; } /** * Détection de signatures de backdoors connus */ private function scanBackdoorSignatures($file_path, $content) { $threats = []; foreach ($this->backdoor_signatures as $backdoor_name => $signature_pattern) { if (preg_match("/{$signature_pattern}/i", $content)) { $threats[] = [ 'type' => 'backdoor', 'name' => $backdoor_name, 'severity' => 'critical', 'description' => "Backdoor connu détecté: {$backdoor_name}" ]; $this->statistics['backdoors_found']++; } } return $threats; } /** * Analyse heuristique avancée */ private function heuristicAnalysis($file_path, $content) { $threats = []; $suspicion_score = 0; // Analyse de l'entropie $entropy = $this->calculateEntropy($content); if ($entropy > 7.5) { $suspicion_score += 3; $threats[] = [ 'type' => 'heuristic', 'name' => 'high_entropy', 'severity' => 'medium', 'description' => "Entropie élevée détectée: {$entropy} (code potentiellement obfusqué)" ]; } // Ratio de caractères non-ASCII $non_ascii_count = strlen($content) - strlen(filter_var($content, FILTER_SANITIZE_STRING, FILTER_FLAG_STRIP_HIGH)); $non_ascii_ratio = $non_ascii_count / strlen($content); if ($non_ascii_ratio > 0.3) { $suspicion_score += 2; $threats[] = [ 'type' => 'heuristic', 'name' => 'high_non_ascii', 'severity' => 'medium', 'description' => "Ratio élevé de caractères non-ASCII: " . round($non_ascii_ratio * 100, 2) . "%" ]; } // Détection de code très dense (potentiellement minifié/obfusqué) $lines = explode("\n", $content); $long_lines = array_filter($lines, function($line) { return strlen($line) > 500; }); if (count($long_lines) > 3) { $suspicion_score += 2; $threats[] = [ 'type' => 'heuristic', 'name' => 'dense_code', 'severity' => 'low', 'description' => "Code très dense détecté (lignes > 500 caractères)" ]; } // Détection de variables suspicieuses $suspicious_vars = ['$_', '$__', '$___', '$GLOBALS', '$_POST', '$_GET', '$_REQUEST']; foreach ($suspicious_vars as $var) { if (substr_count($content, $var) > 10) { $suspicion_score += 1; break; } } // Score global if ($suspicion_score >= 5) { $threats[] = [ 'type' => 'heuristic', 'name' => 'high_suspicion_score', 'severity' => 'high', 'description' => "Score de suspicion élevé: {$suspicion_score}/10" ]; } return $threats; } /** * Analyse des permissions de fichiers */ private function analyzeFilePermissions($file_path) { $threats = []; $perms = fileperms($file_path); // Fichier exécutable par tous (777) if (($perms & 0777) === 0777) { $threats[] = [ 'type' => 'permission', 'name' => 'world_writable', 'severity' => 'high', 'description' => "Fichier accessible en écriture par tous (777)" ]; } // Fichier PHP dans uploads if (strpos($file_path, '/uploads/') !== false && pathinfo($file_path, PATHINFO_EXTENSION) === 'php') { $threats[] = [ 'type' => 'permission', 'name' => 'php_in_uploads', 'severity' => 'high', 'description' => "Fichier PHP dans le dossier uploads" ]; } return $threats; } /** * Détection de fichiers suspects par nom */ private function detectSuspiciousFilenames($file_path) { $threats = []; $filename = basename($file_path); $suspicious_patterns = [ '/^[a-f0-9]{32}\.php$/' => 'Nom MD5 suspect', '/^[a-f0-9]{8,16}\.php$/' => 'Nom hexadécimal suspect', '/^[0-9]{10,}\.php$/' => 'Nom timestamp suspect', '/^wp-[a-z]{2,}\.php$/' => 'Faux fichier WordPress', '/^index[0-9]+\.php$/' => 'Faux index', '/^config[0-9]*\.php$/' => 'Faux config', '/^admin[0-9]*\.php$/' => 'Faux admin', '/^\.(.*\.php|php.*)$/' => 'Fichier PHP caché', '/^error[_-]?log\.php$/' => 'Faux fichier de log', '/^(data|db|database)\.php$/' => 'Fichier base suspect' ]; foreach ($suspicious_patterns as $pattern => $description) { if (preg_match($pattern, $filename)) { $threats[] = [ 'type' => 'filename', 'name' => 'suspicious_filename', 'severity' => 'medium', 'description' => $description . ": {$filename}" ]; $this->statistics['suspicious_files']++; break; } } return $threats; } /** * Scan approfondi d'un fichier */ private function deepScanFile($file_path) { $this->statistics['files_scanned']++; // Ignorer les gros fichiers (>10MB) if (filesize($file_path) > 10 * 1024 * 1024) { return []; } $content = file_get_contents($file_path); if ($content === false) { return []; } $all_threats = []; // Différents types de scans $all_threats = array_merge($all_threats, $this->scanMalwarePatterns($file_path, $content)); $all_threats = array_merge($all_threats, $this->scanBackdoorSignatures($file_path, $content)); $all_threats = array_merge($all_threats, $this->heuristicAnalysis($file_path, $content)); $all_threats = array_merge($all_threats, $this->analyzeFilePermissions($file_path)); $all_threats = array_merge($all_threats, $this->detectSuspiciousFilenames($file_path)); if (!empty($all_threats)) { $this->statistics['infections_found']++; // Compter les injections foreach ($all_threats as $threat) { if (strpos($threat['name'], 'injection') !== false) { $this->statistics['injections_found']++; } } } return $all_threats; } /** * Scan récursif d'un répertoire */ private function scanDirectory($directory) { $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS) ); foreach ($iterator as $file) { if ($file->isFile()) { $file_path = $file->getPathname(); $extension = strtolower($file->getExtension()); // Vérifier si le fichier doit être scanné if (in_array($extension, $this->scan_extensions)) { // Exclure certains dossiers $skip = false; foreach ($this->exclude_dirs as $exclude_dir) { if (strpos($file_path, "/{$exclude_dir}/") !== false) { $skip = true; break; } } if (!$skip) { $threats = $this->deepScanFile($file_path); if (!empty($threats)) { $this->scan_results[$file_path] = $threats; } } } } } } /** * Scan complet du site WordPress */ public function fullScan() { $this->log('INFO', 'Démarrage du scan complet...'); // Réinitialiser les résultats $this->scan_results = []; $this->statistics = array_fill_keys(array_keys($this->statistics), 0); try { $this->scanDirectory($this->wp_path); // Scanner également les fichiers à la racine $root_files = glob($this->wp_path . '/*'); foreach ($root_files as $file) { if (is_file($file)) { $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION)); if (in_array($extension, $this->scan_extensions)) { $threats = $this->deepScanFile($file); if (!empty($threats)) { $this->scan_results[$file] = $threats; } } } } $this->log('SUCCESS', "Scan terminé - {$this->statistics['files_scanned']} fichiers scannés, {$this->statistics['infections_found']} infections détectées"); } catch (Exception $e) { $this->log('ERROR', 'Erreur lors du scan: ' . $e->getMessage()); throw $e; } return $this->scan_results; } /** * Mise en quarantaine d'un fichier */ private function quarantineFile($file_path) { $quarantine_name = self::QUARANTINE_DIR . '/' . basename($file_path) . '_' . time() . '_' . rand(1000, 9999); if (copy($file_path, $quarantine_name)) { $this->log('INFO', "Fichier mis en quarantaine: {$file_path} -> {$quarantine_name}"); $this->statistics['quarantined_files']++; return $quarantine_name; } return false; } /** * Nettoyage intelligent d'un fichier infecté */ private function cleanInfectedFile($file_path, $threats) { $content = file_get_contents($file_path); if ($content === false) { return false; } $original_content = $content; $cleaned = false; // Nettoyer selon les types de menaces foreach ($threats as $threat) { switch ($threat['type']) { case 'pattern': $content = $this->cleanMalwarePattern($content, $threat['name']); $cleaned = true; break; case 'backdoor': // Les backdoors sont généralement supprimés entièrement $this->quarantineFile($file_path); return 'quarantined'; case 'filename': // Fichiers avec noms suspects sont mis en quarantaine $this->quarantineFile($file_path); return 'quarantined'; } } // Sauvegarder le fichier nettoyé si des modifications ont été apportées if ($cleaned && $content !== $original_content) { // Sauvegarder l'original copy($file_path, $file_path . '.infected.backup'); // Écrire le contenu nettoyé if (file_put_contents($file_path, $content) !== false) { $this->log('SUCCESS', "Fichier nettoyé: {$file_path}"); $this->statistics['cleaned_files']++; return 'cleaned'; } } return false; } /** * Nettoyage spécifique par pattern */ private function cleanMalwarePattern($content, $pattern_name) { switch ($pattern_name) { case 'js_injection_eval': case 'js_injection_unescape': case 'js_injection_fromcharcode': // Supprimer les scripts malveillants $content = preg_replace('/]*>.*?eval.*?<\/script>/is', '', $content); $content = preg_replace('/]*>.*?unescape.*?<\/script>/is', '', $content); break; case 'js_injection_iframe_hidden': // Supprimer les iframes cachées $content = preg_replace('/]*width\s*=\s*[\'"]?1[\'"]?[^>]*>.*?<\/iframe>/is', '', $content); break; case 'pharma_links': // Supprimer les liens pharmaceutiques $content = preg_replace('/]*href=[\'"][^\'\"]*pharmacy[^\'\"]*[\'"][^>]*>.*?<\/a>/is', '', $content); break; case 'redirect_meta': // Supprimer les redirections meta $content = preg_replace('/]*http-equiv\s*=\s*[\'"]refresh[\'"][^>]*>/is', '', $content); break; default: // Nettoyage générique pour les patterns de base foreach ($this->malware_patterns as $pname => $pattern) { if ($pname === $pattern_name) { $content = preg_replace($pattern, '/* Code malveillant supprimé */', $content); break; } } } return $content; } /** * Nettoyage automatique de tous les fichiers infectés */ public function autoClean() { $this->log('INFO', 'Démarrage du nettoyage automatique...'); $results = [ 'cleaned' => [], 'quarantined' => [], 'failed' => [] ]; foreach ($this->scan_results as $file_path => $threats) { $result = $this->cleanInfectedFile($file_path, $threats); switch ($result) { case 'cleaned': $results['cleaned'][] = $file_path; break; case 'quarantined': $results['quarantined'][] = $file_path; break; default: $results['failed'][] = $file_path; } } $this->log('SUCCESS', "Nettoyage terminé - " . count($results['cleaned']) . " fichiers nettoyés, " . count($results['quarantined']) . " mis en quarantaine"); return $results; } /** * Sécurisation post-nettoyage */ public function hardenWordPress() { $this->log('INFO', 'Démarrage de la sécurisation WordPress...'); $actions = []; // 1. Sécuriser les permissions des fichiers $actions['permissions'] = $this->hardenFilePermissions(); // 2. Sécuriser .htaccess $actions['htaccess'] = $this->secureHtaccess(); // 3. Sécuriser wp-config.php $actions['wp_config'] = $this->secureWpConfig(); // 4. Supprimer les fichiers indésirables $actions['cleanup'] = $this->cleanupUnnecessaryFiles(); // 5. Créer fichiers de protection $actions['protection'] = $this->createProtectionFiles(); $this->log('SUCCESS', 'Sécurisation WordPress terminée'); return $actions; } /** * Durcissement des permissions de fichiers */ private function hardenFilePermissions() { $fixed = 0; // Permissions recommandées WordPress $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($this->wp_path, RecursiveDirectoryIterator::SKIP_DOTS) ); foreach ($iterator as $file) { if ($file->isFile()) { chmod($file->getPathname(), 0644); $fixed++; } elseif ($file->isDir()) { chmod($file->getPathname(), 0755); } } // Permissions spéciales if (file_exists($this->wp_path . '/wp-config.php')) { chmod($this->wp_path . '/wp-config.php', 0600); } return "Permissions corrigées pour {$fixed} fichiers"; } /** * Sécurisation du fichier .htaccess */ private function secureHtaccess() { $htaccess_file = $this->wp_path . '/.htaccess'; // Supprimer les redirections malveillantes si présentes if (file_exists($htaccess_file)) { $content = file_get_contents($htaccess_file); // Patterns de redirections malveillantes à supprimer $malicious_patterns = [ '/RewriteRule.*http:\/\/[^\/]*\//i', '/RewriteCond.*HTTP_USER_AGENT/i', '/RewriteCond.*HTTP_REFERER.*google/i' ]; foreach ($malicious_patterns as $pattern) { $content = preg_replace($pattern, '', $content); } file_put_contents($htaccess_file, $content); } // Ajouter protections sécuritaires $security_rules = ' # ===== PROTECTIONS SÉCURITAIRES ===== # Protection fichiers sensibles order allow,deny deny from all order allow,deny deny from all # Bloquer injections scripts RewriteCond %{QUERY_STRING} (<|%3C)([^s]*s)+cript.*(>|%3E) [NC,OR] RewriteCond %{QUERY_STRING} GLOBALS(=|\[|\%[0-9A-Z]{0,2}) [OR] RewriteCond %{QUERY_STRING} _REQUEST(=|\[|\%[0-9A-Z]{0,2}) [OR] RewriteCond %{QUERY_STRING} base64_(en|de)code[^(]*\([^)]*\) [OR] RewriteCond %{QUERY_STRING} (\<|%3C).*script.*(\>|%3E) [NC] RewriteRule ^(.*)$ - [F,L] # Bloquer exécution PHP dans uploads Order deny,allow Deny from all '; file_put_contents($htaccess_file, $security_rules, FILE_APPEND); return 'Fichier .htaccess sécurisé'; } /** * Sécurisation du fichier wp-config.php */ private function secureWpConfig() { $wp_config = $this->wp_path . '/wp-config.php'; if (!file_exists($wp_config)) { return 'wp-config.php non trouvé'; } $content = file_get_contents($wp_config); $additions = []; // Constantes de sécurité $security_constants = [ "DISALLOW_FILE_EDIT" => "true", "DISALLOW_FILE_MODS" => "true", "FORCE_SSL_ADMIN" => "true", "WP_POST_REVISIONS" => "3", "EMPTY_TRASH_DAYS" => "7", "AUTOMATIC_UPDATER_DISABLED" => "false" ]; foreach ($security_constants as $constant => $value) { if (strpos($content, $constant) === false) { $additions[] = "define('{$constant}', {$value});"; } } if (!empty($additions)) { $insert_point = strpos($content, 'wp_path . '/' . $file; if (file_exists($file_path)) { unlink($file_path); $removed++; } } return "{$removed} fichiers indésirables supprimés"; } /** * Création de fichiers de protection */ private function createProtectionFiles() { $created = 0; // Protection du dossier uploads $uploads_dir = $this->wp_path . '/wp-content/uploads'; if (is_dir($uploads_dir)) { $uploads_htaccess = $uploads_dir . '/.htaccess'; if (!file_exists($uploads_htaccess)) { $protection_content = '# Bloquer exécution PHP Order Deny,Allow Deny from all '; file_put_contents($uploads_htaccess, $protection_content); $created++; } } // Index.php de protection dans les dossiers sensibles $protect_dirs = [ '/wp-content/', '/wp-content/plugins/', '/wp-content/themes/', '/wp-content/uploads/' ]; foreach ($protect_dirs as $dir) { $dir_path = $this->wp_path . $dir; $index_file = $dir_path . 'index.php'; if (is_dir($dir_path) && !file_exists($index_file)) { file_put_contents($index_file, ' date('Y-m-d H:i:s'), 'version' => self::VERSION, 'wp_path' => $this->wp_path, 'wp_info' => $this->getWordPressInfo(), 'statistics' => $this->statistics, 'scan_results' => $this->scan_results, 'recommendations' => $this->generateRecommendations() ]; $filename = self::REPORTS_DIR . '/malware_report_' . date('Y-m-d_H-i-s'); switch ($format) { case 'json': $filename .= '.json'; file_put_contents($filename, json_encode($report_data, JSON_PRETTY_PRINT)); break; case 'html': $filename .= '.html'; $html_content = $this->generateHtmlReport($report_data); file_put_contents($filename, $html_content); break; default: throw new Exception("Format de rapport non supporté: {$format}"); } $this->log('SUCCESS', "Rapport généré: {$filename}"); return $filename; } /** * Génération de recommandations basées sur les résultats */ private function generateRecommendations() { $recommendations = []; if ($this->statistics['infections_found'] > 0) { $recommendations[] = [ 'priority' => 'critical', 'title' => 'Nettoyer les infections détectées', 'description' => 'Des fichiers infectés ont été détectés et doivent être nettoyés immédiatement.' ]; } if ($this->statistics['backdoors_found'] > 0) { $recommendations[] = [ 'priority' => 'critical', 'title' => 'Backdoors détectés - Intervention urgente', 'description' => 'Des backdoors ont été détectés. Changez tous les mots de passe et contactez un expert.' ]; } $recommendations[] = [ 'priority' => 'high', 'title' => 'Mettre à jour WordPress et plugins', 'description' => 'Assurez-vous que WordPress et tous les plugins/thèmes sont à jour.' ]; $recommendations[] = [ 'priority' => 'medium', 'title' => 'Installer un plugin de sécurité', 'description' => 'Installez Wordfence ou Sucuri pour une protection continue.' ]; $recommendations[] = [ 'priority' => 'medium', 'title' => 'Configurer des sauvegardes automatiques', 'description' => 'Mettez en place des sauvegardes régulières et automatiques.' ]; return $recommendations; } /** * Génération de rapport HTML */ private function generateHtmlReport($data) { ob_start(); ?> Rapport Scanner Malware WordPress

🛡️ Rapport Scanner Malware WordPress

Généré le: | Version:

📊 Statistiques du Scan

Fichiers scannés
Infections détectées
Backdoors trouvés
Injections détectées
Fichiers suspects

ℹ️ Informations WordPress

  • Chemin:
  • Version:
  • Plugins installés:
  • Thèmes installés:

🚨 Menaces Détectées

$threats): ?>

📁

: (Sévérité: )

✅ Aucune Menace Détectée

Félicitations! Aucun malware n'a été détecté lors de ce scan.

💡 Recommandations

'Backdoor utilisant eval() avec données externes', 'backdoor_system' => 'Backdoor permettant l\'exécution de commandes système', 'backdoor_exec' => 'Backdoor permettant l\'exécution de code', 'backdoor_shell' => 'Backdoor shell permettant l\'exécution de commandes', 'backdoor_base64' => 'Code malveillant obfusqué en base64', 'js_injection_eval' => 'Injection JavaScript malveillante', 'js_injection_iframe_hidden' => 'Iframe cachée potentiellement malveillante', 'pharma_viagra' => 'Contenu lié au pharma hack', 'redirect_meta' => 'Redirection malveillante via meta refresh', 'obfuscated_chr' => 'Code obfusqué utilisant des caractères', 'dangerous_file_get_contents' => 'Téléchargement de fichier distant suspect' ]; return $descriptions[$pattern_name] ?? 'Pattern malveillant détecté'; } /** * Interface web principale */ public function renderWebInterface() { $action = $_GET['action'] ?? 'dashboard'; switch ($action) { case 'scan': return $this->handleScanRequest(); case 'clean': return $this->handleCleanRequest(); case 'harden': return $this->handleHardenRequest(); case 'report': return $this->handleReportRequest(); case 'api': return $this->handleApiRequest(); default: return $this->renderDashboard(); } } /** * Gestionnaire de requête de scan */ private function handleScanRequest() { if ($_SERVER['REQUEST_METHOD'] === 'POST') { try { $results = $this->fullScan(); $_SESSION['last_scan'] = [ 'timestamp' => time(), 'results' => $results, 'statistics' => $this->statistics ]; return json_encode(['success' => true, 'results' => $results, 'statistics' => $this->statistics]); } catch (Exception $e) { return json_encode(['success' => false, 'error' => $e->getMessage()]); } } return $this->renderScanInterface(); } /** * Gestionnaire de requête de nettoyage */ private function handleCleanRequest() { if ($_SERVER['REQUEST_METHOD'] === 'POST' && !empty($this->scan_results)) { try { $results = $this->autoClean(); return json_encode(['success' => true, 'results' => $results]); } catch (Exception $e) { return json_encode(['success' => false, 'error' => $e->getMessage()]); } } return json_encode(['success' => false, 'error' => 'Aucun scan préalable détecté']); } /** * Gestionnaire de requête de sécurisation */ private function handleHardenRequest() { if ($_SERVER['REQUEST_METHOD'] === 'POST') { try { $results = $this->hardenWordPress(); return json_encode(['success' => true, 'results' => $results]); } catch (Exception $e) { return json_encode(['success' => false, 'error' => $e->getMessage()]); } } return json_encode(['success' => false, 'error' => 'Méthode non autorisée']); } /** * Gestionnaire de génération de rapport */ private function handleReportRequest() { $format = $_GET['format'] ?? 'html'; try { $filename = $this->generateReport($format); return json_encode(['success' => true, 'filename' => $filename]); } catch (Exception $e) { return json_encode(['success' => false, 'error' => $e->getMessage()]); } } /** * Rendu du tableau de bord principal */ private function renderDashboard() { ob_start(); ?> WordPress Expert Malware Scanner

🛡️ WordPress Expert Malware Scanner

Scanner professionnel de détection et nettoyage de malware WordPress

Version | Chemin: wp_path) ?>

🔍 Scanner le Site

Effectuer un scan complet pour détecter les malwares, backdoors et fichiers suspects.

Scan en cours...

🧹 Nettoyage Automatique

Nettoyer automatiquement les fichiers infectés détectés lors du dernier scan.

🔒 Sécurisation WordPress

Durcir la sécurité de WordPress (permissions, .htaccess, wp-config.php).

📊 Rapports

Générer des rapports détaillés des scans et actions effectuées.

📈 Dernier Scan

Effectué le:

Fichiers scannés
Infections trouvées
Backdoors détectés
0): ?>
⚠️ Attention: Des infections ont été détectées lors du dernier scan. Il est recommandé de nettoyer immédiatement.
✅ Excellent: Aucune infection détectée lors du dernier scan.
validateWordPress(); // Si c'est une requête AJAX, renvoyer directement la réponse JSON if (isset($_GET['action']) && $_GET['action'] !== 'dashboard') { header('Content-Type: application/json'); echo $scanner->renderWebInterface(); exit; } // Sinon, afficher l'interface web echo $scanner->renderWebInterface(); } catch (Exception $e) { // Gestion d'erreur avec interface basique ?> Erreur - WordPress Malware Scanner

🚨 Erreur d'Initialisation

Message: getMessage()) ?>

Solutions possibles:

  • Vérifiez que le script est placé dans un répertoire WordPress valide
  • Assurez-vous que les permissions sont correctes
  • Spécifiez le chemin WordPress: ?wp_path=/chemin/vers/wordpress