Google's Project Zero team is well-known for discovering vulnerabilities in the software developed by the company itself as well as those built by other firms. Its methodology involves identifying security flaws in software and privately reporting them to vendors, giving them 90 days to fix them before public disclosure. Depending upon the complexity of the fix required, it sometimes also offers additional days in the form of a grace period.
The security team has discovered and disclosed multiple security flaws in the past few years following the respective vendor's inability to patch them in a timely manner. This includes Qualcomm's Adreno GPU drivers, Microsoft's Windows, Apple's macOS, and more. It recently also unveiled a new Rowhammer variant that can be used to alter the memory contents of new DRAM chips. Following a botched fix by Microsoft, it has now disclosed a "low" severity Windows bug that can lead to elevation of privilege.
The issue in question was reported by James Forshaw of Google Project Zero. The full details of the problem can be viewed here, but as usual, are quite technical in nature. The gist of the matter relates to how the Windows Filtering Platform doesn't correctly verify token impersonation when checking filters, which can lead to EoP attacks.
Essentially, when an IP-based socket is created, the security context of the current caller is extracted by the TCP/IP driver, which then uses this information to perform firewall checks. So whenever an activity is carried out on the socket, the TCP/IP driver sends a call to the NETIO driver to see if it is allowed based on your Windows Firewall and Base Filtering Engine configurations. In a nutshell, if these rules are somehow bypassed by the caller, an attacker can perform network operations even though the firewall shouldn't allow it to do so.
Forshaw was able to bypass these firewall conditions in Windows 10 20H2 because of how the operating system sets the default rules for AppContainers (AC), which do not allow them to connect to the network unless certain permissions are granted. According to the security researcher, there are multiple issues with how firewall rules are validated.
After the token is converted to a specific structure, no impersonation-level check is performed. While this is not a problem on its own, there can be a potential issue when the second check validates whether the token is already cached or not. Essentially, if an AppContainer process is able to steal a validated non-AppContainer process' token, it can bypass this check by impersonation without the firewall knowing that it's actually another process and is not allowed to bypass the filters.
Forshaw described other vulnerabilities in the process as well, saying that if the token is not already cached, it manually enumerates Security Identifies (SIDs) for validation of network capabilities and sets certain flags, which are probably used to bypass other checks in the firewall. It is important to note that no impersonation level validation has still been made. As the security researcher describes:
At this point the socket’s been created with the security information stored with it. Nothing will happen until an operation such as a connect call gets the filtering involved. While the lack of impersonation checks is a problem it might not matter as long as the code doing the access checks is correct. Unfortunately they’re not. The checks seem to be in NETIO!MatchValues which goes through the filter rules and applies the operations to the network connection. This might include checking SIDs from the token information or calling SeAccessCheckFromStateEx.
There’s again no checking for the impersonation level when just checking SIDs, but there probably should be. However the biggest issue is the call to SeAccessCheckFromStateEx. It takes two tokens from the caller, the primary token and the impersonation token. As the code in TCPIP only captures one token MatchValues always passes the token as the primary token. The way the underlying access check APIs work is the impersonation check for SecurityImpersonation or above is only done if an impersonation token has been passed as an impersonation token. If you pass an impersonation token as a primary token the code never checks for the level and proceeds with the access check. This means that the caller can pass access checks as if they weren’t in an AC assuming they impersonate a non-AC token.
James Foshaw has also explained that it is relatively easy for AppContainer processes to retrieve a non-AppContainer token and bypass firewall checks. Even though most device drivers restrict access to AppContainer or identification level tokens, this is not the case when it comes to the Windows Ancillary Function Driver (AFD), which allows socket creation for both of these. Forshaw claims that utilizing this capability to your advantage is a fairly trivial process to exploit as well.
The security researcher suggested that socket creation should be blocked for all callers impersonating identification tokens except in certain edge cases, and provided a proof-of-concept (PoC) piece of code demonstrating the exploit as well.
The issue was privately reported to Microsoft on March 24, and the company confirmed that a fix has been rolled out in June's Patch Tuesday update released on June 8. Details of the vulnerability can be seen in CVE-2021-31970 where Microsoft has acknowledged Google Project Zero, while confirming that this is a local attack vector on various operating systems including Windows 8.1, Windows 10, and Windows Server 2016, among others.
However, upon further investigation, Forshaw determined that while the patch mitigates the PoC's exploit, it doesn't actually fix the underlying issue, so is incomplete. The security researcher developed a new PoC to demonstrate that the exploit is still possible and reported it to Microsoft on June 18. However, given that the allotted 90 days lapsed on June 23 without a complete fix, the exploit is being made public. Given that it is a local attack vector with low chances of exploitation, it's likely that Microsoft will release a complete fix in the next Patch Tuesday which falls on July 13. However, this has not been confirmed as of yet.