Windows Error Reporting Manager arbitrary file move Elevation of Privilege (CVE-2019-1315)

Published on Tue 08 October 2019 by @clavoillotte

Product: Windows 10, Windows Server 2019 (older version also affected but not tested)

Type: Local Privilege Escalation

Summary: The privileged file operations performed by the Windows Error Reporting service on user-writable files can be abused to rename/move arbitrary files with SYSTEM privileges. This can be used by an unprivileged user to elevate privileges on the local machine.

This vulnerability is patched with Windows October 2019 security updates.

It was also independently discovered by David Cash.

Description

When the Windows Error Reporting service is triggered (e.g. after an application crash), the wermgr.exe process will look for report files in %ProgramData%\Microsoft\Windows\WER\ReportQueue\*_*_*_*_* subdirectories of the user-writable %ProgramData%\Microsoft\Windows\WER\ReportQueue directory, read the Report.wer report file, create a Report.wer.tmp temporary file, write to it, and then rename (SetRenameInformationFile) that file to Report.wer, overwriting the existing report file.

E.g. the final rename operation on a report generated by a PowerShell FailFast() call show up in Procmon as such:

wermgr rename operation in ProcMon

These operations are performed with SYSTEM privileges, on user-writable directories & files - the subdirectory and report file are normally created by WerFault.exe with the user's privileges before wermgr.exe starts, and without impersonation or checks against junctions and symbolic links.

This can be abused by a standard, non-admin user to rename/move files as SYSTEM.

Indeed, because the user has control over the directory where these operations take place, an unprivileged user can change it to an NTFS junction that points to an arbitrary location, and/or change its content to links targeting other files.

While unprivileged users can't create "real" NTFS symbolic links on the filesystem by default, they can chain a mount point that resolves to the \RPC Control\ object directory with an object manager symbolic links that resolves to the target path to get a "pseudo-symlink", as demonstrated by James Forshaw (e.g. here and here). For more on this, a general explanation on privileged file operation bugs is available here.

So, with the following setup:

  • C:\ProgramData\Microsoft\Windows\WER\ReportQueue\a_b_c_d_e -> \RPC Control (NTFS junction)
  • \RPC Control\Report.wer -> C:\Windows\System32\evil.dll (object manager symbolic link)

A CreateFile operation on C:\ProgramData\Microsoft\Windows\WER\ReportQueue\a_b_c_d_e\Report.wer will actually open the file C:\Windows\System32\evil.dll

There are a few hurdles to overcome for a stable exploitation, such as the fact that the file read by wermgr must be a valid report file and the timing of links substitution, but these can be easily worked around using oplocks.

By targeting the rename operation, an unprivileged user can then create or replace files on which SYSTEM has write access, by setting up the following pseudo-symlinks just before the rename operation:

  • C:\ProgramData\Microsoft\Windows\WER\ReportQueue\a_b_c_d_e\Report.wer -> C:\Windows\System32\evil.dll
  • C:\ProgramData\Microsoft\Windows\WER\ReportQueue\a_b_c_d_e\Report.wer.tmp -> C:\path\to\payload.dll

The rename operation will thus move C:\path\to\payload.dll to C:\Windows\System32\evil.dll with SYSTEM privileges.

Proof of Concept

I’ve provided a PoC (available here) for Windows 10 1903 to demonstrate the vulnerability by creating user-writable a %SystemRoot%\evil.txt file with content test, when the Test-Exploit function is run.

Below is a video of it in action, exploiting the bug to plant a DLL file and obtain a SYSTEM shell (this last part is not provided in the PoC, and left as an exercise to the reader):

Fix

The vendor has released a patch and an advisory. Users should apply updates through usual channels.

References

https://portal.msrc.microsoft.com/en-us/security-guidance/advisory/CVE-2019-1315

Timeline

2019-09-22: Initial report sent to vendor

2019-09-23: Vendor acknowledges reception of report

2019-09-27: Vendor responds this bug is already being fixed on next patch Tuesday

2019-10-08: Vendor published fix and advisory

2019-10-08: Publication of this advisory