{
	"id": "e27a1e6a-9f42-426b-9e21-89f6880f97cc",
	"created_at": "2026-04-06T00:07:19.085706Z",
	"updated_at": "2026-04-10T03:23:52.299349Z",
	"deleted_at": null,
	"sha1_hash": "ca0140dd8dba33e7a4c3f4061b589aeb2e4273ee",
	"title": "Memory Forensics R\u0026D Illustrated: Detecting Mimikatz's Skeleton Key Attack",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 1464201,
	"plain_text": "Memory Forensics R\u0026D Illustrated: Detecting Mimikatz's\r\nSkeleton Key Attack\r\nArchived: 2026-04-05 19:11:46 UTC\r\nNow that we understand how Mimikatz implements its attack—forcing a downgrade to RC4 followed by hooking\r\nthe RC4 initialization and decryption routines—we can devise a strategy to detect the attack in memory.\r\nWe could start by attempting to detect the RC4 downgrade, but this has a few limitations. First, the string needed\r\nto find this data structure (Kerberos-Newer-Keys) is zeroed out as part of the attack, removing the possibility of a\r\nscanning-based approach to finding it. Second, attempting to detect that this string has been zeroed out would lead\r\nto many false positives due to paging of data out to disk, as well as the possibility of the page holding the string\r\nbeing smeared. Third, there are other methods to force a downgrade to RC4 without directly altering this string (as\r\ndiscussed in earlier references), meaning several approaches would be needed to completely detect it. Finally,\r\nfinding proof of the downgrade only gives a clue that a Skeleton Key attack might have been performed, but it\r\ndoes not offer direct evidence. \r\nOn the other hand, by examining the RC4 data structure directly, we can inspect the handlers for the initialization\r\nand decryption routines and determine if they were altered at runtime. This not only definitively tells us if a\r\nSkeleton Key attack occurred, but it also tells us exactly where the malicious handlers are inside of the infected\r\nlsass.exe process. Given that this approach gives direct evidence of the attack, as well as directly points out the\r\nmalicious code, inspecting these handlers was chosen as the detection method for our plugin.\r\nAs seen above, the function is pretty small and simple. It begins (the first instruction of CDLocateCSystem in the\r\ndisassembly view) by copying the current value of cCSystems global variable into the r8d register, which is an\r\nalias for the lower 32 bits of 64-bit r8 register. It then tests (CDLocateCSystem+22) if the value is zero and bails\r\nwith an error (+27) if it is. If the value is anything but zero, then it moves to basic block, starting at offset +9. This\r\nbasic block begins by decrementing the r8d register (+9). This code pattern of storing a variable, checking if it is\r\nzero, and then decrementing the value tells us that this is likely a counter for looping (iterating) through a data\r\nstructure. Looking ahead, the red line leading from +20 back to +22 in the graph confirms this, as the code at +22\r\nwill be evaluated every time the basic block starting at +9 fails to exit. This is exactly how loops look in IDA Pro\r\nand other basic block graphing tools. \r\nFurther studying the basic block starting at +9, we see the address of the CSystems global variable copied into the\r\nr9 register. Next (+13), the value in r8d is copied into eax, and then rax is shifted left by 7\r\n(+16), which is the same thing as being multiplied by 128 (2 to the 7th power). This computed value is then stored\r\ninto r9, and the data r9 points to is compared with the value in ecx (+1D). If this comparison matches, then the\r\nfunction returns. Otherwise, the flow starting at +9 repeats. \r\nBreaking this down, the code is using the current value of r8d multiplied by 128 (shifted left by 7) as an index into\r\nCSystems. This is exactly what iterating through an array looks like. As each array element is stored contiguously\r\nhttps://volatility-labs.blogspot.com/2021/10/memory-forensics-r-illustrated.html\r\nPage 1 of 14\n\nin memory, by knowing the size and count, you can successfully locate each element. This understanding of the\r\ncode now tells us two things: \r\n1. cCSystems holds the number of elements in CSystems. \r\n2. The size of each CSystems element is 128 bytes.\r\nFor the basic block at +9, the only remaining parts to understand are which values are being compared at +1D and\r\nthe purpose of that comparison. Since the loop breaks dependent on that comparison, it is likely critical to the\r\nfunction’s overall purpose. Looking at the two values, [r9] and ecx, we know a few things. First, the comparison\r\nwill be comparing two 32-bit values, as that is the size of ecx, which is the lower 32 bits of rcx. Second, the\r\nbrackets around r9 mean to treat the value of r9 as an address in memory and then retrieve the value at that\r\naddress, which is known as dereferencing an address (pointer). From our previous discussion, we know that r9\r\nholds the address of the current CSystems element being inspected. Dereferencing it as [r9] is equivalent to\r\ndereferencing [r9+0], which tells us that the first 4 bytes (32 bits) of the referenced structure are being accessed. \r\nAs for ecx, the instruction at +1D is the first time ecx (or any of rcx) is referenced. This means the value must\r\nhave been set before the function was called. Consulting the Microsoft documentation on function-calling\r\nconventions, we see that the rcx register is used on 64-bit systems to store the first parameter sent to a function.\r\nEarlier, when we examined how Mimikatz called CDLocateCSystem, we noted that the first argument was the\r\nKERB_ETYPE_RC4_HMAC_NT constant, which is defined in NTSecAPI.h of the Windows SDK as 0x17 hex (23\r\ndecimal). This means that CDLocateCSystem will be searching for an element of CSystems that has 0x17 (23) as\r\nthe first integer. \r\nLooking at the end of the function (+2E -\u003e +33), we see that r9 is stored into the address pointed to by rdx; the\r\nprevious Microsoft documentation tells us rdx stores the second parameter to a function. We know for\r\nCDLocateCSystem that this is the address of where the calling code (Mimikatz) wants Windows to store the\r\naddress of the requested authentication system (RC4).\r\nSeeing that the address of the CSystems element found in the loop is directly returned to the caller tells us that the\r\ndata structure returned is also of type _KERB_ECRYPT, since we know that is the type of the second parameter to\r\nCDLocateCSystem. This then tells us that the integer at offset 0, that is compared in the loop, is actually the\r\nEncryptionType member of structure. This makes sense, since it holds the integer value for the particular\r\nauthentication system type. It also means that the elements in CSystems are the ones actually used by Windows\r\nduring the authentication process, since these are the ones directly targeted by Skeleton Key attacks.\r\nIn summary, reverse engineering has showed us that the active RC4 authentication system structure can be located\r\nby enumerating CSystems and then looking for the element that has an EncryptionType of 0x17 (23). This\r\nprecisely matches how CDLocateCSystem uses its first parameter to determine which element of the CSystems\r\narray to return to the caller. It also tells us that the type of each element is KERB_ECRYPT, which is very handy\r\nsince we already have the definition for this type.\r\nReverse Engineering the RC4 Structure Origin\r\nAfter learning how CDLocateCSystem operated, the next analysis step taken was to determine if the RC4 structure\r\ninside the CSystems array could be found directly. While enumerating the array is not difficult nor time\r\nhttps://volatility-labs.blogspot.com/2021/10/memory-forensics-r-illustrated.html\r\nPage 2 of 14\n\nconsuming, in memory forensics research we aim to find the most direct path to data to avoid analysis issues that\r\ncan be caused by smear. \r\nTo begin this analysis, we wanted to determine how elements of CSystems were registered, with particular interest\r\nin the RC4 system. Examining cross-references (meaning, finding code that references), CSystems showed only a\r\nfew locations inside of cryptdll.dll. Of these, the CDRegisterCSystem function sounded the most promising, as it\r\nwould hopefully lead us to RC4 being registered. \r\nThe following image shows the decompiled view of this function:\r\nAs can be seen, this is a pretty simple function that first (line 6) checks against the maximum number of registered\r\nsystems (0x18), and then bails if already at the maximum. Next, the function determines the offset into CSystems\r\n(line 9) by using cCSystems shifted by 7. This matches our understanding of cCSystems and the shifting by 7 from\r\nearlier. The function then simply copies in the values from the passed in data structure (a1) into the correct offsets\r\nof CSystems. In summary, whatever values are in the system being registered are copied separately inside of\r\nCSystems, duplicating them in memory.\r\nFollowing cross-references to CDRegisterCSystem leads us to many references inside of LibAttach; a decompiled\r\nview is shown below:\r\nhttps://volatility-labs.blogspot.com/2021/10/memory-forensics-r-illustrated.html\r\nPage 3 of 14\n\nThis function is exactly what we were looking for, as we can see all the different systems being registered. We\r\nalso see our system of interest, csRC4_HMAC, being registered on line 5. If we examine the data at this address,\r\nwe can verify this with seeing 0x17 (23) as the first integer. We learned earlier that this is the EncryptionType\r\ntargeted by Mimikatz.\r\nhttps://volatility-labs.blogspot.com/2021/10/memory-forensics-r-illustrated.html\r\nPage 4 of 14\n\nAs seen above, not only is the 0x17 (23) present at the first offset, but a little further down we also see the string\r\ndefined for the system (RSADSI RC4-HMAC), as well as the handlers for events the system must support. Looking\r\nat the list of functions, we find the legitimate handlers for the initialization (rc4HmacInitialize) and decryption\r\n(rc4HmacDecrypt) routines that Mimikatz targets. This gives us the specific symbol names that should correspond\r\nto the handlers we find inside of analyzed memory samples.\r\nIn summary, this reverse-engineering effort to find the origin structure led us to two import conclusions. First,\r\neven though we know the symbol name of the static RC4 structure (csRC4_HMAC), we cannot analyze this\r\ndirectly, as a copy of its values will be placed inside of CSystems. This means we will still need to enumerate\r\nCSystems to get the “active” values, but it also means that we can potentially choose to leverage the duplicate,\r\noriginal data in our plugin. Second, by knowing the symbol names of the legitimate initialization and decryption\r\nhandlers, we can make the sanity checks performed by our plugins as specific as possible.\r\nWith these two reversing efforts complete, we can now start to develop our plugin!\r\nDesigning the windows.skeleton_key_check Plugin\r\nOur previous analysis gave us all the information we need to design and implement our plugin; we saw exactly\r\nhow the operating system retrieves our desired data structure. As a direct approach, this would include the\r\nfollowing steps:\r\n1. Find the address of CSystems\r\n2. Walk each element to find the active RC4 system\r\n3. Compare its initialization and decryption handlers to the known-good symbols\r\nAfter the handlers are processed, the plugin would then report whether the handler’s value is legitimate or if a\r\nSkeleton Key attack has been performed. \r\nCreating a New Plugin\r\nTo start, we must create a base Volatility 3 plugin that is capable of processing Windows samples. A major goal of\r\nVolatility 3 was to have significant and always-up-to-date documentation for both users and developers. This\r\ndocumentation is stored on the Volatility 3 page of readthedocs. There is also a section specifically on writing a\r\nbasic plugin here. \r\nAt a high level, all plugins must define their requirements, a run method, and a generator method. The run\r\nmethod executes first and calls the generator method to create the data sets that will be displayed on the terminal\r\n(or output in whatever format other interfaces support). For more information, please see the documentation\r\nabove.\r\nFor our Skeleton Key plugin, we use the basic starting form to then implement the steps listed previously. Note\r\nthat the plugin being described in this blog post is already available in Volatility 3 here. Since line numbers change\r\nafter each new commit, we instead will be referencing portions of the plugin by the function name. Also, we will\r\nbe showing screenshots of code portions being discussed with the line numbers starting at 1. This will guide the\r\ndiscussion in a consistent manner. \r\nhttps://volatility-labs.blogspot.com/2021/10/memory-forensics-r-illustrated.html\r\nPage 5 of 14\n\nImplementation - Writing the run Function\r\nThe run function is called first when a plugin’s execution begins. The expected return value is a TreeGrid that the\r\ncalling user interface will then display for the analyst. The following image shows the run function, along with the\r\nprocess filter from our Skeleton Key plugin:\r\nOn line 12, the return statement begins with the construction of the required TreeGrid instance. The first parameter\r\nto the TreeGrid constructor is the list of columns that the plugin will display. Each column is specified with its\r\nname and type. For this plugin, we have chosen to display the process ID and name of analyzed lsass.exe\r\ninstances; whether or not a Skeleton Key attack was found; and the addresses of the initialization and decryption\r\nhandlers. Note that the handlers are listed by their address in memory, which Volatility 3 will automatically print\r\nin hexadecimal due to the format_hints.Hex specifier. This is similar to the [addrpad] specifier of Volatility 2.\r\nNext, the generator function is called. For plugins that operate on data not made available by another plugin, the\r\ngenerator function will be called with no arguments. For Skeleton Key, since we only want to analyze lsass.exe\r\nprocesses, we can leverage list_processes to perform the filtering for us. This filtering occurs through the use of\r\nthe filter_func argument, which specifies a callback that evaluates if a process object should be yielded to the\r\ncaller. Our filtering function, lsassproc_filter, is very simple; it only needs to evaluate if the process name is\r\nlsass.exe. \r\nImplementation – Leveraging PDBs\r\nOur reverse-engineering effort showed us that four symbols—cSystems, cCSystems, rc4HmacInitialize,\r\nrc4HmacDecrypt—hold the key data we need to write a complete plugin. Luckily, one of the new features of\r\nVolatility 3 is the ability to automatically download and incorporate PDB (symbol) files into the analysis flow of\r\nplugins. This is accomplished by locating the PE file (.exe, .dll, .sys) of interest and parsing it with the PDB utility\r\nAPI. Since cryptdll.dll holds the symbols our plugins need, the first step is to find the DLL within the address of\r\nlsass.exe:\r\nhttps://volatility-labs.blogspot.com/2021/10/memory-forensics-r-illustrated.html\r\nPage 6 of 14\n\nThe above image shows that _find_cryptdll—a function that receives the process object for lsass.exe—iterates\r\nthrough its memory regions (line 12), retrieves the filename for the current region (line 13), and checks for the file\r\nof interest (13-15). Once cryptdll.dll is found, its base address and size are returned (16-17). \r\nOnce cryptdll.dll has been located, its information can then be passed to the PDB utility APIs:\r\nAs shown, calling into the PDB API is straightforward, but this actually triggers quite a bit of activity inside the\r\ncore of Volatility 3. First, the memory range specified for the PE file is scanned to find its GUID, which is unique\r\nidentifier for the file. Next, the local Volatility cache is checked to see if the PDB for this GUID has already been\r\ndownloaded and processed during previous plugin runs. If so, then the cached file is parsed and returned to the\r\ncaller.\r\nIf the GUID is not in the cache, then Volatility will attempt to download the PDB file from the Microsoft symbol\r\nserver.  If successful, then the PDB will be parsed, converted to Volatility’s symbol table format, and stored within\r\nthe cache. \r\nAssuming the PDB is successfully downloaded and parsed, then our plugin has direct access to the offsets of the\r\nneeded symbols within the particular version of cryptdll.dll. This allows us to trivially find their values within a\r\nhttps://volatility-labs.blogspot.com/2021/10/memory-forensics-r-illustrated.html\r\nPage 7 of 14\n\nparticular memory sample:\r\nThe code shown gathers the runtime address for each of the four desired symbols. For the handlers, we only need\r\ntheir address in memory to compare to the ones in the active RC4 system. For cCSystems, we treat it separately, as\r\nwe do not want processing to fail simply because the page holding the count is unavailable. \r\nWe also treat CSystems separately, as we need to construct an array type to cleanly enumerate its elements.\r\nConstructing this object requires not only the address of where CSystems is in memory, but also the structure\r\ndefinition for the array elements. Unlike the PDB file for the kernel, which includes both symbol offsets and type\r\ninformation, the PDB file for cryptdll.dll only includes the symbol offsets. This means we need to manually\r\ninform Volatility of the data structure layout. This is performed in Volatility 3 by creating a JSON file that\r\ndescribes the data structure(s) a plugin requires. You can view this file for the _KERB_ECRYPT structure here,\r\nwhich was based on the definition from Mimikatz discussed earlier.\r\nhttps://volatility-labs.blogspot.com/2021/10/memory-forensics-r-illustrated.html\r\nPage 8 of 14\n\nOnce the array is constructed, it can then be enumerated as shown below:\r\nVolatility has built-in support for enumerating arrays, so the for loop will walk each element, creating the csystem\r\nvariable as the _KERB_ECRYPT type. Before processing an element, it is checked for being valid (mapped) into\r\nthe process address space (lines 2-3). Next, the EncryptionType value is compared with our type of interest (lines\r\n6-7). To determine if a Skeleton Key is present, we compare the Initialize and Decrypt members of the system\r\nfound in memory to the expected values from the PDB file. If either of these have been modified, then a Skeleton\r\nKey attack has occurred, or at a minimum, a modification has occurred that an analyst would want to know about. \r\nWith all of the values computed, displaying the results to the analyst requires just a simple yield of the data. This\r\ncan be seen in lines 13-17 and will result in the process name and PID, presence of a Skeleton Key, and handler\r\naddresses being displayed. This immediately informs the analyst if a Skeleton Key was found, and if so, where the\r\nmalicious handler values are in memory. \r\nThe following image shows a run of our new plugin against an infected memory sample:\r\nAdding Resiliency to windows.skeleton_key_check\r\nSo far, our plugin is able to successfully detect Skeleton Key attacks by leveraging the cryptdll.dll PDB file to\r\ndetermine where our four symbols of interest are located in memory. Unfortunately, real-world memory forensics\r\nis not always this straightforward, and the data we would like may not be memory resident or it may be smeared.\r\nThus, it is also advantageous to consider other approaches.\r\nhttps://volatility-labs.blogspot.com/2021/10/memory-forensics-r-illustrated.html\r\nPage 9 of 14\n\nIn the case of leveraging a PDB file for analysis, there are a few situations that could prevent us from determining\r\nwhich PDB file is needed for analysis, as well as obtaining that PDB file.\r\n1. The page containing cryptdll.dll’s GUID could be paged out or smeared. \r\n2. The analysis system may be offline and unable to download the PDB file from Microsoft’s symbol server.\r\n3. Although rare, Microsoft has published corrupt/broken PDB files for modules shipped with stable versions\r\nof Windows.\r\nIn these situations, we would still like to be able to detect Skeleton Key attacks, but we need a different approach\r\nto gather the required data. \r\nFinding CSystems Without a PDB File\r\nUsing knowledge gained from previous work on the plugin, we know that the CDLocateCSystem function directly\r\nreferences two of the four symbols we need: CSystems and cCSystems.  This means that by performing static\r\nbinary analysis of CDLocateCSystem, we should be able to determine the address of these symbols, since the\r\nfunction’s instructions will reference the addresses themselves. This is a common tactic in memory analysis and\r\nreverse engineering tasks to find symbols that are not exported or where a symbol file cannot be obtained. \r\nTo attempt to find CDLocateCSystem without the use of a PDB file, we parse the export directory of cryptdll.dll,\r\nsince it exports CDLocateCSystem by name. The following image shows how this is performed in Volatility 3:\r\nhttps://volatility-labs.blogspot.com/2021/10/memory-forensics-r-illustrated.html\r\nPage 10 of 14\n\nhttps://volatility-labs.blogspot.com/2021/10/memory-forensics-r-illustrated.html\r\nPage 11 of 14\n\nFirst, a reference is obtained to the type information for PE files (lines 1-7). Next, a Volatility 3 PE file object is\r\nconstructed starting at the base address of cryptdll.dll (lines 9-11). This object contains a number of convenience\r\nmethods for accessing common data, such as the data directories. This is leveraged on line 15 to parse the export\r\ndirectory, and then loop through its exported symbols starting on line 22. The body of this loop then looks for\r\nCDLocateCSystem, and when found, attempts to read the bytes (opcodes of the instructions) from its location in\r\nmemory. \r\nIf these bytes can be read, then the _analyze_cdlocatecsystem function is called, which leverages capstone to\r\nperform the static disassembly necessary to locate both symbols. After locating them, it will construct the array\r\nobject using the same method as described when the PDB file symbols were used. \r\nAssuming the export table and opcodes for CDLocationCSystem are present, this method will successfully find\r\nCSystems and allow us to locate the RC4 structure as we did previously. \r\nFinding rc4HmacInitialize and rc4HmacDecrypt\r\nSo far, we have been able to locate the RC4 structure without the PDB file. Unfortunately, there are no direct\r\nreferences to the legitimate initialize and decrypt handlers that we can leverage. This leaves us with two options.\r\nThe first option is to verify the memory region holding the handlers, which will be discussed in this section. The\r\nsecond option is to attempt to scan for the values, which is discussed in the next section. Each has advantages and\r\ndrawbacks, as we will discuss.\r\nEach memory region within a process’s address space is tracked by a virtual address descriptor (VAD).\r\nInformation in the VAD includes the starting and ending address of the region; the initial protection of the region;\r\nand the number of committed pages. For executables, such as lsass.exe and cryptdll.dll, one VAD will track all\r\nregions of the executable, including its code and data. Knowing this, we can check if the values of the\r\ninitialization and decryption handlers are within the region for cryptdll.dll. This is shown in the following image:\r\nThis simple check ensures that the value of the handler is within the starting and ending range of the VAD for\r\ncryptdll.dll.  Although this check is not as precise as having the exact, legitimate values from the PDB file, this\r\nmethod still detects all forms of Skeleton Key attacks found in the wild, as they all allocate new VADs to hold the\r\nshellcode of the malicious handlers.\r\nNote: Theoretically, an in-memory code cave could be used to place redirection stubs within cryptdll.dll and this\r\ncheck would be bypassed, but no malware—in the wild or proof-of-concept—has leveraged this approach.\r\nFurthermore, the PDB-based method and the one described in the next section would still detect these, rendering\r\nthem not particularly stealthy. These types of attacks are also much less portable to differing operating system\r\nversions, which is one of the reasons they are uncommon in the real world.\r\nAdding Scanning as a Last Resort to windows.skeleton_key_check\r\nhttps://volatility-labs.blogspot.com/2021/10/memory-forensics-r-illustrated.html\r\nPage 12 of 14\n\nWe currently have two methods to gather the data needed for Skeleton Key attacks: PDB files and export table\r\nanalysis. As discussed previously, the PDB file method can be unavailable for a number of reasons, and\r\nunfortunately, the export table method can be as well. The most common reason for this is the PE header metadata\r\nbeing paged out or the page(s) holding the export table information are paged out. The end result is that we cannot\r\nuse the export table to tell us directly where to look for our needed information.\r\nIn these situations, there is a long history of memory forensic tools scanning for the data they need. Since we have\r\naccess to all pages that are present within a process’s address space, we can simply scan them in hopes of finding\r\nwhat we need. In the case of our Skeleton Key plugin, we were able to develop a highly effective and efficient\r\nscanner to meet our needs.\r\nTo begin, we used our knowledge that the data we need is contained within cryptdll.dll. This means we only have\r\nto scan a very small space (the size of the DLL). Second, as shown before, the layout of the active structure starts\r\nwith the integer for the encryption type, which we know is 0x17 for RC4. Other research showed that the second\r\nmember, BlockSize, had a value of 1 in all of our test samples. Using this knowledge, we developed a scanner\r\nbased on Volatility 3’s scanning API:\r\nThe scanner is configured to look for an 8-byte pattern of 0x17 followed by 1 in little-endian integer format. It\r\nattempts to instantiate a _KERB_ECRYPT type at each address where this pattern is found. To strengthen the\r\ncheck, we also verify that the Encrypt and Finish members our potential structure reference addresses are inside of\r\ncryptdll.dll. Neither of these are targeted by Skeleton Key attacks and validating their values provides a strong\r\ncheck against false positives.\r\nThe following shows the output of our plugin when the scanning method is used:\r\nhttps://volatility-labs.blogspot.com/2021/10/memory-forensics-r-illustrated.html\r\nPage 13 of 14\n\nNote that there are two lines of output. This occurs beause the scanner finds both the active version of the RC4\r\nstructure and the version that is statically compiled into the application. Having both outputs provides some\r\nadvantages: there is direct visual confirmation that the active structure is hooked, and the statically compiled\r\nversion reveals the addresses for the legitimate handlers, even without PDB usage.\r\nWrap Up\r\nIn this blog post, we have walked through the entire process for memory forensics research and development. We\r\nanalyzed a target (Mimikatz’s Skeleton Key attack), analyzed the subsystem it abuses (the authentication systems\r\nmanaged by cryptdll.dll), and developed a new Volatility plugin that can automatically analyze this subsystem for\r\nabuse. This is a common workflow used to develop Volatility plugins.\r\nIf you find this type of research interesting, please consider developing a new plugin and submitting it to our\r\nVolatility Plugin Contest. Note that your submission does not have to be anywhere near as thorough as the plugin\r\npresented here; even submitting a new capability with just one of the discovery methods (PDB files, export\r\nanalysis, scanning) used would be sufficient for an entry. We showed the full range here to display many of\r\nVolatility 3's new capabilities, but we certainly do not expect all plugins to meet this level of complexity. \r\nWe hope you have enjoyed this post. If you have any questions or comments, please let us know. You can find us\r\non Twitter (@volatility) and our Slack server.\r\n-- The Volatility Team\r\nSource: https://volatility-labs.blogspot.com/2021/10/memory-forensics-r-illustrated.html\r\nhttps://volatility-labs.blogspot.com/2021/10/memory-forensics-r-illustrated.html\r\nPage 14 of 14",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://volatility-labs.blogspot.com/2021/10/memory-forensics-r-illustrated.html"
	],
	"report_names": [
		"memory-forensics-r-illustrated.html"
	],
	"threat_actors": [
		{
			"id": "d90307b6-14a9-4d0b-9156-89e453d6eb13",
			"created_at": "2022-10-25T16:07:23.773944Z",
			"updated_at": "2026-04-10T02:00:04.746188Z",
			"deleted_at": null,
			"main_name": "Lead",
			"aliases": [
				"Casper",
				"TG-3279"
			],
			"source_name": "ETDA:Lead",
			"tools": [
				"Agentemis",
				"BleDoor",
				"Cobalt Strike",
				"CobaltStrike",
				"RbDoor",
				"RibDoor",
				"Winnti",
				"cobeacon"
			],
			"source_id": "ETDA",
			"reports": null
		}
	],
	"ts_created_at": 1775434039,
	"ts_updated_at": 1775791432,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/ca0140dd8dba33e7a4c3f4061b589aeb2e4273ee.pdf",
		"text": "https://archive.orkl.eu/ca0140dd8dba33e7a4c3f4061b589aeb2e4273ee.txt",
		"img": "https://archive.orkl.eu/ca0140dd8dba33e7a4c3f4061b589aeb2e4273ee.jpg"
	}
}