Leak prevention in Microsoft Windows

The information provided is based on reverse-engineered code and may contain some speculation on specific functionality.
winver in Windows 8 build 8422 (fbl_woa), displaying a EULA hash and a confidentiality warning

Since late 2000, Microsoft have employed a multitude of security measures in order to prevent pre-release Windows builds from being publicly disclosed onto the open Internet. Almost all anti-leak measures focus on fingerprinting entities or persons that may or may not intend to disclose the contents of an internal Windows build. Fingerprints can then be used to trace back to the originating leak source and pursue legal action wherever possible.

Windows XP through early post-reset Longhorn[edit | edit source]

The earliest implementation of fingerprinting was observed through the inclusion of UUIDREFs, seen in Microsoft-authored disc images for Windows XP, Windows Server 2003, pre-reset Longhorn and early post-reset Windows Vista. The company's internal disc image pre-mastering utility (CDIMAGE) includes an undocumented -xx parameter to allow the creation of disc images with a header CRC32 of FFFFFFFF; these images can be easily modified to include the identifiers in the unused header sectors, while keeping the header and overall CRC unchanged (only 1 kilobyte of contiguous data needs to be modified to include a different identifier). The UUIDREF value is merely an ASCII string bearing no actual meaning to end users and beta testers, but can be decoded by Microsoft to track the source of the disc image, e.g.: which machine downloaded the build, or who mastered the disc.

Below is a sample identifer:

;UUIDREF=562D5041534341575C4555524F50452057494E58502D504332
;

The identifier is the hexadecimal representation of an ASCII string, which can then be decoded into V-PASCAW\EUROPE WINXP-PC2. This reveals the username of the originating employee or automated build account (V-PASCAW), the source domain name (EUROPE) and the offending machine's name or IP address (in this case, WINXP-PC2). These identifiers are applied against disc images during the download process.

Information contained in identifiers were never directly used for tracking down leaks, unless the leak was sourced from a Microsoft employee; the identifiers were instead used to identify who and which machine mastered the leaked media and the respective group(s) of beta testers who received the discs, providing Microsoft a rough estimation of the leak's origin.

UUIDREF stamping was implemented inside the SMB server (SMB.SYS), and configured via the registry (REG_MULTI_SZ values in HKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters: CheckFile for testing purposes, a file whose content will be replaced by the UUIDREF value when reading over SMB (only the first REG_MULTI_SZ entry is used); CheckExtension for a file extension to add UUIDREF value into memory when reading over SMB (only the first REG_MULTI_SZ entry is used); CheckShares for a list of shares of which the functionality will be enabled when reading files from).

If a UUIDREF value is already present in an ISO image, it can get (partially) overwritten again if it was copied from a monitored share to another monitored share, and then again from the second monitored share: this can be observed with Windows Vista build 5219 (winmain_idx02.050830-2010).

The relevant code remains in SMB.SYS as late as Windows 10 2022 Update; although the code to read the configuration from the registry was removed at some point, from which time the functionality became inaccessible.

Effectiveness[edit | edit source]

Unique identifiers proved ineffective in leak sourcing as it does not fingerprint data stored on discs or within the official disc images. The mechanism would have only worked if the leaked image is an exact sector-for-sector disc dump of official media (such as those sourced from partner drops or burnlab discs), or if it had been sourced directly from Microsoft in the form of an ISO image. Build repacks were done primarily to save space or to add credits to their disc images. As a result, very few builds had ever leaked with an intact identifier.

Windows Vista/7[edit | edit source]

Not yet researched, or possibly lacks an appropriate leak prevention implementation.

Windows 8 through Windows 10 November Update[edit | edit source]

Throughout the development timeframes of Windows 8 and Windows 10 November Update, an updated version of the Windows Fingerprinting Service was implemented in a similar fashion to the unique identifier mechanism first included as part of Windows XP, designed in such a way that the fingerprint be present in every leaked Windows build irrespective of the amount of times the build is repacked.

Early implementations of leak prevention were initially present in the form of a simple wallpaper replacement and a warning in winver in client build 7777, and was later iterated upon through the introduction of a fingerprint blob and a dedicated confidentiality warning between builds 7788 (server) through 7875 (client), which are shown on the desktop watermark and are displayed by the shell32.dll dynamic link library. The fingerprint is directly appended at the end of the BuildLab string (queried from registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion) in the form of a build hash (officially named the "EULA hash"), computed by splitting the WFS blob into 8 arrays of 16 bytes and XORing each of the 16 bytes together. The EULA hash can then be derived in order to source build leaks to existing Microsoft affiliates; the visibility of the EULA hash and the confidentiality warnings depend on the presence of certain compiler flags.

Three different Windows 8 builds. Left to right: build 8330 (fbl_grfx_dev1) (left), build 8375 (center), and build 8400 (right).
Note how the EULA hash is unique to different builds (or variations of the same build, such as a different CPU architecture or partner release/download source[a]), and how the visibility of the confidentiality warning and the EULA hash depend on the presence of specific compiler flags.

Fingerprinting data is now stored in both the registry and in the form of a file, respectively under registry key HKLM\SYSTEM\WPA\478C035F-04BC-48C7-B324-2462D786DAD7-5P-9 and as file FP in the Windows\System32\config directory. The registry key and the file must both exist in the Windows install, or the operating system will either refuse to boot or non-deterministically bugcheck with codes KERNEL_SECURITY_CHECK_FAILURE (during boot) or CRITICAL_STRUCTURE_CORRUPTION (if the periodic WFS check during runtime fails). Furthermore, most parts of the fingerprint data are now encrypted, and therefore require reverse engineering efforts to decode and extract the relevant information. These leak prevention measures were removed very early into the development cycle of the Windows 10 Anniversary Update (after build 11073) due to the increased relevance of the Windows Insider Program, an initiative allowing volunteering beta testers (referred to as Insiders) access to freshly-compiled mainline Windows development builds.

Implementation details[edit | edit source]

Fingerprint data[edit | edit source]

The fingerprint data is essentially a 164-byte file named FP, stored inside the Windows\System32\config directory. It utilizes the following structure:

typedef struct _FPData
{
    WFSBlob WPACertificateHash; // Encrypted WFS blob
	BYTE Time[32]; // nt5.cat SHA-256 hash
	DWORD Type; // Unknown; possibly a timestamp
} FPData;

WPACertificateHash is the encrypted WFS blob containing the actual fingerprint data. Contrary to popular belief, it is not related to the Windows Product Activation functionalities and is named such merely as cover. Time relates to the SHA-256 hash of the nt5.cat security catalog, stored in Windows\System32\CatRoot\{F750E6C3-38EE-11D1-85E5-00C04FC295EE} (also named such to confuse reverse engineers). The Type value appears to be a timestamp of sorts, presumably for the aforementioned security catalog.

WFS blob[edit | edit source]

The Windows Fingerprinting Service blob (also referred to as the WFS blob) utilizes the following structure:

typedef struct _WFSBlob
{
    BYTE ValidationSequence[36]; // Magic 'number' (string)
    BYTE UserIdHash[32]; // (SHA-256?) hash of user ID
    BYTE Nt5Hash[32]; // SHA-256 hash of nt5.cat
    BYTE Nt5TimeStamp[12]; // Timestamp of nt5.cat (string)
    BYTE BlobCrc[16]; // Truncated SHA-256 hash of the blob
} WFSBlob;

The WFS blob must first be decrypted using the following public RSA key:

0000 52 53 41 31 00 04 00 00 03 00 00 00 80 00 00 00  RSA1........€...
0010 00 00 00 00 00 00 00 00 01 00 01 A9 E6 BB AA 49  ...........©æ»ªI 
0020 D4 A9 25 6B 22 48 69 85 8C C8 09 D8 DC 68 87 CB  Ô©%k"Hi…ŒÈ.ØÜh‡Ë 
0030 ED 1E E0 35 31 0B 27 F6 E0 1B 1D F6 54 D5 62 B2  í.à51.'öà..öTÕb² 
0040 84 F9 2C 95 2B CD 5B 8C 8C EC B2 05 6E C4 66 5B  „ù,•+Í[ŒŒì².nÄf[ 
0050 9B ED 56 14 07 03 91 39 57 F1 FD 64 DB EB 7E 92  ›íV...‘9WñýdÛë~’ 
0060 2D 0C AB AD CD FF D4 4B EC B9 84 6C B2 73 75 3D  -.«.ÍÿÔK칄l²su= 
0070 D3 47 7B F0 0C 24 D4 90 BB C2 71 AF A1 27 65 82  ÓG{ð.$Ô.»Âq¯¡'e‚ 
0080 D0 51 20 4A 70 0B A4 84 BA 6E 77 97 6E 2B 57 77  ÐQ Jp.¤„ºnw—n+Ww 
0090 70 E6 06 11 F7 A1 BD E2 D6 DB 7B                 pæ..÷¡½âÖÛ{

ValidationSequence must be equivalent to the string Windows Fingerprinting Service 2.0 and is used to verify if the decrypted blob is valid. Only the UserIdHash is unique across different fingerprint blobs of the same build, and is used to track down leak sources. Nt5Hash is the SHA-256 hash of the nt5.cat code signing catalog, and its associated timestamp is stored as Nt5TimeStamp in the form of a string in format YYYYMMDDhhmm (following the ISO 8601 international date/time standard). BlobCrc is a partial SHA-256 hash of the blob used for integrity validation.

The Nt5Hash and Nt5TimeStamp values are used to ensure that the blob is only valid for a specific build, therefore preventing other individuals from using blobs from previously leaked builds on top of a newly leaked one. The timestamp does not include the seconds field in order to completely ignore rounding caused by switching between file systems.

Upon every boot, the Windows kernel checks for the existence of the fingerprinting blob on the disk and bugchecks with code KERNEL_SECURITY_CHECK_FAILURE if not present, although it loads the one included within the Windows registry instead. Subsequent integrity checks against the fingerprinting blob present in the registry are made by the kernel at random times (once between 300 - 310 seconds) and will bugcheck with code CRITICAL_STRUCTURE_CORRUPTION if the data within the Windows registry is not valid.

Fingerprinting method[edit | edit source]

When a build is compiled, a generic WFS blob containing the appropriate fingerprinting data is generated, utilizing value A3CC5B12B2DABE8E47FF9EBA8DD7522269781D4A5F3C7F47B7D0096FDE6B9978 as its user ID hash. A generic Windows image file containing the aforementioned data is then produced; whenever the installation media is distributed, the generic fingerprint data is replaced with a variation specific to the intended individual or organization.

Windows Imaging Format[edit | edit source]

Windows image files created during these development periods are non-standard; they generally include four kilobytes of buffer after each metadata resource, and the chunk(s) of each metadata resource containing the entry for Windows\System32\config\FP are left uncompressed; this was done to allow the fingerprint data to be easily and efficiently replaced when one attempts to download the existing installation media. As chunks with metadata for Windows\System32\config\FP are uncompressed, no decompression/recompression are required to read or modify the included SHA-1 hash. The four-kilobyte buffers were included to ensure that the recompressed metadata resources will fit, in the event that the relevant chunks are somehow compressed, and therefore must be recompressed after modification.

Effectiveness[edit | edit source]

This form of fingerprinting is very effective as it is theoretically impossible to remove while keeping the OS functional. The fingerprint data could be completely removed, but doing so would result in an unbootable operating system image or periodic bugchecks due to inconsistent data. The fingerprint data can also not be modified as it is encrypted by a private RSA key.

A number of builds can be practically unfingerprinted due to the presence of generic fingerprint data in the SYSTEM registry hive and/or the Windows Recovery Environment WIM image. Some builds are also built with the Windows Fingerprinting Service disabled through compiler flags, and will not bugcheck if fingerprint data is invalid or is otherwise absent.

Early Windows 11 development builds[edit | edit source]

Display[edit | edit source]

The watermark on the desktop and in the Windows Preinstallation Environment's wallpaper host application includes a notice that advises Microsoft employees not to take screenshots of the build. Since build 21376, a hexadecimal build hash is additionally also present at the bottom-left corner of the screen.

Every string in the watermark and within the File Explorer application has whitespace, colon and dash characters predictably replaced by their Unicode full-width counterparts based on the value of WNF_SHEL_INTERNAL_EXPERIMENT and a constant number of bits used in a rotate-left instruction, which is always constant for each line; rotation values 0-4 are used and increments for each string. The same effect is also applied against the taskbar clock and the legal copyright/trademark protections string in winver (rotation value 0 is used here), and was additionally attempted against the OS version string in the about box (containing the build number). The pointer to the first string is passed in again in build 21380 (and possibly earlier internal builds) due to human error (which would either be NULL, leading to a null dereference crash, or a freed buffer). The visibility of the current calendar day and the size of the Show Desktop button are adjusted depending on the value of the above-mentioned variable.

The LogonController.dll dynamic link library initially sets variable WNF_SHEL_INTERNAL_EXPERIMENT from DWORD value Attributes located in HKEY_LOCAL_MACHINE\Software\Classes\CLSID\{2C57C51B-FD43-4E74-B077-551AE6228AD6}, and then saved to the registry again as binary value 0D83063EA3B87C75 in HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Notifications\Data (the last 4 bytes are the DWORD value); some of the bits are responsible for controlling other functionality as well.

Enablement and implementation details[edit | edit source]

The functionality is controlled by Velocity staging key 31496852, enabled by default in Firesteel builds 21376 onwards and internally referred to as XPTest. The leak warning string is hardcoded into the dynamic link library shell32.dll; this would remain untranslated in every other language.

The text is concatenated to a buffer where the test code signing watermark is written to; if test code signing is enabled in the current boot entry, two additional period and whitespace characters are concatenated to the buffer first, such that the watermark would read Test Mode. Do not take screen shots of this build.; this is additionally shown in the publicly available footage of build 21990.

Leak prevention methods in action, demonstrated on build 21380.
Note how the watermark, the hash (and its position), the size of the Show Desktop button, the date/time format and the winver legal notices are dynamically changed as DWORD value 0D83063EA3B87C75 is modified through the Registry Editor and after the system has been rebooted.

The hash ID is implemented in a different manner to older major versions of Windows:

  • The current user's SID is obtained, and its sub-authorities are XORed together.
  • The DWORD from WNF state value WNF_SHEL_INTERNAL_EXPERIMENT is obtained, and XORed by constant value 0x5475A568;
  • Let the previous two values be x and y; the hash is initialized to zero then obtained from 32 rounds of hash += hash + _addcarry_u32(0, x, x, &x); hash += hash + _addcarry_u32(0, y, y, &y).

The height of the hash also depends on the current value of the WNF_SHEL_INTERNAL_EXPERIMENT variable. When it is painted onto the desktop, the Y-position is derived from bits 11-12 of WNF_SHEL_INTERNAL_EXPERIMENT: y = bottom_of_watermark - height_of_single_watermark_line * ((WNF_SHEL_INTERNAL_EXPERIMENT >> 11) & 0b11);.

Due to the additional code mentioned above, a screenshot with hash-ID leaks the WNF_SHEL_INTERNAL_EXPERIMENT value, which could be used to derive the current user's SID from the hash (which would reveal the domain user inside Microsoft's corporate network).

Effectiveness[edit | edit source]

The fingerprinting method has been observed to result in unintended breakage within existing system functionality, as the original installation media for build 21380 is known to have been produced with bad metadata; the primary installation image was captured while undergoing a servicing operation that regenerates the WNF_SHEL_INTERNAL_EXPERIMENT seed, resulting in invalid access control lists and bad reparsing data persisting across thousands of files within the images and additionally causing underlying system services and built-in applications (and by extension part of the Windows shell) to misbehave.

Notes[edit | edit source]

  1. As observed in Windows 8 build 8520; despite most language variations for its ARMv7 compile including an identical fingerprint, the one included as part of the Simplified Chinese language variation features a completely different fingerprint; likely the result of another Connect download or alternative partner release handed down to another individual or organization.