diff --git a/CTF.py b/CTF.py new file mode 100644 index 0000000..eb7c4d8 --- /dev/null +++ b/CTF.py @@ -0,0 +1,799 @@ +from flask import Flask, render_template, request, jsonify, session +import subprocess +import os +import uuid +import time +from datetime import datetime +import base64 +import io +import platform +import socket +from PIL import Image + +app = Flask(__name__) +app.secret_key = os.urandom(24) + + +class RemoteDesktop: + def __init__(self): + self.sessions = {} + self.screen_quality = 80 + self.screen_scale = 0.7 + self.screenshot_method = None + self._detect_screenshot_method() + + def _detect_screenshot_method(self): + """Автоматическое определение доступного метода захвата экрана""" + methods = [] + + # Проверяем системные утилиты для Ubuntu + if subprocess.run(['which', 'gnome-screenshot'], capture_output=True).returncode == 0: + methods.append('gnome-screenshot') + if subprocess.run(['which', 'scrot'], capture_output=True).returncode == 0: + methods.append('scrot') + if subprocess.run(['which', 'import'], capture_output=True).returncode == 0: + methods.append('imagemagick') + + # Проверяем Python библиотеки + try: + import mss + methods.append('mss') + except ImportError: + pass + + print(f"📸 Доступные методы захвата экрана: {methods}") + + if methods: + self.screenshot_method = methods[0] + print(f"✅ Выбран метод: {self.screenshot_method}") + else: + print("❌ Не найдены методы захвата экрана") + + def create_session(self): + session_id = str(uuid.uuid4()) + self.sessions[session_id] = { + 'created_at': datetime.now(), + 'last_activity': datetime.now() + } + return session_id + + def get_system_info(self): + """Получение информации о системе""" + try: + # Получаем информацию о дистрибутиве Ubuntu + distro_info = "" + try: + with open('/etc/lsb-release', 'r') as f: + for line in f: + if line.startswith('DISTRIB_DESCRIPTION'): + distro_info = line.split('=')[1].strip().strip('"') + except: + distro_info = "Ubuntu (точная версия неизвестна)" + + system_info = { + 'distribution': distro_info, + 'platform': platform.system(), + 'platform_release': platform.release(), + 'architecture': platform.machine(), + 'hostname': socket.gethostname(), + 'username': os.getenv('USER'), + 'display': os.environ.get('DISPLAY', ':0'), + 'screenshot_method': self.screenshot_method, + 'python_version': platform.python_version(), + 'current_directory': os.getcwd() + } + return system_info + except Exception as e: + return {'error': str(e)} + + def capture_screenshot(self): + """Создание скриншота рабочего стола""" + try: + if not self.screenshot_method: + return None, "Не найдены методы захвата экрана" + + if self.screenshot_method == 'gnome-screenshot': + return self._capture_with_gnome_screenshot() + elif self.screenshot_method == 'scrot': + return self._capture_with_scrot() + elif self.screenshot_method == 'imagemagick': + return self._capture_with_imagemagick() + elif self.screenshot_method == 'mss': + return self._capture_with_mss() + else: + return None, f"Неизвестный метод: {self.screenshot_method}" + + except Exception as e: + return None, f"Ошибка захвата экрана: {str(e)}" + + def _capture_with_gnome_screenshot(self): + """Захват экрана с помощью gnome-screenshot (рекомендуется для Ubuntu)""" + try: + # Используем временный файл для надежности + temp_file = f"/tmp/screenshot_{int(time.time())}.png" + + result = subprocess.run([ + 'gnome-screenshot', '-f', temp_file, '--include-pointer' + ], capture_output=True, text=True, timeout=10) + + if result.returncode != 0: + return None, f"GNOME Screenshot failed: {result.stderr}" + + # Читаем файл + with open(temp_file, 'rb') as f: + img_data = f.read() + + # Удаляем временный файл + os.unlink(temp_file) + + img = Image.open(io.BytesIO(img_data)) + return self._encode_image(img), None + + except subprocess.TimeoutExpired: + return None, "GNOME Screenshot timeout" + except Exception as e: + return None, f"GNOME Screenshot error: {str(e)}" + + def _capture_with_scrot(self): + """Захват экрана с помощью scrot""" + try: + temp_file = f"/tmp/screenshot_{int(time.time())}.png" + + result = subprocess.run(['scrot', '-o', temp_file], + capture_output=True, text=True, timeout=10) + + if result.returncode != 0: + return None, f"Scrot failed: {result.stderr}" + + with open(temp_file, 'rb') as f: + img_data = f.read() + os.unlink(temp_file) + + img = Image.open(io.BytesIO(img_data)) + return self._encode_image(img), None + + except subprocess.TimeoutExpired: + return None, "Scrot timeout" + except Exception as e: + return None, f"Scrot error: {str(e)}" + + def _capture_with_imagemagick(self): + """Захват экрана с помощью ImageMagick""" + try: + result = subprocess.run(['import', '-window', 'root', 'png:-'], + capture_output=True, timeout=10) + + if result.returncode != 0: + return None, f"ImageMagick failed: {result.stderr}" + + img = Image.open(io.BytesIO(result.stdout)) + return self._encode_image(img), None + except subprocess.TimeoutExpired: + return None, "ImageMagick timeout" + except Exception as e: + return None, f"ImageMagick error: {str(e)}" + + def _capture_with_mss(self): + """Захват экрана с помощью mss""" + try: + import mss + with mss.mss() as sct: + monitor = sct.monitors[1] + screenshot = sct.grab(monitor) + img = Image.frombytes("RGB", screenshot.size, screenshot.bgra, "raw", "BGRX") + return self._encode_image(img), None + except Exception as e: + return None, f"MSS error: {str(e)}" + + def _encode_image(self, img): + """Кодирование изображения в base64""" + try: + # Масштабирование + if self.screen_scale != 1.0: + new_size = (int(img.width * self.screen_scale), + int(img.height * self.screen_scale)) + img = img.resize(new_size, Image.Resampling.LANCZOS) + + buffer = io.BytesIO() + img.save(buffer, format='JPEG', quality=self.screen_quality) + return base64.b64encode(buffer.getvalue()).decode('utf-8') + except Exception as e: + raise Exception(f"Image encoding error: {str(e)}") + + def execute_command(self, command): + """Выполнение команды в оболочке""" + try: + result = subprocess.run(command, shell=True, capture_output=True, text=True, timeout=30) + output = result.stdout + if result.stderr: + output += f"\nSTDERR: {result.stderr}" + return output, None + except subprocess.TimeoutExpired: + return None, "Command timeout" + except Exception as e: + return None, f"Command error: {str(e)}" + + def send_key(self, key): + """Отправка клавиши (эмуляция)""" + try: + # Используем xdotool для эмуляции клавиатуры + result = subprocess.run(['xdotool', 'key', key], + capture_output=True, text=True, timeout=10) + if result.returncode == 0: + return True, None + else: + return False, result.stderr + except Exception as e: + return False, f"Keyboard error: {str(e)}" + + def mouse_click(self, x, y, button='left'): + """Клик мыши в указанных координатах""" + try: + # Используем xdotool для эмуляции мыши + if button == 'left': + click_arg = '1' + elif button == 'right': + click_arg = '3' + else: + click_arg = '1' + + result = subprocess.run([ + 'xdotool', 'mousemove', str(x), str(y), 'click', click_arg + ], capture_output=True, text=True, timeout=10) + + if result.returncode == 0: + return True, None + else: + return False, result.stderr + except Exception as e: + return False, f"Mouse click error: {str(e)}" + + +remote_desktop = RemoteDesktop() + + +@app.route('/') +def index(): + if 'session_id' not in session: + session['session_id'] = remote_desktop.create_session() + + system_info = remote_desktop.get_system_info() + return render_template('remote_desktop.html', system_info=system_info) + + +@app.route('/system-info') +def system_info(): + info = remote_desktop.get_system_info() + return jsonify(info) + + +@app.route('/screenshot') +def screenshot(): + """Получение скриншота""" + if 'session_id' not in session: + return jsonify({'error': 'Сессия не найдена'}) + + image_data, error = remote_desktop.capture_screenshot() + if error: + return jsonify({'error': error}) + + return jsonify({'image': image_data}) + + +@app.route('/command', 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, error = remote_desktop.execute_command(command) + if error: + return jsonify({'error': error}) + + return jsonify({'output': output}) + + +@app.route('/keyboard', methods=['POST']) +def keyboard_action(): + """Эмуляция клавиатуры""" + if 'session_id' not in session: + return jsonify({'error': 'Сессия не найдена'}) + + data = request.get_json() + key = data.get('key', '') + + if not key: + return jsonify({'error': 'Не указана клавиша'}) + + success, error = remote_desktop.send_key(key) + if not success: + return jsonify({'error': error}) + + return jsonify({'status': 'success'}) + + +@app.route('/mouse/click', methods=['POST']) +def mouse_click(): + """Клик мыши""" + if 'session_id' not in session: + return jsonify({'error': 'Сессия не найдена'}) + + data = request.get_json() + x = data.get('x', 0) + y = data.get('y', 0) + button = data.get('button', 'left') + + success, error = remote_desktop.mouse_click(x, y, button) + if not success: + return jsonify({'error': error}) + + return jsonify({'status': 'success'}) + + +@app.route('/settings', methods=['POST']) +def update_settings(): + """Обновление настроек""" + if 'session_id' not in session: + return jsonify({'error': 'Сессия не найдена'}) + + data = request.get_json() + quality = data.get('quality') + scale = data.get('scale') + + if quality is not None: + remote_desktop.screen_quality = max(10, min(100, quality)) + if scale is not None: + remote_desktop.screen_scale = max(0.1, min(1.0, scale)) + + return jsonify({ + 'quality': remote_desktop.screen_quality, + 'scale': remote_desktop.screen_scale + }) + + +@app.route('/test') +def test_page(): + """Тестовая страница""" + image_data, error = remote_desktop.capture_screenshot() + + if error: + return f""" + + +

❌ Ошибка захвата экрана

+

{error}

+

Решение для Ubuntu:

+ + sudo apt update
+ sudo apt install gnome-screenshot scrot imagemagick xdotool
+ pip install mss pillow +
+ + + """ + + return f""" + + +

✅ Тест захвата экрана - УСПЕШНО!

+

Метод: {remote_desktop.screenshot_method}

+ +

← Вернуться к удаленному рабочему столу

+ + + """ + + +if __name__ == '__main__': + os.makedirs('templates', exist_ok=True) + + with open('templates/remote_desktop.html', 'w', encoding='utf-8') as f: + f.write(''' + + + + + Удаленный рабочий стол Ubuntu + + + +
+

🖥️ Удаленный рабочий стол Ubuntu

+

Управление рабочим столом через веб-интерфейс

+
+ +
+ + + + + + +
+ +
+
+ +
+
+ 🖼️ Нажмите "Обновить экран" для захвата рабочего стола +
+ +
+ +
+

💻 Командная строка

+ + +
+
+ +
+ Статус: Готов + Метод: {{ system_info.screenshot_method }} | Ubuntu +
+ + + +''') + + print("=" * 60) + print("🖥️ УДАЛЕННЫЙ РАБОЧИЙ СТОЛ ДЛЯ UBUNTU") + print("=" * 60) + + system_info = remote_desktop.get_system_info() + print(f"💻 Система: {system_info.get('distribution', 'Ubuntu')}") + print(f"📸 Метод захвата: {remote_desktop.screenshot_method}") + + if remote_desktop.screenshot_method: + print("✅ Захват экрана настроен корректно") + else: + print("❌ Установите зависимости:") + print(" sudo apt install gnome-screenshot scrot imagemagick xdotool") + + print("🌐 Сервер запущен: http://0.0.0.0:5000") + print("🧪 Тест: http://0.0.0.0:5000/test") + print("=" * 60) + + app.run(host='0.0.0.0', port=5000, debug=False, threaded=True) \ No newline at end of file