Issue description

Windows: StorSvc SvcMoveFileInheritSecurity Arbitrary File Creation EoP
Platform: Windows 10 1709 (not tested earlier versions)
Class: Elevation of Privilege
Summary: The SvcMoveFileInheritSecurity RPC method in StorSvc can be used to move an arbitrary file to an arbitrary location resulting in elevation of privilege.
Description:
I was reading Clément Rouault & Thomas Imbert excellent PacSec’s slides on ALPC+RPC issues and they highlighted the SvcMoveFileInheritSecurity method used to exploit the ALPC bug CVE-2017-11783. The function impersonates the user and calls MoveFileEx to move the file to a new destination, then reverts the impersonation and tries to reset the security descriptor of the new file so that it matches the inheritable permissions. The ALPC bug in CVE-2017-11783 has apparently been fixed but the behavior of the SvcMoveFileInheritSecurity has not been modified as far as I can tell.
The main problem occurs if the call to SetNamedSecurityInfo fails, in that case the code tries to move the file back to its original location, however it does reassert the impersonation. This probably makes sense because it’s possible to have a file/directory which you can open for DELETE but without the rights to create a new file in the same directory. In the case the original move would succeed but the revert would fail. However there’s a TOCTOU issue in that the original path might have been replaced with a mount point which redirects the revert to a totally arbitrary location while running at SYSTEM. The exploit controls both the name and the contents of the file so this would be a trivial privilege escalation.
It’s possible to cause SetNamedSecurityInfo to fail just by adding a Deny ACE to the file for SYSTEM. This will cause the function to get ERROR_ACCESS_DENIED and the revert will take place. By placing an oplock on the original file open we can switch in a mount point and always win the race condition.
Ideally all operations should take place under user impersonation, but if that was the case there’d be no point in doing it in a SYSTEM service to begin with. Note that there’s a second issue specifically with SetNamedSecurityInfo which I’ve sent as a separate issue, just in case it gets missed.
Proof of Concept:
I’ve provided a PoC as a C++ project. It will abuse the SvcMoveFileInheritSecurity method to create the file test.txt in the windows folder.
1) Compile the C++ project.
2) Execute the PoC as a normal user.
Expected Result:
The file reversion fails trying to copy the file back to its original location.
Observed Result:
The file is reverted which results in the test.txt file being creating in c:\windows.
This bug is subject to a 90 day disclosure deadline. After 90 days elapse or a patch has been made broadly available, the bug report will become visible to the public.