Shim Shady Part 2

Technical Details

The structure and location of the Application Compatibility Cache is Operating System and platform dependent. This section provides the details of the structures across all Operating System versions and platforms since Windows XP. It also includes an overview of the algorithms implemented in the ShimCacheMem Volatility plugin to parse the cache.

Windows XP x32

On 32-bit versions of Windows XP, the cache is stored within a shared memory object in kernel32.dll, named ShimSharedMemory. The process winlogon.exe creates this section object during the boot process, and all user processes have a handle to the object. The cache itself is maintained by API functions exported by kernel32.dll and serialized access to this shared memory object is controlled using the ShimCacheMutex mutex.

The cache contains a 400-byte header that begins with the magic value 0xDEADBEEF. The header contains the current number of entries as well as indexes used by the cache manager. Each of the entry structures contains the full path of the executed file (Path), the last modified time of the file (ftLastModTime), the file size (qwFileSize), and the time the entry was last updated (ftLastUpdateTime). The last update time may indicate the last time that the file was executed on the system.

Figure 9 provides the structure of Application Compatibility Cache entries found on 32-bit Windows XP systems. The cache will contain up to 96 entries, where each entry is 552 bytes in size.

Figure 9: Windows XP x86 in-memory Shim Cache Entry

To parse the Windows XP x32 Application Compatibility Cache, the ShimCacheMem Volatility plugin implements the following algorithm:

  1. Find a handle to the ShimSharedMemory section object from any process

  2. Using the section object handle, identify the following:
    • The process that contains the Application Compatibility Cache (winlogon.exe)
    • The virtual offset in winlogon.exe where the cache begins
  3. Obtain the process memory space of winlogon.exe and identify the Virtual Address Descriptor (VAD) node corresponding to the virtual offset of the cache
  4. Traverse through the cache entries using the order specified in the cache header

Windows XP (x64) and Windows Server 2003 through Windows 7

Starting with Windows XP x64 and Windows Server 2003, the Application Compatibility Cache is located in the .data section of the ntoskrnl.exe module. Figure 10 provides the data structure representing the Application Compatibility Cache.

Figure 10: In-memory Shim Cache data structure

The Application Compatibility Cache is implemented as an AVL tree, of RTL_AVL_TABLE type, where the cache entries are stored in a least-recently used (LRU) circular double-linked list.  The first node of the LRUList, of LIST_ENTRY type, immediately follows the RTL_AVL_TABLE data structure.

The Cache AVL tree is always preceded by an ERESOURCE data structure; due to platform alignment, several padding bytes are inserted between the ERESOURCE and RTL_AVL_TABLE data structures. The number of padding bytes is based on the platform, where 0x8 bytes are added on x86 platforms and 0x18 bytes are added on x64 platforms. The ERESOURCE data structures are used by drivers to implement exclusive/shared synchronization; to read the cache entries in the AVL tree, the driver needs to acquire the resource exclusively with a call to ExAcquireResourceExclusiveLite.

Figure 11 provides an example of the INNER_SHIM_CACHE data structure representing the Application Compatibility Cache under Windows 7 x86.

Figure 11: Windows 7 x86 in-memory Shim Cache

Figure 12 provides an example of the INNER_SHIM_CACHE data structure representing the Application Compatibility Cache under Windows 7 x64.

Figure 12: Windows 7 x64 in-memory Shim Cache

To parse the Application Compatibility Cache on Windows XP x64 and Windows Server 2003 through Windows 7, the ShimCacheMem Volatility plugin implements the following algorithm:

  1. Obtain the offset and size of the .data and PAGE sections of the ntoskrnl.exe module

  2. Scan the .data section for valid RTL_AVL_TABLE data structures
    • Several conditions are checked to validate potential RTL_AVL_TABLE data structures, including confirming that the structure’s function pointers point to offsets on the same memory page (hence the need for the PAGE section offset obtained previously)
  3. For each potential RTL_AVL_TABLE data structure, check if the structure is preceded by a valid ERESOURCE data structure and followed by a LIST_ENTRY data structure
    • Several conditions are checked to validate potential ERESOURCE and  LIST_ENTRY data structures, including confirming that the structures’ linked list pointers (Flink and Blink) point to other entries in the list
  4. If all conditions are met, traverse the LIST_ENTRY data structure to capture each Application Compatibility cache entry

The structure of entries in the Application Compatibility Cache varies between Windows 2003, Windows Vista, and Windows 7 Operating Systems. The remainder of this section describes the structures on each platform.

Cache Entry Structure (Windows Server 2003)

Under Windows Server 2003, the Application Compatibility Cache entry contains the full path of the application needed to be shimmed (usKey), the last modified timestamp (ftLastModTime) and the size (ulFileSize) of file specified in usKey.

Figure 13 provides the structure of the x86 Application Compatibility Cache Entry.

Figure 13: Windows 2003 x86 Shim Cache Entry

Figure 14 provides the structure of the x64 Application Compatibility Cache Entry.

Figure 14: Windows 2003 x64 Shim Cache Entry

Cache Entry Structure (Windows Vista/Windows Server 2008)

Under Windows Vista and Windows Server 2008, the Application Compatibility Cache entry contains the full path of the application needed to be shimmed (usKey), the last modified timestamp (ftLastModTime) and flags (dwInsertFlags and dwShimFlags).

Figure 15 provides the structure of the x86 Application Compatibility Cache Entry.

Figure 15: Windows Vista x86 Shim Cache Entry

Figure 16 provides the structure of the x86 Application Compatibility Cache Entry.

Figure 16: Windows Vista x64 Shim Cache Entry

Cache Entry Structure (Windows 7/Windows Server 2008 R2)

Under Windows 7 and Windows Server 2008 R2, the Application Compatibility Cache entry contains the full path of the application needed to be shimmed (usKey), the last modified timestamp (ftLastModTime), flags (dwInsertFlags and dwShimFlags) and an opaque data blob (ulBlobSize and pBlob).

Figure 17 provides the structure of the x86 Application Compatibility Cache Entry.

Figure 17: Windows 7 x86 Shim Cache Entry

Figure 18 provides the structure of the x64 Application Compatibility Cache Entry.

Figure 18: Windows 7 x64 Shim Cache Entry

Figure 19 shows an example of a Windows 7 x86 of a parsed Application Compatibility Cache Entry.

Figure 19: Parsed Shim Cache Entry (Windows 7 x86)

Windows 8 through Windows 10

Starting in Windows 8, the Application Compatibility Cache is accessed through the AhcCacheHandle global variable. In Windows 8 and Windows Server 2012, the AhcCacheHandle is found in the .data section of the ntoskrnl.exe module. From Windows 8.1 on, the Application Compatibility Cache functionality was moved to the ahcache.sys driver, thus the handle is found in the .data section of the previously mentioned driver.

The Application Compatibility Cache data is implemented as an AVL tree, of RTL_AVL_TABLE type, where the entries of the cache are stored in a least-recently used (LRU) circular double-linked list.  The first node of the LRU list, of LIST_ENTRY type, immediately follows the RTL_AVL_TABLE data structure. Unlike prior Operating System versions, the RTL_AVL_TABLE data structure is no longer preceded by the ERESOURCE data structure.

The AhcCacheHandle points to a memory location with a structure described in Figure 20:

Figure 20: Memory pointed by the AhcCacheHandle structure

Both the ERESOURCE and RTL_AVL_TABLE data structures are preceded by an Operating System dependent signature. Figure 20 provides an example of the RTL_AVL_TABLE data structure representing the Application Compatibility Cache under Windows 8 x86.

Figure 21: Windows 8 x86 Shim Cache Tree

Figure 22 provides an example of the RTL_AVL_TABLE data structure representing the Application Compatibility Cache under Windows 10 x64.

Figure 22: Windows 10 x64 Shim Cache Tree

To parse the Application Compatibility Cache on Windows 8 and later, the ShimCacheMem Volatility plugin implements the following algorithm:

  1. Obtain the offset and size of the .data and PAGE sections of the ntoskrnl.exe module (Windows 8) or the ahcache.sys driver (Windows 8.1 onwards)

  2. Scan the .data section for a valid AhcCacheHandle data structure which consists of a pointer to an ERESOURCE data structure followed by a pointer to an RTL_AVL_TABLE data structure
    • For both data structures, dereference the pointers and validate the structures in the same manner described for prior Operating Systems
  3. For each potential RTL_AVL_TABLE data structure, check if the structure is followed by a valid LIST_ENTRY data structure

  4. Traverse the LIST_ENTRY data structure to capture each Application Compatibility cache entry

The structure of entries in the Application Compatibility Cache varies between Windows 8 and Windows 8.1 Operating Systems. The remainder of this section describes the structures on each platform.

Cache Entry Structure (Windows 8 / Windows Server 2012)

The AhcCacheHandle is located in the .data section of the ntoskrnl.exe module. Both the ERESOURCE and RTL_AVL_TABLE data structures are preceded by the ASCII signature  Ahca. The Application Compatibility Cache Entry contains the full path of the application needed to be shimmed (usKey), the last modified timestamp (ftLastModTime), flags (dwInsertFlags and dwShimFlags) and an opaque data blob (ulBlobSize and pBlob).

Figure 23 provides the structure of the x86 Application Compatibility Cache Entry.

Figure 23: Windows 8 x86 Shim Cache Entry

Figure 24 provides the structure of the x64 Application Compatibility Cache Entry.

Figure 24: Windows 8 x64 Shim Cache Entry

Cache Entry Structure (Windows 8.1 / Windows Server 2012 R2)

The AhcCacheHandle is located in the .data section of the ahcache.sys module. Both the ERESOURCE and RTL_AVL_TABLE data structures are preceded by the ASCII signature Ahca. The Application Compatibility Cache entry contains the full path of the application needed to be shimmed (usKey), the last modified timestamp (ftLastModTime), flags (dwInsertFlags and dwShimFlags) and an opaque data blob (ulBlobSize and pBlob).

Figure 25 provides the structure of the x86 Application Compatibility Cache Entry.

Figure 25: Windows 8.1 x86 Shim Cache Entry

Figure 26 provides the structure of the x86 Application Compatibility Cache Entry.

Figure 26: Windows 8.1 x64 Shim Cache Entry

Cache Entry Structure (Windows 10)

The AhcCacheHandle is located in the .data section of the ahcache.sys module. Both the ERESOURCE and RTL_AVL_TABLE data structures are preceded by the ASCII signature APpt. The Application Compatibility Cache entry contains the full path of the application needed to be shimmed (usKey) and the last modified timestamp (ftLastModTime).

Figure 27 provides the structure of the x86 Application Compatibility Cache Entry.

Figure 27: Windows 10 x86 Shim Cache Entry

Figure 28 provides the structure of the x86 Application Compatibility Cache Entry.

Figure 28: Windows 10 x64 Shim Cache Entry

 

Figure 29 provides an example of a parsed Application Compatibility Cache Entry for Windows 10 x64.

Figure 29: Parsed Shim Cache Entry (Windows 10 x64)

Conclusion

The Application Compatibility Cache provides valuable evidence of file execution. However, because the cache is only serialized to the registry when the system is shutdown or restarted, existing tools do not provide investigators access to the most recent cache data. The current solution is to reboot systems, which in many situations is not desirable (or even possible). By acquiring a memory image and using the ShimCacheMem Volatility plugin, investigators now have the ability to obtain the most up-to-date view of the cache regardless of when a system was last rebooted.

[1] https://msdn.microsoft.com/en-us/library/windows/desktop/ms724284(v=vs.85).aspx
[2] https://msdn.microsoft.com/en-us/library/windows/desktop/aa383713(v=vs.85).aspx
[3] https://msdn.microsoft.com/en-us/library/windows/hardware/ff544351(v=vs.85).aspx
[4] https://msdn.microsoft.com/en-us/library/windows/hardware/Ff553327(v=VS.85).aspx
[5] https://msdn.microsoft.com/en-us/library/windows/hardware/ff554296(v=vs.85).aspx
[6] https://msdn.microsoft.com/en-us/library/windows/desktop/aa380518(v=vs.85).aspx
[7] https://msdn.microsoft.com/en-us/library/windows/hardware/ff544351(v=vs.85).aspx
[8] https://msdn.microsoft.com/en-us/library/windows/hardware/Ff553327(v=VS.85).aspx