Oh, brilliant.

So Windows 10 now has the ability for any application to get system-unique tracking identifiers that persist across reinstalls by storing them in the TPM or UEFI firmware variables...

Look at these APIs:

To add insult to injury, the APIs lead into clipc!GetOfflineDeviceUniqueID, which calls into a licensing-related service which would be obfuscated by Warbird...

So apparently the "intended audience" for these "system-unique tracking identifiers that persist across reinstalls" APIs is mobile device management.

If so, then why add it to OneCore and include a seperate codepath for Xbox One?! (Also, just allowing the "real" API to be called by anyone...)

It turns out that clipsvc.dll is NOT obfuscated by Warbird, and public symbols are on MS's symbols server?!

The "offlinedeviceuniqueID" is SHA256(salt.identifier) where "identifier" is one of the following:
* TPM public endorsement key.
* OfflineUniqueIDEKPub UEFI variable, from namespace eaec226f-c9a3-477a-a826-ddc716cdc0e3
* OfflineUniqueIDRandomSeed UEFI variable (from the same namespace)
* in RS2+: Registry entry HKLM\System\CurrentControlSet\Services\TPM\ODUID\RandomSeed

If the calling process is IL=Low or in an AppContainer (not sure which), you cannot pass a zero-length salt; but this is checked by the usermode clipc.dll and not the remote service clipsvc.dll (which runs as SYSTEM). So to work around this I guess the best way would be to call into clipsvc yourself.

As for those four identifiers, the worst one would be the TPM public endorsement key, that can't ever be changed...

@slipstream Say it with me now...

Information Feudalism.

You are a meat serf in a digital cropshare.

@slipstream @architect

"The identifier returned by this method is specific to a user on the current device and allows for correlation of usage across different applications running on the same device for a particular user."

Eww! 😬

To others who follow me and who think my hatred of UEFI is unjustified, . . .

To reiterate, I personally refuse to run UEFI on my Kestrel computers, and I refuse to trust ANY computer with UEFI baked into firmware, now and forever more.

Any computer equipped with UEFI is to be considered no more than a mere appliance, a convenient means to an end at best. This includes all Linux and BSD machines as well. They are not to be trusted otherwise.


@vertigo @slipstream Shame that for x86 there's few options other than legacy BIOS or UEFI.

@samis @slipstream Legacy BIOS is, IMHO, a vast improvement over UEFI. Just boot the kernel of your desired operating system, and let it take over the details of your machine.

UEFI tries to not only serve as a glorified boot loader, but indeed, also a small OS unto itself, and then there's the whole TPM racket. And, IIRC, UEFI also has components that run in negative rings, which means even with OSes that take over the hardware, it's always running.

@slipstream @samis Both ARM and x86 are lost causes as far as I'm concerned (certainly AArch64, if not 32-bit ISAs as well). This is in large part why I chose RISC-V for the Kestrel project, as it's one of the few open standards that gives me complete and total autonomy in building the hardware and system software for it. With the whole stack being MPLv2, I hope it'll attract folks who are trust-conscious with their platforms.

@vertigo @slipstream The problems with BIOS is that at this point it's a pile of backwards compatible hacks, and while UEFI is too complex for it's own good (I agree that it's basically an OS itself), it has the advantage of being able to make a clean break.

My ideal world is one where both are dead, replaced by a different architecture more inspired by coreboot and OpenFirmware.

@samis @slipstream Yes, coreboot is a great option. I even spoke with Ron Minnich about porting CoreBoot to the Kestrel, but I was surprised when he asked, "Why?" It seems because my own firmware is fully open-source, he saw no reason to port it (at least, to embed it in ROM).

Here's a quick proof-of-concept of clipc!GetOfflineDeviceUniqueID.

uses a zero-length salt,
>getduid salt
uses salt "salt"
>getduid 0x1234
uses salt "\x12\x34".

@slipstream isn't there a way to deny any calls that require userSystemId capability?

@slipstream yep. Isn't there a way to check privileges on that call as well? I don't use Windows that much, but shouldn't all this require some kind of privileges in the system? Or is it available to literally any process?

@newt It's available to literally any process. In theory, you need a capability if you want a non-package-unique identifier and you're calling from an AppContainer, but you can (probably) bypass that by calling GetOfflineDeviceUniqueID directly...

@slipstream well, that's something. On a related note, any resource to read about how Windows handles privilege separation? I really have no clue.

@slipstream it sounds like a fine identifier for locking drm licenses to the machine

@MightyPork it also sounds like a fine identifier for things like "network investigative techniques" to use

also, i should go try calling it in a low-integrity Chrome/Edge process. if that works then one can theorise that adtech scum might use browser code exec sploits just to get their hands on such identifiers...

@Wolf480pl probably, but the question here is: what happens if you make a request to the TPM to get its EK pubkey with it "disabled"?

@slipstream something like pagefault? dunno...
anyway, couldn't you just patch the dll to return whatever you want?

Sign in to participate in the conversation

Server run by the main developers of the project 🐘 It is not focused on any particular niche interest - everyone is welcome as long as you follow our code of conduct!