RDWeb/RDS 2016: como identificar o IP no Evento 4625 e bloquear falhas de logon por força‑bruta

Seu RDWeb sofre tentativas de força‑bruta e os eventos 4625 não mostram o IP? Este guia prático explica por que o “Source Network Address” aparece como “–”, como registrar o c‑ip no IIS, correlacionar com o Security Log e bloquear ofensores no Windows Server/RDS 2016.

Índice

Visão geral do problema

Ambientes com Remote Desktop Services (RDS) publicados via RDWeb frequentemente registram uma enxurrada de logons malsucedidos no log de Segurança do Windows (evento 4625). O desafio clássico: o campo Source Network Address aparece como “–”. Isso acontece porque a autenticação inicial ocorre no IIS (aplicação web do RDWeb, com formulário), e o evento de falha gravado pelo LSA/Schannel nem sempre herda o IP do cliente — especialmente quando existe balanceador, proxy reverso ou tradução de endereços. A solução é complementar o Security Log com os logs W3C do IIS, onde o campo c-ip (e opcionalmente X-Forwarded-For) revela a origem real.

Fluxo de trabalho resumido

EtapaObjetivoComo fazer
Ativar auditoria avançada de logonRegistrar detalhes de IP/host na Security logGPMC → Configuração do Computador → Windows Settings → Advanced Audit Policy Configuration → Audit Policy → Logon/Logoff → Audit Logon: Success + Failure
Filtrar os eventos relevantesLocalizar rapidamente falhasEvent Viewer → Windows Logs → Security → Filter Current Log → Event ID 4624, 4625
Habilitar logs do IIS no RDWebIIS registra o campo c-ip (endereço do cliente)IIS Manager → Sites → RDWeb → Logging → Campos avançados: c-ip, cs-username, sc-status
Correlacionar Evento 4625 × Log IISIdentificar IP ofensoresCombinar o horário do evento com o IP capturado nos logs do IIS
Bloquear IPs e automatizarMitigar força‑brutaRegra no Windows Firewall ou firewall perimetral; considerar RdpGuard, Syspeace ou política de bloqueio de conta (< 5 tentativas)
Endurecer exposiçãoReduzir superfície de ataquePublicar via RD Gateway (443), restringir acesso externo por IP/VPN, habilitar NLA e exigir TLS 1.2
Monitorar tráfegoDiagnóstico avançadoCapturar com Microsoft Network Monitor ou Wireshark para inspecionar pacotes suspeitos

Por que o IP some no evento 4625

No RDWeb o usuário envia as credenciais via HTTP(S) para o IIS, que por sua vez aciona mecanismos de autenticação no sistema. Quando há proxy/WAF, NAT ou balanceador, o Windows enxerga o originador imediato (muitas vezes o próprio servidor local ou o VIP do balanceador), e o evento 4625 preenche o campo IpAddress como “–”. Entretanto, o log W3C do IIS registra o c-ip do cliente e, quando configurado, o X-Forwarded-For contendo o IP “original” atrás do proxy. Por isso, a estratégia vencedora é correlação de Security Log com log do IIS.

Habilitar auditoria avançada de logon

Para que o evento 4625 traga o máximo de contexto, habilite as subcategorias certas via GPO (recomendado) ou localmente:

  • Audit Logon – Success e Failure
  • Credential Validation – Success e Failure
  • Other Logon/Logoff Events – Success e Failure
  • Account Lockout – Failure

Via linha de comando (executar em elevated prompt):

auditpol /set /subcategory:"Logon" /success:enable /failure:enable
auditpol /set /subcategory:"Credential Validation" /success:enable /failure:enable
auditpol /set /subcategory:"Other Logon/Logoff Events" /success:enable /failure:enable
auditpol /set /subcategory:"Account Lockout" /failure:enable

wevtutil sl Security /ms:419430400 

No comando acima, a última linha aumenta o retention do log de Segurança para ~400 MB; ajuste conforme sua política.

Filtrar rapidamente os eventos relevantes

No Visualizador de Eventos, aplique um filtro para 4625 (falhas) e 4624 (sucessos). Para investigações mais ricas, use um filtro XML de exemplo:

&lt;QueryList&gt;
  &lt;Query Id="0" Path="Security"&gt;
    &lt;Select Path="Security"&gt;
      *[System[(EventID=4625)]] and
      *[EventData[Data[@Name='AuthenticationPackageName'] != 'Negotiate']]
    &lt;/Select&gt;
  &lt;/Query&gt;
&lt;/QueryList&gt;

Dica: No 4625 verifique Account For Which Logon Failed, Failure Information (Status/SubStatus) e Logon Type (no RDWeb geralmente se comporta como “Network”).

Habilitar logs do IIS no site RDWeb

Abra o IIS Manager e, no site que hospeda o RDWeb:

  1. Acesse Logging e confirme o formato W3C com rotação diária.
  2. Clique em Select Fields… e certifique‑se de registrar:
    • date, time
    • c-ip (cliente)
    • cs-username
    • cs-method, cs-uri-stem
    • sc-status, sc-substatus, sc-win32-status
    • cs(User-Agent), cs(Referer) (úteis em análise)
  3. Se existir proxy reverso ou balanceador, adicione um campo de cabeçalho:
    • Em Select Fields… → Add Field, escolha Request Header e informe X-Forwarded-For.

Local dos logs: por padrão, C:\inetpub\logs\LogFiles\W3SVC<ID-do-site>. O ID do site pode ser visto nas Bindings ou no próprio IIS Manager.

Correlacionar Security Log e IIS

O princípio é simples: alinhar no tempo o evento 4625 com o POST de autenticação no RDWeb (tipicamente um POST para /RDWeb/Pages/...). O IIS grava em UTC, enquanto o Security Log aparece no horário local. Ajuste o fuso para a correlação ficar precisa.

Exemplo de PowerShell que captura 4625 da última hora, lê o último log do IIS e cruza informações, priorizando X-Forwarded-For quando presente:

# Janela de análise
$since = (Get-Date).AddHours(-1)

1) Security Log: extrai campos úteis do 4625

$evts = Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625; StartTime=$since} |
ForEach-Object {
$xml = [xml]$*.ToXml()
[pscustomobject]@{
TimeCreated = $*.TimeCreated
TargetUser  = ($xml.Event.EventData.Data | Where-Object {$*.Name -eq 'TargetUserName'}).'#text'
Status      = ($xml.Event.EventData.Data | Where-Object {$*.Name -eq 'Status'}).'#text'
SubStatus   = ($xml.Event.EventData.Data | Where-Object {$*.Name -eq 'SubStatus'}).'#text'
IpAddress   = ($xml.Event.EventData.Data | Where-Object {$*.Name -eq 'IpAddress'}).'#text'
LogonType   = ($xml.Event.EventData.Data | Where-Object {$_.Name -eq 'LogonType'}).'#text'
}
}

2) IIS: encontra o arquivo de log mais recente do site RDWeb

Import-Module WebAdministration
$site = Get-Website | Where-Object { $_.Name -match 'RDWeb' } | Select-Object -First 1
$logPath = Join-Path 'C:\inetpub\logs\LogFiles' ("W3SVC{0}" -f $site.Id)
$latest = Get-ChildItem $logPath -Filter *.log | Sort-Object LastWriteTime -Descending | Select-Object -First 1

3) Converte log W3C em objetos Powershell

$fieldsLine = (Select-String -Path $latest.FullName -Pattern '^#Fields:' | Select-Object -Last 1).Line
$headers = ($fieldsLine -replace '^#Fields:\s*','').Split(' ')
$rows = Get-Content $latest.FullName | Where-Object { $_ -notmatch '^#' }
$iis = $rows | ConvertFrom-Csv -Delimiter ' ' -Header $headers

4) Converte data/hora UTC do IIS para local e filtra URLs do RDWeb

$iis | ForEach-Object {
$utc = [datetime]::ParseExact(($.date + ' ' + $.time), 'yyyy-MM-dd HH:mm:ss', $null)
$_ | Add-Member -NotePropertyName LocalTime -NotePropertyValue ([datetime]::SpecifyKind($utc,'Utc').ToLocalTime())
} | Out-Null

$iisAuth = $iis | Where-Object { $.'cs-method' -eq 'POST' -and $.'cs-uri-stem' -match '/RDWeb' }

5) Correlaciona por janela de tempo e usuário

$window = 10 # segundos
$match = foreach ($e in $evts) {
$start = $e.TimeCreated.AddSeconds(-$window)
$end   = $e.TimeCreated.AddSeconds($window)
$cand = $iisAuth | Where-Object {
$.LocalTime -ge $start -and $.LocalTime -le $end -and
($.('cs-username') -like "$($e.TargetUser)" -or $*.('cs-username') -eq '-')
}
foreach ($c in $cand) {
[pscustomobject]@{
Time      = $e.TimeCreated
User      = $e.TargetUser
Status    = "$($e.Status)/$($e.SubStatus)"
CIp       = if ($c.'x-forwarded-for') { $c.'x-forwarded-for' } else { $c.'c-ip' }
Uri       = $c.'cs-uri-stem'
ScStatus  = $c.'sc-status'
LogonType = $e.LogonType
}
}
}

$match | Sort-Object Time | Format-Table -AutoSize 

O resultado lista o IP do atacante (CIp) associado a cada 4625. Ajuste a janela ($window) para ambientes muito carregados.

Automatizar bloqueio por limiar

Depois de correlacionar IP→falhas, é possível bloquear automaticamente quando ultrapassar um limiar (p.ex., 5 falhas em 10 minutos). O script abaixo cria um grupo de regras no Windows Firewall, adiciona bloqueios temporários e remove as entradas expiradas:

$since = (Get-Date).AddMinutes(-15)
$threshold = 5
$ruleGroup = 'RDWebAutoBlock'
$ttlHours = 24

Reutiliza a correlação do bloco anterior em $match (ou recalcule)

$offenders = $match | Group-Object CIp | Where-Object { $_.Count -ge $threshold }

foreach ($grp in $offenders) {
$ip = $grp.Name
if (-not (Get-NetFirewallRule -PolicyStore ActiveStore -ErrorAction SilentlyContinue |
Where-Object { $.DisplayName -eq "Block $ip" -and $.Group -eq $ruleGroup })) {
New-NetFirewallRule -DisplayName ("Block {0}" -f $ip) `      -Direction Inbound -Action Block -RemoteAddress $ip -Profile Any -Group $ruleGroup
    New-ItemProperty -Path ("HKLM:\SOFTWARE\RDWebAutoBlock\{0}" -f $ip)`
-Name 'Created' -Value (Get-Date).ToString('o') -Force | Out-Null
}
}

Expira regras antigas

$now = Get-Date
$keys = Get-ChildItem 'HKLM:\SOFTWARE\RDWebAutoBlock' -ErrorAction SilentlyContinue
foreach ($k in $keys) {
$created = Get-ItemPropertyValue $k.PSPath -Name 'Created'
if ([datetime]::Parse($created).AddHours($ttlHours) -lt $now) {
$ip = Split-Path $k.PSChildName -Leaf
Get-NetFirewallRule -PolicyStore ActiveStore | Where-Object { $.DisplayName -eq "Block $ip" -and $.Group -eq $ruleGroup } |
Remove-NetFirewallRule
Remove-Item $k.PSPath -Recurse -Force
}
} 

Boas práticas: teste em ambiente de homologação, evite falsos positivos (usuários legítimos com senha expirada podem gerar várias falhas), e registre quem/por que foi bloqueado.

Endurecer a publicação

  • Publicar exclusivamente via RD Gateway (porta 443) em vez de expor 3389. Crie políticas CAP/RAP restritivas e, se possível, exija MFA.
  • Restringir por IP ou VPN: permita apenas ranges corporativos, filiais ou parceiros.
  • NLA obrigatório nos hosts RDS: em “System Properties → Remote”, marque “Permitir conexões somente de computadores que executem Área de Trabalho Remota com NLA”.
  • Forçar TLS 1.2 e desabilitar protocolos antigos no servidor (Schannel). Exemplo de chaves de registro: Windows Registry Editor Version 5.00 [HKEYLOCALMACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server] "Enabled"=dword:00000000 "DisabledByDefault"=dword:00000001 [HKEYLOCALMACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server] "Enabled"=dword:00000000 "DisabledByDefault"=dword:00000001 [HKEYLOCALMACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.2\Server] "Enabled"=dword:00000001 "DisabledByDefault"=dword:00000000
  • Políticas de senha e bloqueio de conta: senha forte e bloqueio após 5 tentativas por 15 minutos são bons pontos de partida sem punir usuários legítimos por muito tempo.

Monitorar tráfego para diagnóstico

Se persistirem falhas sem correlação, capture tráfego no intervalo afetado:

  • netsh trace no próprio servidor: netsh trace start capture=yes scenario=InternetClient maxsize=500 filemode=circular REM reproduza o problema... netsh trace stop
  • Wireshark ou Microsoft Network Monitor com filtros por porta 443/80 e host/URI do RDWeb.

Tenha em mente que o tráfego HTTPS é criptografado; o objetivo é observar metadados (IPs, tentativas sequenciais, padrões por User-Agent), não o conteúdo.

Entendendo os códigos de falha

O par Status/SubStatus do 4625 ajuda a separar ataques de problemas de configuração:

Status/SubStatusSignificadoAção recomendada
0xC0000064Conta inexistenteBloqueio de IP, renomeie/desabilite contas padrão
0xC000006ASenha incorretaVerificar spray de senha; aplicar lockout
0xC0000234Conta bloqueadaChecar política de bloqueio e alertar SOC
0xC0000072Conta desabilitadaRevisar higiene de identidades
0xC0000070Restrição de estação de trabalhoAjustar restrições no AD
0xC000006FRestrição de horárioCorrigir janela de logon
0xC0000193Conta expiradaRenovar conta e revalidar acesso
0xC0000133Diferença de tempoSincronizar NTP do domínio/servidor
0xC000018DTrust quebradaReingressar no domínio
0xC000015BPolítica de logon nega acessoRevisar “Logon locally/through Terminal Services”

Dicas complementares

  • MFA ajuda, mas o ruído no log pode persistir (as falhas ocorrem antes do desafio Duo/OTP). Ao bloquear IP você elimina a origem.
  • Renomeie ou desabilite contas padrão (Administrator, Guest) para reduzir ataques por dicionário.
  • Mantenha Windows/IIS atualizados para corrigir lacunas de auditoria e aprimorar campos de log.
  • Use políticas de senha e lockout sensatas (por exemplo, 5 tentativas/15 minutos) evitando negação de serviço prolongada.

Boas práticas de correlação e análise

  • Normalizar horário: lembre‑se, IIS em UTC e Security em local. Ajuste sempre.
  • Casar por usuário e janela de tempo: a combinação de TargetUser + ±10 s reduz falsos positivos.
  • Priorizar X‑Forwarded‑For: se houver WAF/balanceador, este é o IP real do cliente.
  • Registrar mais campos: User‑Agent e Referer ajudam a identificar bots e padrões de ataque.
  • Guardar evidências: exporte planilhas com o IP, usuário alvo, status/substatus, janela de tempo e ação tomada.

Exemplos de consultas para agilizar investigações

Eventos 4625 por usuário nas últimas 24h:

Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625; StartTime=(Get-Date).AddDays(-1)} |
  Group-Object -Property { ([xml]$.ToXml()).Event.EventData.Data | Where-Object {$.Name -eq 'TargetUserName'} | Select-Object -ExpandProperty '#text' } |
  Sort-Object Count -Descending | Select-Object Count, Name

Falhas por IP a partir do IIS (sem correlação):

$log = Get-ChildItem 'C:\inetpub\logs\LogFiles\W3SVC1' -Filter *.log |
  Sort-Object LastWriteTime -Descending | Select-Object -First 1
$fields = (Select-String -Path $log.FullName -Pattern '^#Fields:' | Select-Object -Last 1).Line -replace '^#Fields:\s*',''
$data = (Get-Content $log.FullName | Where-Object {$_ -notmatch '^#'}) |
  ConvertFrom-Csv -Delimiter ' ' -Header ($fields -split '\s+')
$data | Where-Object { $.'cs-method' -eq 'POST' -and $.'cs-uri-stem' -match '/RDWeb' } |
  Group-Object 'c-ip' | Sort-Object Count -Descending | Select-Object Count, Name

Use a contagem por IP como indicador; para medidas punitivas, prefira a correlação com o 4625.

Políticas de bloqueio de conta com responsabilidade

O bloqueio de conta é eficiente contra brute force, mas pode ser explorado para doS contra usuários. Sugestões:

  • Limiar moderado: 5 tentativas/15 min costuma ser um meio‑termo.
  • Notificação: alerte o usuário e a equipe de segurança quando uma conta bloquear.
  • Revisão de IPs: confirme se não há dispositivos corporativos com senha antiga (serviços, apps móveis).

Controles adicionais de superfície de ataque

  • Restringir métodos de autenticação no IIS para o necessário (geralmente apenas Form/Windows conforme desenho).
  • Desabilitar protocolos legados (SSL 2/3, TLS 1.0/1.1) e cifras fracas. Teste previamente.
  • Separar funções: RDWeb, RD Gateway e Session Hosts em servidores distintos melhora telemetria e contenção.
  • Auditar permissões de “Log on through Remote Desktop Services” somente a grupos apropriados.

Erros comuns e como evitar

  • Fuso horário inconsistente: sem converter UTC→Local, a correlação falha.
  • Site errado do IIS: confira o Site ID do RDWeb para apontar ao diretório de log correto.
  • Falta do X‑Forwarded‑For: se houver WAF/proxy, sem esse cabeçalho você verá apenas o IP do balanceador.
  • Janela de tempo estreita demais: em servidores ocupados, amplie de 10 para 20/30 s.
  • Bloqueio de IP precipitado: valide se não é um usuário legítimo com credenciais desatualizadas.

Checklist prático

  • Auditoria avançada ativa para Logon, Credential Validation e correlatos.
  • IIS registrando c-ip, cs-username, sc-status e X-Forwarded-For (se aplicável).
  • Script de correlação testado e com fuso horário ajustado.
  • Mecanismo de bloqueio automático com expiração.
  • RD Gateway publicado, NLA obrigatório e TLS 1.2 forçado.
  • Políticas de senha e bloqueio de conta revisadas.
  • Contas padrão renomeadas/desabilitadas e atualizações em dia.

Conclusão

O “Source Network Address: –” no evento 4625 do RDWeb não é o fim da trilha — é um convite para correlacionar logs. Ao ativar auditoria adequada, registrar o c‑ip e X‑Forwarded‑For no IIS, e cruzar os dados, você revela de forma confiável o IP de origem de cada falha. Com bloqueio automatizado e ajustes de exposição (RD Gateway, NLA, TLS 1.2), o ruído cai e a superfície de ataque encolhe. O resultado é um RDWeb/RDS 2016 mais silencioso, previsível e seguro.


Resumo final: seguindo as etapas de auditoria, filtragem, logging no IIS e correlação, você recupera o IP por trás de cada 4625; na sequência, bloqueie e previna novas tentativas com automação e endurecimento da publicação.

Índice