/
/
home
/
u523034047
/
domains
Server: in-mum-web1112.main-hosting.eu (62.72.28.111)
You: 216.73.216.4
PHP 8.3.16
Dir:
/home/u523034047/domains
Edit:
/home/u523034047/domains/detect_malicious_shared.php
<?php // detect_malicious_shared.php // Scans a path, logs suspicious files, optionally moves them to quarantine or deletes them. // Usage: place in your home dir (outside public_html if possible) and run via cron or CLI. // Produces scan_report.json and scan_report.txt in same dir. // ---------------- CONFIG ---------------- $rootToScan = '/home/u523034047/domains/'; // <-- set to your path $reportJson = __DIR__ . '/scan_report.json'; $reportTxt = __DIR__ . '/scan_report.txt'; $quarantineDir = __DIR__ . '/quarantine/'; // files moved here when autoDelete enabled $maxContentScanBytes = 2 * 1024 * 1024; // 2 MB - avoid huge files $recentDays = 7; // modified within N days considered recent // Safety flags $autoDelete = false; // false = DO NOT move/delete. true = move to quarantine (preferred) or unlink fallback. $deleteZips = false; // if true, .zip files flagged by patterns will also be removed/moved. // Patterns to flag (obfuscation/execution) $patterns = [ '/eval\s*\(/i' => 'eval()', '/base64_decode\s*\(/i' => 'base64_decode() - probable obfuscation', '/gzinflate\s*\(/i' => 'gzinflate()/gzuncompress - obfuscation', '/str_rot13\s*\(/i' => 'str_rot13()', '/preg_replace\s*\(.*\/e.*\)/is' => 'preg_replace with /e (risky)', '/shell_exec\s*\(/i' => 'shell_exec()', '/passthru\s*\(/i' => 'passthru()', '/exec\s*\(/i' => 'exec()', '/popen\s*\(/i' => 'popen()', '/proc_open\s*\(/i' => 'proc_open()', '/assert\s*\(/i' => 'assert()', '/create_function\s*\(/i' => 'create_function()', '/file_put_contents\s*\(.*\.php/i' => 'writing .php file', '/php:\/\/input/i' => 'php://input usage', '/base64_decode\([\s\S]{200,}\)/i' => 'large base64 payload inline', ]; // suspicious filenames (common shells/backdoors) $suspiciousNames = array_map('strtolower', [ 'pass.php','pass.php4','pass.mp4','monarx-analyzer.php','adminer.php','wp-takito.php', 'mainhackbypass.php','wp-trackbackj.php','wp-blog-header.php','test1.php','root.php','db.php', '705.zip','715.zip','810.zip','811.zip','db.zip' ]); // ---------------------------------------- function appendReportLine($line) { global $reportTxt; file_put_contents($reportTxt, $line . PHP_EOL, FILE_APPEND); } function safeGetContents($file, $maxBytes) { $size = @filesize($file); if ($size === false) return false; if ($size > $maxBytes) $size = $maxBytes; $h = @fopen($file, 'rb'); if (!$h) return false; $data = @fread($h, $size); fclose($h); return $data; } function ensureDir($dir) { if (!is_dir($dir)) { @mkdir($dir, 0750, true); } return is_dir($dir); } function moveToQuarantine($path, $quarantineDir) { $base = basename($path); $target = rtrim($quarantineDir, '/') . '/' . date('Ymd_His') . '_' . uniqid() . '_' . $base; if (@rename($path, $target)) { return $target; } // fallback: try copy then unlink if (@copy($path, $target)) { if (@unlink($path)) return $target; } return false; } function safeUnlink($path) { try { if (!file_exists($path)) return false; return @unlink($path); } catch (Exception $e) { return false; } } // initialize @unlink($reportJson); @unlink($reportTxt); ensureDir($quarantineDir); $report = [ 'scanned_root' => $rootToScan, 'time' => date('c'), 'suspicious_files' => [], 'recently_modified' => [], 'world_writable' => [], 'htaccess_userini_issues' => [], 'moved_to_quarantine' => [], 'deleted_files' => [], 'notes' => [] ]; appendReportLine("=== Scan started: " . date('c') . " ==="); appendReportLine("Scan root: $rootToScan"); appendReportLine("Auto-delete (move to quarantine) is " . ($GLOBALS['autoDelete'] ? 'ENABLED' : 'DISABLED')); appendReportLine("Quarantine dir: $quarantineDir"); appendReportLine("This script WILL log all actions. Review before taking more steps."); // validate root if (!is_dir($rootToScan)) { appendReportLine("ERROR: rootToScan not found or not a directory: $rootToScan"); $report['notes'][] = "rootToScan missing"; file_put_contents($reportJson, json_encode($report, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES)); exit; } $recentLimit = time() - ($recentDays * 24 * 3600); $rii = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($rootToScan, FilesystemIterator::SKIP_DOTS)); foreach ($rii as $file) { $path = $file->getPathname(); $fname = $file->getFilename(); $lowerName = strtolower($fname); // skip vendor/node_modules/.git to speed up if (strpos($path, '/node_modules/') !== false || strpos($path, '/.git/') !== false) continue; // basic stat $isFile = $file->isFile(); $isDir = $file->isDir(); // recently modified $mtime = @filemtime($path); if ($mtime !== false && $mtime >= $recentLimit) { $report['recently_modified'][] = ['path'=> $path, 'mtime'=> date('c', $mtime)]; appendReportLine("[RECENT] $path (mtime: ".date('c',$mtime).")"); } // world-writable check (file or dir) if (@is_writable($path)) { $perms = @fileperms($path); if ($perms !== false && ($perms & 0x0002)) { // others write bit $report['world_writable'][] = ['path'=>$path, 'perms'=>sprintf('%o', $perms)]; appendReportLine("[WRITABLE] $path perms: ".sprintf('%o',$perms)); } } // suspicious filename if ($isFile && in_array($lowerName, $GLOBALS['suspiciousNames'], true)) { $report['suspicious_files'][$path][] = 'filename matches known suspicious name: ' . $fname; appendReportLine("[SUS NAME] $path"); // deletion/move action if ($GLOBALS['autoDelete']) { $moved = moveToQuarantine($path, $quarantineDir); if ($moved) { $report['moved_to_quarantine'][] = $moved; appendReportLine("[MOVED] $path -> $moved"); } else { // try unlink if (safeUnlink($path)) { $report['deleted_files'][] = $path; appendReportLine("[DELETED] $path (unlink fallback)"); } else { appendReportLine("[FAILED] Could not move or delete: $path"); } } } } // check .htaccess / .user.ini for auto_prepend/append or suspicious php_value if ($isFile && in_array($lowerName, ['.htaccess', '.user.ini', 'php.ini'])) { $content = safeGetContents($path, 50000); if ($content) { if (preg_match('/auto_prepend_file\s*=\s*(.*)/i', $content, $m) || preg_match('/php_value\s+auto_prepend_file\s+(.*)/i', $content, $m2)) { $report['htaccess_userini_issues'][$path] = 'auto_prepend detected'; appendReportLine("[AUTOPREPEND] $path -> " . trim($m[1]??$m2[1]??'')); } if (preg_match('/auto_append_file\s*=\s*(.*)/i', $content, $m3)) { $report['htaccess_userini_issues'][$path] = 'auto_append detected'; appendReportLine("[AUTOAPPEND] $path -> " . trim($m3[1] ?? '')); } } } // content-based scanning for files (limit size) if ($isFile) { $ext = strtolower(pathinfo($path, PATHINFO_EXTENSION)); // only scan text-like files: php, inc, html, js, txt, css, zip optionally if (in_array($ext, ['php','inc','phtml','html','htm','js','css','txt','tpl','ini','zip'])) { $content = safeGetContents($path, $maxContentScanBytes); if ($content === false) continue; // check patterns foreach ($patterns as $regex => $desc) { if (preg_match($regex, $content)) { $report['suspicious_files'][$path][] = $desc; appendReportLine("[SUSPICIOUS] $path -> $desc"); } } // very long base64-like blobs if (preg_match('/[A-Za-z0-9\/+\s]{200,}={0,2}/', $content)) { $report['suspicious_files'][$path][] = 'long base64-like blob in file'; appendReportLine("[SUSPICIOUS] $path -> long base64-like content"); } // if it's a zip and deleteZips is enabled, mark for action if ($ext === 'zip' && $GLOBALS['deleteZips'] && preg_match('/[A-Za-z0-9\/+\s]{50,}={0,2}/', $content)) { // treat as suspicious zip (but content of zip isn't read here) $report['suspicious_files'][$path][] = 'zip flagged (deleteZips enabled)'; appendReportLine("[SUSPICIOUS-ZIP] $path"); } // If file was flagged (has suspicious entries) and autoDelete enabled -> move/unlink if ($GLOBALS['autoDelete'] && isset($report['suspicious_files'][$path])) { $moved = moveToQuarantine($path, $quarantineDir); if ($moved) { $report['moved_to_quarantine'][] = $moved; appendReportLine("[MOVED] $path -> $moved"); } else { if (safeUnlink($path)) { $report['deleted_files'][] = $path; appendReportLine("[DELETED] $path (unlink fallback)"); } else { appendReportLine("[FAILED] Could not move or delete: $path"); } } } } } } // write JSON and text report file_put_contents($reportJson, json_encode($report, JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES)); appendReportLine("=== Scan finished: ".date('c')." ==="); appendReportLine("JSON report: $reportJson"); appendReportLine("Text report: $reportTxt"); appendReportLine("Quarantine directory: $quarantineDir"); appendReportLine("IMPORTANT: Review quarantine BEFORE permanent deletion. Keep backups."); // output small summary to STDOUT if run via CLI if (php_sapi_name() === 'cli') { echo "Scan complete. Reports: $reportJson and $reportTxt\n"; echo "Auto-delete is " . ($autoDelete ? 'ENABLED' : 'DISABLED') . "\n"; }
Ukuran: 10.1 KB