{
	"id": "74869f77-e90c-4f6c-b6bc-485672de831a",
	"created_at": "2026-04-06T00:21:08.589598Z",
	"updated_at": "2026-04-10T03:21:52.237683Z",
	"deleted_at": null,
	"sha1_hash": "03e87f96266a5db1b289708921d7f8aae117f4ee",
	"title": "Zero Day Initiative — Activation Context Cache Poisoning: Exploiting CSRSS for Privilege Escalation",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 169127,
	"plain_text": "Zero Day Initiative — Activation Context Cache Poisoning: Exploiting\r\nCSRSS for Privilege Escalation\r\nPublished: 2023-01-23 · Archived: 2026-04-05 14:02:42 UTC\r\nStarting in July of 2022, the Windows CSRSS process entered the consciousness of the infosec community as the source of\r\nseveral local privilege escalation vulnerabilities in Microsoft Windows. The first public information appeared on July 12\r\nwith the release of the patch for CVE-2022-22047, which was being actively exploited. Shortly thereafter, Microsoft\r\npublished an article providing some technical details and revealing that the threat actor involved was an Austrian hack-for-hire group tracked by Microsoft as KNOTWEED. Fortuitously, these developments coincided with closely related research I\r\nhad been conducting, and in that same month, I reported to Microsoft two additional vulnerabilities affecting the same\r\ncomponent. These have now been patched as CVE-2022-37987 and CVE-2022-37989 respectively. All these bugs, which\r\nhave been commonly known as the “CSRSS” bugs, are best understood as examples of a new class of privilege escalation\r\nvulnerabilities: activation context cache poisoning. In this article, we will describe this new bug class in depth. We will then\r\nexplore the strengths and weaknesses of the code changes that Microsoft has introduced in response.\r\nUnderstanding Activation Contexts\r\nTo begin, we must understand some of the basics of activation contexts.\r\nThere are various Windows APIs that a process can use to load additional components. The two most salient are\r\nLoadLibrary for the loading of DLLs, and CoCreateInstance for instantiation of COM components. For the purpose of\r\nthis discussion, we will focus primarily on LoadLibrary , but parallel considerations apply to CoCreateInstance . Also,\r\nwhat applies for LoadLibrary applies equally for implicit DLL loads via linkage.\r\nLoadLibrary may be called with either an absolute or a relative path, but in either case, ambiguity remains as to which\r\nversion of the requested DLL is appropriate to load. For example, even if an application specifically requests\r\nC:\\Windows\\System32\\comctl32.dll , there is no assurance that the comctl32.dll presently installed at that location on\r\nthe local machine is the version intended by the author of the application. This is one basic use-case for activation contexts.\r\nAn activation context is defined as state that Windows uses to resolve (“bind”) a component reference to the appropriate\r\ncomponent version. Every thread always has exactly one activation context in effect (“active”) at any given time. To resolve\r\na reference, Windows uses the currently active activation context.\r\nTo specify activation context data for a thread, code can use the Activation Context APIs. Much more commonly, though, an\r\nactivation context is specified declaratively by deploying a manifest. The manifest has the form of XML data. It is generally\r\nembedded as a resource in an EXE or DLL, though Windows will alternatively look for a .manifest file sibling to an EXE\r\nat launch.\r\nLet’s see a representative example of a manifest. The following manifest is found as a resource in notepad.exe on\r\nWindows 10 22H2 19045.2251 x64:\r\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?\u003e\r\n\u003c!-- Copyright (c) Microsoft Corporation --\u003e\r\n\u003cassembly xmlns=\"urn:schemas-microsoft-com:asm.v1\" manifestVersion=\"1.0\"\u003e\r\n\u003cassemblyIdentity\r\nname=\"Microsoft.Windows.Shell.notepad\"\r\nprocessorArchitecture=\"amd64\"\r\nversion=\"5.1.0.0\"\r\nhttps://www.thezdi.com/blog/2023/1/23/activation-context-cache-poisoning-exploiting-csrss-for-privilege-escalation\r\nPage 1 of 12\n\ntype=\"win32\"/\u003e\nWindows ShellPerMonitorV2 Figure 1: Manifest of notepad.exe\nThis manifest defines an activation context to be activated upon launch of notepad.exe . Note the element.\nIt declares that the stated assembly version ( Microsoft.Windows.Common-Controls , version 6.0.0.0 ) should be\nincorporated. That would be found within C:\\Windows\\WinSxS , the location for side-by-side assembly installations. After\nprobing, Windows will locate an acceptable match, having its own manifest at\nC:\\Windows\\WinSxS\\Manifests\\amd64_microsoft.windows.common-controls_6595b64144ccf1df_6.0.19041.1110_none_60b5254171f9507e.manifest :\nhttps://www.thezdi.com/blog/2023/1/23/activation-context-cache-poisoning-exploiting-csrss-for-privilege-escalation\nPage 2 of 12\n\n?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?\u003e\nToolbarWindow32ComboBoxEx32msctls_trackbar32msctls_updown32msctls_progress32msctls_hotkey32msctls_statusbar32SysHeader32SysListView32SysTreeView32SysTabControl32SysIPAddress32SysPagerNativeFontCtlButtonStaticListboxScrollBarSysLinktooltips_class32ButtonListBoxSysAnimate32SysMonthCal32SysDateTimePick32ReBarWindow32 https://www.thezdi.com/blog/2023/1/23/activation-context-cache-poisoning-exploiting-csrss-for-privilege-escalation\nPage 3 of 12\n\nEditComboboxComboLBoxDropDowniXKqUejv96Ddh9vG1w798vL5l6Ox+DrmzOqVtWULo24= Figure 2: Manifest of Microsoft.Windows.Common-Controls version 6.0.19041.1110 from WinSxS\nThe element\n\nIn sum, these manifests set up an activation context for notepad.exe , so that when notepad.exe loads comctl32.dll\r\n(whether through linkage, or through an explicit call to LoadLibrary ), the appropriate version of comctl32.dll will be\r\nlocated.\r\nThere is a great deal more to be discussed on the topic of activation contexts. The best all-in-one resource on the topic I have\r\nfound is the article here. The details presented above, though, should be sufficient for our present purposes.\r\nThe Activation Context Cache\r\nThe procedure of locating manifests, parsing them, and probing for their dependencies which themselves must be processed\r\nrecursively, is fairly intensive both in terms of computational steps and disk accesses. For this reason, Microsoft introduced\r\na caching mechanism. Naturally, for the cache to deliver a performance benefit, it must be capable of persisting beyond the\r\nlifetime of a single process, so that cached results can be reused. It is probably for this very reason that activation context\r\ncreation does not take place in-process but is instead delegated to the per-session CSRSS.EXE process. In the example\r\nabove, the notepad.exe process will start by making a cross-process call into CSRSS.EXE to create its activation context.\r\nCSRSS.EXE performs all the required probing steps and places the results into an in-memory activation context structure. It\r\npasses this structure back to the caller. When the notepad.exe process needs to load a module such as comctl32.dll , it\r\nrefers to this in-memory activation context structure to direct the library load correctly. In addition to returning the activation\r\ncontext structure to the caller, CSRSS.EXE keeps a copy in a cache. The cache comes into play the next time notepad.exe\r\nlaunches. Then, when calling into CSRSS.EXE to generate an activation context, CSRSS.EXE does not have to go through as\r\nmany steps to probe for on-disk manifests and parse them. Instead, it retrieves the activation context it previously stored in\r\nthe cache. To validate that the cached data is still valid, it needs only to check that the file modification time has not changed\r\nfor notepad.exe (though I am intentionally omitting some less-important details for simplicity).\r\nWithin each cache entry, CSRSS stores the executable’s file modification time, to make it possible to later determine if the\r\ncache entry is still valid, as I have just explained. It also stores the 128-bit FILE_ID_INFORMATION value generated by NTFS\r\nthat serves as a guaranteed unique identifier for the file. This serves to prevent canonicalization bugs, in which the same\r\ntextual path could resolve to two different files due to changes to symbolic links.\r\nAs happens all too often, though, and despite the above precautions, the introduction of caching is accompanied by major\r\nrisks.\r\nThe Danger of Cache Poisoning\r\nIf the cache contains incorrect data, the execution of any process using that data can be compromised. For example,\r\nincorrect (“poisoned”) data in the activation context cache might result in an arbitrary DLL being loaded into a privileged\r\nprocess, yielding privilege escalation.\r\nHow might the cache become poisoned? One problem with the architecture of activation contexts is that, while CSRSS.EXE\r\nperforms activation context generation and caching, it does so for the benefit of the client (caller) process. Whatever\r\nactivation context the client wishes to create, it is the job of CSRSS to create that context. I suppose it is for this reason that\r\nthe interface supported by CSRSS is rather permissive, allowing the client process to specify the exact manifest XML that\r\nwill be parsed. This makes perfect sense when CSRSS is thought of as a server acting on behalf of a client. But when\r\ncaching comes into the picture, this arrangement becomes toxic. The activation context generated from the arbitrary\r\nmanifest XML provided by the client becomes a semi-permanent part of the system’s functioning and later can affect\r\nexecution of a more highly privileged process.\r\nCVE-2022-22047: KNOTWEED Exploits Cache Poisoning\r\nThis is the approach that was taken by the exploit code found in the wild, originating from the KNOTWEED hacking group.\r\nThe exploit crafts a call into CSRSS. The call requests an activation context for a privileged executable and specifies a\r\nmalicious manifest. The manifest makes use of an undocumented manifest XML attribute named loadFrom . This attribute\r\nallows unrestricted redirection of DLLs to any location on disk, including locations outside of the normal search patch (the\r\nnormal search path being the executable’s folder and subfolders thereof, in addition to the shared assemblies installed to\r\nC:\\Windows\\WinSxS ):\r\nhttps://www.thezdi.com/blog/2023/1/23/activation-context-cache-poisoning-exploiting-csrss-for-privilege-escalation\r\nPage 5 of 12\n\nWindows Shell Figure 3: A malicious manifest of the sort used in the KNOTWEED exploit\nThe manifest shown in Figure 3 specifies that all requests to load library advapi32.dll should instead load\nc:\\repro\\payload.dll . After CSRSS.EXE creates the requested activation context, it enters it into the cache. Upon a\nsubsequent launch of the targeted executable, CSRSS.EXE provides the targeted process with the cached activation context.\nThus, when the privileged process attempts to load the advapi32.dll module it depends on, the attacker’s code will load\ninstead.\nTo conduct this attack, the attacker’s only prerequisite is the ability to write the payload.dll file somewhere within the\nfilesystem. To ensure the cache will be affected, the exploit code can first flood CSRSS with requests to clear out all\nexisting cache entries, and conclude with one final message to create a new poisoned entry for the targeted executable.\nNote that the attacker must choose a target that is highly privileged but runs in the same session as the interactive user\n(typically session 1, when there is only one interactive user). This is because there is one CSRSS.EXE process per session,\nand hence one activation context cache per session. The session-wide shared cache makes the attack possible.\nMicrosoft patched this as CVE-2022-22047 in the July 2022 patches, but the fix was extremely narrow. It addressed only the\nusage of the undocumented loadFrom attribute. After the patch, code in sxs.dll!CDllRedir::ContributorCallback ,\nwhich handles DLL redirections specified with loadFrom , sets a newly defined flag in the activation context indicating that\nthe activation context contains a DLL redirection. By checking this flag, CSRSS will now treat any such activation context\nas non-cacheable. The logic that controls which activation contexts are inserted into the cache is found in\nsxssrv.dll!BaseSrvSxsCreateActivationContextFromStructEx .\nThis patch was too narrow, however. Activation context cache poisoning can be accomplished in other ways besides using a\nloadFrom attribute, as we will now see.\nCVE-2022-37989: Bypassing the Patch for the KNOTWEED Exploit\nUpon examining the patch for the KNOTWEED exploit I realized that using loadFrom was probably not the only way to\nwrite a malicious manifest that injects arbitrary code into the target process. Indeed, I quickly found that I was able to write\na manifest that injected code via a different technique: declaring a dependent assembly that resides in an attacker-controlled\nportion of the filesystem:\n\nversion=\"1.0.0.0\"\nprocessorArchitecture=\"amd64\"\nlanguage=\"*\"\npublicKeyToken=\"6595b64144ccf1df\"\ntype=\"win32\"/\u003e\nFigure 4: A malicious manifest using a dependentAssembly element\nThe malicious manifest shown in Figure 4 leads CSRSS to load a second manifest for the named dependency, which it finds\nat the attacker-controlled location C:\\pwn\\pwn.MANIFEST :\n?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?\u003e\nFigure 5: Manifest for dependent assembly, stored at C:\\pwn\\pwn.MANIFEST\nHere, advapi32.dll is the name of a DLL needed by the target process. As a result of the combination of these two\nmanifests, when the target process loads advapi32.dll , the DLL will be loaded from the attacker-controlled location\nC:\\pwn\\ instead of the legitimate location C:\\Windows\\System32\\ . As before, local privilege escalation results when the\nhighly privileged target process launches within the current user’s session.\nMicrosoft patched this variant in October 2022 as CVE-2022-37989. The patch was analogous to the patch for the original\nKNOTWEED exploit. This time, the main code change was in\nsxs.dll!CNodeFactory::XMLParser_Element_doc_assembly_dependency_dependentAssembly_assemblyIdentity , which\nhandles the assemblyIdentity subelement of the dependentAssembly element. After the patch, the code in that function\nchecks if the name of the dependency contains any forward slashes or backslashes. If so, it sets another newly defined flag,\nmuch like the new flag introduced in the patch for CVE-2022-37989.\nsxssrv.dll!BaseSrvSxsCreateActivationContextFromStructEx recognizes activation contexts that have this flag set and\ndoes not enter them into the cache.\nIt’s dubious whether it was ever intended to allow the dependentAssembly element to contain directory traversal.\nNevertheless, Microsoft has decided to continue supporting this behavior, perhaps for the sake of backwards compatibility.\nAs a reasonable trade-off, they made activation contexts non-cacheable when they rely on this behavior.\nCVE-2022-37987: A New Vector for Activation Context Cache Poisoning\nhttps://www.thezdi.com/blog/2023/1/23/activation-context-cache-poisoning-exploiting-csrss-for-privilege-escalation\nPage 7 of 12\n\nThe two attacks discussed above both work by crafting messages to CSRSS to create a customized, malicious activation\r\ncontext that differs from the legitimate activation context that would normally be created by reading the manifest XML from\r\ndisk. It is surprising that CSRSS was architected to accept such sensitive data from untrusted clients. As I mentioned earlier,\r\nthis might be thought of as a reasonable design if you view CSRSS as merely providing a service to a client. From that\r\nperspective, the client should be able to specify whatever activation context details it wishes. The problem arises due to\r\ncaching: crafted data from an untrusted process can affect not only that client, but also other clients that consult CSRSS\r\nafterwards.\r\nAs it happens, though, there is a completely separate vector for injecting arbitrary activation context data into CSRSS , one\r\nthat has nothing at all to do with the interface that CSRSS exposes.\r\nThe trouble arises because CSRSS.EXE performs many of its filesystem accesses while impersonating the caller. I believe\r\nthis is unavoidable, because CSRSS needs to generate an accurate activation context based upon how the caller would view\r\nthe filesystem.\r\nWhat is not so widely appreciated, however, is how vastly different a filesystem can appear when operating under\r\nimpersonation. In particular: An unprivileged process can redirect a DOS device by creating an object namespace symlink.\r\nFor example, if a process creates a symlink from \\??\\C: to \\GLOBAL??\\C:\\evil , then all accesses to the filesystem rooted\r\nat C:\\ are instead redirected to the root C:\\evil . The redirection is not limited to the process that creates the symlink.\r\nRather, it affects the entire logon session. (The concept of “logon session” is unrelated to the concept of Windows sessions.\r\nSee here and here for an explanation of logon sessions.) Not only that, but if a more highly privileged process impersonates\r\na token for which the symlink is active, the privileged process sees the bogus filesystem as well. This is true even if the\r\nprivileged process is in a different Windows session, for example, session 0.\r\nIf that spooks you, it should. James Forshaw discovered back in 2015 that it creates a massive security hole. Any time a\r\nprivileged process impersonates a user, and the privileged process loads a library (or can be influenced to load a library)\r\nwhile that impersonation is ongoing, that privileged process can be completely compromised. All an attacker needs to do is\r\nredirect C:\\ to a bogus location where the privileged process will pick up a malicious version of the requested library.\r\nTo fix this security hole, Microsoft was compelled to add a new object attribute flag recognized by NtOpenFile (and\r\nsimilar APIs) instructing the kernel to ignore any DOS device redirections originating from the impersonation token.\r\nUltimately, Microsoft publicly documented this flag as OBJ_IGNORE_IMPERSONATED_DEVICEMAP . You can find its use in the\r\nloader code in this excerpt from ntdll!LdrpMapDllNtFileName ( ntdll.dll 10.0.19041.2130, Oct. 2022 patch level):\r\nattributes = OBJ_CASE_INSENSITIVE;\r\nObjectAttributes.Length = 48;\r\nif ( !LdrpUseImpersonatedDeviceMap ) // Note how Microsoft left legacy\r\n// vulnerable behavior available\r\n// via configuration\r\nattributes = OBJ_IGNORE_IMPERSONATED_DEVICEMAP|OBJ_CASE_INSENSITIVE;\r\nObjectAttributes.RootDirectory = 0i64;\r\nObjectAttributes.Attributes = attributes;\r\nObjectAttributes.ObjectName = a2;\r\n*(_OWORD *)\u0026ObjectAttributes.SecurityDescriptor = 0i64;\r\n...\r\nntStatus = NtOpenFile(\r\n\u0026FileHandle,\r\nhttps://www.thezdi.com/blog/2023/1/23/activation-context-cache-poisoning-exploiting-csrss-for-privilege-escalation\r\nPage 8 of 12\n\nSYNCHRONIZE|FILE_TRAVERSE|FILE_LIST_DIRECTORY,\n\u0026ObjectAttributes,\n\u0026IoStatusBlock,\nFILE_SHARE_DELETE|FILE_SHARE_READ,\nFILE_NON_DIRECTORY_FILE|FILE_SYNCHRONOUS_IO_NONALERT);\nFigure 6: Excerpt from ntdll!LdrpMapDllNtFileName showing patch for CVE-2015-1644\nBy contrast, CSRSS prior to the December 2022 patch level still did not make use of the\nOBJ_IGNORE_IMPERSONATED_DEVICEMAP flag. Thus, those filesystem operations CSRSS performs under impersonation were\nstill vulnerable to manipulation by an attacker who establishes a DOS device redirection.\nWe can exploit this behavior by establishing a redirection for the C:\\ device while CSRSS is performing probing\noperations. The redirection will lead CSRSS into a bogus C:\\Windows\\WinSxS\\ folder, where we can place crafted\nmanifests. CSRSS will cache the activation context created from a crafted manifest, and local privilege escalation can then\nproceed in the same way as in the other attacks described above.\nFor example, suppose we create a fake root at C:\\ActCtX\\ . (The name ActCtX is arbitrary.) Within C:\\ActCtX we can\nplace a fake Windows\\WinSxS folder, containing a crafted copy of the side-by-side assembly Microsoft.Windows.GdiPlus .\nThe malicious copy is identical to the original except for the addition of one dependency within the manifest:\n?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?\u003e\n...\nFigure 7: Crafted manifest to be dropped to\nC:\\ActCtX\\Windows\\WinSxS\\Manifests\\amd64_microsoft.windows.gdiplus_6595b64144ccf1df_1.1.19041.1706_none_919e8e54cc8d4ca1.m\nThis tricks CSRSS into thinking that Microsoft.Windows.GdiPlus has a dependency on an assembly named ActCtX ,\nlocated at the filesystem root. Since it will be looking for that assembly, we’ll need to put one there:\n?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?\u003e\nhttps://www.thezdi.com/blog/2023/1/23/activation-context-cache-poisoning-exploiting-csrss-for-privilege-escalation\nPage 9 of 12\n\nFigure 8: Manifest for fake dependent assembly, to be dropped to C:\\ActCtX\\ActCtX\\ActCtX.MANIFEST\nNote that we drop this manifest to C:\\ActCtX\\ActCtX\\ActCtX.MANIFEST , with an extra folder named ActCtX in the path.\nThis compensates for the fact that CSRSS will access this manifest while the DOS device redirection is in effect. Credit to\nOliver Lyak (@ly4k_) for working out the details of the required folder structure.\nThe overall effect of these manifests is that CSRSS will generate an activation context specifying that any load of\nadvapi32.dll should be loaded from the attacker-controlled location C:\\ActCtX\\advapi32.dll . CSRSS will cache this\nactivation context. When the cached activation context is reused for a privileged process in the same session, a load of DLL\nadvapi32.dll will instead load attacker code into the process, thus achieving privilege escalation to NT\nAUTHORITY\\SYSTEM .\nMicrosoft patched this in October 2022 as CVE-2022-37987. The patch consists of a change to\nsxssrv.dll!BaseSrvSxsCreateActivationContextFromMessage . In that function, the code retrieves the\nFILE_ID_INFORMATION of the EXE or DLL file for which CSRSS is creating the activation context. This value becomes part\nof the cache key. We mentioned earlier why this is an important precaution for ensuring that an activation context created for\none executable is not later retrieved from cache and applied to a different executable. Prior to the patch, the\nNtQueryInformationFile operation that retrieves the FILE_ID_INFORMATION value was not performed under\nimpersonation. Therefore, when an attacker would create a cache entry for, e.g.,\nC:\\Windows\\System32\\SomePrivilegedExecutable.exe , even if the attacker had redirected C:\\ to C:\\evil , the resulting\ncache entry would apply to the legitimate C:\\Windows\\System32\\SomePrivilegedExecutable.exe as opposed to\nC:\\evil\\Windows\\System32\\SomePrivilegedExecutable.exe . The latter would be useless to an attacker, because\nC:\\evil\\Windows\\System32\\SomePrivilegedExecutable.exe is not an executable that would ever be launched as a\nprivileged process. Microsoft’s patch was to add impersonation during the call to retrieve the FILE_ID_INFORMATION . The\nintention of this change, apparently, was so that any activation context generated during a DOS device redirection would\napply only to a spoofed file and never to the legitimate one.\nAs soon as I examined this patch, I was quite skeptical of its effectiveness, and after further analysis and experimentation I\nconcluded that my skepticism was warranted. Unfortunately, the patch accomplishes nothing. An attacker can bypass it just\nby removing the DOS device redirection for the duration of the NtQueryInformationFile operation and putting the DOS\ndevice redirection back in place immediately thereafter. With this adjustment, everything can be made to work again in the\nexact way it worked prior to the patch. I additionally found that an attacker can reliably determine the precise time to revert\nand reestablish the redirection by using an oplock.\nNevertheless, there is no reason to panic. First it should be noted that in December 2022, Microsoft augmented their patch\nfor CVE-2022-37987 by adding in use of the OBJ_IGNORE_IMPERSONATED_DEVICEMAP flag during manifest probing.\nFurthermore, although the original patch for CVE-2022-37987 was easily bypassed, that did not necessarily mean it was\npossible to make the attack work again. The reason is that the attack shown here relies on directory traversal within a\ndependentAssembly element, and that technique was effectively blocked by the patch for CVE-2022-37989 discussed\nearlier. You could instead request a DLL redirection with a loadFrom attribute, but then you would be blocked similarly by\nthe CVE-2022-22047 patch. Other manifest features could be tried, but at this time I don’t see any obvious paths to arbitrary\ncode execution. One could specify a COM class redirection, via a comClass element, to cause an unexpected DLL to be\nloaded into a privileged process, but one would be limited to DLLs already existing in a secure location (e.g., System32 ).\nThis would cause a failure within the privileged process, but exploitation for arbitrary code execution remains extremely\ndifficult. Determining whether any potentially hazardous features of manifest files remain unpatched is an interesting open\nresearch question.\nhttps://www.thezdi.com/blog/2023/1/23/activation-context-cache-poisoning-exploiting-csrss-for-privilege-escalation\nPage 10 of 12\n\nThere is an additional reason the threat of local privilege escalation using activation context cache poisoning is now greatly\r\nreduced: Microsoft has introduced a general mitigation.\r\nMitigating the Threat from Activation Context Cache Poisoning\r\nIn addition to the specific July 2022, October and December 2022 patches described above, Microsoft wisely added a\r\ngeneral mitigation in October 2022.\r\nAs of the October 2022 patch, an integrity level value is now stored together with each cache entry. For example, an\r\nordinary non-privileged process running within an interactive session has an integrity level of Medium (decimal 8192, hex\r\n0x2000). If this process calls into CSRSS to create an activation context, and CSRSS creates a new corresponding cache\r\nentry, the cache entry will be tagged with 0x2000 (Medium) as its integrity level. Subsequently, if another process running at\r\nMedium or lower integrity calls into CSRSS to create an activation context for the same executable, CSRSS will satisfy the\r\nrequest from the cache. By contrast, if a process running at an integrity level higher than Medium makes such a request,\r\nCSRSS will treat it as a cache miss. In this event, CSRSS will create an activation context from scratch and evict the\r\nexisting cache entry, replacing it with the new one bearing the higher integrity label. This logic is found in\r\nsxssrv!BaseSrvSxsCreateActivationContextFromStructEx .\r\nThis mitigation is highly beneficial. It enormously reduces the range of scenarios where the cache might be a means of\r\nprivilege escalation. For example, in the KNOTWORM attack and all variations described above, a process running as\r\nMedium creates a malicious cache entry, to be picked up later by a process running as NT AUTHORITY\\SYSTEM within the\r\nuser’s session. As far as I am aware, in a generic install of Windows, all processes that launch as NT AUTHORITY\\SYSTEM\r\nwithin an interactive session have an integrity level of System (decimal 16384, hex 0x4000). So, thanks to this mitigation,\r\nwhen it comes time for the cache entry to be retrieved for use by the privileged process, CSRSS will discard the lower-integrity entry, so that the privileged process will remain completely unaffected by it.\r\nThis mitigation is not a panacea. Activation context cache poisoning remains a viable attack technique, but only in a much-reduced set of circumstances. Recall that there is one CSRSS.EXE process per session, so by nature, the cache is per-session.\r\nAdd to this the restriction imposed by the mitigation, that a cache entry created by a lower-integrity process will never be\r\npicked up by a higher-integrity process. There remains a small subset of privilege escalation scenarios that skirt these\r\nrestrictions. I will give two examples:\r\n• The Dnscache (also known as “DNS Client”) service process runs as NETWORK SERVICE , but SeImpersonatePrivilege\r\nhas been removed from its token. Technically, this makes Dnscache a low-privileged process. If an attacker compromises\r\nthis process, it is ordinarily not trivial to escalate to NT AUTHORITY\\SYSTEM . Nevertheless, since the process runs with\r\nSystem integrity (not to be confused with NT AUTHORITY\\SYSTEM ), and its session is session 0, malicious code running\r\nwithin Dnscache could poison the activation context cache to compromise any service running in session 0 as NT\r\nAUTHORITY\\SYSTEM . Note, though, that to complete the privilege escalation, it would also be necessary to find an unpatched\r\nmanifest feature, as discussed earlier.\r\n• dwm.exe is a process that runs in each interactive session. It runs as the interactive user, but with System integrity.\r\nTherefore, an attacker who achieves code execution in dwm.exe would be in a position to create a cache entry with System\r\nintegrity level that would be picked up by highly privileged processes that also run within the interactive session, just as in\r\nthe original KNOTWEED attack. Notably, there has been a report of probable compromise of dwm.exe used by an exploit\r\nchain in the wild, though since that report predates the cache mitigation, the attacker in that case must have had a different\r\naim in compromising dwm.exe . Again, to complete the privilege escalation, an unpatched manifest feature must be found.\r\nConclusion\r\nWe have taken the wraps off a new bug class in Microsoft Windows, which we call activation context cache poisoning.\r\nSuccessful exploitation generally results in privilege escalation, as achieved in the wild by the KNOTWEED group. The\r\nvulnerabilities recently disclosed as the “CSRSS” vulnerabilities all fall into this new bug class. Though Microsoft has now\r\nreleased a general mitigation, corner cases remain that fall outside the mitigation’s scope. It remains an open research\r\nquestion whether Microsoft’s specific patches for the known vulnerabilities are sufficient to make activation contexts safely\r\ncacheable across processes.\r\nhttps://www.thezdi.com/blog/2023/1/23/activation-context-cache-poisoning-exploiting-csrss-for-privilege-escalation\r\nPage 11 of 12\n\nFollow us on Twitter, Mastodon, LinkedIn, or Instagram for the latest updates from the ZDI and any new developments we\r\nmay find in this new bug class. \r\nSource: https://www.thezdi.com/blog/2023/1/23/activation-context-cache-poisoning-exploiting-csrss-for-privilege-escalation\r\nhttps://www.thezdi.com/blog/2023/1/23/activation-context-cache-poisoning-exploiting-csrss-for-privilege-escalation\r\nPage 12 of 12",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"MISPGALAXY",
		"Malpedia"
	],
	"references": [
		"https://www.thezdi.com/blog/2023/1/23/activation-context-cache-poisoning-exploiting-csrss-for-privilege-escalation"
	],
	"report_names": [
		"activation-context-cache-poisoning-exploiting-csrss-for-privilege-escalation"
	],
	"threat_actors": [],
	"ts_created_at": 1775434868,
	"ts_updated_at": 1775791312,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/03e87f96266a5db1b289708921d7f8aae117f4ee.pdf",
		"text": "https://archive.orkl.eu/03e87f96266a5db1b289708921d7f8aae117f4ee.txt",
		"img": "https://archive.orkl.eu/03e87f96266a5db1b289708921d7f8aae117f4ee.jpg"
	}
}