Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2026-83991-writeup-and-poc — Proof-of-concept demonstrating a Windows Cloud Files access-check bypass (CVE-2026-83991) that converts a read-only file into a cloud placeholder via supersede semantics, with detailed technical analysis and reproduction steps. | Kitploit
Tools/GitHubGitHub/karollooool/cve-2026-83991-writeup-and-poc
Privilege EscalationVulnerability AnalysisExploitationBinary Exploitation
GitHubkarollooool/cve-2026-83991-writeup-and-poc

CVE-2026-83991-writeup-and-poc

Proof-of-concept demonstrating a Windows Cloud Files access-check bypass (CVE-2026-83991) that converts a read-only file into a cloud placeholder via supersede semantics, with detailed technical analysis and reproduction steps.

View Repository

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share
Website
11 day agoNot yet reviewed

The File Said No. Cloud Files Said Supersede.

CVE-2026-83991 is a Windows Cloud Files tampering vulnerability whose published affected range begins with Windows 10 version 1809, almost eight years before the September 2026 fix.

I asked Windows to open a file for writing. It answered ERROR_ACCESS_DENIED.

I asked Windows to delete the same file. Again, ERROR_ACCESS_DENIED.

Then I asked the Cloud Files stack to supersede that filename. It returned S_OK and changed the existing file into a Cloud Files placeholder.

The file had said no twice. The supersede path heard something closer to “please continue.”

That authorization split is CVE-2026-83991. Microsoft calls it the Windows Cloud Files Mini Filter Driver Tampering Vulnerability, rates it Important, and assigned a CVSS 3.1 base score of 5.5 Medium. The official vector is CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:N/E:U/RL:O/RC:C.

The short version

The proof of concept creates a fresh directory and an ordinary file. It gives the caller write access to the directory, then applies a protected DACL to the file that grants the caller read access without ordinary write or delete access.

Using one restricted medium-integrity thread token, it proves the following sequence:

The call processed one entry, returned a nonzero creation USN, and gave the file the IO_REPARSE_TAG_CLOUD tag, value 0x9000001A. In the reproduced run, the file ID was identical before and after the call. The same NTFS file persisted while its state changed into a cloud placeholder.

A small map of Cloud Files

Windows 10 version 1709 introduced the Cloud Files API. It gives desktop sync engines a supported way to register a directory tree, create placeholder entries, and hydrate their content when needed.

Three pieces matter here:

  • CldApi.dll exposes the user-mode Cloud Filter API.
  • cldflt.sys is the file-system minifilter at the center of the storage path.
  • A sync root is a registered directory tree managed by a sync provider.

Cloud placeholders use reparse points. A reparse point is a file-system mechanism with a tag and associated data. It is a broader concept than a symbolic link, and the two should not be treated as synonyms.

The relevant API is CfCreatePlaceholders. It creates one or more placeholder files or directories beneath a registered sync root. Microsoft’s documentation says the caller must have WRITE_DATA or WRITE_DAC access to the base directory.

The per-entry flag CF_PLACEHOLDER_CREATE_FLAG_SUPERSEDE, value 0x4, supplies overwrite semantics for an existing placeholder. The interesting detail in this CVE is that the vulnerable path also accepted an ordinary existing file and converted it into a placeholder.

Parent authority is not leaf authority

The experiment separates rights on the directory from rights on the existing file.

The parent directory grants the current user:

root@kitploit:~
FILE_GENERIC_READ
FILE_GENERIC_WRITE
FILE_GENERIC_EXECUTE
DELETE

For a directory, FILE_GENERIC_WRITE includes FILE_WRITE_DATA, also called FILE_ADD_FILE. That is enough for the documented base-directory requirement used by CfRegisterSyncRoot and CfCreatePlaceholders.

The parent ACE does not grant FILE_DELETE_CHILD. Its DELETE bit applies to the parent object itself. This distinction matters because DeleteFileW requires either DELETE on the target file or FILE_DELETE_CHILD on its parent.

The existing leaf grants the current user only FILE_GENERIC_READ. Its DACL is marked protected with PROTECTED_DACL_SECURITY_INFORMATION, so it does not inherit the parent’s ACEs.

This creates the central question:

Does permission to create a new child in a directory also authorize a state-changing supersede operation against a more restrictive child that already exists?

Ordinary file access answers no. The vulnerable Cloud Files path answered yes.

Microsoft’s file security documentation explains why the distinction is expected. Access to a file is normally controlled by that file’s security descriptor. The parent’s descriptor does not generally replace the child’s access check, apart from specific rules such as inheritance and FILE_DELETE_CHILD.

The token stays put

Access-control demonstrations become unconvincing when the setup runs as one identity and the interesting operation runs as another. This PoC avoids that problem.

It derives a restricted token from the current process token, makes the Administrators SID absent or deny-only, sets medium integrity, duplicates an impersonation token at SecurityImpersonation, and installs it on the current thread with SetThreadToken.

The exact privilege wording deserves care. CreateRestrictedToken with DISABLE_MAX_PRIVILEGE disables every privilege except SeChangeNotifyPrivilege. That remaining privilege bypasses some directory traversal checks. It does not grant file data writes or deletion rights.

The PoC then performs the setup, control checks, sync-root registration, connection, and supersede call while that same thread impersonation token remains active. There is no convenient identity swap between “access denied” and S_OK.

Walking through the PoC

The full source is in main_poc.c, with build.bat for GCC or Microsoft’s C compiler.

1. Start with a fresh namespace

The program creates a new GUID-named test directory beneath the current user’s local application-data directory. An optional path can be supplied, but the program refuses to use one that already exists.

That restriction is deliberate. The PoC demonstrates the bug against data it creates for itself. It does not need an installed third-party sync provider and does not aim at an existing sync root.

2. Create an ordinary file

The program creates protected_existing.bin, writes known test data, and gives it ordinary file attributes. It records the file’s basic metadata, logical size, attributes, and file ID.

Before the Cloud Files call, the file is not a reparse point.

3. Apply and verify the DACL

The program replaces the leaf DACL with three non-inheriting allow ACEs:

PrincipalLeaf rights
SYSTEMFull control
AdministratorsFull control
Current userFILE_GENERIC_READ

Because the Administrators SID in the effective token is absent or deny-only, the Administrators allow ACE cannot grant administrator access to the thread.

The PoC then performs three controls. GENERIC_WRITE fails with error 5, DeleteFileW fails with error 5, and GENERIC_READ succeeds. It also confirms that the DACL is protected.

Those controls prove the permissions used by the two ordinary operations. The PoC does not test WRITE_DAC or every possible way the owner of its synthetic test file could affect that file. The demonstrated discrepancy is specifically between the denied write and delete operations and the successful Cloud Files supersede operation.

4. Become a minimal sync provider

The PoC registers its new directory with a progressive hydration policy and a full population policy. It supplies a fresh GUID as the provider and root identity.

It then calls CfConnectSyncRoot with a callback table containing only the terminating CF_CALLBACK_NONE entry. No hydration callback is needed for the metadata transition being tested.

5. Ask for supersede

The placeholder entry preserves the original file’s timestamps and logical size, supplies a GUID file identity, and sets the local constant that maps to the official supersede flag:

root@kitploit:~
#define CF_CREATE_SUPERSEDE 0x00000004UL

placeholder.RelativeFileName = leaf_name;
placeholder.FsMetadata.BasicInfo = basic_info;
placeholder.FsMetadata.FileSize = standard_info.EndOfFile;
placeholder.FileIdentity = &run_id;
placeholder.FileIdentityLength = sizeof(run_id);
placeholder.Flags = CF_CREATE_SUPERSEDE;

create_hr = cf.Create(root, &placeholder, 1, 0, &processed);

The source loads CldApi.dll dynamically and resolves the public functions at runtime. Its hand-declared structures cover only the ABI needed by this test.

6. Refuse to celebrate too early

A batch API can process an entry that failed. Microsoft’s documentation explicitly says EntriesProcessed includes failed entries, so a value of one does not establish success by itself.

The PoC therefore requires all of these conditions before it prints CONFIRMED and exits with code zero:

  • CfCreatePlaceholders returns exactly S_OK.
  • The individual entry result is exactly S_OK.
  • One entry was processed.
  • The creation USN is nonzero.
  • The resulting file exists and has FILE_ATTRIBUTE_REPARSE_POINT.
  • FSCTL_GET_REPARSE_POINT returns IO_REPARSE_TAG_CLOUD.

The direct write, delete, read, DACL, and preexisting-file checks must also pass earlier in the program, or execution stops before the Cloud Files operation.

What changed on disk

The reproduced state transition was:

0x00000020 is FILE_ATTRIBUTE_ARCHIVE. The resulting 0x00401600 mask contains FILE_ATTRIBUTE_SPARSE_FILE, FILE_ATTRIBUTE_REPARSE_POINT, FILE_ATTRIBUTE_OFFLINE, and FILE_ATTRIBUTE_RECALL_ON_DATA_ACCESS.

The unchanged file ID is especially useful. It shows that, in this run, the result was not merely a different file appearing at the same pathname. The existing file object survived while acquiring Cloud Files state.

The program preserves the logical file size, but it does not validate the original bytes after conversion. No claim about arbitrary content control follows from this PoC.

Where the authorization failure sits

The observable failure can be stated without inventing an internal call stack:

  1. The caller has enough authority over the base directory to register it and create children.
  2. The existing leaf’s current DACL denies the tested write and delete operations.
  3. CfCreatePlaceholders accepts a supersede request for that leaf.
  4. CldFlt changes the leaf into a Cloud Files placeholder.

This behavior is consistent with a missing or incomplete check against the existing leaf on the supersede path. It does not identify the precise internal function, branch, IRP, or kernel callback responsible. The PoC contains no kernel debugging or binary-difference analysis, so the explanation stops at the externally verified boundary.

Microsoft assigned CWE-306, Missing Authentication for Critical Function. At the Windows object level, the experiment exposes inconsistent authorization enforcement. I use Microsoft’s official CWE in the metadata and describe the observed access-control behavior in the technical analysis.

Impact, with the adjectives kept on a short leash

The PoC demonstrates an integrity and file-state change that the tested direct operations could not perform. A local low-privilege caller with the required base-directory access can make an existing read-only leaf become a Cloud Files placeholder through the affected path.

Microsoft’s advisory gives the broader product impact: an attacker could make unauthorized changes to protected system data and alter system state or configuration beyond normal privileges. That is Microsoft’s assessment of the vulnerability. The isolated PoC does not select a protected system target or demonstrate a complete post-exploitation chain.

The CVSS vector reflects the same broad shape:

  • Local attack vector
  • Low attack complexity
  • Low privileges required
  • No user interaction
  • High integrity impact
  • No claimed confidentiality or availability impact

How far back does it go?

The careful answer is almost eight years in Microsoft’s published affected range.

The official CVE record starts the oldest affected branch at 10.0.17763.0 for Windows 10 version 1809 and Windows Server 2019. Microsoft’s Windows 10 release history lists the first version 1809 build, 17763.1, on October 2, 2018. Microsoft published the fix on September 8, 2026.

That puts the earliest confirmed point in the public range just under eight years before the fix.

The Cloud Files API itself arrived with Windows 10 version 1709 in 2017, and the API documentation lists 1709 as the minimum supported client. That does not prove this vulnerability existed in 1709. Microsoft’s CVE record does not list 1709, and this research did not test it. An API’s birthday is not automatically a bug’s birthday, however tempting the headline may be.

Repro

Use an affected test system on NTFS. Run the PoC from a normal, non-elevated command prompt.

root@kitploit:~
build.bat
main_poc.exe

The build script uses MinGW-w64 GCC when available and falls back to Microsoft’s C compiler. The program creates and registers its own fresh test root. It unregisters and disconnects during cleanup, then leaves the test directory in place for inspection.

The optional path form is:

root@kitploit:~
main_poc.exe C:\path\to\a\new-test-directory

The supplied path must not already exist. Keep the test isolated and remove its directory after collecting the results.

On a fixed system, the complete condition should not reach CONFIRMED. Do not infer patch status from one console line. Check the overall result, exit code, per-entry result, USN, attributes, and reparse tag together.

Closing the file

The most interesting Windows vulnerabilities are often arguments over which object an access check was really about.

Here, permission to create beneath a directory reached a path that could transform a stricter child already inside it. The ordinary file APIs respected that child’s current DACL. Cloud Files supersede did not preserve the same boundary.

No spectacular memory corruption was required. One object said no, another object supplied enough authority to continue, and a familiar filename quietly became something else.

That is the whole trick. It is also why the trick matters.

Download Tool
OperationResult
Open the existing file with GENERIC_WRITEERROR_ACCESS_DENIED
Delete it with DeleteFileWERROR_ACCESS_DENIED
Open it with GENERIC_READSuccess
Register and connect the parent as a sync rootS_OK
Call CfCreatePlaceholders with supersede semanticsS_OK
Inspect the resulting entryCloud reparse point
PropertyBeforeAfter
Attributes0x000000200x00401600
Reparse pointNoYes
Reparse tagNone0x9000001A
Entry resultNot applicableS_OK
Creation USNNot applicableNonzero
File IDRecordedUnchanged