
Analisi di reverse engineering dell'identificatore globale di dispositivo (GDID) di Microsoft che rivela la sua generazione come MSA Device PUID assegnato dal server, l'archiviazione nel registro e la trasmissione tramite Connected Devices Platform, con una metodologia forense riproducibile.
Come il "Global Device Identifier" di Microsoft, l'impronta persistente di Windows menzionata nella denuncia di Scattered Spider del luglio 2026, viene effettivamente generato, archiviato e trasmesso.
[!NOTE] Quanto elencato di seguito è vero, ma mancano alcune informazioni. Indipendentemente dall'accesso con un MSA, avrai comunque un GDID. Non me ne ero reso conto al momento del post, ma l'ho verificato. CDP ha un percorso dispositivo anonimo che viene utilizzato se non è connesso alcun MSA. Il sistema sottostante è ancora sostanzialmente corretto, mancano solo alcuni dettagli.
Global Device Identifier g:6755467234350028.g:<decimale>.wlidsvc (servizio account Microsoft) fornisce il dispositivo a login.live.com e riceve un device PUID -> lo archivia nel registro -> Connected Devices Platform (cdp.dll / CDPSvc) lo legge e lo registra nel grafo del Device Directory Service (DDS) -> Delivery Optimization lo riporta come il documentato UCDOStatus.GlobalDeviceId.[!NOTE] Etichettatura di affidabilità. Ogni affermazione è contrassegnata in modo che tu possa valutarle autonomamente:
[COURT]fatto da fonte primaria,[OBSERVED]riprodotto live sulla mia macchina di test,[STATIC]provato da binari e PDB pubblici di Windows,[ASSESSED]inferenza forte dalle prove.
wlidsvc)Il 1° luglio 2026 il Dipartimento di Giustizia ha reso pubblica una denuncia penale contro Peter Stokes, un presunto membro di Scattered Spider (noto anche come Octo Tempest / UNC3944 / 0ktapus). L'affidavit descrive come Microsoft ha aiutato l'FBI ad attribuire attività a un dispositivo.
[!IMPORTANT]
[COURT]Dalla denuncia suppletiva (¶25, p.34), testualmente:"l'account ngrok è stato configurato tramite Global Device Identifier g:6755467234350028 ('il GDID'). Secondo un rappresentante Microsoft, un Global Device Identifier nell'ecosistema Windows è un identificatore persistente a livello di dispositivo progettato per identificare in modo univoco un'installazione di un sistema operativo Windows su un dispositivo... Un GDID è un identificatore globalmente univoco legato all'installazione di Windows su un dispositivo. Un GDID rimane coerente attraverso gli aggiornamenti del sistema operativo Windows su un dispositivo, ma una reinstallazione di Windows... sarà legata a un nuovo GDID univoco. "
Una nota a piè di pagina aggiunge che un singolo utente Microsoft può avere più GDID. L'affidavit correla quindi la cronologia IP e la navigazione del GDID (es. empirehotelnyc.com, un URL di accesso a Growtopia/Ubisoft) con gli account in cui il sospetto era connesso.
Due cose qui sostengono il resto di questa analisi:
g: più un intero decimale (g:6755467234350028). In esadecimale è 0x0018000FC8CB93CC, quindi un numero a 64 bit.Il riassunto sui social media sosteneva che il GDID fosse "un identificatore a 128 bit generato da numeri di serie durante l'installazione." Entrambe le metà sono false:
| Affermazione (social media) | Realtà (fonte primaria) |
|---|---|
| "128 bit" | Il valore nella denuncia è g:6755467234350028, un decimale che rientra in 64 bit (0x0018000FC8CB93CC). |
| "generato da numeri di serie durante l'installazione" |
[!NOTE] Dopo aver fatto ulteriore reverse engineering di CDP, ho fornito alcune informazioni errate. L'uso di un account locale non impedisce un GDID. CDP ha un percorso dispositivo anonimo che viene seguito se non c'è un account Microsoft. Tienilo a mente durante la lettura.
[STATIC] La documentazione pubblica di Azure Monitor di Microsoft definisce una colonna GlobalDeviceId nella tabella UCDOStatus (Update Compliance / Delivery Optimization):
GlobalDeviceId(string): "Identificatore globale del dispositivo Microsoft. Questo è un identificatore utilizzato internamente da Microsoft."
Si trova accanto a LastCensusSeenTime, ISP, City, Country, quindi un ID dispositivo allineato a dati geografici e IP. Questo è l'unico posto in cui Microsoft nomina il valore nei documenti pubblici. Ma Delivery Optimization si limita a riportarlo. È importante notare che non lo possiede. Seguendo a monte si arriva alla Connected Devices Platform.
[STATIC] C:\Windows\System32\cdp.dll (la Connected Devices Platform, servizi CDPSvc + CDPUserSvc) contiene il simbolo GlobalDeviceId e un intero sottosistema di registrazione del 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
formato stringa ID dispositivo: "g:%s"
DDS = Device Directory Service, il grafo di identità cross-dispositivo di Microsoft (il backend dietro Phone Link, appunti sul cloud, "Continua sul PC", Condivisione nelle vicinanze). CDP è il client Windows che registra l'installazione in quel grafo, dove viene associata come g:<decimale>.
[OBSERVED] Forzando una nuova registrazione (riavvio di CDPSvc con lo stato locale cancellato) e catturando i provider ETW di CDP, è stata ottenuta l'intera handshake:
DdsClient::RegisterUserDeviceAsync() RegistrationReason: Startup Account Type: MSA
DDSClient: Registration response received. HTTP status code: 200
OnRegisterUserDeviceComplete
GetDeviceIdAndTicketActivity -> deviceid: 0018XXXXXXXXXXXX
Quel deviceid, scritto come g:<decimale>, corrisponde strutturalmente al valore della denuncia:
Entrambi sono valori a 64 bit nella stessa classe di parola alta 0x0018 (il namespace device PUID, vedi §6). Il prefisso g: è semplicemente quell'intero in decimale.
[STATIC] Con il PDB pubblico (cdp.pdb), il percorso dell'ID dispositivo in cdp.dll è solo una richiesta e attesa contro lo stack di identità. CDP non calcola mai l'ID stesso:
flowchart TD
A["GetStableDeviceIdFromProvider<br/>0x0A3140"] --> B["provider.GetStableDeviceIdAsync<br/>(vtable +0x48)"]
B --> C["OneCoreAccountProvider::<br/>GetStableDeviceIdAsync 0x0C8370"]
C --> D["IWebAccountBackedAccountProvider<br/>(MSA / AAD identity COM)"]
D --> E["OnGetStableDeviceIdCompleted<br/>(const char* deviceId) 0x06CEA0"]
E -->|"assign() string, signal flag"| ALa callback che lo riceve lo rende ovvio. L'ID arriva come stringa e viene semplicemente archiviato:
; OnGetStableDeviceIdCompleted
mov rbp, r9 ; r9 = device-id STRING handed in by the identity provider
lea rcx, [rsi+0xD8] ; CDP member field
mov rdx, rbp
call assign@basic_string ; store it, no computation, no serials
call Set@CdpWaitableFlag ; unblock the waiter
Conclusione: il GDID viene coniato al di sotto di CDP, nello stack di identità di Windows, e passato a CDP come stringa opaca. Questo punta al servizio Microsoft Account.
wlidsvc)[STATIC] C:\Windows\System32\wlidsvc.dll, il servizio Microsoft Account / Passport (Windows Live ID), è l'unico binario di identità che contiene il letterale GlobalDeviceId e possiede l'intero meccanismo di provisioning del dispositivo:
CDeviceIdentityBase::CreateNewDeviceIdentity / Provision / BindDeviceToHardware / GetDeviceCert
DeviceAssociateRequest (Passport PPCRL SOAP -> login.live.com)
<ps:DevicePUID> ... </ps:DevicePUID>
DeviceIdStore::LogToRegistry
BCryptGenRandom / CCryptRandom::GenRandom (chiave del dispositivo, NON l'ID)
L'identificatore è un Device PUID (Passport Unique ID), un ID MSA a 64 bit. Il BCryptGenRandom presente serve per generare la chiave di autenticazione del dispositivo che BindDeviceToHardware vincola alla macchina, non il PUID.
[STATIC] Il client estrae il PUID dalla risposta SOAP del server, con un XPath nel corpo della risposta:
/S:Envelope/S:Body/ps:DeviceUpdatePropertiesResponse/HWPUIDFlipped
CAssociateDeviceRequest::ParseResponseBody e i relativi metodi ParseResponse leggono i nodi XML della risposta in BSTR. Quindi il flusso è: client fornisce il dispositivo -> login.live.com assegna e restituisce il device PUID -> client lo archivia. Questo è esattamente il motivo per cui una reinstallazione produce un nuovo GDID (nuovo provisioning, nuovo PUID assegnato dal server), e perché non è un hash hardware.
[OBSERVED] L'archivio di identità dell'account Microsoft conserva il valore direttamente nel registro, nel tuo hive utente:
HKCU\SOFTWARE\Microsoft\IdentityCRL\ExtendedProperties
LID = 0018XXXXXXXXXXXX
HKCU\SOFTWARE\Microsoft\IdentityCRL\Immersive\production\Token\{...}
DeviceId = 0018XXXXXXXXXXXX
Stesso valore byte per byte che CDP ha registrato in DDS live. Il PUID del tuo account utente è un numero diverso archiviato altrove come puid = 0003... (es. 00034002XXXXXXXX). Esiste anche una chiave della cache HKLM denominata con il PUID (HKLM\SOFTWARE\Microsoft\IdentityCRL\NegativeCache\<PUID>_<userSID>), ma quella è solo SYSTEM, quindi leggi il valore da HKCU.
[!NOTE] Il prefisso ti dice cos'è. I PUID utente sono di classe
0003, i PUID dispositivo sono di classe0018. Il GDID del tribunale (0018000FC8CB93CC) è nello spazio PUID dispositivo0018, come il mio.
[OBSERVED] La cache dei token MSA (HKLM\SOFTWARE\Microsoft\IdentityCRL\NegativeCache\...) contiene token dispositivo con ambito esattamente gli endpoint utilizzati da CDP:
scope=service::dds.microsoft.com::MBI_SSL_TOKEN_BROKER
scope=service::activity.windows.com::MBI_SSL_SA_TOKEN_BROKER
Quindi il servizio Microsoft Account distribuisce le credenziali del dispositivo che autenticano la registrazione DDS e i caricamenti delle attività che trasportano il GDID.
flowchart TD
subgraph MSA["MSA identity layer: wlidsvc.dll"]
A1["Provision device with login.live.com<br/>(Passport PPCRL SOAP)"] --> A2["Server assigns Device PUID<br/><ps:DevicePUID> / HWPUIDFlipped"]
A2 --> A3["Store DeviceId / LID = PUID<br/>HKLM\...\IdentityStore"]
A3 --> A4["Issue device tokens for<br/>dds.microsoft.com and activity.windows.com"]
end
subgraph CDP["Device graph client: cdp.dll / CDPSvc"]
B1["GetStableDeviceId -> receives PUID string"] --> B2["RegisterUserDeviceAsync -> DDS<br/>OBSERVED: HTTP 200"]
end
subgraph SRV["Server: Device Directory Service"]
C1["Keys g:PUID to the MSA account,<br/>activity and IP history"]
end
subgraph REP["Reporting"]
D1["Delivery Optimization -><br/>UCDOStatus.GlobalDeviceId"]
end
A4 --> B1
B2 --> C1
C1 --> D1Tutto ciò che la denuncia attribuisce a "il GDID" – persistente per installazione, sopravvive agli aggiornamenti, nuovo in caso di reinstallazione, legato a un account Microsoft, tracciabile attraverso IP e navigazione – deriva dal fatto che si tratta di un MSA Device PUID assegnato dal server che CDP registra nel grafo del dispositivo.
[OBSERVED] Su una macchina connessa a un account Microsoft, una lettura del registro dal tuo hive utente, senza necessità di amministratore:
(Get-ItemProperty 'HKCU:\SOFTWARE\Microsoft\IdentityCRL\ExtendedProperties').LID
Questo ti dà il tuo device PUID come 16 cifre esadecimali (es. 0018XXXXXXXXXXXX). Per vederlo nella forma g:<decimale> come appare lato server:
$hex = (Get-ItemProperty 'HKCU:\SOFTWARE\Microsoft\IdentityCRL\ExtendedProperties').LID
"g:$([Convert]::ToUInt64($hex,16))"
Se ExtendedProperties\LID è vuoto sulla tua macchina, lo stesso valore si trova sotto HKCU\SOFTWARE\Microsoft\IdentityCRL\Immersive\production\Token\{...}\DeviceId.
[!WARNING] Non pubblicare il tuo valore. Il tuo device PUID, il tuo MSA CID (
0003...) e il tuo SID utente ti deanonimizzano. Oscurali in qualsiasi analisi pubblica. L'unico valore sicuro da citare è quello del tribunale, perché è già pubblico.
Il GDID esiste perché il tuo dispositivo è registrato nel grafo dei dispositivi dell'account Microsoft e la Connected Devices Platform lo mantiene sincronizzato. Per limitarlo:
CDPSvc, CDPUserSvc) e spegni la Cronologia attività (Impostazioni, Privacy, Cronologia attività) per interrompere la sincronizzazione del grafo e i caricamenti delle attività.%LOCALAPPDATA%\ConnectedDevicesPlatform cancella solo lo stato locale di CDP. Il PUID ritorna immediatamente dall'archivio di identità, quindi da solo non basta.Tutto è stato ottenuto da una macchina Windows 11 (build 26200) standard.
Microsoft.Windows.CDP.*) tramite logman forzando una nuova registrazione di CDPSvc, decodificati con tracerpt.IdentityStore e IdentityCRL sotto HKLM\SOFTWARE\Microsoft.ETW e l'analisi statica sono ciò che ha funzionato. Un proxy ti farà solo perdere tempo.
Calcolati con l'hash del nome EventSource (SHA1 del namespace più il nome del provider in UTF-16BE maiuscolo). Verifica con il valore noto di 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}
[!NOTE] NullZeroX su Twitter mi ha detto che GDID viene inviato anche se non si è connessi con un account Microsoft sul dispositivo. Non sono sicuro di quanto sia vero, ma vale la pena prenderne nota.
Analisi diretta. Correzioni benvenute. Grazie anche a claude per l'aiuto in questa analisi e nei diagrammi :3
| La denuncia dice che una reinstallazione produce un nuovo GDID. Un valore derivato da seriali fissi rimarrebbe uguale dopo una reinstallazione, non cambierebbe. |
| valore | hex (64 bit) | prefisso classe |
|---|
| La mia macchina (oscurato) | g:XXXXXXXXXXXXXXXX | 0x0018XXXXXXXXXXXX | 0018 |
| Documento giudiziario | g:6755467234350028 | 0x0018000FC8CB93CC | 0018 |
| Binario | Ruolo | Simboli notevoli |
|---|
wlidsvc.dll | Servizio Microsoft Account / Passport, conia il Device PUID | CDeviceIdentityBase::CreateNewDeviceIdentity, CAssociateDeviceRequest::ParseResponseBody, DeviceIdStore::LogToRegistry |
cdp.dll | Connected Devices Platform, registra il PUID in DDS | DdsRegistrationClient, GetStableDeviceIdFromProvider (0x0A3140), OnGetStableDeviceIdCompleted (0x06CEA0) |
dosvc.dll / DO | Riporta l'ID come UCDOStatus.GlobalDeviceId | n/a |
Registro: HKLM\SOFTWARE\Microsoft\IdentityStore (DeviceId e LID), HKLM\SOFTWARE\Microsoft\IdentityCRL\NegativeCache (ambiti dei token).