Files
RDP/WEBSHELL/gotty.py
admin 2726c4aa4d Загрузить файлы в «WEBSHELL»
gotty.py - WEB шелл с разрешенным списком команд

gotty(unsafe).py - WEB шелл без фильтрации команд (допускает любые команды оболочки ЛИНУКС BASH)
2026-03-29 19:00:28 +00:00

273 lines
8.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from flask import Flask, render_template, request, jsonify, session
import subprocess
import os
import threading
import uuid
from datetime import datetime
app = Flask(__name__)
app.secret_key = 'your-secret-key-here' # Измените на случайный ключ
# Безопасные команды (можно расширить)
SAFE_COMMANDS = ['ls', 'pwd', 'whoami', 'date', 'uptime', 'uname', 'df', 'free']
class CommandSession:
def __init__(self):
self.sessions = {}
def create_session(self):
session_id = str(uuid.uuid4())
self.sessions[session_id] = {
'created_at': datetime.now(),
'working_dir': os.getcwd()
}
return session_id
def execute_command(self, session_id, command):
if session_id not in self.sessions:
return "Сессия не найдена"
session_data = self.sessions[session_id]
# Безопасность: проверяем команду
cmd_parts = command.strip().split()
if not cmd_parts:
return ""
base_command = cmd_parts[0]
# Ограничиваем доступные команды для безопасности
if base_command not in SAFE_COMMANDS:
return f"Команда '{base_command}' не разрешена для выполнения"
try:
# Выполняем команду в текущей директории сессии
result = subprocess.run(
command,
shell=True,
capture_output=True,
text=True,
cwd=session_data['working_dir'],
timeout=30 # Таймаут 30 секунд
)
output = result.stdout
if result.stderr:
output += f"\nОшибка: {result.stderr}"
return output
except subprocess.TimeoutExpired:
return "Ошибка: команда выполнялась слишком долго"
except Exception as e:
return f"Ошибка выполнения: {str(e)}"
command_manager = CommandSession()
@app.route('/')
def index():
if 'session_id' not in session:
session['session_id'] = command_manager.create_session()
return render_template('index.html')
@app.route('/execute', methods=['POST'])
def execute_command():
if 'session_id' not in session:
return jsonify({'error': 'Сессия не найдена'})
data = request.get_json()
command = data.get('command', '').strip()
if not command:
return jsonify({'error': 'Пустая команда'})
# Выполняем команду
output = command_manager.execute_command(session['session_id'], command)
return jsonify({
'output': output,
'command': command,
'timestamp': datetime.now().strftime('%H:%M:%S')
})
@app.route('/sessions', methods=['GET'])
def list_sessions():
return jsonify({
'active_sessions': len(command_manager.sessions),
'current_session': session.get('session_id')
})
@app.route('/clear-session', methods=['POST'])
def clear_session():
session_id = session.get('session_id')
if session_id in command_manager.sessions:
del command_manager.sessions[session_id]
session.pop('session_id', None)
return jsonify({'message': 'Сессия очищена'})
if __name__ == '__main__':
# Создаем папку для шаблонов если её нет
os.makedirs('templates', exist_ok=True)
# Создаем HTML шаблон
with open('templates/index.html', 'w', encoding='utf-8') as f:
f.write('''<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Web Shell</title>
<style>
body {
font-family: 'Courier New', monospace;
background-color: #1e1e1e;
color: #00ff00;
margin: 0;
padding: 20px;
}
.terminal {
background-color: #000;
border: 1px solid #333;
border-radius: 5px;
padding: 20px;
height: 70vh;
overflow-y: auto;
}
.output {
margin-bottom: 10px;
white-space: pre-wrap;
word-break: break-all;
}
.command-line {
display: flex;
align-items: center;
}
.prompt {
margin-right: 10px;
}
#command-input {
background: transparent;
border: none;
color: #00ff00;
font-family: 'Courier New', monospace;
font-size: 16px;
outline: none;
flex-grow: 1;
}
.timestamp {
color: #888;
font-size: 12px;
}
.error {
color: #ff4444;
}
.info {
color: #4488ff;
}
</style>
</head>
<body>
<h1>Web Shell Interface</h1>
<div class="info">
Разрешенные команды: {{ safe_commands|join(', ') }}
</div>
<div class="terminal" id="terminal">
<div class="output info">
Добро пожаловать в Web Shell!<br>
Введите команду ниже. Доступные команды: {{ safe_commands|join(', ') }}
</div>
</div>
<div class="command-line">
<span class="prompt">$</span>
<input type="text" id="command-input" placeholder="Введите команду...">
</div>
<div style="margin-top: 20px;">
<button onclick="clearTerminal()">Очистить терминал</button>
<button onclick="clearSession()">Новая сессия</button>
<span id="session-info"></span>
</div>
<script>
const terminal = document.getElementById('terminal');
const commandInput = document.getElementById('command-input');
const sessionInfo = document.getElementById('session-info');
// Фокус на поле ввода
commandInput.focus();
// Обработка отправки команды
commandInput.addEventListener('keypress', function(e) {
if (e.key === 'Enter') {
const command = commandInput.value.trim();
if (command) {
executeCommand(command);
commandInput.value = '';
}
}
});
function executeCommand(command) {
// Показываем команду в терминале
addOutput('$ ' + command, 'user-command');
// Отправляем на сервер
fetch('/execute', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({command: command})
})
.then(response => response.json())
.then(data => {
if (data.error) {
addOutput(data.error, 'error');
} else {
addOutput(data.output, 'command-output');
}
})
.catch(error => {
addOutput('Ошибка: ' + error, 'error');
});
}
function addOutput(text, className) {
const output = document.createElement('div');
output.className = `output ${className}`;
output.textContent = text;
terminal.appendChild(output);
terminal.scrollTop = terminal.scrollHeight;
}
function clearTerminal() {
terminal.innerHTML = '<div class="output info">Терминал очищен</div>';
}
function clearSession() {
fetch('/clear-session', {method: 'POST'})
.then(() => {
location.reload();
});
}
// Загружаем информацию о сессии
fetch('/sessions')
.then(response => response.json())
.then(data => {
sessionInfo.textContent = `Активных сессий: ${data.active_sessions}`;
});
</script>
</body>
</html>''')
app.run(host='0.0.0.0', port=5000, debug=True)