## GraceWrapper: The new TA505’s post-exploitation enabler # 2022 ----- ##### 1. Introduction���������������������������������������������������������������������������������3 2. MirrorBlast Campaign Recap�����������������������������������������������������3 3. Technical Analysis�����������������������������������������������������������������������5 ###### 3.1. Anti-Analysis��������������������������������������������������������������������������������������������������5 3.1.1. Packer����������������������������������������������������������������������������������������������������������������������������������������������5 3.2. Obfuscation���������������������������������������������������������������������������������������������������6 3.2.1. Random Sleeps����������������������������������������������������������������������������������������������������������������������������10 3.2.2. Heavy Use of Low-Level Windows Functions�����������������������������������������������������������������������11 3.3. Command Line Arguments����������������������������������������������������������������������12 3.4. Injection Mechanisms�������������������������������������������������������������������������������12 3.4.1. Leveraging APC queues and ROP�������������������������������������������������������������������������������������������12 3.4.2. Fallback Injection Routine���������������������������������������������������������������������������������������������������������18 3.5. Configuration����������������������������������������������������������������������������������������������19 3.6. Payload Execution��������������������������������������������������������������������������������������24 3.6.1. Building the Payload�������������������������������������������������������������������������������������������������������������������24 3.6.2. Unprivileged Execution��������������������������������������������������������������������������������������������������������������26 3.6.3. Injection to Remote Processes������������������������������������������������������������������������������������������������26 ##### 4. Conclusions��������������������������������������������������������������������������������28 5. YARA��������������������������������������������������������������������������������������������29 6. References����������������������������������������������������������������������������������29 7. Appendix�������������������������������������������������������������������������������������31 ###### 7.1. Appendix A: Original Import Address Table����������������������������������������31 7.2. Appendix B: Original Strings��������������������������������������������������������������������34 © 2022 Leap In Value S.L. & Outpost24 All rights reserved. The information provided in this document is the property of Blueliv, and any modification or use of all or part of the content of this document without the express written consent of Blueliv is strictly prohibited. Failure to reply to a request for consent shall in no case be understood as tacit authorization for the use thereof. Bl li ® i i t d t d k f © 2021 L I V l S L & O t t24 All i ht d All th b d d t t d k ----- ### 1. Introduction TA505 is an infamous, financially motivated threat actor group believed to have been operating for almost a decade. Operating the Necurs botnet, the group started its core business by selling access to compromised networks to other malware operators, through which it was able to operate some of the most notorious spam campaigns in recent memory. In addition to this, it is believed that TA505, or a subset of the group, started conducting ransomware operations. This was likely motivated by the estimated $25 million income that the nefarious group was generating back in 2016 [1]. This signaled the group’s first steps in the ransomware game as [it teamed up with none other than the Locky gang, one of the most successful ransomware-as-a-](https://threatpost.com/ransomware-gang-arrested-locky-hospitals/155842/) service (RaaS) providers to date [2]. Since then, a vast number of tools have been claimed to belong to the group’s arsenal, and the attacks attributed to them have demonstrated a diverse set of tactics, techniques and procedures (TTPs). Thus, attributing them to a specific attack has always been a challenging task. [Today it is believed that the group is responsible for operating the Clop ransomware after compromising](https://www.bleepingcomputer.com/news/security/operation-cyclone-deals-blow-to-clop-ransomware-operation/) corporate networks by using a variety of remote administration malware such as SDBbot, FlawedAmmy and FlawedGrace, which were downloaded via Get2, Gelup or Mirrorblast. [In this research, Outpost24’s Blueliv Labs shares findings from the analysis of the Mirrorblast spam](https://outpost24.com/products/cyber-threat-intelligence) campaign, the last known spam operation attributed to TA505. Within the convoluted sequence of malware pieces involved in the attack, one is believed to be an updated version of the FlawedGrace RAT, due to the evident relations in its code and behaviour similarities. However, a thorough inspection reveals a very interesting component belonging to the Grace family, whose main purpose appears to be hindering the detection of the actual RAT and its modules while facilitating the deployment of post-exploitation tools in the infected machine. The rest of this report shows the technical details of this new component that we have named GraceWrapper. ### 2. MirrorBlast Campaign Recap [Back in September 2021, Proofpoint detected a new malware, dubbed MirrorBlast, used in large spam](https://www.scmagazine.com/brief/phishing/new-mirrorblast-phishing-campaign-targets-financial-entities) campaigns that replicated the modus operandi of previous TA505 attacks. The last member of the [infection chain was none other than a fresh version of FlawedGrace, which was already identified to](https://threatpost.com/ta505-retooled-flawedgrace-rat/175559/) have a close bond with the group. [3] Like many other spam campaigns, the MirrorBlast attacks started with a phishing email containing a link to a malicious XLS document that, upon opening and allowing its macros to run, would trigger the download and execution of the next stage of malware. The first downloaded executable would be an MSI containing a script written in the KiXtar scripting language that would download the MirrorBlast ----- malware. MirrorBlast is a Rebol script, contained within another MSI file, which would generate a unique identifier for the victim’s machine and access its command and control for the next stage of malware, the ReflectiveGnome loader. That loader would be responsible for downloading FlawedGrace and executing it within its own process memory. Send PC/User/Domain names and process list KXL CNC Receive Next CnC 1 KiXtar Loader Get next stage malware KXL CNC 2 Send PC/User/Domain names, OS Version and arch Receive unique identifier MB MirrorBlast CnC Send uuid until next stage / Rebol script ready ReflectiveGnome Run payload in memory RG Download Shellcode CnC GraceWrapper During the analysis of the MirrorBlast infection chain, we identified notable differences between ReflectiveGnome’s payload and previous FlawedGrace RAT samples Naturally we decided to take a Send PC/User/Domain names and process list KXL CNC Receive Next CnC 1 KiXtar Loader Get next stage malware KXL CNC 2 Send PC/User/Domain names, OS Version and arch Receive unique identifier MB MirrorBlast CnC Send uuid until next stage / Rebol script ready ReflectiveGnome Run payload in memory RG Download Shellcode CnC GraceWrapper ----- closer look at the sample. ### 3. Technical Analysis ###### 3.1. Anti-Analysis 3.1.1. Packer Even after that many stages, ReflectiveGnome’s payload is still packed. Again, this packer is a small piece of code with the sole purpose of allocating, decoding and executing its payload. An interesting characteristic of this sample is that it tries to impersonate ATMLIB.DLL, a library belonging to Adobe Type Manager, which is present on many workplace computers. _Figure 1: ATM related metadata._ The malicious library does not contain any export, as it is designed to be executed straight from the memory of a (down)loader process. Additionally, it does not specify any import as it employs a dynamic API resolution function to obtain the addresses of the Windows functions needed. By only using three low-level API functions (i.e., LdrGetProcedureAddress, ZwAllocateVirtualMemory and ZwFreeVirtualMemory) and a simple decoding function, the packer loads the payload to its own memory and executes it by a call to its entry point. ----- _Figure 2: Packer’s decoding routine._ _Figure 3: Main packer’s function after some renaming._ ###### 3.2. Obfuscation After unpacking, a first look at the obtained sample with a disassembler reveals that it contains different obfuscation mechanisms designed to complicate the malware analysis tasks. The malware has been filled with plenty of junk code in a bid to discourage reverse engineers from analyzing the ----- sample. _Figure 4: Main function of the obtained sample showing many lines of junk code._ _Figure 5: Main function after deobfuscation jobs._ In order to properly analyze the sample, this junk code needs to be removed Once the code has been ----- recovered, it is possible to find two other common obfuscation mechanisms present in most modern malware: string encryption and dynamic Windows API resolutions. Combined, these mechanisms prevent analysts from obtaining an approximate picture of a program’s capabilities at first sight. The string encryption function consists of a xor loop that takes three parameters: the bytes of the encrypted string, a hardcoded encryption key contained in the sample and a single byte passed as an argument to the function. After replicating its code, it is possible to recover all the original strings from the binary. As an extra defense against memory analysis techniques, the strings are decrypted only when they are needed and erased from the memory once they have been used. _Figure 6: String decryption function._ Within the decrypted strings, the original import address table (IAT) function names are found. As a result, this process offers a good first picture of the capabilities of this software. Both the original IAT and the plain text strings can be found in the appendix of this document. At this point of the analysis, it is obvious that the sample does not correspond to a FlawedGrace binary, as it lacks some of its capabilities. For example, it does not have any means to communicate with its command and control. The dynamic Windows API resolution function is quite simple; it will receive a number as an argument and translate it to its corresponding function address. ----- _Figure 7: Dynamic Windows API resolution code._ Combining all the knowledge exposed in this section, it is possible to alter the disassembly of the binary to further simplify its analysis. ----- _Figure 8: Start of main’s thread function code before deobfuscation._ _Figure 9: Cleaned code._ ###### 3.2.1. Random Sleeps GraceWrapper’s developers included a function to put the malware to sleep before executing some ----- important parts of the code, either to add extra noise to behaviour logs or to confuse malware detection software. The function will randomly call Sleep, or create a thread that randomly chooses between Sleep or WaitForSingleObject for its purpose. _Figure 10: Randomly sleeping or creating a new thread._ _Figure 11: Randomly choosing between Sleep or WaitForSingleObject._ As mentioned above, this function is called before executing some crucial code within the malware, such as: - Creating the main execution thread. - First call within the main thread. - After config initialization. - Various times within the main injection routine. - During the payload loading thread. The developers also added a way to prevent these periods of sleep from being executed by employing the command line argument –nm. ###### 3.2.2. Heavy Use of Low-Level Windows Functions After obtaining the original IAT of the sample, it is possible to observe how GraceWrapper’s developers make frequent use of low-level (Rtl*, Nt*, Zw*) Windows functions. This is a well-known technique to evade analysis tooling that monitors only the higher-level libraries while also complicating manual ----- ###### 3.3. Command Line Arguments GraceWrapper’s behaviour can be manipulated by the command line parameters listed below: - -cs [dword]: allows setting up a different value for encoding the identifiers of the config. - -nm: prevents the random sleep function from executing if present. Also causes the self-injection routine not to execute. - -em: after injecting itself into another process, if it has not been run from powershell.exe or rundll32.exe and this argument is not present, the program exits by calling ExitThread instead of RtlExitUserProcess. It is likely that more functionalities will be added. - -ss [s]: sets the program to sleep for s seconds before executing the self-injection routine. - -sf [file path]: creates the specified empty file. - -wf [file path]: wipes the specified file. ‘ _Figure 12: -ss command line arg being checked._ ###### 3.4. Injection Mechanisms 3.4.1. Leveraging APC queues and ROP GraceWrapper’s main purpose is to make its payload as evasive as possible, and the painstaking implementation of its main injection routine is unmistakable evidence of that. This software combines Return-Oriented Programming (ROP) and heavy use of Windows’s Asynchronous Procedure Calls (APC) to make its execution unnoticed. ROP [4] is a well-known software exploitation technique which consists of searching for small code fragments, referred to as gadgets, within the code section of a program. After getting all gadgets needed for the exploitation, the stack of the program is manipulated so that the gadgets will be executed in a specific order, which is known as the ROP chain. This technique allows bypassing operating systems to implement ‘write or execute’ policies which prevent memory regions from being writable and executable at the same time, as the malicious code is already present in an executable memory area. To begin its injection routine, GraceWrapper builds an array of ROP gadgets present in NTDLL.DLL. h l b d d h l l d d h ‘ ----- address for each system startup, making it the perfect target for building ROP chains that can be executed in any remote process. To further complicate things, instead of searching for the gadgets at the code section of the currently loaded NTDLL, which would cause a huge amount of memory accesses in its address space that could potentially trigger some alarms, GraceWrapper loads a copy of the library from the filesystem. _Figure 13: Loading NTDLL from the filesystem to search the ROP gadgets._ After reading NTDLL’s contents, the malware walks its .text section to find the following gadgets: ``` • pop esp; ret • pop eax; ret • pop ecx; ret • pop ebx; ret • pop esi; ret • pop r8; ret • add rsp 0x8; ret • add rsp 0x28; ret • mov qw [ecx], rax; ret • add rsp, 0x50; pop rbx; ret • mov rdx, rbx; call rax • mov r9, rsi; call rax • pop r9; pop r8; pop rdx; pop rcx; jmp rax • pop rdx; pop rcx; pop r8; pop r9; pop r10; pop r11; ret • pop rdx; pop rcx; pop r8; pop r9; ret ``` Once the offsets of the gadgets have been found, GraceWrapper translates them into their absolute ----- _Figure 14: ROP Gadgets being built before searching them._ Following the collection of ROP gadgets, GraceWrapper will programmatically pick a thread of the host process using APC tasks [8]. Here, the code chooses between explorer.exe or lsass.exe, electing the former when executed under Administrator privileges. After enumerating all target threads, the same number of events will be created by calling CreateEventW as many times as necessary. The purpose of these events is to create an event-thread relationship by duplicating each handle into a single thread by means of NtDuplicateObject. Once every target’s thread has an event handle, NtQueueApcThreadEx is used to submit a call to SetEvent for each thread’s APC queue that will signal its corresponding event handle. By means of WaitForMultipleObjects, GraceWrapper receives the first event signalled and keeps the corresponding thread handle to use for the injection. ----- _Figure 15: Picking the first thread executing its APC queue as the victim of the injection._ After deciding its victim thread, the loader proceeds to build the payload that will trigger the execution. On one side, a named image mapping is created and filled with a small code stub, embedded in GraceWrapper’s executable, which is followed by the contents of the injected binary. The sole purpose of this stub is to calculate and jump at the address of the binary’s original entry point. ----- _Figure 17: Named mapping creation, filled with the payload to be executed._ At this stage, the ROP chain is finally built. This is due to a function that combines the array of ROP gadgets, the addresses of OpenFileMappingW, NtMapViewOfSection and RtlCreateUserThread and the CONTEXT structure of the elected thread. The ROP chain’s code will open the previously described file mapping, load its contents and create a new thread within the target process to execute the malware. GraceWrapper’s developers took exceptional care in developing this routine, as causing a thread to malfunction within the Explorer’s process might cause the entire system to freeze, followed by an Explorer’s restart, which will terminate the malware’s execution. ----- _Figure 18: ROP chain_ After all the important pieces have been gathered, GraceWrapper will proceed to replace the contents of the targeted thread stack with those from the ROP chain buffer. It employs APC tasks to accomplish this objective. By issuing calls per byte to the memset function using ZwQueueApcThreadEx, GraceWrapper overrides the stack of the host thread with the ROP chain to finally call NtResumeThread, finishing with this twisted injection routine. ----- _Figure 19: Overriding the stack of the host thread with the ROP chain, using one APC task per byte._ This routine is employed firstly to inject the whole GraceWrapper binary and restart its execution in a safer environment (which can be avoided if executed with –nm, or if the process name is TestStart. exe or TestService.exe), and secondly to inject the embedded FlawedGrace binary into winlogon.exe and other processes, if the malware is being run with Administrator privileges. The use of the APC functions to execute evasive payloads is a well know technique employed by some red teaming tools. However, it is not yet popular in modern malware; just a few families or actors, such as IcedID or FIN8, have been reported to actively use this Windows feature during their malicious activities [5]. With this piece of software, TA505 goes a step further by combining APC process injection together with ROP in an intensive effort to prevent the detection of new FlawedGrace samples. ###### 3.4.2. Fallback Injection Routine In case the main injection routine fails or if the operating system version is not new enough to make use of APC, GraceWrapper’s developers created a more conservative mechanism of injection. By means of NtAllocateVirtualMemory, NtWriteVirtualMemory and RtlCreateUserThread, the remote process gets the payload written in its memory, and a new thread is created to execute the malware. This function will also check if the process is running under the Windows on Windows subsystem (WoW), which allows running 32-bit applications on 64-bit systems in order to perform the good old Heaven’s Gate technique, which adds the capability to inject a 64-bit payload from a 32-bit version of this loader. ----- _Figure 20: Heaven’s Gate code to switch contexts within GraceWrapper’s .rdata section._ ###### 3.5. Configuration During its first execution on a machine, GraceWrapper will obtain its configuration file from an embedded resource included in its binary. By means of LdrFindResource_U and LdrAccessResource, the encrypted config file is read. The original file is compressed using the LZMA algorithm and then encrypted with AES before being embedded in the binary. That process is reversed to access the plain contents of the configuration file. _Figure 21: Obtaining original config file._ ----- _Figure 22: Grace config file._ The resulting file is employed to instantiate a custom data collection. The implementation of this data collection is accomplished by a complex and carefully thought out set of classes and plenty of data structures, all belonging to FlawedGrace. Oversimplifying its inners, the Grace malware family organizes its config data as a set of named entries which contain data streams and/or other named entries in a similar way to a traditional dictionary. The implementation also contains memory management features and supports concurrency, allowing different instances or threads of the malware and its modules to access and modify its data safely. The configuration has many different named entries. It is remarkable that in previous FlawedGrace versions [6], the names were significative strings such as ‘port’ or ‘servers’, whereas in this GraceWrapper sample, just a few letters represent each entry. During the analysis of the wrapper’s sample, the following entry names have been identified: - Sr: used to store if the current execution is running as Administrator. - P1, p2: contain a binary to be used to hide FlawedGrace executable. - L1, l2: contain the FlawedGrace executable. - Hv: set to the hardcoded value of 1074. Unknown purpose. - Hnu: if present, a PE will be extracted from h and executed in a new thread. - H: the entry is created during GraceWrapper’s first execution, containing its own executable. ----- - Avt: set to a number that represents the vendor of the installed anti-virus, if any. The supported AV products/vendors are Windows Defender (2), Symantec (3), Norton (4), TrendMicro (5), Bitdefender (6), Sophos (7). If no listed AV is detected, avt Is set to 1. - Ni: this entry is assigned to a GUID generated by CoCreateGuid the first time the wrapper executes in a machine. It is also the parent entry for ‘mt’ and ‘mo’. The code shows that such GUID can be used to format different config entry names if provided with the wildcard character ‘%’. For example, instead of having a ‘p1’ entry, the config could contain a ‘p1%’, that will be converted to ‘p1[ni-GUID]’ before its usage. The specific use of this feature cannot be inferred from the analysis of a sample but, hypothetically, this could allow setting different configuration parameters for different running executions of the Grace family. The entries that support this kind of formatting are at least: p1, p2, hv, hnu, hfu, h and m. - Mt: contains ‘se’ and ‘mo’ entries. - Mo, se and huf purposes are unknown currently. - H1: C&C IP. To hide all the binaries embedded in the config file from memory analysis, the configuration is never allowed to be loaded in memory while it is not being used. The Grace malware family employs Windows’s file mapping objects to keep an encrypted copy of the serialized configuration that is loaded and decrypted on demand. The name for the configuration file mapping is generated by combining data from the victim’s machine and data from GraceWrapper’s binary itself, a cautious approach to preventing third parties from being able to generate those artefacts for detection purposes. To further complicate the process, the operators of the malware can use the –cs command line argument to provide a different encoding key that will replace the one embedded in the binary. ----- _Figure 23: Using -cs to alter the result of the name generation algorithm._ To generate machine-bound strings, the Grace family retrieves the computer name and the volume’s serial number to construct a stream of 16 bytes. The first 8 bytes are the result of a xor operation between the encoding key and the volume’s serial number. Whereas the last bytes are produced by, again, a xor operation using the computer name, the volume’s serial number and the previously generated bytes. The resulting buffer is passed to a string formatting function to obtain the final name. _Figure 24: Name generation function._ After obtaining the corresponding name, GraceWrapper will create the named mapping and assign a i ----- or processes from manipulating the configuration while it is being used. If executed with Administrator privileges, a global file mapping will be created, which means processes from other logon sessions will have access to it. Once the file mapping is created, it is filled with the config contents re-encrypted. GraceWrapper again uses AES for this, but instead of employing the hardcoded key used during decryption after obtaining it from the binary’s resources, it will instead generate a key bound to the infected machine by using the function described above. To store the changes made to the config, GraceWrapper stores an encrypted copy at the registry. To do so, the malware opens the HKCU key, or HKLM if executed with enough privileges, and creates a subkey under Software\Classes\CLSID\{[CLSID]}. The CLSID is created using the same function that generates the encryption key and the config mapping name. _Figure 25: Config subkey generation._ This way, the data stored by the Grace family is masked as COM object data. The encrypted config contents are split into blocks of 524288 bytes and stored in enumerated values that combine its index with another generated CLSID. Additionally, the InprocServer32 subkey is created empty, most likely in order to further improve its impersonation of a COM object. _Figure 26: Encrypted conf stored_ ----- ###### 3.6. Payload Execution Once the wrapper has hidden its own execution within another process and its configuration is ready to function, it can execute its payload. Depending on the privileges of the current process, GraceWrapper will allocate memory within its own process and execute FlawedGrace by creating a new thread or choosing a remote process to inject its payload using the mechanisms previously exposed. ###### 3.6.1. Building the Payload Another additional defense against analysis included in this malware is the capability to hide the original FlawedGrace executable, or any other PE file, by encoding its contents and appending them to another embedded executable that will decode and run it upon its execution. _Figure 27: Grace contents within GraceWrapper’s configuration file._ First, GraceWrapper will source the fields l1 and p1 or l2 and p2 for 32-bit or 64-bit executions from its config, respectively. After calculating their combined size, the same amount multiplied by five will be used to allocate that many bytes and fill them with random values. Then, the contents of the pX field (i.e., the packer executable) will be placed at the beginning of the randomized memory area. Notably, the packer is the same one used to distribute GraceWrapper, which we described at the beginning of the analysis. By parsing its headers, the last entry of its section table [7] is retrieved to modify the fields SizeOfVirtualData and SizeOfRawData to match the size it will have after appending the guest binary. The SizeOfImage, as well as either SizeOfInitializedData, SizeOfUninitializedData or SizeOfCode, are used depending on the type of section, and PE optional header fields are patched accordingly. After patching pX’s header, lX contents are appended to it; the malware will encode its contents to hide the actual malware from memory analysis tools, but before that, it will crawl pX’s code to find a pattern and replace it with lX’s start position. ----- _Figure 28: Patching packer’s code with lX’s start position._ GraceWrapper’s code contains three different encoding sequences depending on the exported name of the host binary, indicating that at least three different packer binaries exist. In any case, the first four bytes of the guest binary are patched with their own size. If the pX PE doesn’t contain any library name, or if it matches ‘b.dll’, the fifth byte will be replaced by a randomly generated value that will be combined in an XOR operation with a key embedded within GraceWrapper’s data sections. _Figure 29: Encoding function for binaries with no exports, ‘b.dll’ and other names different than ‘c.dll’_ If the exported library name matches ‘c.dll’, a 56 random bytes buffer will be generated, replacing the bytes following the patched binary size, resulting in most of the DOS Header being overridden. Afterwards, the buffer is used in an XOR operation against the rest of the binary to hide its contents. ----- _Figure 30: Encoding function used for ‘c.dll’_ If the exported name is other than the ones mentioned, the same process as with ‘b.dll’ is replicated, but this time the single-byte key is a fixed value that is not patched into the memory of the binary. In this sample, the ‘c.dll’ packer is used, which matches the one used to pack GraceWrapper itself. ###### 3.6.2. Unprivileged Execution If the current process does not have Administrator privileges, GraceWrapper will build the payload, allocate memory for each of the regions within its own process and call its entry point. At the state of development manifested by the analyzed sample, GraceWrapper would not support binaries that need relocations or have an actual IAT. _Figure 31: Incomplete PE loader._ ###### 3.6.3. Injection to Remote Processes If executed with enough privileges, GraceWrapper will target the winlogon.exe process to inject FlawedGrace by using the routine combining APC and ROP described within this report. It will also make use of the function WTSEnumerateSessionsExW to get a list of the currently active user sessions on the infected computer and attempt the infection of the corresponding explorer.exe instance of every section ----- This course of action was likely designed to allow it to execute FlawedGrace and its modules under different user sessions, which is a very valuable capability for post exploitation tasks. _Figure 32: Targeting other users’ explorer.exe to inject FlawedGrace in._ ###### Explorer.exe 1. Injects itself ###### GraceWrapper GraceWrapper 2. Load and run Grace _Figure 33: Unprivileged execution._ ###### Explorer.exe 1. Injects itself ###### GraceWrapper GraceWrapper 2. Load and run Grace ----- LSASS WINLOGON GraceWrapper GraceWrapper Grace User 1 EXPLORER Grace User 2 EXPLORER Grace User N EXPLORER Grace _Figure 34: Privileged execution_ ### 4. Conclusions We know that during the MirrorBlast campaign, TA505 deployed a fully refurbished toolkit. Employing a set of easily replaceable new downloaders as intermediate links of the infection chain, the group was able to bypass detection mechanisms while disguising the attribution of the attacks. Not content with stopping there, TA505 deployed an evolved multi-component Grace version. The characteristics and features included in GraceWrapper show that the developers of this malware family are taking a step forward to protect and hide their tools from both analysts and automatic detection tools. In addition, by compromising the LSASS, WINLOGON and all EXPLORER process instances, the Grace family has positioned itself as a strong enabler for post-exploitation tasks. ----- Due to the appearance of testing and death code within the sample, we strongly believe the Grace family was under active development during the MirrorBlast campaign, and it is likely that newer versions of the malware exist at this moment. At Outpost24 Kraken Labs, we consider the monitoring of the evolution of this sophisticated family a crucial task if we are to better understand the activities of TA505 and its allies. ### 5. YARA ``` rule atmlib_packer { meta: description = “Rule to detect the packer used with the Grace family during MirrorBlast campaign.” author = “David Catalán at Outpost24 Kraken Labs.” date = “2022-08-1” strings: $c1 = {48 B8 00 60 00 00 00 00 00 00 C3} $c2 = {C6 44 24 59 4D C6 44 24 5A 65 C6 44 24 5B 6D C6 44 24 5C 6F C6 44 24 5D 72 C6 44 24 5E 79} condition: all of them } ``` rule flawedgrace64_2021 ``` { meta: description = “Rule to detect FlawedGrace” author = “David Catalán at Outpost24 Kraken Labs” strings: $o1 = {B8 ?? ?? 00 00 48 6B C0 ?? 48 8B 0D ?? ?? ?? ?? 0F BE 04 01 83 F8 ?? 75 ?? B8 ?? ?? 00 00 48 6B C0 ?? 48 8B 0D ?? ?? ?? ?? C6 04 01 ??} $o2 = {0F B7 05 ?? ?? ?? ?? 69 C0 ?? ?? ?? ?? 66 89 05 ?? ?? ?? ??} $o3 = {48 B8 ?? ?? ?? ?? ?? ?? ?? ?? 48 8B 0D ?? ?? ?? ?? 48 ?? C8 48 8B C1 48 89 05 ?? ?? ?? ??} condition: #o1 > 70 and #o2 > 400 and #o3 > 2000 } ### 6. References ``` 1. [https://ucsdnews.ucsd.edu/pressrelease/google_uc_san_diego_and_nyu_estimate_25_million_in_ransomware_payouts](https://ucsdnews.ucsd.edu/pressrelease/google_uc_san_diego_and_nyu_estimate_25_million_in_ransomware_payouts) 2. [https://outpost24.com/blog/a-history-of-ransomware](https://outpost24.com/blog/a-history-of-ransomware) 3. [https://www.proofpoint.com/us/blog/threat-insight/whatta-ta-ta505-ramps-activity-delivers-new-flawedgrace-variant](https://www.proofpoint.com/us/blog/threat-insight/whatta-ta-ta505-ramps-activity-delivers-new-flawedgrace-variant) 4. [https://hovav.net/ucsd/dist/rop.pdf](https://hovav.net/ucsd/dist/rop.pdf) 5. [https://attack.mitre.org/techniques/T1055/004/](https://attack.mitre.org/techniques/T1055/004/) 6. [https://www.msreverseengineering.com/blog/2021/3/2/an-exhaustively-analyzed-idb-for-flawedgrace](https://www.msreverseengineering.com/blog/2021/3/2/an-exhaustively-analyzed-idb-for-flawedgrace) 7. [https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#section-table-section-headers](https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#section-table-section-headers) 8. https://repnz.github.io/posts/apc/user-apc/ ----- ### 7. Appendix ###### 7.1. Appendix A: Original Import Address Table ``` LdrFindResource_U LdrAccessResource RtlInitUnicodeString RtlGetVersion RtlDeleteRegistryValue RtlCompareUnicodeString RtlGetNtVersionNumbers RtlGetCompressionWorkSpaceSize RtlCompressBuffer RtlDecompressBuffer RtlCompareString RtlAnsiStringToUnicodeString RtlUnicodeStringToAnsiString RtlRandomEx RtlCreateUserThread RtlUnicodeStringToInteger RtlEqualString NtCreateKey NtFlushKey NtClose NtOpenKey NtRenameKey NtEnumerateKey NtEnumerateValueKey NtDeleteKey NtSetValueKey NtQueryValueKey NtCreateFile NtOpenFile NtQueryInformationFile NtReadFile NtWriteFile NtFlushBuffersFile NtSetInformationFile NtQueryDirectoryFile NtDeviceIoControlFile NtQuerySystemInformation NtSetInformationProcess NtQueryInformationProcess ``` ----- ``` NtDuplicateObject NtAllocateVirtualMemory NtOpenProcess NtFreeVirtualMemory NtCreateEvent NtLoadDriver NtQueueApcThreadEx NtOpenThread NtResumeThread NtMapViewOfSection NtOpenSection _wcsicmp _snprintf _snwprintf NtProtectVirtualMemory NtWriteVirtualMemory NtReadVirtualMemory NtCreateThreadEx Wow64EnableWow64FsRedirection Wow64DisableWow64FsRedirection CreateRemoteThreadEx IsWow64Process HeapFree Sleep CloseHandle CreateThread GetCurrentProcessId GetProcessHeap TerminateProcess GetSystemDirectoryW ResumeThread ExitProcess CreateProcessW GetSystemTimeAsFileTime GetProcAddress GetModuleHandleW HeapAlloc OpenProcess GetLastError CreateFileW GetCurrentProcess MultiByteToWideChar WideCharToMultiByte CompareStringA CompareStringW WriteFile ``` ``` SetFilePointerEx FindClose VirtualProtect GetCurrentThreadId VirtualQuery FlushFileBuffers GetStringTypeW GetFileType GetStdHandle GetACP SetConsoleCtrlHandler VirtualFree WaitForMultipleObjects TerminateThread WTSGetActiveConsoleSessionId GetConsoleWindow GetTickCount LocalFree GetFullPathNameW SetEvent ResetEvent WaitForSingleObject CreateEventW OpenEventW VirtualAlloc GetCommandLineW FreeLibrary LoadLibraryW GetWindowsDirectoryW GetVolumeInformationW GetComputerNameA CreateDirectoryW GetModuleFileNameW CreateToolhelp32Snapshot Process32FirstW Process32NextW LoadLibraryExW OutputDebugStringA VirtualFreeEx ReleaseMutex CreateMutexW MapViewOfFile UnmapViewOfFile CreateFileMappingW OpenFileMappingW GetSystemTime ``` ----- ``` GetLocalTime OpenMutexW GetModuleFileNameA GetModuleHandleExW DeleteCriticalSection LeaveCriticalSection EnterCriticalSection SetLastError LCMapStringW FindFirstFileExA FindNextFileA IsValidCodePage GetOEMCP GetCPInfo GetCommandLineA GetEnvironmentStringsW FreeEnvironmentStringsW SetStdHandle HeapSize GetConsoleCP GetConsoleMode WriteConsoleW ProcessIdToSessionId InterlockedFlushSList RtlUnwindEx GetStartupInfoW IsDebuggerPresent InitializeSListHead RtlCaptureContext RtlLookupFunctionEntry RtlVirtualUnwind UnhandledExceptionFilter SetUnhandledExceptionFilter IsProcessorFeaturePresent QueryPerformanceCounter HeapReAlloc RaiseException InitializeCriticalSectionAndSpinCount TlsAlloc TlsGetValue TlsSetValue WaitForSingleObjectEx EncodePointer ReleaseSemaphore GetSystemInfo SetThreadIdealProcessor ``` ``` CreateSemaphoreW GetModuleHandleA GetNativeSystemInfo OutputDebugStringW RtlPcToFileHeader DuplicateHandle GetExitCodeProcess SetHandleInformation CreatePipe PeekNamedPipe DeviceIoControl GetFirmwareEnvironmentVariableW GetComputerNameW GetLocaleInfoW Thread32First Thread32Next SuspendThread GetThreadContext RegCloseKey RegDeleteValueW RegFlushKey RegOpenKeyExW RegQueryValueExW RegSetValueExW ConvertStringSecurityDescriptorToSecurityDescriptorW CheckTokenMembership LookupPrivilegeValueW SetSecurityDescriptorDacl InitializeSecurityDescriptor FreeSid AllocateAndInitializeSid EqualSid AdjustTokenPrivileges GetTokenInformation OpenProcessToken InitiateSystemShutdownW RegDeleteTreeW RegDeleteKeyW RegCreateKeyExW RegOpenCurrentUser ConvertSidToStringSidW RegisterServiceCtrlHandlerExW SetServiceStatus StartServiceCtrlDispatcherW CreateProcessAsUserW GetUserNameW ``` ----- ``` MessageBoxW MessageBoxA ShowWindow GetSystemMetrics wsprintfW ReleaseDC GetDC IsCharAlphaA SendMessageA PostMessageA GetWindowTextA EnumWindows CommandLineToArgvW SHFileOperationW SHGetFolderPathW CoCreateGuid CoSetProxyBlanket CoInitializeSecurity CoInitializeEx CoCreateInstance CoUninitialize WTSFreeMemory WTSEnumerateSessionsW WTSQueryUserToken GetModuleFileNameExW StrStrIW CreateEnvironmentBlock DestroyEnvironmentBlock NetApiBufferFree NetWkstaGetInfo GetFileVersionInfoSizeW GetFileVersionInfoW VerQueryValueW GetDeviceCaps CryptBinaryToStringA SeDebugPrivilege ``` ----- ``` psapi dll ``` ----- #### About Outpost24 outpost24.com The Outpost24 group is pioneering cyber risk management with vulnerability management, application security testing, info@outpost24.com threat intelligence and access management – in a single solution. Over 2,500 customers in more than 65 countries trust Outpost24’s unified solution to identify vulnerabilities, [twitter.com/outpost24](https://twitter.com/outpost24) monitor external threats and reduce the attack surface with speed and confidence. Delivered through our cloud platform with powerful automation [linkedin.com/outpost24](https://se.linkedin.com/company/outpost24) supported by our cyber security experts, Outpost24 enables organizations to improve business outcomes by focusing on Blueliv ® is part of the Outpost24 Group. is a registred trademark of Leap inValue S.L. in the United States and other countries. All brand names, product names or trademarks belong to their respective owners. the cyber risk that matters © LEAP INVALUE S L ALL RIGHTS RESERVED -----