内网横移中的RDP威胁狩猎

内网横移中的RDP威胁狩猎

在大量真实入侵事件中,远程桌面协议(RDP)几乎已经成为攻击者进行横向移动的“标配工具”。这个最初由微软设计、用于远程系统管理和运维的协议,在现实环境中却频繁被滥用,成为内网扩散和权限放大的关键通道。

从应急响应的角度来看,RDP 的危险之处并不在于它本身有多“恶意”,而在于它太正常了。正因为企业日常运维和远程办公高度依赖 RDP,攻击者的行为很容易隐藏在合法流量和正常操作之中。

为什么 RDP 会成为内网横移的首选

在一次典型的入侵中,攻击者往往并不会满足于最初控制的一台主机。真正的目标通常是更有价值的系统,比如文件服务器、数据库服务器,甚至是域控。

横向移动就是攻击者在已经拿下一台主机后,利用凭据、信任关系或系统配置,在同一信任域内不断扩展控制范围的过程。和“纵向提权”不同,横向移动更像是在内网中“悄悄换房间”。

RDP 在这个阶段非常好用,原因很简单:

  • 它提供完整的图形界面,攻击者可以像真正的用户一样操作系统
  • 不需要复杂的工具链,一个系统自带的 RDP 客户端就够了
  • 合法运维行为天然为攻击行为提供了掩护

在多起应急响应案例中,都能看到:攻击者最终横向移动的“最后一公里”,往往就是 RDP。

常见的 RDP 横向移动手法

凭据窃取与复用

这是最常见、也是最有效的一种方式。在已经被控制的主机上,攻击者通常会想办法获取更多账号凭据,例如:

  • 从 LSASS 内存中提取明文密码或哈希值
  • 通过键盘记录截获用户输入
  • 利用系统缓存的凭据或票据

在真实事件中,“Pass-the-Hash” 尤其常见。攻击者并不需要破解密码,只要拿到 NTLM 哈希,就可以直接通过 RDP 或其他远程协议完成认证。一旦这些凭据在多台机器上复用,横向移动就会变得异常顺畅。

RDP 会话劫持

相比新建连接,会话劫持更加隐蔽。

攻击者会先枚举系统中已有的 RDP 会话,然后通过提权操作获取 SYSTEM 权限,直接接管已有会话的令牌,并将会话重定向到自己的客户端。

这种方式最大的特点是:几乎不会产生新的登录事件,对日志分析和规则检测极不友好。在很多情况下,只有通过内存取证或异常行为分析才能发现蛛丝马迹。

利用 RDP 协议漏洞

历史上,RDP 也曾多次成为高危漏洞的重灾区。

最著名的例子是 BlueKeep(CVE-2019-0708),该漏洞允许攻击者在无需有效凭据的情况下直接远程执行代码。类似的漏洞(如 DejaBlue)也曾被用于在内网中快速横向传播。

在应急响应中,一旦发现老旧系统开启了 RDP 且未打补丁,往往需要优先评估是否存在“无凭据横向移动”的风险。

从事件日志入手定位 RDP 行为

在真实的应急响应过程中,事件日志往往是我们最先接触、也是最容易被攻击者“动手脚”的数据源之一。但即便如此,Windows 仍然会在多个位置记录 RDP 相关行为,只要理解这些日志之间的关联关系,就很难被完全清除干净。

一个非常重要的认知是:一次 RDP 行为,日志并不只存在于一台主机上

  • 发起 RDP 的源主机会留下网络与身份相关痕迹
  • 被登录的目标主机会记录会话、登录和桌面初始化过程

这对于分析横向移动尤其关键,因为攻击者不可能同时完美清理所有系统。

内网横移 vs 外部入侵 差异

在内网横向移动场景中(比如攻击者从一台已控主机跳到另一台内网服务器),我们往往可以同时看到源主机和目标主机的日志,这为溯源提供了极大的便利。

而在外部攻击场景中,如果攻击者是从互联网直接连接暴露在公网的 RDP 服务器,那么我们通常只能看到目标系统的日志,因为源主机并不在我们的取证范围内。

理解这一点,有助于我们在事件分析阶段合理调整预期,不会“执着地去找不存在的日志”。

Terminal Services :识别 RDP 尝试的入口

在所有与 RDP 相关的日志中,有一个经常被忽视、但价值极高的日志源:

Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational

这个日志有一个非常重要的特点:
无论 RDP 是否最终登录成功,只要发生连接尝试,就会被记录。

其中最核心的事件是:Event ID 1149

这个事件表示一次 RDP 连接尝试已经发生。需要特别注意的是,1149 并不等同于“成功登录”,它只能说明:有人尝试通过 RDP 与这台主机建立会话。

在应急响应中,我们通常把 1149 当作**“RDP 行为的存在性证据”**,而不是成功入侵的直接证明。

很多应急响应的初学者看到事件描述中的 “User authentication succeeded” 就会误判为成功登录,但实际上,这里指的是 NLA(Network Level Authentication)阶段通过,并不代表用户已经进入桌面。

安全日志中的关键证据:4624 登录事件

如果说 1149 是“敲门声”,那么 Windows Security 日志中的 4624,才是真正的“进门记录”。

Event ID 4624 – An account was successfully logged on

这是 Windows 中最重要的认证事件之一,包含了大量对溯源至关重要的信息,例如:

  • 登录时间(UTC)
  • 使用的账号
  • 源 IP 地址
  • 登录类型(Logon Type)
  • 源工作站名称

在分析 RDP 横向移动时,Logon Type 是重中之重

Logon Type 是理解 RDP 的核心

Windows 一共定义了多种登录类型,但在 RDP 场景下,真正需要重点关注的只有几种:

  • Logon Type 2(Interactive):本地物理登录
  • Logon Type 3(Network):网络级认证(几乎所有远程登录都会出现)
  • Logon Type 5(Service):当 Windows 服务使用服务账户进行身份验证以运行后台进程时触发。
  • Logon Type 7(Unlock):解锁已有会话
  • Logon Type 10(RemoteInteractive):典型的 RDP 新会话登录

一个非常关键、但在实战中经常被忽略的细节是:

RDP 登录并不是只出现 Logon Type 10

在一次完整的 RDP 登录过程中,通常会先出现 Logon Type 3,随后才是 Logon Type 10 或 7。这意味着,如果只盯着 Type 10,很容易漏掉真实的攻击行为。

新建会话 vs 重连会话

这里有一个在实战中非常有价值的判断点。

  • 如果攻击者使用一个从未在该系统登录过的账号通过 RDP 登录,通常会看到 Logon Type 10
  • 如果攻击者使用的是已经存在的会话账号(比如管理员之前登录过),那么更可能看到的是 Logon Type 7(Unlock)

这在横向移动中非常常见。攻击者往往不会频繁新建会话,而是反复“接管”已有会话,以降低日志噪音。

因此,在日志中看到大量重复的 Logon Type 7,而不是 Type 10,本身就是一个值得警惕的信号。

会话生命周期日志:确认攻击者是否真正进入桌面

仅靠 4624 还不足以完全确认攻击者是否成功操作系统。接下来需要结合另一个日志源:

Microsoft-Windows-TerminalServices-LocalSessionManager/Operational

这个日志记录的是 RDP 会话从创建、初始化到断开的完整生命周期。

在应急响应中,我们重点关注几个事件:

  • Event ID 21:RDP 会话登录成功
  • Event ID 22:用户 Shell(如 Explorer)启动
  • Event ID 25:会话重新连接成功
  • Event ID 24 / 39 / 40:会话断开

当在同一个 Session ID 下,看到 21 和 22 连续出现时,基本可以确认:攻击者已经成功进入图形桌面,并具备完整操作能力这一步,对于判断攻击是否进入“实质性操作阶段”非常关键。

断开 ≠ 登出:攻击者维持访问的常见方式

很多人误以为关闭 RDP 窗口就等同于退出系统,但实际上这只是断开会话在断开而非登出的情况下:

  • 会话仍然存在于内存中
  • 下次连接不会触发完整的登录流程
  • 日志中往往只出现 Logon Type 7(Unlock)

攻击者非常喜欢这种方式,因为它能:

  • 减少新登录事件
  • 避免引起基于 Type 10 的告警
  • 快速恢复访问

在日志中,如果看到频繁出现:

  • Session disconnect(24 / 40)
  • Session reconnect(25)
  • 配合 Logon Type 7

那么就需要高度怀疑这是一个被反复利用的 RDP 会话。

从进程执行痕迹还原 RDP 行为

在很多真实的入侵事件中,攻击者都会尝试清理或篡改事件日志。这个时候,如果分析只停留在 Event Log 层面,结论往往是不完整的,甚至会被误导。

在应急响应中,一个非常重要的原则是:

日志用来“指方向”,执行痕迹用来“定事实”。

进程执行证据,恰好是验证 RDP 行为是否真实发生、是否被攻击者实际使用过的关键补充。

从两端入手:源主机与目标主机的角色差异

分析 RDP 的进程执行行为时,必须明确一个前提:
RDP 是一个“跨主机行为”,两端留下的痕迹完全不同。

  • 源主机(发起 RDP 的机器)
    攻击者主动操作,通常通过 GUI 启动远程桌面客户端
  • 目标主机(被登录的机器)
    系统被动接收连接,相关进程由系统自动拉起

这一差异,直接决定了我们在两端应该关注哪些取证点。

源主机的 mstsc.exe 是最直接的突破口

在内网横向移动场景中,攻击者通常已经控制了一台工作站或服务器,并以此作为跳板,去连接下一个目标。当攻击者在源主机上发起 RDP 时,几乎一定会执行一个进程:

mstsc.exe(Microsoft Remote Desktop Client)

这是 Windows 自带的远程桌面客户端,大多数情况下通过 GUI 启动。因此,在源主机上,我们重点关注的不是“系统级服务”,而是用户侧执行痕迹。输出框的下拉按钮会展示历史的连接记录。

UserAssist:确认攻击者是否真的“点过远程桌面”

在所有 GUI 执行证据中,UserAssist 的价值非常高。它记录在用户的 NTUSER.DAT 中,反映的是用户实际交互过的程序,这点对判断“人为操作”尤其重要。

C:\Users\用户名\NTUSER.DAT
Software\Microsoft\Windows\CurrentVersion\Explorer\UserAssist

通过 UserAssist,我们通常可以获取到:

  • 程序的名称(如 Microsoft.Windows.RemoteDesktop)
  • 启动次数(Run Counter)
  • 窗口处于前台的时间(Focus Time)
  • 最近一次执行时间

在应急响应中,一旦在 UserAssist 中看到远程桌面客户端,并且时间点与可疑 RDP 登录行为吻合,基本可以确认:这不是系统行为,而是一次明确的人工操作。这对判断是否为横向移动,而非运维自动化行为,意义非常大。

建议:用RegistryExplorer来查看NTUSER.DAT文件,不要用系统自带的注册表工具(只能看到未解码的数据)。

BAM:从系统层面印证执行行为

为了避免单一证据点造成误判,我们通常会进一步查看 BAM(Background Activity Moderator)

SYSTEM\bam\State\UserSettings\<USER-SID>

BAM 位于 SYSTEM 注册表中,记录的是进程在后台被执行的时间信息。在 BAM 中再次看到 mstsc.exe,且时间与 UserAssist 对齐时,这种“交叉验证”会让证据更充分。

这个截图是Windows11上的,实测很多Windows Server系统版本并没有BAM的记录。因为BAM本质上是:Windows 为“电源 / 资源调度”设计的后台程序活动记录机制。而且BAM 不是只要执行进程就记录。它更偏向记录:后台运行、长时间存活的进程。

目标主机视角:系统拉起的进程

和源主机不同,目标主机上的 RDP 相关进程,并不是由用户手动启动的,而是由系统在会话建立过程中自动拉起。因此,这里有一个非常重要的取证误区需要避免:

不要在目标主机上找 UserAssist 或 RecentDocs 里的 RDP 痕迹

你什么都找不到,这是正常的。在目标主机上,我们关注的是系统执行证据,其中最直观的就是 Prefetch。

目标主机上常见的 RDP 相关进程

在一次完整的 RDP 会话中,目标系统通常会执行以下进程:

  • tstheme.exe:负责远程桌面会话的主题与界面
  • rdpclip.exe:处理剪贴板重定向(复制 / 粘贴)

这两个进程的出现,往往意味着:攻击者已经进入图形桌面,并开始进行真实操作。

Prefetch:确认 RDP 会话的存在与时间范围

在开启 Prefetch 的系统上,这些进程通常都会留下 Prefetch 文件。通过解析 Prefetch,我们可以获取到:

  • 进程是否被执行过
  • 最近一次执行时间
  • 执行次数

在时间线分析中,一个非常关键的点是:

  • 源主机 mstsc.exe 的执行时间
  • 目标主机 tstheme.exe / rdpclip.exe 的执行时间

这两者之间通常只相差几秒钟到几十秒,这个时间差正好对应 RDP 会话建立过程

在应急响应中,这种跨主机、跨证据源的时间线对齐,是判断横向移动是否真实发生的“铁证”。

Prefetch 不存在怎么办?

需要注意的是,在很多 Windows Server 环境中,Prefetch 默认是关闭的。这并不意味着就无法分析。

reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management\PrefetchParameters" /v EnablePrefetcher

在这种情况下,可以考虑:

  • Shimcache
  • Amcache
  • 结合事件日志中的会话 ID 和登录行为

核心思想不是“非要某一种证据”,而是用多种弱证据拼出一个强结论

在大量真实案例中,我们都遇到过类似情况:

  • 日志被清空或不完整
  • SIEM 中只有零散的认证事件
  • 攻击者否认进行过横向移动

而进程执行证据,尤其是 UserAssist + Prefetch 的组合,往往能直接击穿这些不确定性。它回答的不是“有没有登录”,而是:攻击者是否真的在远程桌面前操作过这台机器。

注册表里的RDP历史痕迹

在应急响应中,注册表往往不是第一时间被关注的对象。很多应急人员更习惯先看日志、再看进程执行,但在不少真实案件中,真正补全攻击路径的,反而是注册表里那些看似不起眼的键值

对于 RDP 横向移动来说,有一个注册表位置,几乎可以称得上是“低调但杀伤力极强”。

Terminal Server Client:RDP 连接的“使用记录”

当攻击者使用 Windows 自带的远程桌面客户端(mstsc.exe) 发起连接时,系统会在用户级注册表中留下连接历史。这些信息存放在:

NTUSER.DAT
└─ Software
   └─ Microsoft
      └─ Terminal Server Client
         └─ Servers

这个位置有几个非常重要的特点:

  • 位于 用户的 NTUSER.DAT 中,具备明确的用户归属
  • 记录的是 曾经连接过的远程主机
  • 不依赖事件日志是否开启
  • 通常不会被攻击者主动清理

在“攻击者有意识清日志,但没想到清注册表”的场景中,这个位置经常成为关键突破口

Servers 键下,会看到一组以 MRU 开头的值,这些值代表的是 Most Recently Used(最近使用) 列表:

  • MRU0:最近一次 RDP 连接
  • 数字越大,时间越早

每一个 MRU 值中,保存的都是攻击者通过 RDP 连接过的 主机名或 IP 地址。在横向移动分析中,可以直接看到攻击者“按顺序去过哪些机器”。

如果点开 Terminal Server Client 的上层键,会发现这里不仅记录了目标主机信息,还往往能看到:

  • 使用的用户名
  • 注册表键的最后写入时间(LastWrite Time)

这两个信息,在应急响应中非常关键。当能把 RDP 目标主机 + 用户账号 + 时间戳 放在一起时,很多原本模糊的行为,就会突然变得非常清晰。

为什么这个注册表证据如此重要?

从实战经验来看,这个位置的价值主要体现在三个方面:

第一,它天然具备“用户归因能力”。
相比系统级日志,NTUSER.DAT 明确对应某一个用户配置文件,几乎不存在“到底是谁干的”这种歧义。

第二,它反映的是“真实使用行为”。
只有通过 Windows 原生 RDP 客户端发起的连接,才会在这里留下记录。这意味着它更接近“人为操作”,而不是脚本或服务行为。

第三,它极难被完全抹除。
攻击者即便清理事件日志,也很少会逐个用户加载 NTUSER.DAT 并清空相关键值。这使得它在事后取证中存活率极高。

Bitmap Cache:从“行为证据”跃迁到“行为画面”

在大多数应急响应场景中,我们习惯用日志、进程、注册表去回答一个问题:攻击者有没有做过某件事?

而 Bitmap Cache 提供的,是一个更激进、也更直观的能力:攻击者当时在屏幕前“看到了什么、点了什么”。这在 Windows 取证体系中是极其罕见的。

Bitmap Cache 的本质:RDP 的性能优化产物

从技术原理上看,Bitmap Cache 并不是为了取证而设计的。

在 RDP 会话中,为了减少带宽占用、提升图形刷新效率,系统会将常用的界面元素拆分成小块(tile),并缓存在客户端本地。当这些界面再次出现时,就无需重新从远端传输。

这些缓存文件,默认存放在:

C:\Users\<Username>\AppData\Local\Microsoft\Terminal Server Client\Cache\

对于攻击者来说,这只是性能优化;对于应急响应人员来说,这是一次完整远程桌面操作留下的“视觉残留”

在 Bitmap Cache 目录中,通常会看到类似:

  • Cache0000.bin
  • Cache0001.bin
  • Cache0002.bin

这些编号并不是随机的,而是按 RDP 会话顺序递增的:

  • 数字越大,通常代表越新的会话
  • 最新一次横向移动,往往就藏在编号最大的文件中

在实战中,这一点非常重要,因为它让我们可以快速聚焦到最有价值的一次会话,而不是被历史缓存淹没。

从“碎片”到“画面”:专用拼图工具

https://github.com/ANSSI-FR/bmc-tools

Bitmap Cache 文件本身是不可读的,它们存储的是大量零散的图形块。单独看任何一个 tile,都几乎没有意义。这也是为什么 Bitmap Cache 长期被忽视——直到专门的解析和拼接工具出现。

通过 Bitmap Cache 解析工具,我们可以:

  • 将缓存中的图形块导出为图片
  • 自动生成拼接预览图(collage)
  • 再进一步重建接近真实桌面的截图

虽然无法保证 100% 还原,但在多数场景下,80%~90% 的画面可读性已经足够用于取证和归因

RDP爆破:横向移动最常见的起点

在很多真实事件中,RDP 横向移动并不是从“高端技巧”开始的。相反,它往往源于一种非常原始、甚至看起来有些“粗糙”的手段——暴力破解或密码喷洒

但正是这种方式,在大量企业内网中依然屡试不爽。

暴力破解并不隐蔽但经常被忽略

从检测角度看,RDP 暴力破解其实并不难发现。在 Windows 安全日志中,它通常表现为:

  • 大量 Event ID 4625(登录失败)
  • 在极短时间内集中出现
  • 源 IP 或源工作站高度一致

在一些案例中,几十甚至上百次失败登录,发生在一分钟之内,但却没有触发任何告警。这并不是因为攻击者多高明,而是因为内部网络默认被认为是“可信的”

一个很有价值的细节:源主机名

在很多真实环境中,暴力破解的“源主机名”本身就是一个强烈信号。

  • 明显不符合企业命名规范
  • 出现渗透测试或攻击系统常见的名称
  • 或者来自一台本不应该主动连接其他系统的终端

即便攻击者对 IP 做了隐藏,工作站名依然会在日志中留下痕迹。在应急响应中,这往往是确定“攻击起点”的重要线索。

典型的真实攻击场景

在多起实战案例中,攻击路径往往高度相似:

攻击者通过钓鱼邮件拿下一台普通员工的工作站。随后利用漏洞或配置问题完成本地提权。在系统中运行凭据抓取工具,获取曾经登录过该主机的高权限账号信息。使用这些凭据,通过 RDP 登录到其他服务器。在新的系统中重复上述过程,逐步逼近域控。最终的结果,往往是整个域环境被完全控制。

再举个常见的例子:如果员工通常在早上 9 点到下午 5 点之间通过 RDP 登录办公主机,那么凌晨 3 点、周末或节假日出现的 RDP 登录行为,就值得高度警惕。

再比如,如果一台人力资源部门hr的电脑,突然尝试通过 RDP 连接运维系统或服务器集群,这在正常业务场景下几乎说不通。攻击者正是利用了“RDP 本身是合法行为”这一点,刻意选择非工作时间跨部门系统进行操作,以降低被人工或自动化监控发现的概率。

从应急响应的角度看,这类事件真正的“失控点”,并不在最后一步,而在最初那几次异常的 RDP 登录行为

赞赏

微信赞赏支付宝赞赏

Zgao

愿有一日,安全圈的师傅们都能用上Zgao写的工具。

目前为止有一条评论

Sex Dating. Let’s Go ⭐➜ yandex.com/poll/43o224okZdReGRb1Q8PXXJ?hs=a3e90dce18e4f857f87634f3572d3098& Push Notification № CPKA5241583 发布于7:04 下午 - 1月 22, 2026

hjols2

发表评论