远程工具凭据的离线固定

如果你接过一台被控嫌疑的 Windows 机器,需要回答委托方最常问的那个问题——"这台机器什么时候被谁控制了、控到了哪些主机"——你并不需要解出任何密码。设备 ID、对方识别码、连接时间线这三样在绝大多数远控工具里是明文存的,它们躺在几个配置文件和日志文件里,等着你用关键字去捞。

最后更新 2026-10-09版本 v1.0维护 DigiForensics查看历史 0

关键词:远控软件痕迹、AnyDesk、向日葵、ToDesk、TeamViewer、RustDesk、Navicat、Xshell、FinalShell、WinSCP、MRemote、绝不连接 难度:进阶 前置知识:Windows 注册表取证、配置文件的编码与加密(见 数据库与配置文件加密)、内存取证基础

一、概述

如果你接过一台被控嫌疑的 Windows 机器,需要回答委托方最常问的那个问题——"这台机器什么时候被谁控制了、控到了哪些主机"——你并不需要解出任何密码。设备 ID、对方识别码、连接时间线这三样在绝大多数远控工具里是明文存的,它们躺在几个配置文件和日志文件里,等着你用关键字去捞。

所以本篇要解决的第一个问题是:远控取证的瓶颈从来不是解密,而是定位与时间相关性。

分析员真正的困难不在密码学。你不知道工具把配置放在了哪,不知道哪个目录才是这台机器实际在用的那一份,也不知道"装过"和"被控过"之间那道沟要用什么证据才跨得过去。

本篇把"关键词全盘扫描 → 判定归属与时间 → 读明文字段 → 按格式分级处置"这条主链一次走通。明文能解决的,绝不多走一步。

第二个问题是边界划在哪里。本篇涉及的工具里有一半(Navicat、Xshell、FinalShell、WinSCP)根本不是远控软件,是业务客户端。

但它们保存的数据库与 SSH 凭据,在案件里的价值往往比远控痕迹更高。

哪些该固定、哪些能还原、哪些必须停在"存在"这一层,本章要交给你的就是这个判断。尤其是单向哈希字段——把它当成"解不开的加密"反复换工具,既浪费时间,又容易滑向越界。

第三个问题是合规。

本领域最容易犯的错不是技术错误,是性质错误:用检材里还原出来的凭据去连一下目标主机,看看是不是真的有效。

这个动作会把你的工作从"取证"变成"入侵",同时在远控服务端留下你的登录时间与来源 IP,污染证据。

这条红线的完整论证见 2.5,没有例外条款。

本篇处理的证据形态(这些文件名与字段名是判断"是什么工具、什么代次"的第一手依据):

工具 关键文件或位置 决定性的字段
AnyDesk service.conf(%ProgramData% 或 %APPDATA%) ad.anynet.id、ad.anynet.pwd_hash + pwd_salt + token_salt
向日葵 注册表 HKU\.DEFAULT\Software\Oray\SunLogin\SunloginClient\SunloginInfo;旧版 config.ini fastcode、encry_pwd
TeamViewer Connections_incoming.txt(入向成功)、connections.txt(出向)、TeamViewer15_Logfile.log 对方 ID、UTC 起止时间、认证事件行
ToDesk %APPDATA%\ToDesk、C:\ProgramData\ToDesk\ access_pin_hash(PBKDF2 加盐,单向)
Navicat *.tncf 连接配置 主机名/端口/用户名为明文,密码为 AES
WinSCP 注册表 HKCU\Software\Martin Prikryl\WinSCP 2\Sessions Password 值(代次决定是可逆变换还是 AES-256-CBC)
FinalShell conn.json password 字段(AES,密钥与本机绑定)
RustDesk RustDesk.toml 配置项版本差异大,先看文件本身

记住这张表是起点,不是事实表。

同一款工具的配置位置会在版本间迁移,向日葵从 config.ini 移到注册表就是典型。所以任何时候只在一个位置拿到空值,正确动作是换位置再找一次,而不是下"不存在"的结论。

表里的路径最终要靠两件事确认:目录或键是否存在、文件或值的修改时间是否与本案时间窗吻合。

版本一变,这张表就过期。所以本篇的操作步骤刻意从"全盘关键字扫描"开始,而不是从查表开始。

本篇的处置主链是四步,每一步都有明确的产出与停手条件:

步骤 动作 产出 什么时候就该停
1 全盘关键字扫描 命中路径清单 + 大小 + 最后修改时间 零命中时先核对关键字覆盖面,再下结论
2 判定归属与时间相关性 系统级 or 哪个用户、是否落在时间窗内 时间不吻合就到此为止,不写"被控"
3 读明文字段 设备 ID、IP、主机名、连接记录 多数案件到这一步就结束了
4 判断并还原密码字段 字段按明文 / 编码 / 加密 / 单向哈希四类定级 判定为单向哈希时到此为止,不换工具

"多数案件到第三步就结束了"这件事,值得单独强调。

委托方的问题往往是"这台机器被谁控过、什么时候",而这三个答案都是明文。

把口令解出来,技术上更有趣,交付上却毫无增量,却把处置风险从"取证"整体推向了"入侵"。

本篇第四章的合规红线不是形式主义,它就是这条判断的具体保障。

在取证流程中的位置:本篇属于分析环节的前段,紧跟在镜像制作之后。

上游依赖是镜像制作与只读挂载与安全接入。你需要一个只读挂载点,以及一份已经固定哈希的镜像。注册表取证里的 hive 离线提取手法,是本篇读取日葵、TeamViewer、WinSCP 三个工具的共同前置。

下游支撑的是时间线重建。定位与时间判定做完后,产出直接喂给时间线重建与其他痕迹源做交叉印证,跨文件的时序比较必须先统一到同一时间基准。同一批远控软件在 Linux 侧的行为侧形态见远程控制工具痕迹。

本篇的产出形态是一张结构化记录表:工具与版本、配置完整路径、归属主体、最后修改时间(UTC)、字段按 2.2 四类分级、关键明文值(脱敏)、关联日志路径与时间范围、处置记录(是否尝试还原、是否连接——后者恒为"否")。

这张表可以直接进报告,也可以作为时间线重建的输入。

本篇能回答什么:工具是否安装、属于哪个用户、最后活动时间、是否存在成功入向连接、对方标识与 IP 是什么、连接时间窗落在哪里、访问口令是否被设置过、是否存在哈希或密文凭据材料及其类型。

本篇不能回答什么,先说三类。

单向哈希字段(pwd_hash、access_pin_hash)的明文——那不是能力不足,是单向函数的定义,换工具不会改变结果。设了主密码的 WinSCP 与绑定用户环境的 Navicat 的密码内容。还有连接是否真的发生过——配置存在只能证明装过,成功连接必须靠 Connections_incoming.txt 或详细日志里的认证事件行。

至于对方主机上发生了什么,那超出委托授权范围,本篇明确不涉及。

读者前提:你需要先掌握注册表 hive 的离线提取与查询(注册表取证)、能读懂 ini/toml/json/注册表值这几种配置载体、以及时间戳换算的基本纪律(时间戳换算)。

如果你的检材是刚做完镜像、还没固定过哈希,本篇的一切结论都不具备可辩护性,先回去补证据保管链与委托证明。口令哈希的处置方法论不在本篇,见通用密码恢复的授权与最小化要求。

读完本篇你应当能独立回答的一句话是:"在这份 DigiForensics.dd 的全盘范围内,按 13 个工具名与已知文件名模式扫描,发现 N 处安装痕迹,其中 M 处的最后修改时间落在委托方给出的 <起> 至 <止> 窗口内,其中 K 处有成功入向连接记录;本次分析未使用检材中任何凭据对被控主机发起连接。"

这句话里每一个限定词都有对应章节——"全盘范围"对应第四章陷阱 1,"时间窗"对应陷阱 8,"成功入向"对应陷阱 9,"未使用凭据连接"对应陷阱 7。如果你写不出带这些限定词的句子,说明本篇的哪一节没读进去。

二、核心原理

2.1 配置定位:先分"每用户"还是"每机器"

同一款工具往往有两套配置目录,选错会得出"该机未安装"的错误结论:

安装形态 目录 取证含义
免安装/绿色版 %APPDATA%\<工具>、%USERPROFILE%\<工具> 属于某个具体用户,时间戳能反映该用户的操作时间
正式安装版 %ProgramData%\<工具>、%ProgramFiles%\<工具> 属于系统,全用户可见,可能是 IT 统一部署

判断原则:两处都要查。

只查 %APPDATA% 会漏掉 IT 部署的;只查 %ProgramData% 会漏掉员工自己偷偷装的——后者往往才是案情核心。

2.2 密码字段的四种格式

拿到配置后,密码字段只有四种可能。先判断格式,再决定要不要动手。

格式特征 实际是什么 典型场景
纯 ASCII 且直接可读 明文 多数国产远控的旧版本、Xshell 旧版、部分工具的 PIN
可被 base64 -d 还原为可读 ASCII base64 编码,不是加密 WinSCP 旧格式、Docker auth
固定长度 hex/base64,且伴随 salt/iv 字段 真正的加密(AES/RC4/自定义) WinSCP 新版(主密码保护)、Navicat 12+、FinalShell
形如 $2y$/$6$/32 位 hex 单向哈希 AnyDesk ad.anynet.pwd_hash、ToDesk access_pin_hash

最后一类无法还原成明文,也不应该还原。 口令哈希的正确用法是作为"该设备设了口令"的证据固定下来,再结合弱口令规则做离线验证(方法论见 04)。不要因为解不出明文就换工具去撞库式尝试——那已经越过取证与攻击的界线。

2.3 WinSCP:可逆混淆,不是加密

WinSCP 的 Password 注册表值在旧版本里是一种可逆的单向字节变换,不是密码学加密:

存储值 = (0xFF - 明文字节) XOR 0xA3

这个变换是对称的。把同样的两步再做一次,就还原了。这是 WinSCP 早期实现的固有弱点。

取证要点:新旧版本差异是这一节最容易翻车的地方——

版本 存储形式 处理方式
旧版(未设主密码) Password 值 = 上面的可逆变换 按同一公式还原,明文可得
新版(设了主密码) 密文为 AES-256-CBC,密钥由主密码派生 必须先拿到主密码,否则不可解
部分企业部署 改存 WinSCP.ini 配置文件 读文件而非注册表

第一条判断指令永远是"先确认有没有主密码"。 有主密码时,正确结论是"凭据受用户自定义主密码保护,本阶段不可解",而不是继续尝试变换公式——公式对上了也解不开加密格式。

2.4 版本差异是这个领域最大的坑

同一个工具的路径与格式在版本间反复变化,这是本节的实用核心:

  • 向日葵:老版本 config.ini(C:\Program Files\Oray\SunLogin\SunloginClient\ 或 C:\ProgramData\Oray\SunloginClient\),新版本主要在注册表 HKU\.DEFAULT\Software\Oray\SunLogin\SunloginClient\SunloginInfo,关键值 encry_pwd(本机验证码)与 fastcode(识别码)。只看 config.ini 会得出错误结论。
  • AnyDesk:目录随安装方式在 %APPDATA%\AnyDesk(免安装)和 %ProgramData%\AnyDesk(已安装)之间切换;密码是 ad.anynet.pwd_hash + pwd_salt + token_salt 三个字段一组,缺一个都算不出。
  • TeamViewer:HKLM\SOFTWARE\WOW6432Node\TeamViewer(机器级)/HKCU\Software\TeamViewer(用户级),PermanentPassword 是二进制值;连接记录在安装目录的 Connections_incoming.txt(只记成功连接)与 %APPDATA%\TeamViewer\connections.txt(出向)。
  • Navicat:12 起用 AES,密钥与当前操作系统用户环境绑定;新版进一步依赖平台安全存储(Windows DPAPI / macOS Keychain),跨机器/跨用户不可解。
  • ToDesk:%APPDATA%\ToDesk 与 C:\ProgramData\ToDesk\,PIN 以 access_pin_hash 形式保存(PBKDF2-SHA256 加盐),单向,不可还原。

通用做法:不要信任任何单一路径,包括我这张表。 表里的路径是起点,最终要靠两件事确认——目录/键是否存在、文件或值的修改时间是否与本案时间窗吻合。版本一变这张表就会过期。

2.5 ⚠️ 为什么"绝不连接"是硬红线

这是全文最重要的一段,请完整读完。

登录他人的远控账号、在他人设备上建立远程会话,在法律性质上属于"入侵行为"。后果与读取配置文件完全是两回事:

行为 法律与合规性质
读取检材中的配置文件、还原字段 取证行为(在授权范围内)
用检材中的凭据连接目标主机 未经授权的入侵,即使"只是看看"也构成实质入侵
在目标主机上执行命令、查看数据 加重情节

具体风险有三条。

一、污染证据。 远控服务在你的连接时会写日志——登录时间、来源 IP、会话记录。委托方之后再看这台机器,会发现"取证人员连接过"。这会直接动摇证据的可靠性,甚至让整个检材在质证中被质疑。

二、越权取证。 委托方授权你检验的是"这台机器",不是"被控的那台机器"。对后者发起连接超出了授权范围。

三、行为本身构成犯罪。 即便目的是"确认凭据是否有效",这个确认过程本身就是未经许可的访问行为。

🚫 硬性禁止

本文及本板块所有操作,一律不得使用检材中还原出的任何凭据发起真实连接。

取证阶段的正确做法是:

  1. 只做离线解密,把还原结果作为**凭据固定(credential fixing)**记录在案。
  2. 需要验证凭据有效性时,由委托方在受控环境中自行验证,或由具备相应资质的机构在其授权范围内验证。
  3. 发现的凭据立即通过正式渠道上报委托方,不私存、不转作他用、不在非授权环境测试。
  4. 报告中凭据必须脱敏——完整口令不进报告正文,只记录存在性、类型、所属主体、发现路径。

报告中的正确表述:"在 DigiForensics.dd 的 %ProgramData%\AnyDesk\service.conf 中发现被控方 AnyDesk 账号的登录口令材料(ad.anynet.pwd_hash,SHA-256 形式,单向不可逆),可用于验证该设备是否设置了访问口令。本次分析未使用该材料对任何目标设备发起连接。"


三、操作步骤

步骤 1:全盘定位工具痕迹(不预设路径)

不要从路径表开始猜,先做一次全盘关键词扫描,让工具自己暴露位置:

# 关键词扫描:一次覆盖主流远控 + 数据库/SSH 客户端
$KW = 'AnyDesk','Sunlogin','Oray','ToDesk','TeamViewer','RustDesk','Navicat',
      'Xshell','FinalShell','WinSCP','MRemote','FileZilla','ToDesk_Service'
$Out = 'D:\evidence\remote_tools_hits.csv'
'Hit,Path,Size,LastWrite' | Set-Content $Out
foreach ($k in $KW) {
  Get-ChildItem C:\ -Recurse -Force -Filter "*$k*" -ErrorAction SilentlyContinue |
    Select-Object -First 50 | ForEach-Object {
      '{0},{1},{2},{3}' -f $k, $_.FullName, $_.Length, $_.LastWriteTimeUtc
    } | Add-Content $Out
}
Get-Content $Out | Select-Object -First 40

只读要求:本命令只做枚举与导出,不打开、不修改、不启动任何被检程序。

永远不要在检材上双击运行远控客户端——启动它本身就会写日志、改配置、可能拉起服务。

步骤 2:判定配置归属与时间相关性

对每个命中目录,回答三个问题。

  1. 属于系统还是某个用户? 路径在 %ProgramData%/%ProgramFiles% = 系统;在 %APPDATA%/%Users\xxx = 该用户。
  2. 最后修改时间是否落在本案时间窗内? 这一条比"是否存在"更重要。存在但半年没动过的配置,说明的不是"近期被控"。
  3. 有多个用户目录吗? 多个 %APPDATA%\<工具> 意味着多台主机/多个操作人,每个都要单独固定。

步骤 3:读出明文字段——这一步通常就够了