Linux server1.signalhg.team 4.18.0-553.134.1.el8_10.x86_64 #1 SMP Tue Jun 16 16:05:57 EDT 2026 x86_64
Apache
: 209.74.80.147 | : 216.73.216.169
150 Domain
8.1.34
signgwph
Terminal
AUTO ROOT
Adminer
Backdoor Destroyer
Linux Exploit
Lock Shell
Lock File
Create User
CREATE RDP
PHP Mailer
BACKCONNECT
UNLOCK SHELL
HASH IDENTIFIER
README
+ Create Folder
+ Create File
/
home /
signgwph /
talkingwithheroes.com /
[ HOME SHELL ]
Name
Size
Permission
Action
.pkexec
[ DIR ]
drwxr-xr-x
.tmb
[ DIR ]
drwxr-xr-x
.well-known
[ DIR ]
drwxr-xr-x
F9EVbg
[ DIR ]
drwxr-xr-x
GCONV_PATH=.
[ DIR ]
drwxr-xr-x
GSwU
[ DIR ]
drwxr-xr-x
Oam3b
[ DIR ]
drwxr-xr-x
__MACOSX
[ DIR ]
drwxr-xr-x
cgi-bin
[ DIR ]
drwxr-xr-x
image
[ DIR ]
drwxr-xr-x
ldY
[ DIR ]
drwxr-xr-x
var
[ DIR ]
drwxr-xr-x
wp-admin
[ DIR ]
drwxr-xr-x
wp-content
[ DIR ]
drwxr-xr-x
wp-includes
[ DIR ]
drwxr-xr-x
yw8Ly
[ DIR ]
drwxr-xr-x
.hcflag
30
B
-rw-r--r--
.htaccess.bk
186
B
-rw-r--r--
.htaccess1
1.06
KB
-rw-r--r--
.idx.dat
128
B
-rw-r--r--
.litespeed_flag
297
B
-rw-r--r--
.mad-root
0
B
-rw-r--r--
.tmb.zip
1.37
GB
-rw-r--r--
3PJcpMFsD8B.php
834
B
-rw-r--r--
air.php
37.83
KB
-rw-r--r--
ee.txt
4
B
-rw-r--r--
error_log
67.11
MB
-rw-r--r--
google4ebe3fc7a43a4452.html
53
B
-rw-r--r--
google62e6ca9fcbf1ca7c.html
53
B
-rw-r--r--
google763d589bea908c67.html
53
B
-rw-r--r--
google85ba7646e0b1fcc1 (1).htm...
53
B
-rw-r--r--
googlee9b09490e78f6c82.html
53
B
-rw-r--r--
home.php
273.6
KB
-rw-r--r--
index.html
273.6
KB
-rw-r--r--
index.php
417.07
KB
-r--r--r--
license-vuxn.php
629
B
-rw-r--r--
license.txt
19.44
KB
-rw-r--r--
old.php
404
B
-rw-r--r--
php.ini
582
B
-rw-r--r--
pwnkit
10.99
KB
-rwxr-xr-x
readme.6bcdda3524d835e991ab493...
7.23
KB
-rw-r--r--
readme.html
7.23
KB
-rw-r--r--
robots.txt
75
B
-rw-r--r--
scan-shell.php
67.71
KB
-rw-r--r--
signaguz_herooo.sql
326.57
MB
-rw-r--r--
wordfence-waf.php
0
B
-rw-r--r--
wp-activate.php
7.54
KB
-rw-r--r--
wp-blog-header.php
351
B
-rw-r--r--
wp-comments-post.php
2.27
KB
-rw-r--r--
wp-config-sample.php
3.26
KB
-rw-r--r--
wp-config.php
3.57
KB
-rw-------
wp-cron.php
5.49
KB
-rw-r--r--
wp-links-opml.php
2.43
KB
-rw-r--r--
wp-load.php
3.84
KB
-rw-r--r--
wp-login.php
51.3
KB
-rw-r--r--
wp-mail.php
8.52
KB
-rw-r--r--
wp-settings.php
32.38
KB
-rw-r--r--
wp-signup.php
34.26
KB
-rw-r--r--
wp-trackback.php
5.27
KB
-rw-r--r--
xmlrpc.php
3.13
KB
-rw-r--r--
Delete
Unzip
Zip
${this.title}
Close
Code Editor : scan-shell.php
<?php /** * Shell Destroyer v2.0 * Compatible: PHP 5.4+ | Windows & Linux/Unix * Author: Security Tool */ error_reporting(0); ini_set('display_errors', 0); session_start(); // ========================================================================= // SHELL PATTERNS DATABASE - Nama-nama shell yang dikenal // ========================================================================= $SHELL_PATTERNS = [ "Saudi Sh3ll</", "<title>DATA CENTER INDONESIA</title>", "<b>FX Shell Backdoor</b>", "<title>#CLS-LEAK#</title>", ">File Upload :<", "Bypass Sh3ll", "Yanz Webshell!", ">[ Home Shell ]<", ">File Manager<", ">webadmin.php</h1>", "C99Shell.<", ">Beyaz_Hacker.php</h1>", "WebShell<", "Web Shell<", "403 Bypass Shell<", "404 Bypass Shell<", "Bypass Shell<", "<th>Permissions</th>", "<th>Owner/Group</th>", "> Choose a file<", ">Uname:<", "TheAlmightyZeus", ">Gel4y Mini Shell</a>", "</i> Terminal</a>", 'value="Upload', "value='Upload", ">-rw-rw-rw- <", "<title>Eclipse File Manager</title>", "<title>{ IndoSec sHell }</title>", "root@indoxploit:~#", "<title>Tiny File Manager</title>", ">22XploiterCrew</h2>", "<title>22XploiterCrew</title>", '<input style="margin:0;background-color:#fff;border:1px solid #fff;" type="password" name="password">', "<input style='margin:0;background-color:#fff;border:1px solid #fff;' type='password' name='password'>", '<input type="password" id="auth" name="auth" required style="margin:0;background-color:#fff;border:1px solid #fff;">', '<input type="password" name="pass" placeholder=" Password"> ', "<title>~ EviLMora-v4.1-Re-Tesla ~</title>", '<input type="password" size="30" name="password" placeholder="password" onfocus="if (this.value == \'password\') this.value = \'\';">', '<input type="password" name="getpwd">', '<input type="password" class="form-control" id="fm_pwd" name="fm_pwd" required autofocus>', '<input type="password" id="password" name="password">', "<title>Komdigi FileManager - Login</title>", ">C0mmand<", ">File Manager | Akmal archtte id<", ">BonsShell403<", ">[ SSG SHELL ]<", "https://aurorafilemanager.github.io/", "<title>Leaf PHPMailer</title>", "<b>ngehe<b>", "United Tunsian Scammers", "Web Console", "http://www.ubhteam.org/images/UBHFinal1.png", "WSO 2.6", "United Bangladeshi Hackers", "[UNAME]:", "xichang1", "Hckd By? Html404", "JEMBOETS", "<title>Mister Spy</title>", "<title>IndoXploit</title>", "AnonymousFox", "Andela1C3", "Tryag File Manager", "<title>Legion</title>", "Mini shell<", "Shell Uploader<", "walex says Fuck Off Kids:", "BlesseD MAILER 2014", "w4l3XzY3 Mailer", "iCloud1337 private shell", "Copyright 2017 | ErrOr SquaD All Rights Reserved.", "Vuln!! patch it Now!", "http://i.imgur.com/kkhH5Ig.png", "<title>File</title>", "U7TiM4T3_H4x0R Plugin", "D0cum3nt_r0ot", "-rw-r--r--", "rwxrwxrwx", "drwxr-xr-x", "drwxrwxrwx", "L I E R SHELL", "{Ninja-Shell}", "x3x3x3x_5h3ll", "LIT COUSRE TEAM", "403WebShell", "Indonesian Darknet", "AnonSec Shell", "<title>MARIJUANA</title>", "File manager -", "bondowoso black hat shell", "BlackDragon", "xXx Kelelawar Cyber Team xXx", "UnknownSec", "NineSec Team Shell", "ineSec Team Shell", "[ HOME SHELL ]", "RC-SHELL", "<title>Mini Shell</title>", "Negat1ve Shell", "[+[MAD TIGER]+]", "Franz Private Shell", "Webshell V1.0", ">Cassano Bypass <", "TEAM-0ROOT", "Fighter Kamrul Plugin", "- FierzaXploit -", "<title>FierzaXploit</title>", "Current dir:", "Current directory:", "[ ! ] Cilent Shell Backdor [ ! ]", "Mini Shell By Black_Shadow", "FileManager Version", "aDriv4-Priv8 TOOL", "B Ge Team File Manager", "CHips L Pro sangad", "Doc Root:", "[+] MINI SH3LL BYPASS [+]", "#No_Identity", "[ Mini Shell ]", "PHU Mini Shell", "MSQ_403", "#wp_config_error#", "Graybyt3 Was Here", "One Hat Cyber Team", "Mr.Combet WebShell", "C0d3d By Dr.D3m0", "Zerion Mini Shell", "<title>AK-74 Security Team Web Shell</title>", "<b>Current Path : </b>", "<title>AnonSec Team</title>", ">407@localhost:~$ <", "<title>Anonim Us</title>", "<title>Ani-Shell | India</title>", "Antichat Shell</title>", ">Alfa Settings<", "~ XList SheLL | XList SheLL v1.9 ::..<", "<title>.: Rebirth Haxor :.</title>", "<title>AnarchoXploit || Shell</title>", "BLACK CODERS ANONYMOUS AND ANON GHOST TEAM", "<title>NuLz WebShell Login</title>", "Uname:", "SEA-GHOST MINSHELL", "[ Avaa Bypassed ]", "0byt3m1n1 Shell", "<title>File manager</title>", "<title>000</title>", "PHP File Manager", "Shell Bypass 403 GE-C666C", "b374k 2.8", "0byte v2 Shell", "Public Shell Version 2.0", "<title>Fuxxer</title>", "<span>Upload file:</span", "<title>WIBUHAX0R1337 - ShelL</title>", "<title>Simple Shell</title>", "Cod3d By AnonymousFox", '<a href="?"><img src="https://github.com/fluidicon.png" width="30" height="30" alt=""></a>', "<h1>Ghost Exploiter Team Official</h1>", "<h2>Your IP :", '<input type="submit" name="mkdir" value="Make directory">', '<div class="corner text-secondary">shell bypass 403</div>', '<input type="submit" value="ok">', 'type="submit" value="upload"', "#block-css#", "vulncode", "<title>||TINY SHELL ||</title>", "<small>Copyright © 2021 - Haxor Clan</small>", "<title>#shwty</title>", 'Upload File : <input type="file" name="file" />', "<h1>Mad Tools Shell</h1>", 'input type="file" id="inputfile" name="inputfile"', " Backdoor Destroyer", "KCT MINI SHELL 403", '<a href="https://github.com/Den1xxx/Filemanager">', "title>V4Mp</title", "AlkantarClanX12", "j3mb03dz m4w0tz sh311", "title>Smoker Backdoor</title", "MINI MO Shell", "[ HOME ]", '" name="command" placeholder="Command"', 'input type="text" readonly="1" id="upload_visible"', "ALFA TEaM Shell", "<title>Get S.H.E.L.L.en v1.0", "Hunter Neel", 'input type="submit" value="Upload Image" name="submit"', "-rwxr-xr-x", "<h1>[ Shin Bypassed ]</h1>", "<title>Qu?n lý File</title>", "404-server!!", "MisterSpyv7up", "Raiz0WorM", "Black Bot", "Madstore.sk!", "nopebee7 [@] skullxploit", "X0MB13", "https://github.com/fluidicon.png", "Priv8 Sh3ll!", "X-Sec Shell V.3", "p0wny@shell:~#", "Priv8 WebShell", "m1n1 Shell", "#p@@#", "#0x1877", "X4Exploit", "kill_the_net", "<title>kaylin", ">Lock Shell</a></li>", "<title>MATTEKUDASAI</title>", "PHP-SHELL HUNTER", "config root man", "X_Shell", "izocin", "x7root", "X7-ROOT", "private shell", "SuramSh3ll", "Walkers404 Xh3ll B4ckd00r", "<title>R@DIK@L</title>", "<title>PhpShells.Com</title>", "MarukoChan Priv8", "King RxR Was", "<div><h5>DSH v0.1</h5>", "RxR HaCkEr", "SOQOR Shell By : HACKERS PAL", '<input type="file" name="apx"', "#0x2525", 'name="uploader" id="uploader"', 'input type="file" name="file"><input name="_upl" type="submit"', "<title>Upload files...</title", "<button>Gaskan</button>", '<input type="file" size="20" name="uploads" /> <input type="submit" value="upload" />', 'input type=text name=path><input type="file" name="files"><input type=submit value="Up"', '<input type="file" size="20" name="file_jpg" /> <input type="submit" value="upload" />', 'type="file"><input type="submit" value="Upload"', "Notice: Do not delete or modify the CERT-FILE", "aDriv4 Uploader", "DeathShop Uploader", "ini PHP Upload By Haxgeno7", 'input type="submit" name="linknya" class="up" value="Upload', 'input type="file" name="__"><input name="_" type="submit" value="Upload"', "<input type=hidden name=p1 value=", "GeliÅŸmiÅŸ Dosya Yöneticisi", "<title>./LahBodoAmat Uploader shells</title>", 'Upload File: <input type="file" name="file"\' type="button">', '<input type="file" name="fileToUpload" id="fileToUpload"', 'name="uploader" id="uploader"><input type="file" name="file"><input name="_upl" type="submit" id="_upl"<Upl file</a></td>', '<input name="ext" type="text" value=".php"/>', 'type="file"/><input type="submit" value="doit"/></form>', 'type="password" name="pwdyt"', "%PDF-0-1<form action", "form method=post>Password: <input type=password name=pass><input type=submit value=", '<input type="password" name="pwd" title="Password" autofocus>', '"<pre align=center><form method=post>Password<br>', '<html><head><title>Login</title></head><body><form action="" method="POST">', "name='watching", "<input type=password name=pass", "<title>DRUNK SHELL BETA </title>", "<input type=password name='xxx'>", "b374k <span=", "[~] S4f3 H4ck3r [~]", "<title>CyberGhost Shell</title>", ">Mr.Root Shell<", ">Defacer ID<", "<title>GreenShell</title>", "<title>RedShell</title>", "<title>BlueShell</title>", "<title>BlackShell</title>", "<title>WhiteShell</title>", "<title>DragonShell</title>", "<title>PhoenixShell</title>", "<title>KrakenShell</title>", "<title>ShadowShell</title>", "<title>PhantomShell</title>", "<title>VenomShell</title>", "<title>PredatorShell</title>", "<title>ReaperShell</title>", "<title>DestroyerShell</title>", "<title>TerminatorShell</title>", "<title>AdminShell</title>", "<title>SecureShell</title>", "<title>UltimateShell</title>", "<title>ProShell</title>", "<title>EasyShell</title>", "<title>SimpleShell</title>", "<title>PowerShell</title>", "<title>MasterShell</title>", "<title>EliteShell</title>", "<title>PrimeShell</title>", "<title>CoreShell</title>", "<title>NexusShell</title>", "<title>ApexShell</title>", "<title>ZenShell</title>", "<title>NovaShell</title>", "<title>QuantumShell</title>", "<title>InfernoShell</title>", "<title>FrostShell</title>", "<title>StormShell</title>", "<title>ThunderShell</title>", "<title>LightningShell</title>", "<title>BlazeShell</title>", "<title>VortexShell</title>", "<title>EclipseShell</title>", "<title>AuroraShell</title>", "<title>NebulaShell</title>", "<title>GalaxyShell</title>", "<title>CosmicShell</title>", "<title>AtomicShell</title>", "<title>NeonShell</title>", "<title>CyberShell</title>", "<title>TechnoShell</title>", "<title>DigitalShell</title>", "<title>BinaryShell</title>", "<title>ZeroShell</title>", "<title>OneShell</title>", "<title>AlphaShell</title>", "<title>BetaShell</title>", "<title>GammaShell</title>", "<title>DeltaShell</title>", "<title>OmegaShell</title>", "<title>SigmaShell</title>", "<title>NanoShell</title>", "<title>MegaShell</title>", "<title>GigaShell</title>", "<title>TeraShell</title>", "<title>PetaShell</title>", "<title>ExaShell</title>", "<title>ZettaShell</title>", "<title>YottaShell</title>", "<title>BrontoShell</title>", "<title>GeoSec Shell</title>", "<title>Lunar Shell</title>", "<title>Solar Shell</title>", "<title>Stellar Shell</title>", "<title>Orion Shell</title>", "<title>Andromeda Shell</title>", "<title>Sirius Shell</title>", "<title>Vega Shell</title>", "<title>Polaris Shell</title>", "<title>Altair Shell</title>", "<title>Rigel Shell</title>", "<title>Betelgeuse Shell</title>", "<title>Antares Shell</title>", "<title>Canopus Shell</title>", "<title>Acamar Shell</title>", "<title>Aldebaran Shell</title>", "<title>Arcturus Shell</title>", "<title>Capella Shell</title>", "<title>Castor Shell</title>", "<title>Pollux Shell</title>", "<title>Deneb Shell</title>", "<title>Fomalhaut Shell</title>", "<title>Mira Shell</title>", "<title>Procyon Shell</title>", "<title>Regulus Shell</title>", "<title>Spica Shell</title>", "<title>Zosma Shell</title>", "<title>Alphard Shell</title>", "<title>Baten Shell</title>", "<title>Cursa Shell</title>", "<title>Diphda Shell</title>", "<title>Enif Shell</title>", "<title>Giedi Shell</title>", "<title>Hadar Shell</title>", "<title>Izar Shell</title>", "<title>Kochab Shell</title>", "<title>Maia Shell</title>", "<title>Mintaka Shell</title>", "<title>Mizar Shell</title>", "<title>Phecda Shell</title>", "<title>Rasalgethi Shell</title>", "<title>Rastaban Shell</title>", "<title>Sadr Shell</title>", "<title>Scheat Shell</title>", "<title>Segin Shell</title>", "<title>Shaula Shell</title>", "<title>Suhail Shell</title>", "<title>Tyl Shell</title>", "<title>Wazn Shell</title>", "<title>Zubenelgenubi Shell</title>", "<title>Zubeneschamali Shell</title>", ]; // ========================================================================= // CROSS-PLATFORM PATH HELPER // ========================================================================= function normalize_path($path) { // Normalize slashes untuk Windows & Linux $path = str_replace('\\', '/', $path); $path = rtrim($path, '/'); return $path; } function get_os() { return (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') ? 'windows' : 'linux'; } function get_default_paths() { if (get_os() === 'windows') { return array( 'C:/xampp/htdocs', 'C:/wamp/www', 'C:/laragon/www', 'C:/inetpub/wwwroot', ); } else { return array( '/var/www/html', '/home/' . get_current_user() . '/public_html', '/srv/www', dirname(__FILE__), ); } } // ========================================================================= // DETECTION ENGINE // ========================================================================= function detect_webshell($filepath) { global $SHELL_PATTERNS; if (!file_exists($filepath)) return null; $content = @file_get_contents($filepath); if (!$content || strlen($content) < 30) return null; if (strpos($content, '<?php') === false && strpos($content, '<?=') === false && strpos($content, '<%') === false) { return null; } $dangerous_funcs = array( 'shell_exec', 'exec', 'system', 'passthru', 'popen', 'proc_open', 'eval', 'assert', 'create_function', 'preg_replace', 'gzuncompress', 'gzinflate', 'gzdecode', 'str_rot13', 'base64_decode', 'hex2bin', 'move_uploaded_file', 'file_put_contents', 'fwrite', 'fputs', 'curl_exec', 'fsockopen', 'pfsockopen', ); $found_funcs = array(); foreach ($dangerous_funcs as $func) { if (preg_match('/\b' . preg_quote($func, '/') . '\s*\(/i', $content)) { $found_funcs[] = $func; } } // Deteksi berdasarkan pola nama shell $shell_pattern_matches = array(); foreach ($SHELL_PATTERNS as $pattern) { if (stripos($content, $pattern) !== false) { $shell_pattern_matches[] = $pattern; } } // Jika ditemukan pola shell, tingkatkan skor $pattern_score = count($shell_pattern_matches) * 2; if (count($found_funcs) < 3 && $pattern_score < 2) return null; // Obfuscation detection $obfuscation_score = 0; if (preg_match('/base64_decode\s*\(\s*["\'][A-Za-z0-9+\/]{50,}/', $content)) $obfuscation_score += 2; if (preg_match('/eval\s*\(\s*(base64_decode|gzinflate|str_rot13|gzuncompress)/i', $content)) $obfuscation_score += 3; if (preg_match('/\$[a-zA-Z0-9_]+\s*=\s*chr\s*\(/', $content)) $obfuscation_score += 2; if (preg_match('/\\\\x[0-9a-fA-F]{2}/', $content)) $obfuscation_score += 1; if (substr_count($content, '$' . '_') > 5) $obfuscation_score += 1; $has_get = (stripos($content, '$_GET') !== false); $has_post = (stripos($content, '$_POST') !== false); $has_request = (stripos($content, '$_REQUEST') !== false); $has_cookie = (stripos($content, '$_COOKIE') !== false); $has_server = (stripos($content, '$_SERVER') !== false); $has_password = (stripos($content, 'type="password"') !== false || stripos($content, "type='password'") !== false); $has_upload = (stripos($content, 'multipart/form-data') !== false || stripos($content, 'type="file"') !== false || stripos($content, 'move_uploaded_file') !== false); $has_input = ($has_get || $has_post || $has_request || $has_cookie); // Determine type if ($has_input && $has_password) { $type = 'Shell with Login'; } elseif ($has_input && $has_upload) { $type = 'Shell with Uploader'; } elseif ($has_input) { $type = 'Shell with Input'; } elseif ($has_upload) { $type = 'File Uploader'; } else { $type = 'Standalone Shell'; } $func_count = count($found_funcs); $base_conf = ($func_count >= 6) ? 3 : (($func_count >= 4) ? 2 : 1); $total_score = $base_conf + $obfuscation_score + $pattern_score; if ($total_score >= 5) $confidence = 'CRITICAL'; elseif ($total_score >= 3) $confidence = 'HIGH'; elseif ($total_score >= 2) $confidence = 'MEDIUM'; else $confidence = 'LOW'; // Jika ditemukan pola shell, minimal MEDIUM if ($pattern_score >= 2 && $confidence === 'LOW') { $confidence = 'MEDIUM'; } // File info $file_size = @filesize($filepath); $file_mtime = @filemtime($filepath); $file_perms = @substr(sprintf('%o', @fileperms($filepath)), -4); // Determine base URL untuk visit link (dari document root) $doc_root = $_SERVER['DOCUMENT_ROOT'] ?? ''; $web_path = ''; if (!empty($doc_root) && strpos($filepath, $doc_root) === 0) { $web_path = '/' . ltrim(substr($filepath, strlen($doc_root)), '/'); } else { // Fallback: coba deteksi dari path $web_path = $filepath; } return array( 'file' => normalize_path($filepath), 'type' => $type, 'confidence' => $confidence, 'functions' => $found_funcs, 'function_count'=> $func_count, 'has_password' => $has_password, 'has_upload' => $has_upload, 'obfuscated' => ($obfuscation_score >= 3), 'shell_patterns'=> $shell_pattern_matches, 'pattern_count' => count($shell_pattern_matches), 'file_size' => $file_size, 'file_mtime' => $file_mtime, 'file_perms' => $file_perms, 'os' => get_os(), 'web_path' => $web_path, ); } function scan_directory($dir, &$results, &$total_scanned, $max_depth = 10, $depth = 0) { if (!is_dir($dir) || $depth > $max_depth) return; $files = @scandir($dir); if (!$files) return; foreach ($files as $file) { if ($file === '.' || $file === '..') continue; $path = normalize_path($dir . '/' . $file); // Skip hidden dirs dan common false-positive folders if (in_array($file, array('.git', '.svn', 'node_modules', 'vendor', '.idea', '__pycache__'))) continue; if (is_dir($path)) { scan_directory($path, $results, $total_scanned, $max_depth, $depth + 1); } else { $ext = strtolower(pathinfo($file, PATHINFO_EXTENSION)); if (in_array($ext, array('php', 'php3', 'php4', 'php5', 'php7', 'php8', 'phtml', 'inc', 'phar'))) { $total_scanned++; $result = detect_webshell($path); if ($result) { $results[] = $result; } } } } } // ========================================================================= // MASS DELETE ACTION // ========================================================================= $delete_result = array(); if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['action']) && $_POST['action'] === 'delete') { $files_to_delete = isset($_POST['files']) ? $_POST['files'] : array(); $deleted = 0; $failed = 0; foreach ($files_to_delete as $f) { $f = normalize_path($f); // Basic safety: must be a real file if (file_exists($f) && is_file($f)) { if (@unlink($f)) { $deleted++; $delete_result['deleted'][] = $f; } else { $failed++; $delete_result['failed'][] = $f; } } } $delete_result['total_deleted'] = $deleted; $delete_result['total_failed'] = $failed; } // ========================================================================= // SCAN PROCESS // ========================================================================= $scan_path = ''; $results = array(); $scanned = false; $error_msg = ''; $total_scanned = 0; $scan_time = 0; if (isset($_GET['path']) && !empty(trim($_GET['path']))) { $scan_path = trim($_GET['path']); $real_path = realpath($scan_path); if ($real_path && is_dir($real_path)) { $t_start = microtime(true); scan_directory($real_path, $results, $total_scanned); $scan_time = round(microtime(true) - $t_start, 2); $scanned = true; // Sort: CRITICAL first usort($results, function($a, $b) { $order = array('CRITICAL' => 0, 'HIGH' => 1, 'MEDIUM' => 2, 'LOW' => 3); return $order[$a['confidence']] - $order[$b['confidence']]; }); } else { $error_msg = "Path tidak valid atau tidak dapat diakses: " . htmlspecialchars($scan_path); } } $default_paths = get_default_paths(); $current_os = get_os(); // Base URL untuk visit link $base_url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 'https' : 'http') . '://' . $_SERVER['HTTP_HOST']; ?> <!DOCTYPE html> <html lang="id"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>WebShell Detector Pro</title> <style> :root { --bg-0: #05070f; --bg-1: #080c18; --bg-2: #0c1120; --bg-3: #101728; --bg-4: #141d32; --border: rgba(0,200,120,0.12); --border-hi: rgba(0,200,120,0.28); --green: #00e87a; --green-dim: #00b85e; --green-glow: rgba(0,232,122,0.15); --red: #ff4060; --red-dim: #cc2040; --orange: #ff8c30; --yellow: #f0c040; --blue: #40a0ff; --purple: #b060ff; --text-1: #e8f4ee; --text-2: #8aadaa; --text-3: #4a6860; --mono: 'Consolas', 'Cascadia Code', 'Courier New', monospace; --sans: 'Consolas', 'Cascadia Code', 'Courier New', monospace; } *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } body { background: var(--bg-0); font-family: var(--mono); color: var(--text-1); min-height: 100vh; overflow-x: hidden; } /* Grid background */ body::before { content: ''; position: fixed; inset: 0; background-image: linear-gradient(rgba(0,200,100,0.03) 1px, transparent 1px), linear-gradient(90deg, rgba(0,200,100,0.03) 1px, transparent 1px); background-size: 40px 40px; pointer-events: none; z-index: 0; } .container { max-width: 1400px; margin: 0 auto; padding: 20px 24px 60px; position: relative; z-index: 1; } /* ── HEADER ── */ .header { display: flex; align-items: center; justify-content: space-between; padding: 28px 36px; background: var(--bg-2); border: 1px solid var(--border-hi); border-radius: 12px; margin-bottom: 24px; position: relative; overflow: hidden; } .header::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px; background: linear-gradient(90deg, transparent, var(--green), transparent); } .header-left h1 { font-family: var(--mono); font-size: 22px; font-weight: 700; color: var(--green); letter-spacing: 0px; line-height: 1; } .header-left p { color: var(--text-3); font-size: 12px; margin-top: 6px; letter-spacing: 0.5px; } .header-badges { display: flex; gap: 8px; flex-wrap: wrap; } .os-badge { display: flex; align-items: center; gap: 6px; padding: 6px 14px; background: var(--bg-4); border: 1px solid var(--border); border-radius: 20px; font-size: 11px; color: var(--text-2); } .os-badge .dot { width: 6px; height: 6px; border-radius: 50%; background: var(--green); box-shadow: 0 0 6px var(--green); animation: pulse 2s infinite; } @keyframes pulse { 0%,100% { opacity: 1; } 50% { opacity: 0.4; } } /* ── PANELS ── */ .panel { background: var(--bg-2); border: 1px solid var(--border); border-radius: 10px; margin-bottom: 20px; overflow: hidden; } .panel-title { display: flex; align-items: center; gap: 8px; padding: 14px 20px; background: var(--bg-3); border-bottom: 1px solid var(--border); font-family: var(--mono); font-size: 12px; font-weight: 700; color: var(--green); letter-spacing: 1px; text-transform: uppercase; } .panel-body { padding: 20px; } /* ── SCAN FORM ── */ .scan-form { display: flex; gap: 10px; margin-bottom: 14px; flex-wrap: wrap; } .scan-input-wrap { flex: 1; min-width: 260px; position: relative; } .scan-input-wrap::before { content: '›'; position: absolute; left: 14px; top: 50%; transform: translateY(-50%); color: var(--green); font-size: 18px; pointer-events: none; } .scan-input { width: 100%; padding: 12px 14px 12px 34px; background: var(--bg-1); border: 1px solid var(--border-hi); border-radius: 8px; color: var(--green); font-family: var(--mono); font-size: 13px; outline: none; transition: border-color 0.2s, box-shadow 0.2s; } .scan-input:focus { border-color: var(--green); box-shadow: 0 0 0 3px var(--green-glow); } .scan-input::placeholder { color: var(--text-3); } .btn { display: inline-flex; align-items: center; gap: 8px; padding: 12px 24px; border: none; border-radius: 8px; font-family: var(--mono); font-size: 13px; font-weight: 600; cursor: pointer; transition: all 0.2s; text-decoration: none; white-space: nowrap; } .btn-primary { background: var(--green); color: #000; } .btn-primary:hover { background: #00ffaa; box-shadow: 0 0 20px var(--green-glow); transform: translateY(-1px); } .btn-danger { background: var(--red); color: #fff; } .btn-danger:hover { background: #ff6080; box-shadow: 0 0 20px rgba(255,64,96,0.3); transform: translateY(-1px); } .btn-secondary { background: var(--bg-4); color: var(--text-2); border: 1px solid var(--border); } .btn-secondary:hover { border-color: var(--green); color: var(--green); } .btn-visit { background: rgba(64,160,255,0.15); color: var(--blue); border: 1px solid rgba(64,160,255,0.3); padding: 4px 12px; font-size: 11px; border-radius: 6px; text-decoration: none; display: inline-flex; align-items: center; gap: 4px; transition: all 0.2s; } .btn-visit:hover { background: rgba(64,160,255,0.25); border-color: var(--blue); transform: translateY(-1px); box-shadow: 0 0 15px rgba(64,160,255,0.15); } .btn:disabled { opacity: 0.4; cursor: not-allowed; transform: none; } /* Quick paths */ .quick-paths { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; } .quick-paths span { font-size: 11px; color: var(--text-3); align-self: center; } .path-chip { padding: 4px 12px; background: var(--bg-4); border: 1px solid var(--border); border-radius: 20px; font-size: 11px; color: var(--text-2); cursor: pointer; transition: all 0.15s; font-family: var(--mono); } .path-chip:hover { border-color: var(--green); color: var(--green); } /* ── STATS BAR ── */ .stats-bar { display: grid; grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 12px; margin-bottom: 20px; } .stat-card { background: var(--bg-2); border: 1px solid var(--border); border-radius: 10px; padding: 16px; text-align: center; transition: border-color 0.2s; } .stat-card:hover { border-color: var(--border-hi); } .stat-card .num { font-family: var(--mono); font-size: 26px; font-weight: 700; line-height: 1; margin-bottom: 4px; } .stat-card .lbl { font-size: 10px; color: var(--text-3); letter-spacing: 1px; text-transform: uppercase; } .stat-critical .num { color: var(--purple); } .stat-high .num { color: var(--red); } .stat-medium .num { color: var(--orange); } .stat-low .num { color: var(--blue); } .stat-total .num { color: var(--green); } .stat-scanned .num { color: var(--text-2); } /* ── TOOLBAR ── */ .toolbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 14px; gap: 12px; flex-wrap: wrap; } .toolbar-left { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; } .filter-btn { padding: 6px 14px; background: var(--bg-4); border: 1px solid var(--border); border-radius: 20px; font-family: var(--mono); font-size: 11px; color: var(--text-2); cursor: pointer; transition: all 0.15s; } .filter-btn:hover, .filter-btn.active { border-color: var(--green); color: var(--green); } .select-all-wrap { display: flex; align-items: center; gap: 8px; font-size: 12px; color: var(--text-2); cursor: pointer; user-select: none; } .custom-check { width: 16px; height: 16px; background: var(--bg-1); border: 1px solid var(--border-hi); border-radius: 4px; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; transition: all 0.15s; flex-shrink: 0; } .custom-check.checked { background: var(--green); border-color: var(--green); } .custom-check.checked::after { content: '✓'; font-size: 10px; color: #000; font-weight: 700; } input[type="checkbox"] { display: none; } /* ── RESULT ITEMS ── */ .result-list { display: flex; flex-direction: column; gap: 8px; } .result-item { background: var(--bg-2); border: 1px solid var(--border); border-radius: 10px; overflow: hidden; transition: border-color 0.2s; } .result-item:hover { border-color: var(--border-hi); } .result-item.selected { border-color: var(--red); background: rgba(255,64,96,0.04); } .result-header { display: flex; align-items: center; gap: 12px; padding: 14px 16px; cursor: pointer; } .result-header:hover { background: rgba(255,255,255,0.02); } .file-path { flex: 1; font-size: 12px; color: var(--text-1); word-break: break-all; line-height: 1.4; min-width: 0; } .file-path .dir-part { color: var(--text-3); } .badges { display: flex; gap: 6px; align-items: center; flex-shrink: 0; flex-wrap: wrap; } .badge { padding: 3px 10px; border-radius: 12px; font-size: 10px; font-weight: 700; letter-spacing: 0.5px; text-transform: uppercase; font-family: var(--mono); } .badge-CRITICAL { background: rgba(176,96,255,0.2); color: var(--purple); border: 1px solid rgba(176,96,255,0.3); } .badge-HIGH { background: rgba(255,64,96,0.15); color: var(--red); border: 1px solid rgba(255,64,96,0.3); } .badge-MEDIUM { background: rgba(255,140,48,0.15); color: var(--orange); border: 1px solid rgba(255,140,48,0.3); } .badge-LOW { background: rgba(64,160,255,0.15); color: var(--blue); border: 1px solid rgba(64,160,255,0.3); } .badge-type { background: var(--bg-4); color: var(--text-2); border: 1px solid var(--border); } .badge-obf { background: rgba(176,96,255,0.1); color: var(--purple); border: 1px solid rgba(176,96,255,0.2); font-size: 9px; } .badge-pattern { background: rgba(0,232,122,0.1); color: var(--green); border: 1px solid rgba(0,232,122,0.2); font-size: 9px; } .actions-group { display: flex; align-items: center; gap: 6px; flex-shrink: 0; } .expand-icon { color: var(--text-3); transition: transform 0.2s; font-size: 14px; flex-shrink: 0; } .expand-icon.open { transform: rotate(90deg); color: var(--green); } /* ── DETAIL PANEL ── */ .result-detail { display: none; padding: 0 16px 16px 16px; border-top: 1px solid var(--border); } .result-detail.show { display: block; } .detail-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); gap: 10px; margin-top: 14px; } .detail-card { background: var(--bg-1); border: 1px solid var(--border); border-radius: 8px; padding: 12px; } .detail-card .lbl { font-size: 10px; color: var(--text-3); text-transform: uppercase; letter-spacing: 1px; margin-bottom: 6px; } .detail-card .val { font-size: 12px; color: var(--text-1); line-height: 1.5; } .func-tag { display: inline-block; padding: 2px 8px; background: rgba(255,64,96,0.1); border: 1px solid rgba(255,64,96,0.2); border-radius: 4px; font-size: 11px; color: #ff8099; margin: 2px; } .func-tag.safe { background: rgba(64,160,255,0.1); border-color: rgba(64,160,255,0.2); color: #80c0ff; } .pattern-tag { display: inline-block; padding: 2px 8px; background: rgba(0,232,122,0.1); border: 1px solid rgba(0,232,122,0.2); border-radius: 4px; font-size: 10px; color: var(--green); margin: 2px; } /* ── DELETE MODAL ── */ .modal-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.8); backdrop-filter: blur(4px); z-index: 1000; display: none; align-items: center; justify-content: center; } .modal-overlay.show { display: flex; } .modal { background: var(--bg-2); border: 1px solid var(--red); border-radius: 12px; padding: 32px; max-width: 500px; width: 90%; position: relative; } .modal::before { content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px; background: linear-gradient(90deg, transparent, var(--red), transparent); border-radius: 12px 12px 0 0; } .modal h3 { font-family: var(--mono); font-size: 18px; color: var(--red); margin-bottom: 12px; } .modal p { color: var(--text-2); font-size: 13px; line-height: 1.6; margin-bottom: 16px; } .modal-files { background: var(--bg-1); border: 1px solid var(--border); border-radius: 6px; padding: 10px; max-height: 160px; overflow-y: auto; margin-bottom: 20px; } .modal-file-item { font-size: 11px; color: var(--red); padding: 3px 0; word-break: break-all; } .modal-actions { display: flex; gap: 10px; justify-content: flex-end; } /* ── DELETE RESULT ── */ .delete-result-box { background: var(--bg-2); border: 1px solid var(--border); border-radius: 10px; padding: 20px; margin-bottom: 20px; } .delete-result-box.has-deleted { border-color: var(--green); } .delete-result-box.has-failed { border-color: var(--orange); } .delete-stat { display: inline-flex; align-items: center; gap: 8px; padding: 6px 16px; border-radius: 20px; font-size: 12px; font-weight: 600; margin-right: 10px; } .delete-stat.ok { background: rgba(0,232,122,0.1); color: var(--green); } .delete-stat.err { background: rgba(255,140,48,0.1); color: var(--orange); } /* ── EMPTY / ERROR ── */ .empty-state { text-align: center; padding: 60px 20px; } .empty-state .icon { font-size: 48px; margin-bottom: 16px; } .empty-state h3 { font-family: var(--mono); font-size: 18px; color: var(--green); margin-bottom: 8px; } .empty-state p { color: var(--text-3); font-size: 13px; } .alert-box { padding: 14px 18px; border-radius: 8px; font-size: 13px; margin-bottom: 16px; display: flex; align-items: flex-start; gap: 10px; } .alert-error { background: rgba(255,64,96,0.08); border: 1px solid rgba(255,64,96,0.3); color: var(--red); } .alert-warning { background: rgba(255,140,48,0.08); border: 1px solid rgba(255,140,48,0.3); color: var(--orange); } /* ── FOOTER ── */ .footer { text-align: center; margin-top: 40px; padding-top: 20px; border-top: 1px solid var(--border); color: var(--text-3); font-size: 11px; letter-spacing: 0.5px; } /* ── SCROLLBAR ── */ ::-webkit-scrollbar { width: 6px; height: 6px; } ::-webkit-scrollbar-track { background: var(--bg-1); } ::-webkit-scrollbar-thumb { background: var(--bg-4); border-radius: 3px; } ::-webkit-scrollbar-thumb:hover { background: var(--text-3); } /* ── ANIMATIONS ── */ @keyframes fadeIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: translateY(0); } } .result-item { animation: fadeIn 0.25s ease both; } /* ── SCAN LOADING ── */ .scan-progress { display: none; align-items: center; gap: 12px; padding: 12px 16px; background: rgba(0,232,122,0.05); border: 1px solid var(--green-glow); border-radius: 8px; margin-top: 12px; font-size: 12px; color: var(--green); } .scan-progress.show { display: flex; } .spinner { width: 16px; height: 16px; border: 2px solid var(--border); border-top-color: var(--green); border-radius: 50%; animation: spin 0.8s linear infinite; flex-shrink: 0; } @keyframes spin { to { transform: rotate(360deg); } } /* Visit button tooltip */ .visit-tooltip { position: relative; display: inline-flex; } .visit-tooltip .tooltip-text { visibility: hidden; width: 180px; background: var(--bg-3); color: var(--text-2); text-align: center; border: 1px solid var(--border); border-radius: 6px; padding: 6px 10px; position: absolute; z-index: 1; bottom: 125%; left: 50%; margin-left: -90px; font-size: 10px; opacity: 0; transition: opacity 0.2s; word-break: break-all; } .visit-tooltip .tooltip-text::after { content: ""; position: absolute; top: 100%; left: 50%; margin-left: -5px; border-width: 5px; border-style: solid; border-color: var(--bg-3) transparent transparent transparent; } .visit-tooltip:hover .tooltip-text { visibility: visible; opacity: 1; } @media (max-width: 600px) { .header { flex-direction: column; gap: 14px; text-align: center; } .stats-bar { grid-template-columns: repeat(3, 1fr); } .result-header { flex-wrap: wrap; } .actions-group { margin-left: auto; } } </style> </head> <body> <div class="container"> <!-- HEADER --> <div class="header"> <div class="header-left"> <h1>🛡 WebShell Detector Pro</h1> <p>Advanced PHP Webshell Scanner · v2.0 · Cross-Platform</p> </div> <div class="header-badges"> <div class="os-badge"> <span class="dot"></span> <?php echo ($current_os === 'windows') ? '🪟 Windows' : '🐧 Linux/Unix'; ?> </div> <div class="os-badge">PHP <?php echo phpversion(); ?></div> </div> </div> <!-- DELETE RESULT --> <?php if (!empty($delete_result)): ?> <div class="delete-result-box <?php echo ($delete_result['total_deleted'] > 0 ? 'has-deleted' : '') . ($delete_result['total_failed'] > 0 ? ' has-failed' : ''); ?>"> <div style="display:flex;align-items:center;gap:10px;margin-bottom:12px;"> <span style="font-family:var(--mono);font-size:13px;font-weight:700;color:var(--text-1);">📋 Hasil Mass Delete</span> </div> <?php if ($delete_result['total_deleted'] > 0): ?> <span class="delete-stat ok">✓ <?php echo $delete_result['total_deleted']; ?> file berhasil dihapus</span> <?php endif; ?> <?php if ($delete_result['total_failed'] > 0): ?> <span class="delete-stat err">⚠ <?php echo $delete_result['total_failed']; ?> file gagal dihapus</span> <?php endif; ?> <?php if (!empty($delete_result['failed'])): ?> <div style="margin-top:12px;"> <div style="font-size:11px;color:var(--text-3);margin-bottom:6px;">File yang gagal dihapus (periksa permission):</div> <?php foreach ($delete_result['failed'] as $f): ?> <div style="font-size:11px;color:var(--orange);padding:2px 0;"><?php echo htmlspecialchars($f); ?></div> <?php endforeach; ?> </div> <?php endif; ?> </div> <?php endif; ?> <!-- SCAN PANEL --> <div class="panel"> <div class="panel-title">🔍 SCAN DIREKTORI</div> <div class="panel-body"> <form method="GET" action="" id="scanForm" onsubmit="showScanProgress()"> <div class="scan-form"> <div class="scan-input-wrap"> <input type="text" name="path" class="scan-input" id="scanInput" placeholder="<?php echo ($current_os === 'windows') ? 'C:/xampp/htdocs atau C:\wamp\www' : '/var/www/html atau /home/user/public_html'; ?>" value="<?php echo htmlspecialchars($scan_path); ?>" required> </div> <button type="submit" class="btn btn-primary">⚡ SCAN</button> <button type="button" class="btn btn-secondary" onclick="document.getElementById('scanInput').value='<?php echo htmlspecialchars(dirname(__FILE__), ENT_QUOTES); ?>'">📂 Dir Ini</button> </div> </form> <div class="scan-progress" id="scanProgress"> <div class="spinner"></div> <span>Sedang scan... harap tunggu</span> </div> <div class="quick-paths"> <span>Quick:</span> <?php foreach ($default_paths as $dp): ?> <div class="path-chip" onclick="setPath('<?php echo htmlspecialchars($dp, ENT_QUOTES); ?>')"><?php echo htmlspecialchars($dp); ?></div> <?php endforeach; ?> </div> <div style="margin-top:12px;padding:10px;background:var(--bg-1);border-radius:6px;border-left:2px solid var(--green);"> <div style="font-size:11px;color:var(--text-3);line-height:1.7;"> 📌 <strong style="color:var(--text-2)">Deteksi:</strong> ≥3 fungsi berbahaya, analisis obfuscation, input superglobal, form password/upload, dan pola nama shell terkenal<br> 🔒 <strong style="color:var(--text-2)">Ekstensi:</strong> .php .php3 .php4 .php5 .php7 .php8 .phtml .inc .phar<br> ⚠️ <strong style="color:var(--text-2)">Peringatan:</strong> Gunakan hanya untuk audit keamanan server Anda sendiri. </div> </div> </div> </div> <!-- ERROR --> <?php if ($error_msg): ?> <div class="alert-box alert-error">⛔ <?php echo $error_msg; ?></div> <?php endif; ?> <!-- SCAN RESULTS --> <?php if ($scanned): ?> <?php if (empty($results)): ?> <div class="panel"> <div class="panel-body"> <div class="empty-state"> <div class="icon">✅</div> <h3>Scan Selesai — Bersih!</h3> <p> <?php echo number_format($total_scanned); ?> file PHP diperiksa dalam <?php echo $scan_time; ?>s<br> Tidak ditemukan webshell berdasarkan aturan deteksi saat ini. </p> </div> </div> </div> <?php else: $crit = $hi = $med = $lo = 0; foreach ($results as $r) { if ($r['confidence'] === 'CRITICAL') $crit++; elseif ($r['confidence'] === 'HIGH') $hi++; elseif ($r['confidence'] === 'MEDIUM') $med++; else $lo++; } $found = count($results); ?> <!-- STATS --> <div class="stats-bar"> <div class="stat-card stat-total"> <div class="num"><?php echo $found; ?></div> <div class="lbl">Terdeteksi</div> </div> <div class="stat-card stat-critical"> <div class="num"><?php echo $crit; ?></div> <div class="lbl">Critical</div> </div> <div class="stat-card stat-high"> <div class="num"><?php echo $hi; ?></div> <div class="lbl">High</div> </div> <div class="stat-card stat-medium"> <div class="num"><?php echo $med; ?></div> <div class="lbl">Medium</div> </div> <div class="stat-card stat-low"> <div class="num"><?php echo $lo; ?></div> <div class="lbl">Low</div> </div> <div class="stat-card stat-scanned"> <div class="num"><?php echo number_format($total_scanned); ?></div> <div class="lbl">Diperiksa</div> </div> <div class="stat-card stat-scanned"> <div class="num"><?php echo $scan_time; ?>s</div> <div class="lbl">Waktu Scan</div> </div> </div> <?php if ($crit > 0 || $hi > 0): ?> <div class="alert-box alert-warning"> ⚠️ Ditemukan <strong><?php echo ($crit + $hi); ?></strong> file dengan confidence CRITICAL/HIGH! Segera verifikasi dan lakukan pembersihan. Backup terlebih dahulu sebelum menghapus. </div> <?php endif; ?> <!-- TOOLBAR --> <div class="toolbar"> <div class="toolbar-left"> <label class="select-all-wrap" onclick="toggleSelectAll()"> <div class="custom-check" id="selectAllCheck"></div> Pilih Semua </label> <button class="filter-btn active" onclick="filterResults('all', this)">Semua (<?php echo $found; ?>)</button> <?php if ($crit > 0): ?><button class="filter-btn" onclick="filterResults('CRITICAL', this)">Critical (<?php echo $crit; ?>)</button><?php endif; ?> <?php if ($hi > 0): ?><button class="filter-btn" onclick="filterResults('HIGH', this)">High (<?php echo $hi; ?>)</button><?php endif; ?> <?php if ($med > 0): ?><button class="filter-btn" onclick="filterResults('MEDIUM', this)">Medium (<?php echo $med; ?>)</button><?php endif; ?> <?php if ($lo > 0): ?><button class="filter-btn" onclick="filterResults('LOW', this)">Low (<?php echo $lo; ?>)</button><?php endif; ?> </div> <button class="btn btn-danger" id="deleteBtn" onclick="openDeleteModal()" disabled> 🗑 Hapus Terpilih (<span id="selectedCount">0</span>) </button> </div> <!-- FILE LIST --> <form method="POST" action="?path=<?php echo urlencode($scan_path); ?>" id="deleteForm"> <input type="hidden" name="action" value="delete"> <div class="result-list" id="resultList"> <?php foreach ($results as $idx => $r): $filename = basename($r['file']); $dirpart = dirname($r['file']); // Build visit URL $visit_url = $base_url . $r['web_path']; ?> <div class="result-item" id="item-<?php echo $idx; ?>" data-confidence="<?php echo $r['confidence']; ?>"> <div class="result-header"> <!-- Checkbox --> <div class="custom-check" id="check-<?php echo $idx; ?>" onclick="event.stopPropagation(); toggleItem(<?php echo $idx; ?>, '<?php echo htmlspecialchars($r['file'], ENT_QUOTES); ?>')"> </div> <input type="checkbox" name="files[]" value="<?php echo htmlspecialchars($r['file']); ?>" id="cb-<?php echo $idx; ?>" onchange="syncCheck(<?php echo $idx; ?>)"> <!-- File path (click to expand) --> <div class="file-path" onclick="toggleDetail(<?php echo $idx; ?>)"> <span class="dir-part"><?php echo htmlspecialchars($dirpart); ?>/</span><strong><?php echo htmlspecialchars($filename); ?></strong> </div> <!-- Badges & Actions --> <div class="actions-group"> <!-- Visit Button --> <?php if (!empty($r['web_path']) && $r['web_path'] !== $r['file']): ?> <div class="visit-tooltip"> <a href="<?php echo htmlspecialchars($visit_url); ?>" target="_blank" class="btn-visit" onclick="event.stopPropagation();" title="Visit file via browser"> 🌐 Visit </a> <span class="tooltip-text"><?php echo htmlspecialchars($visit_url); ?></span> </div> <?php endif; ?> <div class="badges" onclick="toggleDetail(<?php echo $idx; ?>)"> <?php if ($r['pattern_count'] > 0): ?><span class="badge badge-pattern">🎯 <?php echo $r['pattern_count']; ?></span><?php endif; ?> <?php if ($r['obfuscated']): ?><span class="badge badge-obf">OBFUSCATED</span><?php endif; ?> <span class="badge badge-<?php echo $r['confidence']; ?>"><?php echo $r['confidence']; ?></span> <span class="badge badge-type"><?php echo htmlspecialchars($r['type']); ?></span> </div> <div class="expand-icon" id="arrow-<?php echo $idx; ?>" onclick="toggleDetail(<?php echo $idx; ?>)">▶</div> </div> </div> <!-- DETAIL --> <div class="result-detail" id="detail-<?php echo $idx; ?>"> <div class="detail-grid"> <div class="detail-card"> <div class="lbl">Fungsi Berbahaya (<?php echo $r['function_count']; ?>)</div> <div class="val"> <?php $critical_funcs = array('eval','system','exec','shell_exec','passthru','assert','create_function'); foreach ($r['functions'] as $fn): $isCrit = in_array($fn, $critical_funcs); ?> <span class="func-tag <?php echo $isCrit ? '' : 'safe'; ?>"><?php echo $fn; ?></span> <?php endforeach; ?> </div> </div> <div class="detail-card"> <div class="lbl">Pola Shell Terdeteksi (<?php echo $r['pattern_count']; ?>)</div> <div class="val"> <?php if ($r['pattern_count'] > 0): ?> <?php foreach ($r['shell_patterns'] as $pattern): ?> <span class="pattern-tag"><?php echo htmlspecialchars(substr($pattern, 0, 50)) . (strlen($pattern) > 50 ? '...' : ''); ?></span> <?php endforeach; ?> <?php else: ?> <span style="color:var(--text-3);">— Tidak ada pola shell terdeteksi</span> <?php endif; ?> </div> </div> <div class="detail-card"> <div class="lbl">Info File</div> <div class="val"> 📦 <?php echo $r['file_size'] !== false ? number_format($r['file_size']) . ' bytes' : 'N/A'; ?><br> 🕒 <?php echo $r['file_mtime'] ? date('Y-m-d H:i:s', $r['file_mtime']) : 'N/A'; ?><br> <?php if ($r['os'] === 'linux'): ?> 🔑 Permissions: <?php echo $r['file_perms']; ?> <?php else: ?> 🪟 Windows File <?php endif; ?> </div> </div> <div class="detail-card"> <div class="lbl">Indikator Tambahan</div> <div class="val"> <?php echo $r['has_password'] ? '🔐 Form Login Terdeteksi<br>' : ''; ?> <?php echo $r['has_upload'] ? '📤 Form Upload Terdeteksi<br>' : ''; ?> <?php echo $r['obfuscated'] ? '🔒 Kode Obfuscated<br>' : ''; ?> <?php if (!$r['has_password'] && !$r['has_upload'] && !$r['obfuscated']): ?> <span style="color:var(--text-3)">— Tidak ada indikator tambahan</span> <?php endif; ?> </div> </div> <div class="detail-card"> <div class="lbl">Path Lengkap</div> <div class="val" style="word-break:break-all;font-size:11px;color:var(--text-2);"> <?php echo htmlspecialchars($r['file']); ?> </div> <?php if (!empty($r['web_path']) && $r['web_path'] !== $r['file']): ?> <div style="margin-top:6px;font-size:10px;color:var(--blue);"> 🌐 Web URL: <a href="<?php echo htmlspecialchars($visit_url); ?>" target="_blank" style="color:var(--blue);text-decoration:underline;"><?php echo htmlspecialchars($visit_url); ?></a> </div> <?php endif; ?> </div> </div> </div> </div> <?php endforeach; ?> </div> </form> <?php endif; ?> <?php endif; ?> <div class="footer"> Shell Destroyer v2.0 · Compatible Windows & Linux · PHP <?php echo phpversion(); ?> · <?php echo date('Y'); ?> </div> </div> <!-- DELETE CONFIRMATION MODAL --> <div class="modal-overlay" id="deleteModal"> <div class="modal"> <h3>⚠️ Konfirmasi Hapus File</h3> <p>Anda akan <strong style="color:var(--red)">menghapus permanen</strong> file-file berikut. Tindakan ini <strong>tidak dapat dibatalkan</strong>. Pastikan sudah melakukan backup!</p> <div class="modal-files" id="modalFileList"></div> <div class="modal-actions"> <button class="btn btn-secondary" onclick="closeDeleteModal()">Batal</button> <button class="btn btn-danger" onclick="confirmDelete()">🗑 Hapus Sekarang</button> </div> </div> </div> <script> var selectedFiles = {}; function toggleItem(idx, filepath) { var cb = document.getElementById('cb-' + idx); var chk = document.getElementById('check-' + idx); var item = document.getElementById('item-' + idx); if (cb.checked) { cb.checked = false; chk.classList.remove('checked'); item.classList.remove('selected'); delete selectedFiles[idx]; } else { cb.checked = true; chk.classList.add('checked'); item.classList.add('selected'); selectedFiles[idx] = filepath; } updateDeleteBtn(); } function syncCheck(idx) { var cb = document.getElementById('cb-' + idx); var chk = document.getElementById('check-' + idx); var item = document.getElementById('item-' + idx); var filepath = cb.value; if (cb.checked) { chk.classList.add('checked'); item.classList.add('selected'); selectedFiles[idx] = filepath; } else { chk.classList.remove('checked'); item.classList.remove('selected'); delete selectedFiles[idx]; } updateDeleteBtn(); } function updateDeleteBtn() { var count = Object.keys(selectedFiles).length; var btn = document.getElementById('deleteBtn'); document.getElementById('selectedCount').textContent = count; btn.disabled = (count === 0); // Update select-all state var allItems = document.querySelectorAll('#resultList .result-item:not([style*="none"])'); var allChecked = (allItems.length > 0 && count >= allItems.length); var saChk = document.getElementById('selectAllCheck'); if (allChecked) saChk.classList.add('checked'); else saChk.classList.remove('checked'); } function toggleSelectAll() { var allItems = document.querySelectorAll('#resultList .result-item:not([style*="none"])'); var count = Object.keys(selectedFiles).length; var visible = 0; allItems.forEach(function(el) { if (el.style.display !== 'none') visible++; }); var doSelect = (count < visible); allItems.forEach(function(el) { if (el.style.display === 'none') return; var id = el.id.replace('item-', ''); var cb = document.getElementById('cb-' + id); var chk = document.getElementById('check-' + id); if (doSelect) { cb.checked = true; chk.classList.add('checked'); el.classList.add('selected'); selectedFiles[id] = cb.value; } else { cb.checked = false; chk.classList.remove('checked'); el.classList.remove('selected'); delete selectedFiles[id]; } }); updateDeleteBtn(); } function filterResults(level, btn) { document.querySelectorAll('.filter-btn').forEach(function(b) { b.classList.remove('active'); }); btn.classList.add('active'); document.querySelectorAll('.result-item').forEach(function(el) { if (level === 'all' || el.dataset.confidence === level) { el.style.display = ''; } else { el.style.display = 'none'; } }); } function toggleDetail(idx) { var detail = document.getElementById('detail-' + idx); var arrow = document.getElementById('arrow-' + idx); if (detail.classList.contains('show')) { detail.classList.remove('show'); arrow.classList.remove('open'); } else { detail.classList.add('show'); arrow.classList.add('open'); } } function openDeleteModal() { var files = Object.values(selectedFiles); if (files.length === 0) return; var list = document.getElementById('modalFileList'); list.innerHTML = ''; files.forEach(function(f) { var d = document.createElement('div'); d.className = 'modal-file-item'; d.textContent = '🗑 ' + f; list.appendChild(d); }); document.getElementById('deleteModal').classList.add('show'); } function closeDeleteModal() { document.getElementById('deleteModal').classList.remove('show'); } function confirmDelete() { closeDeleteModal(); document.getElementById('deleteForm').submit(); } function setPath(p) { document.getElementById('scanInput').value = p; } function showScanProgress() { document.getElementById('scanProgress').classList.add('show'); } // Close modal on overlay click document.getElementById('deleteModal').addEventListener('click', function(e) { if (e.target === this) closeDeleteModal(); }); // Animate result items on load document.querySelectorAll('.result-item').forEach(function(el, i) { el.style.animationDelay = (i * 0.04) + 's'; }); </script> </body> </html>
Close