Post

BlackCat

BlackCat (also known as Noberus or ALPHV) is a sophisticated ransomware-as-a-service (RaaS) that has been used in operations since November 2021. It is believed to be a successor to the REvil, Darkside, and BlackMatter ransomware gangs, and it has connections to the FIN7 and FIN12 cybercrime groups.

BlackCat is notable for its technical sophistication. It is written in the Rust programming language. BlackCat is also highly customizable, allowing affiliates to tailor it to their specific needs.

Like all ransomware-as-a-service (RaaS) operations, the BlackCat operators recruit affiliates to perform corporate breaches and encrypt devices while retaining code maintenance and development responsibilities for themselves. The executable includes a JSON configuration that allows that customization. This includes extensions, ransom note details, encryption, services targeted for termination and whitelisted folders/files/extensions.

Attack Flow graph :

Attack flow graph

Sample Analysis

PropertyValue
File Type32-bit executable
SHA-256ECEA6B772742758A2240898EF772CA11AA9D870AEC711CFFAB8994C23044117C
SSDEEP49152:VUzeOdI+NDXIgqUPGPiTgvRZHrn7hQyZ9haNSAXpuNh/RgaJ2wf3:VUzekDpRGaTARZHPhQMCcyYvwwf3

The sample provided works as a command-line tool with a couple of options

black_cat

So for this to run, it requires an access token to be provided, as mentioned earlier Since it’s a RaaS I believe such a token is to identify affiliates by the BlackCat authors as they let other attackers use their ransomware, conduct their own campaigns, and keep a percentage of what they earn. Most RaaS operations allow affiliates to keep 70% of their profits. With BlackCat, however, affiliates can expect to keep 80-90%.

Additionally requiring such a token to run would work as an anti-sandbox technique for most sandboxes.

Here’s how it runs with verbose option :

black_cat verbose

We can also find the configuration in JSON format:

black_cat

It contains the public RSA key, the extension to be used after encryption, ransom note text, services/processes to kill to disable recovery/not to be interrupted/noticed while it runs, file extensions/directories/files to avoid, and network propagation capability etc…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
{
  "config_id": "",
  "public_key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAq8kj5LQJngPsY7AhTaJsUXc5FrSGeKS5gw5PIqk2QPM9TY6+us8TRRzWZ7rGk1zns2klpzpRMUzLIqB8lpCkJjqkOUGfgqs+HN4VIOpoJgFY897xstJCxTc+8pYQEsSqClxJllscU0okkLSQqndIR2Gznlg3qfcwyncJAFBInyqM+L4kbwCQZ6x5HNiLe2lJn8RP2aDiMI+RS1uLYron2G7rxDTUQnxThMtgLAeko8ulaB3TpB0g4lmHCenkEZeBNs81986+MjHnv7KkiscZ7ZrezKjNaIxRs8BAcD9y+Q9QQxCvZMS01ITNXcgiItbA4dsGq1fPJ42yBkkiIodsEQIDAQAB",
  "extension": "kh1ftzx",
  "note_file_name": "RECOVER-${EXTENSION}-FILES.txt",
  "note_full_text": ">> What happened?\n\nImportant files on your network was ENCRYPTED and now they have \"${EXTENSION}\" extension.\nIn order to recover your files you need to follow instructions below.\n\n>> Sensitive Data\n\nSensitive data on your system was DOWNLOADED.\nIf you DON'T WANT your sensitive data to be PUBLISHED you have to act quickly.\n\nData includes:\n- Employees personal data, CVs, DL, SSN.\n- Complete network map including credentials for local and remote services.\n- Private financial information including: clients data, bills, budgets, annual reports, bank statements.\n- Manufacturing documents including: datagrams, schemas, drawings in solidworks format\n- And more...\n\n>> CAUTION\n\nDO NOT MODIFY ENCRYPTED FILES YOURSELF.\nDO NOT USE THIRD PARTY SOFTWARE TO RESTORE YOUR DATA.\nYOU MAY DAMAGE YOUR FILES, IT WILL RESULT IN PERMANENT DATA LOSS.\n\n>> What should I do next?\n\nFollow these simple steps to get everything back to normal:\n1) Download and install Tor Browser from: https://torproject.org/\n2) Navigate to: http://rfosusl6qdm4zhoqbqnjxaloprld2qz35u77h4aap46rhwkouejsooqd.onion/?access-key=${ACCESS_KEY}",
  "note_short_text": "Important files on your network was DOWNLOADED and ENCRYPTED.\nSee \"${NOTE_FILE_NAME}\" file to get further instructions.",
  "default_file_mode": "Auto",
  "default_file_cipher": "Best",
  "credentials": [],
  "kill_services": [
    "mepocs",
    "memtas",
    "veeam",
    "svc$",
    "backup",
    "sql",
    "vss",
    "msexchange",
    "sql$",
    "mysql",
    "mysql$",
    "sophos",
    "MSExchange",
    "MSExchange$",
    "WSBExchange",
    "PDVFSService",
    "BackupExecVSSProvider",
    "BackupExecAgentAccelerator",
    "BackupExecAgentBrowser",
    "BackupExecDiveciMediaService",
    "BackupExecJobEngine",
    "BackupExecManagementService",
    "BackupExecRPCService",
    "GxBlr",
    "GxVss",
    "GxClMgrS",
    "GxCVD",
    "GxCIMgr",
    "GXMMM",
    "GxVssHWProv",
    "GxFWD",
    "SAPService",
    "SAP",
    "SAP$",
    "SAPD$",
    "SAPHostControl",
    "SAPHostExec",
    "QBCFMonitorService",
    "QBDBMgrN",
    "QBIDPService",
    "AcronisAgent",
    "VeeamNFSSvc",
    "VeeamDeploymentService",
    "VeeamTransportSvc",
    "MVArmor",
    "MVarmor64",
    "VSNAPVSS",
    "AcrSch2Svc"
  ],
  "kill_processes": [
    "agntsvc",
    "dbeng50",
    "dbsnmp",
    "encsvc",
    "excel",
    "firefox",
    "infopath",
    "isqlplussvc",
    "msaccess",
    "mspub",
    "mydesktopqos",
    "mydesktopservice",
    "notepad",
    "ocautoupds",
    "ocomm",
    "ocssd",
    "onenote",
    "oracle",
    "outlook",
    "powerpnt",
    "sqbcoreservice",
    "sql",
    "steam",
    "synctime",
    "tbirdconfig",
    "thebat",
    "thunderbird",
    "visio",
    "winword",
    "wordpad",
    "xfssvccon",
    "*sql*",
    "bedbh",
    "vxmon",
    "benetns",
    "bengien",
    "pvlsvr",
    "beserver",
    "raw_agent_svc",
    "vsnapvss",
    "CagService",
    "QBIDPService",
    "QBDBMgrN",
    "QBCFMonitorService",
    "SAP",
    "TeamViewer_Service",
    "TeamViewer",
    "tv_w32",
    "tv_x64",
    "CVMountd",
    "cvd",
    "cvfwd",
    "CVODS",
    "saphostexec",
    "saposcol",
    "sapstartsrv",
    "avagent",
    "avscc",
    "DellSystemDetect",
    "EnterpriseClient",
    "VeeamNFSSvc",
    "VeeamTransportSvc",
    "VeeamDeploymentSvc"
  ],
  "exclude_directory_names": [
    "system volume information",
    "intel",
    "$windows.~ws",
    "application data",
    "$recycle.bin",
    "mozilla",
    "$windows.~bt",
    "public",
    "msocache",
    "windows",
    "default",
    "all users",
    "tor browser",
    "programdata",
    "boot",
    "config.msi",
    "google",
    "perflogs",
    "appdata",
    "windows.old"
  ],
  "exclude_file_names": [
    "desktop.ini",
    "autorun.inf",
    "ntldr",
    "bootsect.bak",
    "thumbs.db",
    "boot.ini",
    "ntuser.dat",
    "iconcache.db",
    "bootfont.bin",
    "ntuser.ini",
    "ntuser.dat.log"
  ],
  "exclude_file_extensions": [
    "themepack",
    "nls",
    "diagpkg",
    "msi",
    "lnk",
    "exe",
    "cab",
    "scr",
    "bat",
    "drv",
    "rtp",
    "msp",
    "prf",
    "msc",
    "ico",
    "key",
    "ocx",
    "diagcab",
    "diagcfg",
    "pdb",
    "wpx",
    "hlp",
    "icns",
    "rom",
    "dll",
    "msstyles",
    "mod",
    "ps1",
    "ics",
    "hta",
    "bin",
    "cmd",
    "ani",
    "386",
    "lock",
    "cur",
    "idx",
    "sys",
    "com",
    "deskthemepack",
    "shs",
    "ldf",
    "theme",
    "mpa",
    "nomedia",
    "spl",
    "cpl",
    "adv",
    "icl",
    "msu"
  ],
  "exclude_file_path_wildcard": [],
  "enable_network_discovery": true,
  "enable_self_propagation": true,
  "enable_set_wallpaper": true,
  "enable_esxi_vm_kill": true,
  "enable_esxi_vm_snapshot_kill": true,
  "strict_include_paths": [],
  "esxi_vm_kill_exclude": []
}

BlackCat has 3 TLS callbacks that work as initialization, in addition to setting up Structured Exceptions using SetUnhandledExceptionFilter

It utilizes named pipes to operate and encrypt system files, It creates 2 pipes with FILE_ATTRIBUTE_READONLY and FILE_ATTRIBUTE_HIDDEN attributes, and each pipe is named by adding the BlackCat PID into a randomly generated number concatenated to the string \\\\.\\pipe\\__rust_anonymous_pipe1__. example:

named pipe

PID

It also queries if it has the following privileges and tries to grant it to itself :

1
SeIncreaseQuotaPrivilege, SeSystemProfilePrivilege, SeSecurityPrivilege, SeTakeOwnershipPrivilege, SeLoadDriverPrivilege, SeSystemtimePrivileg, SeRestorePrivilege, SeShutdownPrivilege, SeDebugPrivilege, SeSystemEnvironmentPrivilege, SeChangeNotifyPrivilege, SeRemoteShutdownPrivilege, SeUndockPrivilege, SeManageVolumePrivilege, SeImpersonatePrivilege, SeCreateGlobalPrivilege, SeIncreaseWorkingSetPrivilege, SeTimeZonePrivilege, SeCreateSymbolicLinkPrivilege, SeDelegateSessionUserImpersonatePrivilege

tokens

If BlackCat isn’t running with admin privileges, It attempts to bypass UAC using CMSTPLUA COM interface. Here’s a POC here and here. It uses CoGetObject, CoInitializeEx and the CLSID {3E5FC7F9-9A51-4367-9063-A120244FBEC7}.

clsid ref

It also checks if the user is a domain admin and gets the username/PCname.

BlackCat spawns CMD processes to do the following using the previously created pipes:

  • Getting UUID which I believe is used (with Username and PCname) to generate an access token for the victim on the affiliates’ site.

    UUID

  • Allowing remote-to-local and remote-to-remote symbolic links for file_work.rs file which could contain code that is used by ransomware to encrypt files and it is also often used by ransomware to spread to other drives/machines on the infected network.

    fsutil behavior set SymlinkEvaluation R2R:1

    symlink

  • Stopping the Internet Information Services (IIS) service.

    iisreset.exe /stop

  • Modifying the registry to change the MaxMpxCt setting. The MaxMpxCt setting controls the maximum number of outstanding SMB requests that a server can handle. By increasing the MaxMpxCt setting to 65535, the server can handle more concurrent SMB requests therefore helping in the process of reading/writing or encrypting files.

    reg add HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\LanmanServer\\Parameters /v MaxMpxCt /d 65535 /t REG_DWORD /f

  • Deleting shadow copies that work as a backup.

    vssadmin.exe Delete Shadows /all /quiet\

    wmic.exe Shadowcopy Delete\

  • Gather information about the network.

    arp -a

  • It tries to use BCDedit to set the value of a boot configuration data (BCD) entry but the command doesn’t seem to be correct or complete. Perhaps it was intended for something else but wasn’t completely implemented.

    bcdedit /set {default}

  • Disables the recovery environment for the default boot entry in the Windows boot configuration data (BCD).

    bcdedit /set {default} recoveryenabled No

  • Clears all event logs on the machine.

    cmd.exe /c for /F \\\"tokens=*\\\" %1 in ('wevtutil.exe el') DO wevtutil.exe cl \\\"%1\\\"\"

BlackCat priorities encryption for \Device\HarddiskVolume2\Recovery\WindowsRE\boot.sdi, Winre.wim which is a Windows Recovery Environment (Windows RE) image file and ReAgent.xml this is to prevent the victim from accessing Windows RE and the recovery tools. This makes it more difficult for the victim to recover their files without paying the ransom.

I do believe it also mounts the hidden recovery partition to encrypt that as well. A recovery partition is a special partition on the system hard drive and is used to restore the system to factory settings in the event of system issues.

It also tries to traverse volumes trying to resolve volume symbolic links in an attempt to self-propagate to other network machines. It also utilizes PsExec to execute a command on a remote computer and then detach from the remote session.

psexec

Here it creates the ransom note on the desktop :

ransom note

ransom note

It also creates the short ransom note image that will be set as a desktop background.

ransom note

ransom note

The ransom note is also added in all system folders along with checkpoint files that will later be deleted.

BlackCat spawns multiple threads for file encryption.

BlackCat uses AES encryption with a randomly generated key using BCryptGenRandom.

The way this works is:

  • It iterates over system files using FindFirstFileW and FindNextFileW.
  • generates the random AES key and builds up a JSON block containing information about chunk size, algorithm used (AES) and key used.
  • Such JSON formatted block is encrypted using the public key provided in the configuration.
  • After that, the encrypted block is written at the end of the file in addition to changing the file extension to kh1ftzx.
  • Later on, it reiterates these files encrypting their content and writing it.

The affiliates should have the private key required to decrypt the JSON block and therefore the AES key to decrypt file contents, so unfortunately I don’t think I’m able to write a decryptor at the moment.

json block

Here the JSON block is being written in the process heap.

json key

The beginning and end of the encrypted JSON block are bounded with the bytes 19 47 B3 01.

writing to file

Here it writes the bytes indicating the end of the file/JSON block.

IOCs

Files

  • RECOVER-kh1ftzx-FILES.txt
  • RECOVER-kh1ftzx-FILES.txt.png SHA256: 586a861604dc00f0308a4370f4681e146672f6df13a0fa6f2caef7dba320c0da
  • checkpoints-{filename}.kh1ftzx

Pipes

  • \\\\.\\pipe\\__rust_anonymous_pipe1__{PID}__{RND GEN NUM}

URLs

  • hxxp://rfosusl6qdm4zhoqbqnjxaloprld2qz35u77h4aap46rhwkouejsooqd[.]onion/?access-key=${ACCESS_KEY}

YARA Rule

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
rule BlackCat {
   meta:
      author = "@3weSxZero"
      date = "2023-08-25"
      hash1 = "ECEA6B772742758A2240898EF772CA11AA9D870AEC711CFFAB8994C23044117C"

   strings:
      $s1 = "\"config_id\":" ascii

      $s2 = "\"public_key\":\"" ascii

      $s3 = "enable_esxi_vm_snapshot_kill" ascii

      $x1 = "access-tokenpathsno-netno-propno-wallno-vm-killno-vm-snapshot-killno-vm-kill-namesno-prop-serverspropagatedchilddrop-drag-and-dr" ascii

      $x2 = "cmd.exe /c  for /F \"tokens=*\" %1 in ('wevtutil.exe el') DO wevtutil.exe cl \"%1\"" fullword ascii

      $x3 = "op-targetdrag-and-droplog-fileverboseextra-verboseuibypassACCESS_TOKENAccess TokenPATHSOnly process files inside defined pathsDo" ascii

      $x4 = "drag-and-drop-target.bat${EXECUTABLE}${ACCESS_TOKEN}recycle\\S-clean=ZIh" fullword ascii

      $x5 = " defined serversRun as propagated processRun as child processDrop drag and drop target batch fileInvoked with drag and dropLOG_F" ascii

      $y1 = "UncategorizedOtherOutOfMemoryUnexpectedEofInterruptedArgumentListTooLongFilenameTooLongTooManyLinksCrossesDevicesDeadlockExecuta" ascii

      $y2 = "_RC:\\Users\\runneradmin\\.cargo\\registry\\src\\github.com-                                             .rs" fullword ascii

      $y3 = "ce\",\"SAP\",\"SAP$\",\"SAPD$\",\"SAPHostControl\",\"SAPHostExec\",\"QBCFMonitorService\",\"QBDBMgrN\",\"QBIDPService\",\"Acroni" ascii

      $y4 = "ILEEnable logging to specified fileLog to consoleLog more to consoleShow user interfaceBYPASSConfigextensionpublic_keynote_file_" ascii


   condition:
      uint16(0) == 0x5a4d and 2 of ($s*) and 2 of ($x*) and 2 of ($y*)
}

Config Extractor

Here’s a simple config extractor I wrote for this sample :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import os
import pefile

def config_extract(filename):
    pe = pefile.PE(filename)

    for section in pe.sections:
      if ".rdata" in section.Name.decode():
        config_start_offset = section.get_data().decode('latin-1').find("{\"config_id")
        if config_start_offset == -1 :
           return config_start_offset
        config_end_offset = section.get_data().decode('latin-1').find("]}",config_start_offset, )
        data = section.get_data().decode('latin-1')[config_start_offset:config_end_offset+2]
    return data

def main():
    files = os.listdir()
    for file in files:
            with open(file, "rb") as f:
                magic_number = f.read(2)
                if magic_number == b"MZ":
                    filename = file
                    data = config_extract(filename)
                    if data == -1 :
                        print("couldn't find config, maybe it's located elsewhere or encrypted. please make sure you have the right file.\n")
                    else :
                        print(f"File {filename} -- CONFIG : \n")
                        print(data)
                        print(f"\n================= \n")
                
if __name__ == '__main__':
    main()

Output Example :

config_extractor

Removal Tool

Sadly, since the affiliates would have the private RSA key, I won’t be able to construct a file decryption script.

Yet, here’s a simple removal tool I wrote based on my YARA rule :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import yara
import os

rules = yara.compile(filepaths={
  'blackcat_rule':"rules\\BlackCat_rule.yar"
})

def removal_routine(data=None):
    if data != None :
        print(f"[MATCHED] File :: {file.name} ---- Attempting DELETION\n")
        try :
            file.close()
            os.remove(file.name)
        except() as error:
            print(f"error on deleting {file.name} :: {error} \n")
            pass
        print(f"[DELETED] File :: {file.name} \n")
    return yara.CALLBACK_CONTINUE

directory ='DIR_Name'
for filename in os.listdir(directory):
    f = os.path.join(directory, filename)
    # checking if it is a file
    if os.path.isfile(f):
        with open(f, 'rb') as file:
            matches = rules.match(data=file.read(), callback=removal_routine, which_callbacks=yara.CALLBACK_MATCHES)

MITRE ATT&CK® TTPs

IDNameUse
T1059.003Command and Scripting Interpreter: Windows Command ShellExecute commands on a compromised machine using cmd.exe
T1134Access Token ManipulationModify access tokens
T1548.002Abuse Elevation Control Mechanism: Bypass User Account ControlBypass UAC to escalate privileges
T1082System Information DiscoveryObtain the computer name and UUID, and enumerate local drives
T1069.002Permission Groups Discovery: Domain GroupsDetermine if a user on a compromised host has domain admin privileges
T1033System Owner/User DiscoveryDiscover the user name on a compromised host
T1222.001File and Directory Permissions Modification: Windows File and Directory Permissions ModificationAllowing remote-to-local and remote-to-remote symbolic links to spread to other machiens on the infected network
T1489Service StopAbility to stop services (including VMs’) and processes on compromised machines
T1112Modify RegistryModifying the registry to change the max number of SMB requests handled by a server/machine therefore helping in the process of reading/writing or encrypting files
T1490Inhibit System RecoveryDeleting shadow copies and modify the boot loader to disable recovery options
T1016System Network Configuration DiscoveryGather information about the network
T1070.001Indicator Removal: Clear Windows Event LogsClears all event logs on the infected machine
T1570Lateral Tool TransferInfect other machines on the same network using PsExec
T1047Windows Management InstrumentationUsing wmic.exe to delete shadow copies on infected machines
T1083File and Directory DiscoveryEnumerate system files for encryption
T1491.001Defacement: Internal DefacementChange the desktop wallpaper on infected machines
T1486Data Encrypted for ImpactEncrypt system files
T1561.001Disk Wipe: Disk Content WipeDeletes VM (ESXi) snapshots

References

https://www.cisecurity.org/insights/blog/breaking-down-the-blackcat-ransomware-operation

This post is licensed under CC BY 4.0 by the author.