Windows: DSSVC CheckFilePermission Arbitrary File Delete EoP
The Data Sharing Service doesn’t has a TOCTOU in PolicyChecker::CheckFilePermission resulting in an arbitrary file deletion. In many different places the DSSVC calls PolicyChecker::CheckFilePermission to ensure the calling user has permission to open a file with a certain set of access rights. This function has an unusual behavior, specifically it passes OPEN_ALWAYS as the disposition to CreateFile even if the code expects the file to already exist. The OPEN_ALWAYS disposition will create a file if it doesn’t exist, to handle the the code checks whether GetLastError() is 0, if it is then it assumes the file is new and so will call DeleteFile on the path. This has a big problem, there’s a TOCTOU in that the path passed to CreateFile doesn’t need to refer to the same file that’s passed to DeleteFile. For example when this method is called in DSSCreateSharedFileTokenEx it’s using the path supplied by the user almost directly. One way of exploiting this would be to specify a path with a mount point in it, then between the call to CreateFile and DeleteFile change the mount point to point somewhere else. However, there’s an easier way, as CreateFile is called under impersonation and DeleteFile is not an attacker could just setup a per-user C: redir to a file they don’t have access to, then when the service calls CreateFile it will succeed, but when it calls DeleteFile it will fail.