Related Weaknesses
CWE-ID |
Weakness Name |
Source |
CWE-367 |
Time-of-check Time-of-use (TOCTOU) Race Condition The product checks the state of a resource before using that resource, but the resource's state can change between the check and the use in a way that invalidates the results of the check. This can cause the product to perform invalid actions when the resource is in an unexpected state. |
|
Metrics
Metrics |
Score |
Severity |
CVSS Vector |
Source |
V3.0 |
5.3 |
MEDIUM |
CVSS:3.0/AV:L/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L
Base: Exploitabilty MetricsThe Exploitability metrics reflect the characteristics of the thing that is vulnerable, which we refer to formally as the vulnerable component. Attack Vector This metric reflects the context by which vulnerability exploitation is possible. A vulnerability exploitable with Local access means that the vulnerable component is not bound to the network stack, and the attacker's path is via read/write/execute capabilities. In some cases, the attacker may be logged in locally in order to exploit the vulnerability, otherwise, she may rely on User Interaction to execute a malicious file. Attack Complexity This metric describes the conditions beyond the attacker's control that must exist in order to exploit the vulnerability. Specialized access conditions or extenuating circumstances do not exist. An attacker can expect repeatable success against the vulnerable component. Privileges Required This metric describes the level of privileges an attacker must possess before successfully exploiting the vulnerability. The attacker is authorized with (i.e. requires) privileges that provide basic user capabilities that could normally affect only settings and files owned by a user. Alternatively, an attacker with Low privileges may have the ability to cause an impact only to non-sensitive resources. User Interaction This metric captures the requirement for a user, other than the attacker, to participate in the successful compromise of the vulnerable component. The vulnerable system can be exploited without interaction from any user. Base: Scope MetricsAn important property captured by CVSS v3.0 is the ability for a vulnerability in one software component to impact resources beyond its means, or privileges. Scope Formally, Scope refers to the collection of privileges defined by a computing authority (e.g. an application, an operating system, or a sandbox environment) when granting access to computing resources (e.g. files, CPU, memory, etc). These privileges are assigned based on some method of identification and authorization. In some cases, the authorization may be simple or loosely controlled based upon predefined rules or standards. For example, in the case of Ethernet traffic sent to a network switch, the switch accepts traffic that arrives on its ports and is an authority that controls the traffic flow to other switch ports. An exploited vulnerability can only affect resources managed by the same authority. In this case the vulnerable component and the impacted component are the same. Base: Impact MetricsThe Impact metrics refer to the properties of the impacted component. Confidentiality Impact This metric measures the impact to the confidentiality of the information resources managed by a software component due to a successfully exploited vulnerability. There is some loss of confidentiality. Access to some restricted information is obtained, but the attacker does not have control over what information is obtained, or the amount or kind of loss is constrained. The information disclosure does not cause a direct, serious loss to the impacted component. Integrity Impact This metric measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of information. Modification of data is possible, but the attacker does not have control over the consequence of a modification, or the amount of modification is constrained. The data modification does not have a direct, serious impact on the impacted component. Availability Impact This metric measures the impact to the availability of the impacted component resulting from a successfully exploited vulnerability. There is reduced performance or interruptions in resource availability. Even if repeated exploitation of the vulnerability is possible, the attacker does not have the ability to completely deny service to legitimate users. The resources in the impacted component are either partially available all of the time, or fully available only some of the time, but overall there is no direct, serious consequence to the impacted component. Temporal MetricsThe Temporal metrics measure the current state of exploit techniques or code availability, the existence of any patches or workarounds, or the confidence that one has in the description of a vulnerability. Environmental Metrics
|
[email protected] |
V2 |
4.6 |
|
AV:L/AC:L/Au:N/C:P/I:P/A:P |
[email protected] |
EPSS
EPSS is a scoring model that predicts the likelihood of a vulnerability being exploited.
EPSS Score
The EPSS model produces a probability score between 0 and 1 (0 and 100%). The higher the score, the greater the probability that a vulnerability will be exploited.
EPSS Percentile
The percentile is used to rank CVE according to their EPSS score. For example, a CVE in the 95th percentile according to its EPSS score is more likely to be exploited than 95% of other CVE. Thus, the percentile is used to compare the EPSS score of a CVE with that of other CVE.
Exploit information
Exploit Database EDB-ID : 44466
Publication date : 2018-04-15 22h00 +00:00
Author : Google Security Research
EDB Verified : Yes
Windows: CiSetFileCache TOCTOU CVE-2017-11830 Incomplete Fix
Platform: Windows 10 1709 (including Win10S)
Class: Security Feature Bypass
Summary:
The fix for CVE-2017-11830 is insufficient to prevent a normal user application adding a cached signing level to an unsigned file by exploiting a TOCTOU in CI leading to circumventing Device Guard policies.
Description:
The previous issue I reported was due to not checking for write access on the target file handle when setting the cache. This allows a user application to abuse a TOCTOU and rewrite the file after the hash has been generated for the file. The only changed code seems to be below:
FILE_OBJECT target_file;
ObReferenceObjectByHandle(FileHandle, 0, *IoFileObjectType, &target_file);
if (target_file->SharedWrite) {
return STATUS_SHARING_VIOLATION;
}
if (target_file->WriteAccess) { ← Additional check for the file being opened for write.
if ((PsGetProcessProtection(PsGetCurrentProcess()) & 7) != ProtectedProcessLight)
return STATUS_SHARING_VIOLATION;
}
The fix was to add a check that the target file passed isn’t writable. This combined with the check for FILE_SHARE_WRITE should mean the user can’t hold on to a writable file handle. However, when the file handle is converted to a file object with ObReferenceObjectByHandle the desired access is 0, which means we can pass a handle with any granted access including SYNCHRONIZE or READ_CONTROL, which do not respect file sharing. So we can still exploit this issue by doing the following:
1. Open the file for write access.
2. Reopen another handle to the file for SYNCHRONIZE access. This works as this access right can be used regardless of the sharing mode.
3. Set cached signing level through the handle opened in 2.
4. Wait for oplock, rewrite file using handle opened in 1. Release oplock.
Proof of Concept:
I’ve provided a PoC as a C# project. It will allow you to “cache sign” an arbitrary executable. If you want to test this on a locked down system such as Win10S you’ll need to sign the PoC (and the NtApitDotNet.dll assembly) so it’ll run. Or use it via one of my .NET based DG bypasses, in that case you can call the PoC_CacheSignature.Exploit.Run method directly. It copies notepad to a file, attempts to verify it but uses an oplock to rewrite the contents of the file with the untrusted file before it can set the kernel EA.
1) Compile the C# project. It will need to grab the NtApiDotNet v1.1.7 package from NuGet to work.
2) Execute the PoC passing the path to an unsigned file and to the output “cache signed” file, e.g. poc unsigned.exe output.exe
3) You should see it print the signing level, if successful.
4) You should not be able to execute the unsigned file, bypassing the security policy enforcement.
NOTE: If it prints an exception then the exploit failed. The opened catalog files seemed to be cached for some unknown period of time after use so if the catalog file I’m using for a timing signal is already open then the oplock is never broken. Just rerun the poc which will pick a different catalog file to use. Also the output file must be on to a NTFS volume with the USN Change Journal enabled as that’s relied upon by the signature level cache code. Best to do it to the boot drive as that ensures everything should work correctly.
Expected Result:
Access denied or at least an error setting the cached signing level.
Observed Result:
The signing level cache is applied to the file with no further verification. You can now execute the file as if it was signed.
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/44466.zip
Exploit Database EDB-ID : 45435
Publication date : 2018-09-18 22h00 +00:00
Author : Google Security Research
EDB Verified : Yes
Windows: CiSetFileCache TOCTOU CVE-2017-11830 Variant WDAC Security Feature Bypass
Platform: Windows 10 1803, 1709 (should include S-Mode but not tested)
Class: Security Feature Bypass
Summary:
While the TOCTOU attack against cache signing has been mitigated through NtSetCachedSigningLevel it’s possible to reach the same code via NtCreateSection leading to circumventing WDAC policies and CIG/PPL.
Description:
I'm reporting this as you've fixed the previous issues (cases 43036 and 40101) so I'm making an assumption you'd also fix this one. The previous issues allowed a unprivileged caller to exploit a race condition in the CiSetFileCache kernel function by calling NtSetCachedSigningLevel. These issues should now be fixed. During my research into PPL/PP bypasses I noticed that the cache will also be written during the initial creation of an image section, when the process is running with an increased section signing level. This is presumably to allow the kernel to cache the signature automatically. This is an issue because it’s possible to create an image section with a writable (and executable) handle to the file and no part of CI then checks whether the caller has write access. It’s possible to have an elevated section signing level by enabling the ProcessSignaturePolicy process mitigation policy, it’s not required to be in a PPL. In fact, while I’ve not tested it, it’s possible that just running inside a process on Windows 10 S-Mode would be sufficient as the section signing level should be elevated for WDAC.
So to exploit this we can do the following:
1. Elevated the section signing level of the current process using SetProcessMitigationPolicy or just running in a WDAC/CIG process.
2. Copy a valid signed file to a known name then open a writable and executable handle to that file.
3. Set an oplock on a known catalog file which will be checked
4. Call NtCreateSection with the handle requesting SEC_IMAGE.
5. Wait for oplock to fire, rewrite the file with an untrusted binary, then release oplock.
6. Close section and file handles. The cache should have been applied to the untrusted file.
Perhaps CI should check whether the file handle has been opened for write access and not write out the cache in those cases as realistically creating an image section from a writable handle should be an unusual operation. The normal loader process opens the handle only for read/execute.
Proof of Concept:
I’ve provided a PoC as a C# project. It will allow you to “cache sign” an arbitrary executable. To test on S-Mode you’ll need to sign the PoC (and the NtApitDotNet.dll assembly) so it’ll run. It copies notepad to a file, attempts to verify it but uses an oplock to rewrite the contents of the file with the untrusted file before it can set the kernel EA.
1) Compile the C# project. It will need to grab the NtApiDotNet v1.1.15 package from NuGet to work.
2) Execute the PoC passing the path to an unsigned file and to the output “cache signed” file, e.g. poc unsigned.exe output.exe. Make sure the output file is on a volume which supports cached signing level such as the main boot volume.
3) You should see it print the signing level, if successful.
4) You should now be able to execute the unsigned file, bypassing the security policy enforcement.
NOTE: If it prints an exception then the exploit failed. The opened catalog files seemed to be cached for some unknown period of time after use so if the catalog file I’m using for a timing signal is already open then the oplock is never broken. Just rerun the poc which will pick a different catalog file to use. Also the output file must be on to a NTFS volume with the USN Change Journal enabled as that’s relied upon by the signature level cache code. Best to do it to the boot drive as that ensures everything should work correctly.
Expected Result:
Access denied or at least an error setting the cached signing level.
Observed Result:
The signing level cache is applied to the file with no further verification. You can now execute the file as if it was signed.
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/45435.zip
Exploit Database EDB-ID : 43162
Publication date : 2017-11-19 23h00 +00:00
Author : Google Security Research
EDB Verified : Yes
Source: https://bugs.chromium.org/p/project-zero/issues/detail?id=1332
Windows: CiSetFileCache TOCTOU Security Feature Bypass
Platform: Windows 10 10586/14393/10S not tested 8.1 Update 2 or Windows 7
Class: Security Feature Bypass
Summary:
It’s possible to add a cached signing level to an unsigned file by exploiting a TOCTOU in CI leading to to circumventing Device Guard policies and possibly PPL signing levels.
Description:
Windows Code Integrity has the concept of caching signing level decisions made on individual files. This is done by storing an extended attribute with the name $KERNEL.PURGE.ESBCACHE and filling it with related binary information. As the EA name is a kernel EA it means it can’t be set by user mode code, only kernel mode code calling FsRtlSetKernelEaFile. Also crucially it’s a purgeable EA which means it will be deleted automatically by the USN journal code if any attempt is made to write to the file after being set.
As far as I can tell the binary data doesn’t need to correspond to anything inside the file itself, so if we replace the contents of the file with a valid cached signing level the kernel is entirely relying on the automatic purging of the kernel EA to prevent spoofing. To test that theory I copied the EA entry from a valid signed file onto an unsigned file with a non-kernel EA name then used a disk editor to modify the name offline. This worked when I rebooted the machine, so I was confident it could work if you could write the kernel EA entry. Of course if this was the only way to exploit it I wouldn’t be sending this report.
As user mode code can’t directly set the kernel EA the facility to write the cache entry is exposed through ZwSetCachedSigningLevel(2). This takes a number of arguments, including flags, a list of associated file handles and the target handle to write the EA to. There seems to be 3 modes which are specified through the flags:
Mode 1 - This is used by mscorsvw.exe and seems to be used for blessing NGEN binaries. Calling this requires the caller to be a PPL so I didn’t investigate this too much. I’m sure there’s probably race conditions in NGEN which could be exploited, or ways to run in a PPL if you’re admin. The advantage here is you don’t need to apply the cache to a signed file. This is what piqued my interesting in the first place.
Mode 2 - Didn’t dig into this one TBH
Mode 5 - This sets a cache on a signed file, the list of files must only have 1 entry and the handle must match the target file handle. This is the one we’ll be exploiting as it doesn’t require any privileges to call.
Looking through the code inside the kernel the handles passed to ZwSetCachedSigningLevel are also passed as handles into CiSetFileCache which is slightly odd on the face of it. My first thought was you could race the handle lookup when ObReferenceObjectByHandle is called for the target handle and when the code is enumerating the list of handles. The time window would be short but it’s usually pretty easy to force the kernel to reuse a handle number. However it turns out in Mode 5 as the handle is verified to be equal the code just uses the looked up FILE_OBJECT from the target handle instead which removes this issue (I believe).
So instead I looked at racing the writing of the cache EA with the signature verification. If you could rewrite the file between the kernel verifying the signature of the file and the writing of the kernel EA you could ensure your USN journal entries from the writes are flushed through before hand and so doesn’t cause the EA to be purged. The kernel code calls FsRtlKernelFsControlFile with FSCTL_WRITE_USN_CLOSE_RECORD to force this flush just before writing the EA so that should work.
The question is can you write to the file while you’re doing this? There’s no locking taking place on the file from what I could tell. There is a check for the target file being opened with FILE_SHARE_WRITE (the check for FileObject->SharedWrite) but that’s not the same as the file handle already being writable. So it looks like it’s possible to write to the file.
The final question is whether there’s a time period between signature verification and applying the EA that we can exploit? Turns out CI maps the file as a read only section and calls HashKComputeImageHash to generate the hash once. The code then proceeds to lookup the hash inside a catalog (presumably unless the file has an embedded signature). Therefore there's a clear window of time between the validation and the setting of the kernel EA to write.
The final piece of the puzzle is how to win that race reliably. The key is the validation against the catalog files. We can use an exclusive oplock to block the kernel opening the catalog file temporarily, which crucially happens after the target file has already been hashed. By choosing a catalog we know the kernel will check we can get a timing signal, modify the target file to be an unsigned, untrusted file then release the oplock and let the kernel complete the verification and writing of the cache.
Almost all files on a locked down system such as Win10S are Microsoft Platform signed and so end up in catalogs such as Microsoft-Windows-Client-Features-Package. This seems like a hot-path file which might always be opened by the kernel and so couldn’t be exploited for an oplock. However another useful feature now comes into play, the fact that there’s also an EA which can specify a hint name for the catalog the file is signed in. This is called $CI.CATALOGHINT and so isn’t a kernel EA which means we can set it. It contains a UTF8 encoded file name (without path information). Importantly while CI will check this catalog first, if it can’t find the hash in that catalog it continues searching everything else, so we can pick a non-hot-path catalog (such as Adobe’s Flash catalogs) which we can oplock on, do the write then release and the verification will find the correct real catalog instead. I don’t think you need to do this, but it makes it considerably more convenient.
Note that to exploit this you’d likely need executable code already running, but we already know there’s multiple DG bypasses and things like Office on Win10S can run macros. Or this could be used from shellcode as I can’t see any obvious limitation on exploiting this from a sandbox as long as you can write a file to an NTFS drive with the USN Change Journal enabled. Running this once would give you an executable or a DLL which bypasses the CI policies, so it could be used as a stage in an attack chain to get arbitrary code executing on a DG system.
In theory it think this would also allow you to specify the signing level for an untrusted file which would allow the DLL to be loaded inside a PPL service so you could use this on a vanilla system to try and attack the kernel through PPL’s such as CSRSS as an administrator. I don’t know how long the cache is valid for, but it’s at least a day or two and might only get revoked if you update your system or replace the file.
Proof of Concept:
I’ve provided a PoC as a C# project. It will allow you to “cache sign” an arbitrary executable. If you want to test this on a locked down system such as Win10S you’ll need to sign the PoC (and the NtApitDotNet.dll assembly) so it’ll run. Or use it via one of my .NET based DG bypasses, in that case you can call the POC.Exploit.Run method directly. It copies notepad to a file, attempts to verify it but uses an oplock to rewrite the contents of the file with the untrusted file before it can set the kernel EA.
1) Compile the C# project. It will need to grab the NtApiDotNet v1.0.8 package from NuGet to work.
2) Execute the PoC passing the path to an unsigned file and to the output “cache signed” file, e.g. poc unsigned.exe output.exe
3) You should see it print the signing level, if successful.
4) You should not be able to execute the unsigned file, bypassing the security policy enforcement.
NOTE: If it prints an exception then the exploit failed. The opened catalog files seemed to be cached for some unknown period of time after use so if the catalog file I’m using for a timing signal is already open then the oplock is never broken. Wait a period of time and try again. Also the output file must be on to a NTFS volume with the USN Change Journal enabled as that’s relied upon by the signature level cache code. Best to do it to the boot drive as that ensures everything should work correctly.
Expected Result:
Access denied or at least an error setting the cached signing level.
Observed Result:
The signing level cache is applied to the file with no further verification. You can now execute the file as if it was signed with valid Microsoft signature.
Proof of Concept:
https://gitlab.com/exploit-database/exploitdb-bin-sploits/-/raw/main/bin-sploits/43162.zip
Products Mentioned
Configuraton 0
Microsoft>>Windows_10 >> Version -
Microsoft>>Windows_10 >> Version 1511
Microsoft>>Windows_10 >> Version 1607
Microsoft>>Windows_10 >> Version 1703
Microsoft>>Windows_10 >> Version 1709
Microsoft>>Windows_server >> Version 1709
Microsoft>>Windows_server_2016 >> Version -
References