RDP 暴力破解攻击的真实面貌

解剖每台暴露在公网的 Windows 服务器都会遭遇的攻击:谁在发动、成本如何、为什么常规建议只解决一半问题,以及什么才能真正阻止它。

阅读约 7 分钟

用大白话说,这是什么

RDP 暴力破解并不是针对您的定向行动,而是一种批量商品:有人租一个僵尸网络,喂进一份 IP 段清单,让它对每一台在 3389 端口应答的机器尝试登录。密码表短小而乏味——Administrator 配 Password1、admin 配 admin、公司名加当前年份。机器人既不知道也不在乎您的服务器是做什么的。

让攻击不停歇的是经济账。一次成功登录在勒索软件的初始访问市场上值真金白银,而一次尝试的成本几乎为零。所以机器人永远不会停。把一台全新的 Windows Server 放到公网 IP 上并开放 RDP,第一次失败登录通常一小时内就会出现,一周后稳定在每天几千次。

关键在于量级。一个人手工猜您的密码是个故事;每月十万次来自不断轮换地址的尝试是一种天气现象。按前者设计的防御,对后者毫无用处。

怎么判断这正发生在您身上

Windows 会把每一次失败登录记为安全日志中的事件 ID 4625。打开事件查看器,进入「Windows 日志 → 安全」,按 4625 过滤。在一台安静的服务器上,您会看到几条来自输错密码的用户的记录;在攻击之下,您会看到一面墙。

关键信号不是数量本身,而是形态。输错密码的用户会从一个地址产生两三次失败,针对一个真实存在的账户,然后就停了。机器人则会针对您机器上从未存在过的账户名产生长串记录——admin、sql、backup、test、scanner、user1——来自您从未打过交道的托管商 IP 段,整夜保持稳定速率。

下面这条命令可以列出最近 24 小时内失败次数最多的来源地址:

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

为什么常规建议只解决一半问题

每份加固清单的第一条都是「使用强密码」。这没错,但不够。强密码意味着机器人猜不中——但它们会永远试下去,而每一次尝试都要消耗您一个线程、一行审计日志和一小片 CPU。持续遭受攻击的服务器会出现可测量的变慢,安全日志轮转得太快,以至于您真正需要的那条记录早已不见。

接下来通常是「启用账户锁定策略」。这条要小心。锁定按账户统计失败次数,而机器人是从清单里猜账户名的。设置 Administrator 五次失败即锁定,那么一个根本猜不中密码的攻击者,现在可以从任何地方随时把这个账户永久停用。您把一个骚扰变成了针对自己的拒绝服务。

网络级身份验证(NLA)确实有用:它要求客户端在会话创建之前完成认证,从而消除了一整类认证前漏洞,并降低每次尝试的资源成本。请开启它。但它不会降低尝试频率。

在 RDP 前面加一层 VPN 是现有最强的答案,也是多数组织实际上无法采用的:这意味着每一个外包人员、每一部手机、每一次凌晨三点的紧急登录都要经过额外的基础设施,而那套设施同样需要维护和付费。如果做得到,就去做。但现在正被攻击的大多数服务器,恰恰属于做不到的人。

什么才真正减少尝试次数

唯一能改变量级的做法是拒绝与来源对话,其余所有做法都是在和它谈判。

这意味着盯住失败流,当某个地址越过阈值时,把它加入一条防火墙规则,在 Windows 为它花费任何资源之前丢弃它的数据包。这正是 fail2ban 在 Linux 上做的事,而 Windows 没有内置的对应物——这也是为什么这么多管理员最后都在写计划任务里的 PowerShell 脚本。

三个细节区分了「扛得住的防御」和「会漏的防御」:

  • 封禁子网,而不是单个地址。机器人跑在托管商的 IP 段上。封掉 203.0.113.47,一小时后 .48 就会接上。封掉整个 /24 才能一次终结这一轮——而合法用户几乎不会和扫描器共用一个 /24。
  • 永久封禁,并且能挺过重启。封禁一小时意味着同一个僵尸网络今晚就会回来。规则必须落在防火墙里,而不是在内存中。
  • 先把自己加入白名单,再启用其他任何东西。这件事最常见的翻车方式,就是管理员把自己办公室的 IP 挡在了一台只能通过 RDP 访问的服务器之外。

合并规则,否则防火墙会成为瓶颈

一个只有在生产环境才会暴露的细节:Windows 防火墙处理少量大规则的效率,远高于处理数千条小规则。那些为每个被封地址调用一次 New-NetFirewallRule 的脚本,前两周运行得非常漂亮,随后规则集涨到五位数,规则求值开始耗费数分钟。

解法是保留一条规则并重写它的地址列表,而不是给每个攻击者建一条规则。这是个很小的设计决定,却决定了半年后这套防御是否还能用。

不写脚本也能得到同样的效果

RDP Protector 就是把这套逻辑打包成一个带签名的 Windows 代理。它读取的正是您会去读的那条 4625 流,在本地做出判断——因此断网时仍然有效——并维护一条包含所有被封网段的合并防火墙规则。

安装时,它会从注册表和监听套接字中识别实际的 RDP、FTP 和 MS SQL 端口,因此已经从 3389 迁走的服务器无需配置即可获得保护;并且它会在封禁任何东西之前,先把您当前连入的 IP 加入白名单。

您独自无法构建的部分是共享信誉:攻击过另一位客户的地址,在到达您这里之前就已经被封禁。一台服务器永久免费,这足以让您在自己的机器上观察真实的攻击流,然后基于证据做决定。

FAQ

多少次 RDP 登录失败算正常?
在不暴露于公网的服务器上接近于零——每周几次,来自输错密码的人。在 RDP 可被任意地址访问的服务器上,每天几千次毫不稀奇,也说明不了您有什么特别之处;那只是全网扫描的背景水平。真正重要的是趋势和来源分布,而不是绝对数字。
修改 RDP 端口能阻止暴力破解吗?
它能挡住只探测 3389 的非定向扫描器,而这在实践中占了绝大部分流量——尝试次数往往下降 90% 以上。但它挡不住任何扫描全端口范围的行为,而且 Shodan 之类的服务会持续索引非标准端口上的 RDP。请把它当作降噪,而不是防护。
该用账户锁定策略来对付暴力破解吗?
在面向公网的服务器上,不要把它当作主要防御。锁定是按账户名生效的,而攻击者可以随意选择账户名——也就是说任何人都能从任意地址随时锁死您的 Administrator 账户。请在网络层封禁;如果确实需要锁定策略,就给交互式账户设一个温和的阈值。
封禁整个 /24 子网会不会太激进?
对一个刚刚向您投来数百次失败登录的网段来说,很少算激进。攻击流量来自托管商和 VPS 网段,相邻地址属于同一个运营商;家庭用户几乎不会和扫描器共用一个 /24。只要为自己的办公地点和 VPN 出口保留白名单,误报率就接近于零。

在您自己的攻击流上看看效果

一台服务器,永久免费,无需信用卡。代理一分钟即可安装,并在封禁任何东西之前先把您当前的地址加入白名单。