Windows: NPFS Symlink Security Feature Bypass/Elevation of Privilege/Dangerous Behavior
Platform: Windows 10 1709 (functionality not present prior to this version)
Class: Security Feature Bypass/Elevation of Privilege/Dangerous Behavior
Summary: It’s possible to create NPFS symlinks as a low IL or normal user and the implementation doesn’t behave in a similar manner to other types of Windows symlinks leading to dangerous behavior or EoP.
Description:
Windows 10 1709 introduced a new symlink feature to NPFS which is accessible from a FSCTL. From what I can see the implementation has a number of security issues which concern me:
* 1) Creation of symbolic links is only limited to a user which can open the root named pipe device. I.e. \Device\NamedPipe. This users which can open the device includes restricted tokens with the RESTRICTED SID and Low IL tokens.
* 2) Accessing a symlink results in the NPFS driver synthesizing a NTFS symlink reparse point which is passed back to the object manager. This allows the symlink to reparse to different devices. This is presumably by design but it’s dangerous behavior.
* 3) Opening a symlink doesn’t respect the FILE_OPEN_REPARSE_POINT which could lead to some unusual behavior.
The fact that you can create the symlink as a lower privileged user is bad enough, although I don’t believe it can be done from an AC so maybe you don’t care about it. But the other two issues are examples of dangerous behavior `which _will_ come` back to bite you at some point in the future.
Let’s take point 2 as an example, up to this point NPFS hasn’t had the concept of symbolic links. Sure you could drop an appropriate object manager symlink somewhere and get a caller to follow it but you’d need to be able to influence the callers path or their DOS device directory. With this if a privileged caller is expecting to open a named pipe, say \\.\pipe\ABC then ABC could actually be a symbolic link to a normal file. If the caller then just writes data to the pipe expecting it to be a stream they could actually be writing data into a file which might result in EoP. Basically I see it’s a case of when not if that a EoP bug is found which abuses this behavior.
Also, there’s no way I know of for detecting you’re opening a symbolic link. For example if you open the target with the FILE_OPEN_REPARSE_POINT flag it continues to do the reparse operation. Due to creating a normal NTFS symbolic link this might also have weird behavior when a remote system accessed a named pipe, although I’ve not tested that.
Overall I think the behavior of the implementation has the potential for malicious use and should be limited to privileged users. I don’t know it’s original purpose, perhaps it’s related to Silos (there is a flag to make a global symlink) or it’s to make it easier to implement named pipes in WSL, I don’t know. If the purpose is just to symlink between named pipes then perhaps only allow a caller to specify the name relative to the NPFS device rather than allowing a full object path.
Proof of Concept:
I’ve provided a PoC as a C# project. The PoC will create a symlink called ABC which points to notepad.exe. It will check the file file it opens via the symlink matches the file opened directly.
* 1) Compile the C# project. It will need to grab the NtApiDotNet from NuGet to work.
* 2) Run the poc as Low IL (using say psexec).
Expected Result:
The creation of the symlink should fail with an error.
Observed Result:
The symlink is created, is valid and the poc printed ‘Success’ as it’s opened the copy of notepad.exe via the symlink.
[poc.zip](https://bugs.chromium.org/p/project-zero/issues/attachment?aid=310808&signed_aid=TOkMtt03qDzMT41SCzwPSQ==)
暂无评论