Skip to content

Instantly share code, notes, and snippets.

@rikka0w0
Created November 11, 2023 16:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rikka0w0/99bc91f0684639e3cc95685de9d8d601 to your computer and use it in GitHub Desktop.
Save rikka0w0/99bc91f0684639e3cc95685de9d8d601 to your computer and use it in GitHub Desktop.
A simple shell on Webpage with NodeJS
<!DOCTYPE html>
<html>
<head>
<title>Simple Webshell</title>
<style>
body {
font-family: 'Consolas', monospace;
}
#commandInput {
display: block;
width: 100%;
box-sizing: border-box;
padding: 5px;
font-size: 16px;
}
ul {
padding: 0;
}
li {
list-style: none;
margin-bottom: 5px;
}
</style>
</head>
<body>
<ul id="commandList"></ul>
<input type="text" id="commandInput" placeholder="Enter Command" onkeydown="handleEnter(event)">
<script>
function executeCommand() {
const input = document.getElementById('commandInput').value.trim();
const commandList = document.getElementById('commandList');
if (input === 'clear') {
commandList.innerHTML = ''; // Clear the list
document.getElementById('commandInput').value = ''; // Clear the input field
return;
}
const encodedCommand = encodeURIComponent(input);
const commandItem = document.createElement('li');
fetch(`/cmd?cmd=${encodedCommand}`)
.then(response => response.text())
.then(result => {
const resultItem = document.createElement('li');
resultItem.appendChild(document.createTextNode(`> ${input}`));
commandList.appendChild(resultItem);
const outputLines = result.split('\n');
outputLines.forEach(line => {
const lineItem = document.createElement('li');
lineItem.appendChild(document.createTextNode(line));
commandList.appendChild(lineItem);
});
// Scroll to the bottom of the page
window.scrollTo(0, document.body.scrollHeight);
})
.catch(error => {
const errorItem = document.createElement('li');
errorItem.appendChild(document.createTextNode(`Error: ${error}`));
commandList.appendChild(errorItem);
});
document.getElementById('commandInput').value = ''; // Clear the input field
document.getElementById('commandInput').focus(); // Set focus back to the input field
}
function handleEnter(event) {
if (event.key === "Enter") {
executeCommand();
}
}
</script>
</body>
</html>
import http from 'http';
import { exec } from 'child_process';
import { parse } from 'url';
import fs from 'fs';
const port = process.env.PORT || 8080;
const server = http.createServer((req, res) => {
const { pathname, query } = parse(req.url, true);
if (pathname === '/cmd' && query.cmd) {
const command = query.cmd;
exec(command, (error, stdout, stderr) => {
if (error) {
res.writeHead(500, { 'Content-Type': 'text/plain' });
res.end(`Error: ${error.message}`);
return;
}
if (stderr) {
res.writeHead(400, { 'Content-Type': 'text/plain' });
res.end(`Command execution error: ${stderr}`);
return;
}
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end(stdout);
});
} else {
// Serve the index.html page for other paths
fs.readFile('index.html', (err, data) => {
if (err) {
res.writeHead(500, { 'Content-Type': 'text/plain' });
res.end('Error loading index.html');
} else {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(data);
}
});
}
});
server.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
{
"name": "simple_web_shell",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"dev": "node index.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"type": "module"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment