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.
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
Etapa | Objetivo | Como fazer |
---|---|---|
Ativar auditoria avançada de logon | Registrar detalhes de IP/host na Security log | GPMC → Configuração do Computador → Windows Settings → Advanced Audit Policy Configuration → Audit Policy → Logon/Logoff → Audit Logon: Success + Failure |
Filtrar os eventos relevantes | Localizar rapidamente falhas | Event Viewer → Windows Logs → Security → Filter Current Log → Event ID 4624, 4625 |
Habilitar logs do IIS no RDWeb | IIS 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 IIS | Identificar IP ofensores | Combinar o horário do evento com o IP capturado nos logs do IIS |
Bloquear IPs e automatizar | Mitigar força‑bruta | Regra no Windows Firewall ou firewall perimetral; considerar RdpGuard, Syspeace ou política de bloqueio de conta (< 5 tentativas) |
Endurecer exposição | Reduzir superfície de ataque | Publicar via RD Gateway (443), restringir acesso externo por IP/VPN, habilitar NLA e exigir TLS 1.2 |
Monitorar tráfego | Diagnóstico avançado | Capturar 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:
<QueryList>
<Query Id="0" Path="Security">
<Select Path="Security">
*[System[(EventID=4625)]] and
*[EventData[Data[@Name='AuthenticationPackageName'] != 'Negotiate']]
</Select>
</Query>
</QueryList>
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:
- Acesse Logging e confirme o formato W3C com rotação diária.
- 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)
- 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
.
- Em Select Fields… → Add Field, escolha Request Header e informe
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/SubStatus | Significado | Ação recomendada |
---|---|---|
0xC0000064 | Conta inexistente | Bloqueio de IP, renomeie/desabilite contas padrão |
0xC000006A | Senha incorreta | Verificar spray de senha; aplicar lockout |
0xC0000234 | Conta bloqueada | Checar política de bloqueio e alertar SOC |
0xC0000072 | Conta desabilitada | Revisar higiene de identidades |
0xC0000070 | Restrição de estação de trabalho | Ajustar restrições no AD |
0xC000006F | Restrição de horário | Corrigir janela de logon |
0xC0000193 | Conta expirada | Renovar conta e revalidar acesso |
0xC0000133 | Diferença de tempo | Sincronizar NTP do domínio/servidor |
0xC000018D | Trust quebrada | Reingressar no domínio |
0xC000015B | Política de logon nega acesso | Revisar “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
eX-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.