文章总结: 本文详细逆向分析了WindowsGDID(全局设备标识符)的生成与上报机制。核心结论是GDID并非硬件哈希,而是一个由微软账号服务器下发的64位设备PUID,写入注册表并持久存在,重装系统才会改变。FBI曾利用此标识符锁定黑客组织ScatteredSpider成员。文章提供了通过注册表查找自身GDID的方法,并建议用户注意该标识符的隐私暴露风险。 综合评分: 88 文章分类: 威胁情报,漏洞分析,恶意软件,安全意识,实战经验
好文 | 藏在 Windows 里的永久指纹 GDID —— FBI 靠它锁定了 Scattered Spider
原创
SmtimesIWndr SmtimesIWndr
赛博生存指南
2026年7月14日 08:59 日本
在小说阅读器读本章
去阅读
#
原文:Full writeup of the Windows GDID — Global Device Identifier fully reverse engineered https://github.com/SmtimesIWndr/gdid-reversal
作者:SmtimesIWndr | 平台:GitHub(Star 360+,Fork 24) | 研究方法:CDP 的 ETW 实时抓包 + 公开 PDB 静态逆向 | 复现环境:Windows 11(build 26200)
2026 年 7 月 1 日,美国司法部公开了一份针对 Peter Stokes 的刑事起诉书。检方指控他是 Scattered Spider(又名 Octo Tempest / UNC3944 / 0ktapus)的成员——这个名字在过去两年里和一连串针对大型企业的高调社工+勒索攻击绑定在一起。
起诉书的附件里,出现了一个此前几乎没人听过的词:Global Device Identifier g:6755467234350028(简称 GDID)。微软告诉 FBI,正是这串数字让他们把嫌疑人的活动锁定到了一台具体的 Windows 安装上。
消息一出,社交网络上立刻涌现出一堆”科普”:说 GDID 是个”128 位的、由硬件序列号生成的指纹”。这两个说法都是错的。 一位逆向工程师把整套机制彻底拆开重做了一遍,还原了 GDID 到底是怎么生成、存储、上报的。这篇推文,就是那次逆向的全过程。
核心结论先行:GDID 不是一个硬件哈希,而是一个由微软账号服务器下发、写入你注册表明文、跨更新持久、重装才换新的 64 位”设备护照号”。 你能在一行命令里读出自己的那一个。
置信度标注:原作者给每一条结论都打了标签,方便你自己掂量它的分量——
[COURT]来自法庭一手卷宗,[OBSERVED]在测试机上实测复现,[STATIC]从二进制与公开 PDB 证明,[ASSESSED]基于证据的强推断。本译文保留这些标签。
太长不看
- GDID 是真实的遥测项。 它出现在 2026 年 7 月那份美国联邦刑事起诉书(United States v. Peter Stokes, N.D. Ill., 2026-07)里,写作
Global Device Identifier g:6755467234350028。 - 它本质是微软账号的”设备 PUID”。 一个 64 位的 Passport Unique ID,在 Windows 安装注册微软账号时分配,在设备图谱里以
g:<十进制>的形式登记。 - 网传说法是错的。 它不是“128 位”,也不是“由序列号生成”。法庭记录本身就写明:重装系统会产生一个新的 GDID——这直接排除了”由 GPU 等固定硬件序列号派生”的可能。
- 完整链路自下而上:
wlidsvc(微软账号服务)向login.live.com注册设备并拿回设备 PUID → 写入注册表 → Connected Devices Platform(cdp.dll/CDPSvc)读取它并注册进 Device Directory Service(DDS) 设备图谱 → Delivery Optimization 把它作为文档化的UCDOStatus.GlobalDeviceId上报。 - 全部结论在一台真实的 Windows 11(26200)机器上用公开符号复现。你可以用一行注册表读取找到自己的 GDID(见 §7)。
作者后记纠偏(重要):原文发帖后作者补充——即使你不登录微软账号,你依然会有一个 GDID。CDP 有一条匿名设备路径,在没有微软账号时被启用。整套底层机制依然成立,只是少覆盖了几个细节。读 §6 时请记住这一点。
目录
- 背景:法庭到底说了什么
- 打破网络传言
- GDID 在哪冒头:Delivery Optimization
- 谁拥有它:从 Connected Devices Platform 到 DDS
- CDP 怎么拿到它:它是消费,不是计算
- 铸造厂:MSA 设备 PUID(
wlidsvc) - 查你自己机器的 GDID
- 减少暴露面
- 方法论(可复现)
- 局限与诚实的声明
1. 背景:法庭到底说了什么
[COURT] 2026 年 7 月 1 日,DOJ 解封了针对 Peter Stokes 的刑事起诉书。宣誓书(affidavit)描述了微软如何协助 FBI 把网络活动归因到一台设备。下面这段来自补强起诉书(¶25,p.34),逐字引用:
“the ngrok account was set up through Global Device Identifier g:6755467234350028 (‘the GDID’). According to a Microsoft representative, a Global Device Identifier in the Windows ecosystem is a persistent, device level identifier designed to uniquely identify an installation of a Windows operating system on a device… A GDID is a globally unique identifier tied to the installation of Windows on a device. A GDID remains consistent across Windows operating system updates on a device, but a reinstall of Windows… will be tied to a new unique GDID.“
(”该 ngrok 账号是通过 全局设备标识 g:6755467234350028(即 GDID)建立的。据微软代表称,Windows 生态中的全局设备标识是一个持久的、设备级别的标识符,用于在设备上唯一标识一次 Windows 操作系统的安装……GDID 是一个与设备上 Windows 安装绑定的全局唯一标识符。它在设备的 Windows 更新中保持一致,但重装 Windows 会绑定到一个新的唯一 GDID。”)
一个脚注补充:一个微软用户可以拥有多个 GDID。宣誓书随后把该 GDID 的 IP 历史和浏览记录(例如 empirehotelnyc.com、一个 Growtopia/Ubisoft 的登录 URL)与嫌疑人当时登录的账号做了关联比对。
这段话里有两点,支撑了后面整篇分析:
- 这个值是
g:加一个十进制整数(g:6755467234350028)。换算成十六进制是0x0018000FC8CB93CC,也就是一个 64 位数字。 - 重装会换一个新的 GDID。 所以它不可能只是”不变硬件的函数”。
这两条事实,是后面所有推理的地基。
2. 打破网络传言
社交媒体上的”总结”声称 GDID 是”a 128 bit identifier generated from serial numbers on install”(一个在安装时由序列号生成的 128 位标识符)。前后两半都是错的:
| 网传说法(社交媒体) | 真相(一手来源) |
| — | — |
| “128 位” | 起诉书里的值是 g:6755467234350028,这个十进制数装进 64 位就够了(0x0018000FC8CB93CC)。 |
| “安装时由序列号生成” | 起诉书写明重装会产生新的 GDID。如果它是固定序列号的函数,重装后应该得到同一个值,而不是换一个。 |
这两条传言之所以流传,是因为”硬件指纹”这个心智模型太好懂了——大家都愿意相信微软偷扫了你的 GPU/CPU/硬盘序列号然后 hash 出一个不可变的 ID。但卷宗里的”重装换新”这一句,恰好是证伪它的铁证:真正的硬件序列号不会因为你重装系统而改变。
作者纠偏:在对 CDP 做了更多逆向之后,作者承认最初给了误导信息——使用本地账号并不能阻止产生 GDID。CDP 在没有微软账号时会走一条匿名设备路径。读后续章节时请把这一点记在心里:登录与否,GDID 都在。
3. GDID 在哪冒头:Delivery Optimization
[STATIC] 微软公开的 Azure Monitor 文档里,在 UCDOStatus(Update Compliance / Delivery Optimization,更新合规/传递优化)表里定义了一个 GlobalDeviceId 列:
GlobalDeviceId(string):”Microsoft global device identifier. This is an identifier used by Microsoft internally.”(微软全局设备标识。这是微软内部使用的一个标识符。)
它紧挨着 LastCensusSeenTime、ISP、City、Country——也就是说,一个设备 ID 直接和地理位置、IP 对齐了。这是微软在公开文档里唯一一次给这个值命名的地方。
但要注意:Delivery Optimization 只是上报它,并不拥有它。顺着它往上游追,你会落到 Connected Devices Platform(连接设备平台)头上。
4. 谁拥有它:从 Connected Devices Platform 到 DDS
[STATIC]``C:\Windows\System32\cdp.dll(Connected Devices Platform,对应服务 CDPSvc + CDPUserSvc)里包含 GlobalDeviceId 符号,以及一整套 Device Directory Service(设备目录服务) 注册子系统:
ddsregistrationclient.cpp ddsregistrationmanager.cpp ddsregistrationinfo.cpp
DdsRegistrationClient RegisterUserDevicesObserver DdsRegistrationInfoProviderForCDP
endpoints: dds.microsoft.com fd.dds.microsoft.com aad.cs.dds.microsoft.com cdpcs.access.microsoft.com
device-id format string: "g:%s"
DDS = Device Directory Service(设备目录服务),是微软的跨设备身份图谱(Phone Link 手机连接、云剪贴板、”在此设备上继续”、Nearby Share 近距离共享的后端都是它)。CDP 是 Windows 客户端,把这次安装注册进这个图谱,在那里它被键为 g:<十进制>。
4.1 实时抓包复现
[OBSERVED] 强制一次全新注册(清空 CDPSvc 本地状态后重启它),同时抓取 CDP 自己的 ETW provider,完整握手就出来了:
DdsClient::RegisterUserDeviceAsync() RegistrationReason: Startup Account Type: MSA
DDSClient: Registration response received. HTTP status code:200
OnRegisterUserDeviceComplete
GetDeviceIdAndTicketActivity ->deviceid:0018XXXXXXXXXXXX
那个 deviceid,写成 g:<十进制> 后,在结构上和起诉书里的值对得上:
| | 值 | 十六进制(64 位) | 类前缀 |
| — | — | — | — |
| 我的机器(已脱敏) | g:XXXXXXXXXXXXXXXX | 0x0018XXXXXXXXXXXX | 0018 |
| 法庭证物 | g:6755467234350028 | 0x0018000FC8CB93CC | 0018 |
两者都是 64 位值,都落在同一个 0x0018 高位字类里(设备 PUID 的命名空间,见 §6)。那个 g: 前缀,不过就是这个整数的十进制写法而已。
5. CDP 怎么拿到它:它是消费,不是计算
[STATIC] 有了公开 PDB(cdp.pdb),cdp.dll 里的设备 ID 路径就是对着身份栈发一次请求然后等结果。CDP 自己从不计算这个 ID:
GetStableDeviceIdFromProvider (0x0A3140)
-> provider.GetStableDeviceIdAsync (vtable +0x48)
-> OneCoreAccountProvider::
GetStableDeviceIdAsync (0x0C8370)
-> IWebAccountBackedAccountProvider (MSA / AAD 身份 COM)
-> OnGetStableDeviceIdCompleted (const char* deviceId)(0x06CEA0)
-> assign() 字符串, signal flag
接收 ID 的那个回调让一切昭然若揭。ID 是以字符串形式出现的,然后直接被存下来:
; OnGetStableDeviceIdCompleted
movrbp, r9; r9 = 身份 provider 传进来的 device-id 字符串
learcx, [rsi+0xD8] ; CDP 成员字段
movrdx, rbp
call assign@basic_string ; 直接存,没有任何计算,没有任何序列号
call Set@CdpWaitableFlag ; 唤醒等待者
结论:GDID 在 CDP 之下、Windows 身份栈的更深处被铸造,然后以不透明字符串的形式交给 CDP。这条线索,直指微软账号服务。
6. 铸造厂:MSA 设备 PUID(wlidsvc)
[STATIC]``C:\Windows\System32\wlidsvc.dll——微软账号 / Passport(Windows Live ID)服务——是唯一一个包含字面量 GlobalDeviceId 的身份二进制,并且握有完整的设备配置机器:
CDeviceIdentityBase::CreateNewDeviceIdentity / Provision / BindDeviceToHardware / GetDeviceCert
DeviceAssociateRequest (Passport PPCRL SOAP -> login.live.com)
<ps:DevicePUID> ... </ps:DevicePUID>
DeviceIdStore::LogToRegistry
BCryptGenRandom / CCryptRandom::GenRandom (设备 KEY,不是 ID)
这个标识符是一个 Device PUID(Passport Unique ID),一个 64 位的 MSA 标识符。注意上面那个 BCryptGenRandom——它生成的是设备的认证密钥,由 BindDeviceToHardware 钉到这台机器上,不是 PUID 本身。这是一个容易混淆的点:随机生成的是钥匙,ID 本身是服务器分配的。
6.1 它是服务器分配的
[STATIC] 客户端从服务器的 SOAP 响应里取出 PUID,用一个 XPath 定位到响应体:
/S:Envelope/S:Body/ps:DeviceUpdatePropertiesResponse/HWPUIDFlipped
CAssociateDeviceRequest::ParseResponseBody 及相关的 ParseResponse 方法把响应 XML 节点读进 BSTR。所以流程是:客户端配置设备 → login.live.com 分配并返回设备 PUID → 客户端把它存下来。 这正好解释了两件事——为什么重装会得到一个新的 GDID(新的配置 = 新的服务器分配 PUID),以及为什么它不是硬件哈希。
6.2 它以明文持久化
[OBSERVED] 微软账号的身份存储把这个值直接放在注册表里,就在你自己的用户 hive 下:
HKCU\SOFTWARE\Microsoft\IdentityCRL\ExtendedProperties
LID = 0018XXXXXXXXXXXX
HKCU\SOFTWARE\Microsoft\IdentityCRL\Immersive\production\Token\{...}
DeviceId = 0018XXXXXXXXXXXX
与 CDP 注册进 DDS 的那个值逐字节相同。你的用户账号 PUID 是另一个数字,存在别处,写作 puid = 0003...(例如 00034002XXXXXXXX)。此外还有一个以 PUID 命名的 HKLM 缓存键(HKLM\SOFTWARE\Microsoft\IdentityCRL\NegativeCache\<PUID>_<userSID>),但那个只有 SYSTEM 能读,所以你要读值,得从 HKCU 里读。
前缀告诉你它是什么。 用户 PUID 是
0003类,设备 PUID 是0018类。法庭那个 GDID(0018000FC8CB93CC)在0018设备 PUID 空间里,和我机器上的一样。
6.3 它认证图谱端点
[OBSERVED] MSA 的令牌缓存(HKLM\SOFTWARE\Microsoft\IdentityCRL\NegativeCache\...)里有设备令牌,作用域精确指向 CDP 用到的端点:
scope=service::dds.microsoft.com::MBI_SSL_TOKEN_BROKER
scope=service::activity.windows.com::MBI_SSL_SA_TOKEN_BROKER
也就是说,微软账号服务签发的设备凭据,正是用来认证 DDS 注册、以及承载 GDID 的活动数据上传的。
6.4 完整链路
┌─ MSA 身份层:wlidsvc.dll ──────────────────────────────────────┐
│ ① 向 login.live.com 配置设备(Passport PPCRL SOAP) │
│ ② 服务器分配 Device PUID <ps:DevicePUID> / HWPUIDFlipped │
│ ③ 存储 DeviceId / LID = PUID HKLM\...\IdentityStore │
│ ④ 为 dds.microsoft.com、activity.windows.com 签发设备令牌 │
└──────────────────────────┬──────────────────────────────────────┘
│ 设备令牌 + PUID 字符串
▼
┌─ 设备图谱客户端:cdp.dll / CDPSvc ─────────────────────────────┐
│ ⑤ GetStableDeviceId -> 收到 PUID 字符串 │
│ ⑥ RegisterUserDeviceAsync -> DDS [实测:HTTP 200] │
└──────────────────────────┬──────────────────────────────────────┘
│
▼
┌─ 服务器:Device Directory Service ─────────────────────────────┐
│ ⑦ 把 g:PUID 与 MSA 账号、活动历史、IP 历史绑定 │
└──────────────────────────┬──────────────────────────────────────┘
│
▼
┌─ 上报:Delivery Optimization ──────────────────────────────────┐
│ ⑧ UCDOStatus.GlobalDeviceId │
└────────────────────────────────────────────────────────────────┘
起诉书里所有扣在”GDID”头上的性质——每次安装持久、跨更新存活、重装换新、绑定到微软账号、可跨 IP 与浏览记录追踪——全都从”它是一个服务器分配的 MSA 设备 PUID,CDP 把它注册进了设备图谱“这一点自然推导出来。
7. 查你自己机器的 GDID
[OBSERVED] 在一台登录了微软账号的机器上,从你自己的用户 hive 里读一次注册表就够了,不需要管理员权限:
(Get-ItemProperty'HKCU:\SOFTWARE\Microsoft\IdentityCRL\ExtendedProperties').LID
它会给你 16 位十六进制的设备 PUID(例如 0018XXXXXXXXXXXX)。想看它在服务器端那样的 g:<十进制> 形式:
$hex = (Get-ItemProperty'HKCU:\SOFTWARE\Microsoft\IdentityCRL\ExtendedProperties').LID
"g:$([Convert]::ToUInt64($hex,16))"
如果你的机器上 ExtendedProperties\LID 是空的,同一个值就在 HKCU\SOFTWARE\Microsoft\IdentityCRL\Immersive\production\Token\{...}\DeviceId 下面。
不要公开你自己的值。 你的设备 PUID、你的 MSA CID(
0003...)、你的用户 SID,这三样东西都能把你去匿名化。在任何公开文章里都要脱敏。唯一可以安全引用的,是法庭卷宗里那个值,因为它已经公开了。
8. 减少暴露面
GDID 之所以存在,是因为你的设备被注册进了微软账号的设备图谱,而 Connected Devices Platform 一直在同步它。要削减它,可以这么做:
- 关掉 Connected Devices Platform(
CDPSvc、CDPUserSvc),并关闭活动历史(设置 → 隐私和安全性 → 活动历史),来停止图谱同步和活动数据上传。 - 删除
%LOCALAPPDATA%\ConnectedDevicesPlatform只会清掉 CDP 的本地状态。PUID 会从身份存储里原样回来,所以光删这个不够。 - 重装会给你一个新 GDID(起诉书原话),但它一注册就又会被绑到一个新的上去。
诚实地讲:只要你还想用 Windows 的跨设备特性,这条指纹就很难彻底消除。这里的取舍是”跨设备便利”对”设备可追踪性”——大多数用户其实在不知情的情况下,选了前者。
9. 方法论(可复现)
以上所有结论都来自一台原版 Windows 11(build 26200)机器。
- 实时抓包:用
logman启用 CDP 的 TraceLogging ETW provider(Microsoft.Windows.CDP.*),在强制一次全新CDPSvc注册的同时抓取,用tracerpt解码。 - 注册表与令牌缓存:
HKLM\SOFTWARE\Microsoft下的IdentityStore和IdentityCRL。
ETW + 静态分析才是真正有效的手段。挂个代理去抓包只会浪费你的时间——这些流量是 TLS 加密的,而且关键信息在本地身份存储里就能直接读到,根本不必去抓网络包。
附录 A:CDP ETW provider GUID
用 EventSource 名称哈希(命名空间 + UTF-16BE 大写的 provider 名称做 SHA1)计算得到。可以用已知的 System.Runtime 值 49592c0f-5a05-516d-aa4b-a64e02026c89 来校验这个算法:
Microsoft.Windows.CDP.Core {7762de0c-b0a6-571a-68d3-c018bf009496}
Microsoft.Windows.CDP.Core.Error {a1ea5efc-402e-5285-3898-22a5acce1b76}
Microsoft.Windows.CDP.CDS {dfa6e32a-095f-5f57-d025-0887d33507a1}
Microsoft.Windows.CDP.Aggr {bc1826c8-369c-5b0b-4cd1-3c6ae5bfe2e7}
Microsoft.Windows.CDP.AFS {5fe36556-c4cd-509a-8c3e-2a547ea568ae}
Microsoft.Windows.CDP.OnecoreAccountProvider {4ee5bf9a-3e8f-540b-8bfb-12457a2854b6}
Microsoft.Windows.CDP {9f4cc6dc-1bab-5772-0c71-a89954718d66}
附录 B:关键二进制与符号
| 二进制 | 角色 | 关键符号 |
| — | — | — |
| wlidsvc.dll | 微软账号 / Passport 服务,铸造设备 PUID | CDeviceIdentityBase::CreateNewDeviceIdentity 、CAssociateDeviceRequest::ParseResponseBody、DeviceIdStore::LogToRegistry |
| cdp.dll | Connected Devices Platform,把 PUID 注册进 DDS | DdsRegistrationClient 、GetStableDeviceIdFromProvider(0x0A3140)、OnGetStableDeviceIdCompleted(0x06CEA0) |
| dosvc.dll / DO | 把 ID 作为 UCDOStatus.GlobalDeviceId上报 | 无 |
相关注册表:HKLM\SOFTWARE\Microsoft\IdentityStore(DeviceId 与 LID)、HKLM\SOFTWARE\Microsoft\IdentityCRL\NegativeCache(令牌作用域)。
10. 局限与诚实的声明
这篇分析有几处需要诚实地标注:
- 未登录账号的路径:最初的发帖遗漏了一个事实——即使不登录微软账号,你依然会有 GDID。CDP 有一条匿名设备路径,在没有 MSA 时启用。作者发帖后补充了这一点。底层系统在事实上是正确的,只是最初少覆盖了这条路径。
- 第三方反馈:推特用户 NullZeroX 告诉作者,GDID 在不登录微软账号的设备上同样会被发送。作者表示尚未完全验证,但值得记下。
- AI 辅助:作者在文末致谢了 Claude 协助撰写和绘制图表——这意味着部分图表与文字表述经过 AI 协助打磨,但所有逆向结论(符号、地址、ETW 抓包)都是可复现的工程产物,不依赖 AI 的”记忆”。
解读一句话:GDID 不是什么科幻级的硬件级后门,而是一个工程上相当朴素的设计——微软账号服务器在设备首次配置时下发一个 64 位 ID,存在你注册表里明文,再由跨设备平台同步到云端图谱。它之所以”永久”,是因为它绑的是”一次安装”而不是”一台机器”;它之所以”可追踪”,是因为它和你的 IP、浏览、活动历史绑在了同一个图谱里。卷宗里的那串 g:6755467234350028,就是这么一个再普通不过的服务器分配号——只是这一次,它把一个人送上了起诉书。
参考链接
- 原文仓库:SmtimesIWndr/gdid-reversal
- 起诉书出处:United States v. Peter Stokes, N.D. Ill., 2026-07(DOJ 2026 年 7 月 1 日解封的 Scattered Spider 刑事起诉书)
- Delivery Optimization /
UCDOStatus.GlobalDeviceId:微软 Azure Monitor 文档
本文是对外文安全研究的中文译介与解读,遵循原作者的置信度标注体系。所有技术细节均出于安全研究与取证理解目的。
标签:#GDID``#Windows安全``#数字取证``#设备指纹``#隐私``#逆向工程``#微软账号``#ScatteredSpider
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:赛博生存指南 SmtimesIWndr SmtimesIWndr《好文 | 藏在 Windows 里的永久指纹 GDID —— FBI 靠它锁定了 Scattered Spider》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论