Skip Navigation
BlackBerry Blog

PYSA Loves ChaChi: a New GoLang RAT

Executive Summary

The BlackBerry Threat Research and Intelligence SPEAR® Team have been tracking a previously unnamed Golang remote access Trojan (RAT) targeting Windows® systems. We’ve dubbed this RAT ChaChi. This Trojan has been used by operators of the PYSA (aka Mespinoza) ransomware as part of their toolset to attack victims globally, but most recently targeting education organizations.

ChaChi is another entry in the expanding list of malicious software written in Go, also known as Golang, which is a relatively young programming language. As this is such a new phenomenon, many core tools to the analysis process are still catching up. This can make Go a more challenging language to analyze.

ChaChi has been observed in the wild since at least the first half of 2020 without receiving much attention from the cybersecurity industry. The first known variant of ChaChi was used in attacks on the networks of local government authorities in France, and was listed as an indicator of compromise (IoC) in a publication by CERT France at the time of the attacks.

That first variant of ChaChi was very clearly a new tool in the PYSA operator’s arsenal as it lacked the obfuscation, port-forwarding and DNS tunnelling capabilities that were employed in the vast majority of observed variants, since those attacks indicated some time was invested to rapidly develop ChaChi into the tool it is today.

Since then, BlackBerry analysts have observed the later, more refined versions of ChaChi being deployed by the PYSA Ransomware operators in a campaign that has shifted its focus to targeting educational institutions across the U.S., which has seen a recent increase in activity as reported by the FBI.

BlackBerry has conducted many investigations and responded to incidents involving PYSA ransomware in which ChaChi was also identified on hosts in the victim environment.

Key highlights of the PYSA campaign include:

  • Defense Evasion: PowerShell scripts to uninstall/stop/disable antivirus and other essential services.
  • Credential Access: Dumping credentials from LSASS without Mimikatz (comsvcs.dll).
  • Discovery: Internal network enumeration using Advanced Port Scanner.
  • Persistence: ChaChi installed as a Service.
  • Lateral Movement: RDP and PsExec.
  • Exfiltration: Likely over ChaChi tunnel (not observed).
  • Command and Control (C2): ChaChi RAT.

Introduction

The name ChaChi comes from two key components of the RAT, Chashell and Chisel. These are tools used by the malware operators to perform their intended actions, rather than creating bespoke tools to accomplish this functionality.

The first versions of PYSA have been floating around since late 2018. This threat’s name comes from the file extension (.PYSA) used by early variants to rename encrypted files, and from its ransom note that warned victims to “Protect Your System Amigo.”

This threat is also sometimes referred to as Mespinoza, so named because of the email address used in the dropped ransom notes. The actors behind the PYSA/Mespinoza ransomware campaigns have not been publicly attributed at the time of writing.

The PYSA campaigns are some of the latest in a relatively new breed of malware. Rather than depending on automated propagation to find new victim machines by searching for exploits and vulnerabilities, PYSA campaigns follow the style of “big game hunting” or human-orchestrated and controlled attacks on a given target.

This is a notable change in operation from earlier notable ransomware campaigns such as NotPetya or WannaCry. These actors are utilizing advanced knowledge of enterprise networking and security misconfigurations to achieve lateral movement and gain access to the victim’s environments. These newer types of attacks frequently exfiltrate data, steal credentials, and use other commodity malware in addition to bespoke malware such as ChaChi during campaigns.

PYSA Attacks Change Targets

The earliest variant of ChaChi was used in attacks on the networks of local government authorities in France in March of 2020. Since then, PYSA, and therefore ChaChi, have been observed in attacks across a variety of industries. This includes healthcare organizations, private companies, and most notably, a recent surge in attacks against educational institutions as reported by the FBI earlier this year. In these recent attacks, PYSA ransomware has been found across 12 U.S. states and in the UK, in data breaches targeting higher education and K-12 schools.

These targeted business verticals have been a focal point for attackers and are continuing to be compromised at an alarming rate. This may be due in part to healthcare and educational organizations being more susceptible to cyberattacks as they are less likely to have established security infrastructures or may lack the resources to prioritize security.

Healthcare and education organizations also host large volumes of sensitive data, making them more valuable targets. It is not uncommon for schools and hospitals to have legacy systems, poor email filtering, no data backups, or unpatched systems in their environments. This leaves their networks more vulnerable to exploits and ransomware attacks.

It is particularly concerning that attackers are focusing so heavily on education organizations, as they are especially vulnerable. Higher education environments tend to function like miniature cities, with a heavy cultural emphasis on information-sharing. Not only do they host significant quantities of business data; schools also host traffic from students living on campus.

These students often have little security awareness training, and they might fall victim to suspicious emails, fail to recognize questionable websites, or download malicious programs onto their personal devices while connected. These factors contribute to these industries being easy but valuable targets to threat actors and may explain the sudden increase in PYSA actors attacking educational institutions.

Evolution

It is possible to map out an approximate timeline for the evolution of ChaChi by taking a number of factors into account such as:

  • First documented sightings of ChaChi variants in the wild.
  • First seen dates of C2 Domains extracted from samples of ChaChi.
  • First occurrences of specific functionality in ChaChi variants.

Correlation of each of these data points allow us to give an approximation for the code development timeline for ChaChi:

Figure 1 - Approximate ChaChi Evolution Timeline.

We estimate that ChaChi was first developed no earlier than mid-2019. The actual development time was more likely to be the beginning of 2020.

After initial sightings in attacks during the first quarter of 2020, ChaChi’s code was altered to include obfuscation and persistence in late March or early April. Very soon after that, we started seeing ChaChi variants with the added DNS tunnelling and Port-Forwarding/Proxy functionality. There have been few noteworthy changes after that point.

Obfuscation

Golang malware has been around for a number of years, but obfuscation of Go malware is still relatively uncommon. The Ekans ransomware appeared to be leveraging a new Go obfuscation technique in December 2019, although the technique was not explicitly named at the time.

At the end of 2020, researchers reported the discovery of “BlackRota”, an ELF backdoor written in Go. They declared it “the most obfuscated Go-written malware in ELF format that we have found to date”.

The obfuscation used in Ekans, BlackRota and subsequently ChaChi, was “gobfuscate”, a Golang obfuscation tool publicly available on GitHub. BlackBerry analysts observed samples of ChaChi actively using gobfuscate shortly after the release of Ekans, but several months prior to the discovery of BlackRota.

Gobfuscate attempts to make a lot of information that would normally be easily available to the researcher very difficult to recover. It obfuscates the runtime symbol table and type information, such as package names, function names etc., by replacing them with randomly generated names, and obfuscating strings by replacing them with functions:

Figure 2 - Gobfuscated Function Names.

Figure 3 - Gobfuscated String, which is now a function.

This obfuscation was designed with the purpose of avoiding information leakage relating to the Go source code, such as strings, package paths and field names. It has since been adopted by malware authors as a means of hindering analysis and reverse engineering efforts.

Since its discovery as a tool for defence evasion, there have been a number of quite successful attempts and blog postings dedicated to automating string de-obfuscation using plugins for both Binary Ninja and Cutter. However, at the time of writing, there is no such plugin or script in existence for IDA.

BlackBerry analysts have developed an internal tool – a IDAPython script – to handle string “de-gobfuscation” and subsequently reduce the time required to analyse gobfuscated binaries. Once the de-gobfuscation script is run across the ChaChi binary when loaded into IDA, it will locate all string decoding functions, extract the encoded bytes, and then perform the necessary XOR operation to recover the original strings. These strings are then used to rename all the decoding functions within, where an encoded string was found, and additionally add comments to the disassembly code view where necessary:

Figure 4 - De-Gobfuscated String Function.

With the string gobfuscation defeated, there was still the problem of the randomly named packages, etc. On the surface, the obfuscation of the names appeared to be an effective deterrent to analysis. However, when it was investigated more deeply, this was not overly difficult to overcome.

Package names are renamed in a consistent and uniform manner such that components of the same package, function etc. share the same random name. When you combine this knowledge with the fact that the function method names remain largely unaffected by the obfuscation, then once the usage of a particular package was discovered, all entries that used the same random name could also be renamed via a simple IDAPython helper script:

Figure 5 - Gobfuscated Function Names.

Figure 6 – De-gobfuscated Function Names.

With the obfuscation defeated, efforts could be refocused on analysing ChaChi’s functionality and intent.

Persistence

Shortly after its initial execution ChaChi decodes a service name and service description:

Figure 7 - Decode Service Name and Description.

Using the decoded service name, ChaChi enumerates all installed services to check if a service with the same name already exists. In this case, it is named “JavaJDBC”. If a service with the specified name is found, then ChaChi will randomly select another service name from a hardcoded, albeit gobfuscated, list of service name strings:

Figure 8 - Check if Service Name Exists.

Figure 9 - Decoding Alternate Service Names.

After determining an appropriate name to use for service installation, ChaChi then checks to see if it has sufficient administrator privileges to carry out the service creation operation:

Figure 10 - Checking if running with Administrative Privileges.

If ChaChi is not running with administrative privileges, it bypasses its persistence code and begins to initialize command-and-control (C2) communications. If the backdoor is running with administrative privileges, it will install itself as a new service that is configured to auto-start, before manually starting the service:

Figure 11 - Install as Service and Start the Service.

C2 Communications

ChaChi utilizes two protocols for C2 communications: DNS and HTTP. The primary, preferred method of C2 communication is DNS tunnelling using TXT queries.

TXT or “text” records were originally intended to allow domain admins to associate arbitrary text with a domain, such as domain ownership information or network and server information. Threat actors have taken advantage of this for their own nefarious needs by encoding data in these TXT queries, which is a form of DNS tunnelling.

DNS tunnelling allows malware authors to communicate in a covert channel that can bypass most firewalls. DNS traffic is widely used, and often blindly trusted with little to no monitoring. DNS requests can also get proxied via internal DNS resolvers, making it more difficult to track infected endpoints:

Figure 12 - DNS traffic generated by ChaChi.

Should the DNS communications fail for whatever reason, ChaChi also contains a failover mechanism where it uses HTTP in the form of encoded POST requests to communicate with its C2 servers. HTTP POST requests are generally used to send data to a server to create or update a resource on that server. ChaChi uses these requests for C2 communications instead. Before it can attempt to establish C2 communications, it must first decode its embedded C2 server domains and IP addresses.

Decoding C2 IPs and Domains

ChaChi is preconfigured with a list of C2 domains for DNS tunnelling, as well as IP addresses for HTTP C2 failover. The domains are encoded just like any other string in a gobfuscated binary, using a dedicated function that carries out the XOR decode process:

Figure 13 - C2 Domains are Decoded from Gobfuscated functions.

The domain that will be used is chosen at random through the use of “Intn” from the “rand” package, which is seeded by the value returned from an earlier call to “time.Now”:

Figure 14 - Randomizing C2 Domain Selection.

The decoding of the C2 IP addresses is a little more complicated, although not overly so. As with the C2 domains, the inevitable selection of a C2 IP address is also randomized through calls to “time.Now”, “rand.Seed” and “rand.Shuffle”. The C2 IP decoding function takes several arguments: a pointer to the encoded C2 IP array, an integer value indicating the number of encoded IP addresses, and a hex number used in the decoding of each octet of each IP address. The decoding of the C2 IP addresses works as follows:

  • Read a word (2 bytes) at the initial offset into the C2 IP array determined by the earlier shuffle.
  • Subtract the hex number (0xA in all observed cases) from the retrieved value.
  • Convert the result to its base 10 equivalent (thereby creating a single octet of an IP).
  • Repeat 4 times per encoded IP.
  • Join the decoded octets with a "." (thus fully decoding a stored C2 IP address).

These steps are repeated until all IP addresses have been decoded

The equivalent Python code for the decoding operation can been seen below, or an example CyberChef recipe operating on one encoded IP address can be found here.

Figure 15 - Python Code for C2 Decode.

With the C2 addresses decoded, ChaChi can now initiate a connection to its C2 infrastructure.

Modified Chashell

Rather than implement an entirely bespoke means of DNS tunnelling, the developers opted to leverage an off-the-shelf solution (or at least components of that solution). They used a package called Chashell that provides a reverse shell over DNS.

Chashell operates by taking data from a shell or terminal that it serializes into Protocol Buffers before encrypting it using symmetric encryption in the form of XSalsa20 + Poly1305. This encrypted data is then hex encoded and packed into a TXT query. The response to the TXT query is also subject to the same protocol buffer serialization, encryption, and hex encoding:

Figure 16 - Chashell DNS tunnelling Query and Response.

The default Chashell client takes a target domain and symmetric encryption key at build time, both of which are hardcoded. These are then used to establish the encrypted DNS tunnel to the Chashell server. Once a connection is established, it redirects the standard input/output/error from “cmd.exe” or “/bin/sh” – depending on the operating system target – into the DNS tunnel, thereby creating a reverse shell:

Figure 17 - Standard Chashell Client Code.

The ChaChi operators borrowed the DNS tunnelling transport mechanism from Chashell, but it is no longer operating as a simple reverse shell. They instead opted to make several modifications, including the removal of the default action of spawning a reverse shell, and the addition of an extra layer of encoding on some of the data passing through the DNS stream.

In effect, Chashell is just a cog in the machine that is ChaChi, so it can achieve covert C2 communications. As mentioned, not all data traversing the DNS tunnel is subjected to this additional encoding, which is reserved for a specific proto-buffer field, of which there are five in use by Chashell:

Figure 18 - Chashell Protocol Buffer Message.

  • ClientGUID: This field is an ID that uniquely identifies messages from a specific client so they can be correctly processed by the server. ClientGUID fields are present in all messages.
  • ChunkStart: This message is used to identify messages that belong to the same “chunk”.
  • ChunkData: This is the message which transports the core data that will traverse the tunnel. In the case of a standard Chashell, this would contain the output of the standard streams. These messages contain data that needs to be reconstructed based on the information provided by a “ChunkStart” message.
  • PollQuery: These messages are like heartbeat messages from the client to the server to query if there are commands/data waiting to be transmitted.
  • Infopacket:These messages are used to transport the hostname of the client to the server as a means of more easily identifying active Chashell sessions. Only the “ChunkData” messages, in particular the “packet” field of that message, are subjected to the additional custom encoding that is not present in the standard Chashell client source code:

Figure 19 - ChunkData message structure.

The encoding in “ChunkData” messages happens immediately prior to serializing the data into a protocol buffer, and it is performed in two steps. Step one involves Base64-encoding the data, which is then passed to another function that performs XOR encoding using a hardcoded string:

Figure 20 - Base64 and XOR encoding prior to Serialization.

Now that we understand how data is encoded, serialized, and encrypted, and we can recover both the XOR key and symmetric encryption key through de-Gobfuscation, it is possible to decrypt ChaChi traffic. We will discuss the decryption process in more depth later. In all samples found and analyzed, the XOR key used was “d*ck” (replace * with an i) and the encryption key was “37c3cb07b37d43721b3a8171959d2dff11ff904b048a334012239be9c7b87f63”. This leaves little doubt that it is a singular threat actor or group behind all attacks where a ChaChi binary was found.

Alternative/Failover C2

As already mentioned, ChaChi will initially attempt to establish C2 communications over DNS via Chashells DNS Streams. Should those initial attempts fail, it will failover to HTTP:

Figure 21 - C2 Communications Failover.

This failover method is not ideal for the ChaChi operators. It does not offer the encryption afforded to the DNS tunnelling, and it is nowhere near as covert.

The HTTP C2 communications are performed using POST requests to one of the randomly selected C2 IPs decoded earlier. The content of the HTTP POST is encoded using Base64 and XOR encoding to offer some level of data protection, in the same way as the data was encoded prior to being serialized into the “ChunkData” messages in the case of DNS tunnelling.

Should the C2 check-in fail, it will rotate through the other decoded C2 IPs in an attempt to create a connection. If a connection is established, ChaChi will encode and send POST requests to the C2 and process its responses:

Figure 22 - HTTP POST Request and Response Processing.

Decrypting C2 Traffic

As the use of HTTP for C2 communications is less complicated and involves less steps when compared to DNS tunnelling, this section will focus on decryption of DNS traffic.

Decryption of both HTTP and DNS C2 traffic is possible because, once we obtain both the XOR and encryption keys, we can reverse the process that has taken plaintext data and converted it to an encrypted form. Each phase in the encoding and encryption process is reversible:

Figure 23 - Encoding and Encryption Process to generate TXT Query.

To do this, we perform the following steps:

  • Retrieve DNS TXT queries from packet captures or DNS logs.
  • Strip the domain name and “.” separators.
  • Decode the string from hex back to bytes.
  • Run the decoded content along with the recovered encryption key through a XSalsa20+Poly1305 decryption process.
  • De-serialize the decrypted data in order to access the packet field of the “ChunkData” messages – other message types are fully decrypted at this point.
  • Apply XOR decoding using the recovered XOR key to the packet field of each “ChunkData” message.
  • Base64-decode the result of the XOR operation.

The result of the above process yields decrypted and de-serialized protocol buffers as well as the original data that was encoded and packed into “ChunkData” packets. Given our knowledge of the Chashell protocol buffer message structure, we just need to search through the proto-buffer messages for “ChunkStart” messages. These will inform us about both the number of chunks that make up the original data, and also the exact “ChunkData” messages containing that data:

Figure 24 - ChunkStart Message Structure.

If we do this successfully (and apply some formatting), we are able to decrypt the C2 traffic that is exchanged between the ChaChi server and client. If the ChaChi operators were leveraging a standard Chashell build, we would see something like the content below in the decrypted traffic, where it is evident that a reverse shell has been established:

Figure 25 - Traffic decrypted and Rebuilt from Standard Chashell.

C2 Check-In and Commands

The initial check-in data that is sent to the C2 server takes the following form:

Figure 26 - C2 Check-in Structure.

The “ID” is a hardcoded string value that varies between samples, but generally starts with a 1, 2 or 9, followed by 3 digits (e.g., “1018”). The last three digits are decoded from a gobfuscated string, and the first digit is prepended to the check-in string shortly before check-in.

The MD5 hash is the result of hashing a randomly generated integer value that changes every time ChaChi is executed.

The computer name and username are obtained through the execution of two PowerShell commands that retrieve the values stored in the relevant environment variables:

Figure 27 - Obtaining Computer and Username using PowerShell.

There is a second check-in which occurs that contains just an ID, this time with 2 prepended instead of 1, and the same MD5 from the first check-in. No computer or username is used in the second check-in. Both check-in strings are encoded and encrypted using the method discussed earlier, but it is the responses to each of these individual check-ins that decides what happens next.

Below we can see the two C2 check-ins, and the responses from the server:

Figure 28 - Decrypted C2 Check-ins and Responses.

In the screenshot above, we can see the first check-in string. The response from the server to this first check-in is a string that contains the generated MD5 hash that was passed in the check-in, but with “-zig” appended to it.

The first character of this response (the “9”, in this case) is XOR’d with the first character of the XOR key that is also used in the C2 encoding process (“d” in the sample that generated the above traffic). The result of this XOR operation is further XOR’d with the first, and in this case only, character returned as a response to the second C2 check-in (the letter “m”). The result of these two XOR operations is the number “0”.

This resultant integer, which is not always zero, is the command ID component of a larger string that is passed to a function that will decide the next action that ChaChi has been instructed to take. The expected argument for the command selection function takes the form shown in the image below. The number of arguments expected varies depending on the command ID supplied to ChaChi, but no more than two arguments are expected to follow the command ID. Each element is delimited by triple forward slashes, “///”:

Figure 29 - Command selection and Argument Structure.

The possible command ID options and their corresponding action on the host is documented in the table below. Invalid command IDs will not be processed:

Command ID

Action

1

Decode Base64 encoded arguments and execute them as a command on the host

2

Start reverse SOCKS5 proxy server by connecting to provided client address:port

3

Start reverse SOCKS5 proxy server by connecting to provided client address:port

4

Restart C2 session

7

Start Chisel client

9

Uninstall backdoor – delete service and binary

Table 1 - ChaChi Command ID to Operation Mapping.

Command Execution

Should the ChaChi operators want to execute a command or run a program on the infected host, the expected command structure would look like the example below. The command to be executed (including any arguments and switches) is encoded into a single Base64 string. ChaChi will handle the decoding and parsing of the string into a command line array, splitting the decoded string on every space encountered:

Figure 30 - ChaChi Command Execution Structure.

If an attacker wanted to execute something as simple as “whoami”, the command received by ChaChi would look like the string below, where “whoami” is in Base64 encoded form:

Figure 31 - Format of "whoami" command.

ChaChi will parse this string, identify it as a command, decode it from Base64, and reconstruct the command line string:

Figure 32 - Base64 Decoding of command argument - "whoami".

If the program name itself contains no path separators (as is the case in this example), the underlying Go function “os.exec.Command” will resolve the complete path name where possible. Otherwise, it uses the name directly as the path before executing the command:

Figure 33 - Executing Command.

Reverse SOCKS5 Proxy

SOCKS proxies are a much-used tool by Red Teams and threat actors, as they offer a level of anonymity by making traffic appear as if it is originating from one machine when it is in fact coming from a different machine. SOCKS proxies and in particular reverse SOCKS proxies, can also provide attackers with a means of persistent access into an otherwise inaccessible private network from a machine on the Internet.

The developers of ChaChi again opted to avoid reinventing the wheel when they decided to add SOCKS proxy functionality into ChaChi. They have borrowed yet more code, this time from what appears to be rsocks.

“Rsocks” is a reverse SOCKS5 client and server, but only the server-side code has been integrated into ChaChi. A default rsocks build does not offer any form of encryption of the traffic traversing the proxy, so the ChaChi authors decided to add that functionality to their version of the code. They did this by swapping out the standard call to “net.Dial” with the more secure alternative “crypto[.]tls[.]DialWithDialer”, which encrypts the proxied traffic using TLS:

Figure 34 - Original rsocks source code with "net.Dial".

Figure 35 - Modified "rsocks" with added TLS encryption.

When the ChaChi operators wish to start the proxy server on the infected host, the expected command structure would look like the example in the picture below. In the case of the reverse SOCKS5 proxy, a command ID of 2 or 3 is accepted, because both have the exact same effect:

Figure 36 - Reverse SOCKS5 Proxy Command Structure.

The client address can take the form of an IP or domain. The example in the image below is trying to connect to a client listening on the same machine (i.e., 127.0.0.1) and port 8080. This is the equivalent of running “rsocks -connect 127.0.0.1:8080”. In the case of the ChaChi operators, the “127.0.0.1” could also be replaced by one of their public C2 IPs or domains:

Figure 37 - Reverse SOCKS5 proxy command example.

Base64 encoding is not a requirement for the reverse socks proxy. ChaChi simply parses out the client address and port, joins them with a colon, and passes that new string to the reverse SOCKS5 proxy setup code that sets up the proxy session:

Figure 38 - Passing parsed “client:port” string to reverse socks Go routine.

With a SOCKS5 proxy session established, the ChaChi operators can now run tools such as nmap through the proxy in order to scan the compromised internal network. As this is a reverse proxy, it is the server component that initiates the connection to the client. This is obviously the better option for the operators of ChaChi, because they will be operating from behind enemy lines, so to speak.

It is notable that the string “Starting server” from rsocks is not present in ChaChi. Instead, it is replaced with “Starting client”, which appears in other Golang-base SOCKS proxy code such as the rclient component of rsockstun. It is possible that this is a remnant of experimentation during the development process, as the first iteration of ChaChi was confirmed by BlackBerry analysts as using go-socks5, which is yet another Golang based SOCKS5 server. This indicates that ChaChi developers seem take what they require and leave what they don’t:

Figure 39 - Default "Starting server" string.

Figure 40 - Modified "Starting client" string.

New C2 Session

Command ID 4 triggers a new C2 session. No other arguments are expected or even parsed if they should be provided. This option would be useful in the event of a session timeout or if the session has become unresponsive and the attackers wanted to establish a fresh session. The other choice that is made is whether to connect over DNS or HTTP, but this is automatically determined by which connection protocol was successful in earlier attempts, rather than through any external action:

Figure 41 - Command ID 4 triggers a new C2 Connection over DNS or HTTP.

Chisel Client

Chisel is an application that simplifies port-forwarding and is useful in scenarios where an attacker might not have access to an SSH client or server, as SSH is normally the tool of choice for port-forwarding when it’s available. However, the majority of Windows operating systems either do not have it installed, or it is disabled by default.

Port-forwarding also has some other benefits that would prove useful to the authors of ChaChi, which is potentially why they decided to include the Chisel client in their backdoor.

As described by its README on GitHub, “Chisel is a fast TCP/UDP tunnel, transported over HTTP, secured via SSH … Chisel is mainly useful for passing through firewalls, though it can also be used to provide a secure endpoint into your network.”.

The Chisel client is activated using command ID 7. It expects to receive the IP or a domain name of the Chisel server and a port. As we will see later, this is exposed on the Chisel Server (which is the attacker’s box) that will be forwarded to the local SOCKS port, which is 1080:

Figure 42 - Chisel command example structure.

ChaChi will parse the address of the Chisel server and prepend it with http://, then append it with “:443”:

Figure 43 - Constructing the Chisel Server Address.

The provided port is concatenated with two other decoded strings to form a string that takes the form “R:0.0.0.0:<port>:socks”:

Figure 44 - Construction Chisel Port Forwarding String.

The constructed components are passed to a function that generates a new Chisel client, which – if it were run with a standalone Chisel binary – would look something like this:

Figure 45 - Equivalent Chisel Command.

In effect, this will establish a reverse port forwarding connection to the Chisel server located at evildomain[.]xyz and listening on port 443. It will forward any connections made to the server port 1337 to the local socks port, 1080, on the compromised host.

Because address “0.0.0.0” is specified as the local address on the server side, this would allow access to port 1337 from any interface on the server rather than just localhost. This should therefore allow the attackers to connect from anywhere on the Internet via evildomain[.]xyz:1337 directly into the compromised network and have their traffic emerge on port 1080.

Should they wish to, they could even have the rsocks server connect out via the Chisel tunnel. An interesting point here is that the ChaChi operators have hard coded some of the strings used in this Chisel command string, namely the use of “HTTP” and port “443”. This would cause HTTP traffic to traverse the network on a non-standard port (i.e., 443) which might be a red flag to an observant network analyst.

Uninstalling the Backdoor

As with command ID 4, command ID 9 does not expect any further arguments to be supplied. When the ChaChi operators execute command 9, it undertakes the process of uninstalling itself from the infected host machine. This is done in two stages. The first step involves deletion of the previous installed service using the Windows utility “sc”:

Figure 46 - Use "sc" to delete service then get temp path.

As can be seen above, immediately following the service deletion, ChaChi retrieves the path to the %TEMP% directory using PowerShell. This is done because ChaChi will create and write a batch file, “del.bat”, to the temp directory that will carry out the task of deleting the ChaChi binary from its location on disk:

Figure 47 - Contents of "del.bat" used to delete ChaChi binary.

This command is of particular use to the ChaChi operators because, once they have completed their objectives within the compromised environment, they want to cover their tracks.

Network Infrastructure

Analysis of extracted networking indicators of compromise (IOCs) can yield some information that can be used as TTPs, and which hint at past (and potentially even current) targets. By mapping out a timeline of first-seen dates for domains extracted from ChaChi binaries, we can observe a period of time from late 2019 up to the first quarter of 2021 where the PYSA operators were most active.

A total of 19 new domains were created in that period, which acted as the C2 for ChaChi. From our data, ChaChi domains can and have been created several months prior to an actual attack taking place. The same ChaChi binaries, and therefore domains, were even used in multiple attacks:

Figure 48 - Timeline of Domains by first-seen dates.

When we dig only a little deeper into these domains, we see what could be used as a TTP for the PYSA operators; their overwhelming preference for using the domain name registrar Namecheap:

Domain

Registrar

starhouse[.]xyz

Namecheap Inc.

dowax[.]xyz

Namecheap Inc.

ntservicepack[.]com

OVH Hosting

reportservicefuture[.]website

Namecheap Inc.

spm[.]best

Namecheap Inc.

blitz[.]best

Namecheap Inc.

accounting-consult[.]xyz

Namecheap Inc.

statistics-update[.]xyz

Namecheap Inc.

sbvjhs[.]club

Namecheap Inc.

sbvjhs[.]xyz

Namecheap Inc.

wiki-text[.]xyz

Namecheap Inc.

visual-translator[.]xyz

Namecheap Inc.

firefox-search[.]xyz

Namecheap Inc.

serchtext[.]xyz

Namecheap Inc.

englishdict[.]xyz

Namecheap Inc.

englishdialoge[.]xyz

Namecheap Inc.

english-breakfast[.]xyz

Namecheap Inc.

pump-online[.]xyz

Namecheap Inc.

cvar99[.]xyz

Namecheap Inc.

productoccup[.]tech

Namecheap Inc.

transnet[.]wiki

Namecheap Inc.

Table 2 - Mapping of Domains to Registrars.

Taking the IP Addresses from ChaChi binaries and mapping them to their respective ASNs and Regions, we can see IP addresses based in either Romania or Germany account for over 50% of the total. Approximately 60% of the IP addresses are sourced from just two ASNs:

IP ADDRESS

ASN

Region

23.83.133[.]136

AS19148 - LEASEWEB-USA

U.S.

172.96.189[.]167

AS20068 - HAWKHOST

CA

172.96.189[.]22

AS20068 - HAWKHOST

CA

172.96.189[.]246

AS20068 - HAWKHOST

CA

198.252.100[.]37

AS20068 - HAWKHOST

CA

185.185.27[.]3

AS201206 - LINEVAST

DE

160.20.147[.]184

AS30823 - COMBAHTON

DE

45.147.228[.]49

AS30823 - COMBAHTON

DE

45.147.229[.]29

AS30823 - COMBAHTON

DE

45.147.230[.]162

AS30823 - COMBAHTON

DE

45.147.230[.]212

AS30823 - COMBAHTON

DE

185.186.245[.]85

AS40824 - WZCOM-US

U.S.

185.183.96[.]147

AS60117 - HS

NL

194.5.249[.]137

AS64398 - NXTHOST

RO

194.5.249[.]138

AS64398 - NXTHOST

RO

194.5.249[.]139

AS64398 - NXTHOST

RO

194.5.249[.]18

AS64398 - NXTHOST

RO

194.5.249[.]180

AS64398 - NXTHOST

RO

194.5.250[.]151

AS64398 - NXTHOST

RO

194.5.250[.]162

AS64398 - NXTHOST

RO

194.5.250[.]216

AS64398 - NXTHOST

RO

193.239.84[.]205

AS9009

GB

193.239.85[.]55

AS9009

RO

37.120.140[.]184

AS9009

RO

37.120.140[.]247

AS9009

RO

37.120.145[.]208

AS9009

DK

86.106.20[.]144

AS9009

NL

89.38.225[.]208

AS9009

SG

89.41.26[.]173

AS9009

U.S.

194.187.249[.]102

AS9009

FR

194.187.249[.]138

AS9009

FR

37.221.113[.]66

AS9009

GB

Table 3 - IP to ASN and Region Mapping.

BlackBerry researchers continuously track and monitor C2 servers by using a variety of fingerprinting and discovery techniques, storing all discovered C2 infrastructure in our internal Threat Intelligence systems.

One of the above IP addresses happened to appear in one of our intelligence platforms in early December of 2020 and was active for a period of just over 24 hours. The IP (45.147.230[.]212) is hosted by AS30823 Combahton in Germany. It triggered one of our sensors for PowerShell Empire, artifacts of which have been observed on systems following a PYSA ransomware incident:

Figure 49 - Alert for PowerShell Empire on Public Facing Server.

Checking the domain resolutions on the extracted IP addresses can also provide some interesting results and intelligence. The IP address 194.187.249[.]102 was extracted from a sample of ChaChi along with a domain used as a C2 server. This domain was sbvjhs[.]xyz. Unsurprisingly, the name servers, “ns1” and “ns2” for that domain also resolve to the same IP address. But what is interesting is that the other domain that also resolves to that same IP is login.bancocchile[.]com.

Figure 50 - ChaChi IP resolving to fake Banco Chile Domain.

The legitimate domain for Banco Chile is hosted on a “.cl” Top Level Domain (TLD) and does not have the extra “c” between the words “Banco” and “Chile”. This is a domain that was potentially intended for one of two purposes:

  • A phishing domain that is targeting either employees or customers of Banco Chile
  • A domain used to stage and deliver a copy of ChaChi to unsuspecting clickers of a malicious link

Either one or even both options are possible, considering these domains were active simultaneously and for several months; their last-seen dates were as recent as June 1, 2021. Coincidentally, both nameserver domains and the fake Banco Chile domain were all active before, during, and after the reported Breach at another Chilean bank (Banco Estado), which was reported in September 2020 and attributed to REvil ransomware.

Conclusion

ChaChi is a custom RAT developed using the relatively new programming language Go (aka Golang). By using Go to develop ChaChi, PYSA ransomware operators can frustrate detection and prevention efforts by analysts and tools unfamiliar with the language. The earliest version of ChaChi lacked several features of more mature malware, but its rapid evolution and recent deployment against national governments, healthcare organizations, and educational institutions indicates this malware is being actively developed and improved.

ChaChi is a powerful tool in the hands of malicious actors who are targeting industries notoriously susceptible to cyberattacks. It has demonstrated itself as a capable threat, and its use by PYSA ransomware operatives is a cause for concern, especially at a time when ransomware is experiencing alarming success through a string of high-profile attacks including campaigns conducted by REvil, Avaddon and DarkSide. Organizations ignoring this threat do so at their own risk, in a year of one-after-another cybersecurity disasters.

Appendix

Yara Rule

The following Yara rule was authored by the BlackBerry Threat Research Team to catch the threat described in this document:

rule Mal_Backdoor_ChaChi_RAT
{
            meta:
                        description = "ChaChi RAT used in PYSA Ransomware Campaigns"
                        author = "BlackBerry Threat Research & Intelligence"            

            strings:
                        // "Go build ID:"
                        $go = { 47 6F 20 62 75 69 6C 64 20 49 44 3A }
                        // dnsStream
                        $dnsStream = { 64 6E 73 53 74 72 65 61 6D }
                        // SOCKS5
                        $socks5 = { 53 4F 43 4B 53 35 }
                        // chisel
                        $chisel = { 63 68 69 73 65 6C }                                   

            condition:
                        // MZ signature at offset 0
                        uint16(0) == 0x5A4D and
                        // PE signature at offset stored in MZ header at 0x3C
                        uint32(uint32(0x3C)) == 0x00004550 and
                        // ChaChi Strings
                        all of them
}

 

Indicators of Compromise (IoCs)

At BlackBerry, we take a prevention-first and AI-driven approach to cybersecurity. Putting prevention first neutralizes malware before the exploitation stage of the kill-chain.

By stopping malware at this stage, BlackBerry solutions help organizations increase their resilience. It also helps reduce infrastructure complexity and streamline security management to ensure business, people, and endpoints are secure.

Indicator

Type

Description

12b927235ab1a5eb87222ef34e88d4aababe23804ae12dc0807ca6b256c7281c

SHA256

ChaChi

8a9205709c6a1e5923c66b63addc1f833461df2c7e26d9176993f14de2a39d5b

SHA256

ChaChi

37c3cb07b37d43721b3a8171959d2dff11ff904b048a334012239be9c7b87f63

SHA256

ChaChi

0bcbc1faec0c44d157d5c8170be4764f290d34078516da5dcd8b5039ef54f5ca

SHA256

ChaChi

6eb0455b0ab3073c88fcba0cad92f73cc53459f94008e57100dc741c23cf41a3

SHA256

ChaChi

89b9ba56ebe73362ef83e7197f85f6480c1e85384ad0bc2a76505ba97a681010

SHA256

ChaChi

701791cd5ed3e3b137dd121a0458977099bb194a4580f364802914483c72b3ce

SHA256

ChaChi

c9bed25ab291953872c90126ce5283ce1ad5269ff8c1bca74a42468db7417045

SHA256

ChaChi

e47a632bfd08e72d15517170b06c2de140f5f237b2f370e12fbb3ad4ff75f649

SHA256

ChaChi

0fd13ece461511fbc129f6584d45fea920200116f41d6097e4dffeb965b19ef4

SHA256

ChaChi

3a6ddc4022f6abe7bdb95a3ba491aaf7f9713bcb6db1fbaa299f7c68ab04d4f4

SHA256

ChaChi

5d8459c2170c296288e2c0dd9a77f5d973b22213af8fa0d276a8794ffe8dc159

SHA256

ChaChi

6d1fde9a5963a672f5e4b35cc7b8eaa8520d830eb30c67fadf8ab82aeb28b81a

SHA256

ChaChi

8b5cdbd315da292bbbeb9ff4e933c98f0e3de37b5b813e87a6b9796e10fbe9e8

SHA256

ChaChi

2697bbe0e96c801ff615a97c2258ac27eec015077df5222d52f3fbbcdca901f5

SHA256

ChaChi

85c8ccf45cdb84e99cce74c376ce73fdf08fdd6d0a7809702e317c18a016b388

SHA256

ChaChi

7b5027bd231d8c62f70141fa4f50098d056009b46fa2fac16183d1321be04768

SHA256

ChaChi

9986b6881fc1df8f119a6ed693a7858c606aed291b0b2f2b3d9ed866337bdbde

SHA256

ChaChi

a30e605fa404e3fcbfc50cb94482618add30f8d4dbd9b38ed595764760eb2e80

SHA256

ChaChi

aa2faf0f41cc1710caf736f9c966bf82528a97631e94c7a5d23eadcbe0a2b586

SHA256

ChaChi

af97b35d9e30db252034129b7b3e4e6584d1268d00cde9654024ce460526f61e

SHA256

ChaChi

045510eb6c86fc2d966aded8722f4c0e73690b5078771944ec1a842e50af4410

SHA256

ChaChi

b0629dcb1b95b7d7d65e1dad7549057c11b06600c319db494548c88ec690551e

SHA256

ChaChi

ccfa2c14159a535ff1e5a42c5dcfb2a759a1f4b6a410028fd8b4640b4f7983c1

SHA256

ChaChi

d591f43fc34163c9adbcc98f51bb2771223cc78081e98839ca419e6efd711820

SHA256

ChaChi

ef31b968c71b0e21d9b0674e3200f5a6eb1ebf6700756d4515da7800c2ee6a0f

SHA256

ChaChi

f5cb94aa3e1a4a8b6d107d12081e0770e95f08a96f0fc4d5214e8226d71e7eb7

SHA256

ChaChi

f8a5065eb53b1e3ac81748176f43dce1f9e06ea8db1ecfa38c146e8ea89fcc0b

SHA256

ChaChi

44af9d898f417506b5a1f9387f3ce27b9dfa572aae799295ca95eb0c54403cff

SHA256

Bat file used to delete backdoor binary

PowerShell $env:ComputerName

Command-line

PowerShell used to obtain Computer Name

PowerShell $env:Username

Command-line

PowerShell used to obtain Username

PowerShell $env:tmp

Command-line

PowerShell used to obtain %TEMP% path

JavaJDBC

Service name

Installation Service Name

Azure Agent Controller

Service name

Installation Service Name

Azure Safe controller

Service name

Installation Service Name

AzureAgentController

Service name

Installation Service Name

CorpNativeHostDebugger

Service name

Installation Service Name

Corp Native Host Debugger

Service name

Installation Service Name

Defender Security Agents

Service name

Installation Service Name

DefenderSecurityAgent

Service name

Installation Service Name

Get Service Controller

Service name

Installation Service Name

GetServiceController

Service name

Installation Service Name

Service agent security control

Service name

Installation Service Name

Windows service controller

Service name

Installation Service Name

MicrosoftSecurityManager

Service name

Installation Service Name

Microsoft Security Manager

Service name

Installation Service Name

WindowsSoftwareManagerDebugger

Service name

Installation Service Name

MicrosoftTeamConnectDebugger

Service name

Installation Service Name

MicrosoftTriangleConnectDebugger

Service name

Installation Service Name

Microsoft Triangle Connect Debugger

Service name

Installation Service Name

WindowsProtectionSystem

Service name

Installation Service Name

Windows Protection System

Service name

Installation Service Name

WindowsHealthSubSystem

Service name

Installation Service Name

MsStudioAgentUpdateService

Service name

Installation Service Name

VisualIdeIndexer

Service name

Installation Service Name

Visual studio indexer

Service name

Installation Service Name

Visual Ide Indexer

Service name

Installation Service Name

del.bat

Filename

Bat file used to delete backdoor binary

Englishdialoge[.]xyz

Domain

ChaChi C2

starhouse[.]xyz

Domain

ChaChi C2

accounting-consult[.]xyz

Domain

ChaChi C2

blitzz[.]best

Domain

ChaChi C2

ccenter[.]tech

Domain

ChaChi C2

cvar99[.]xyz

Domain

ChaChi C2

dowax[.]xyz

Domain

ChaChi C2

englishdict[.]xyz

Domain

ChaChi C2

english-breakfast[.]xyz

Domain

ChaChi C2

firefox-search[.]xyz

Domain

ChaChi C2

ntservicepack[.]com

Domain

ChaChi C2

productoccup[.]tech

Domain

ChaChi C2

pump-online[.]xyz

Domain

ChaChi C2

reportservicefuture[.]website

Domain

ChaChi C2

sbvjhs[.]club

Domain

ChaChi C2

sbvjhs[.]xyz

Domain

ChaChi C2

serchtext[.]xyz

Domain

ChaChi C2

spm[.]best

Domain

ChaChi C2

statistics-update[.]xyz

Domain

ChaChi C2

transnet[.]wiki

Domain

ChaChi C2

visual-translator[.]xyz

Domain

ChaChi C2

wiki-text[.]xyz

Domain

ChaChi C2

160.20.147[.]184

IP

ChaChi C2 IP

172.96.189[.]167

IP

ChaChi C2 IP

193.239.84[.]205

IP

ChaChi C2 IP

89.41.26[.]173

IP

ChaChi C2 IP

172.96.189[.]22

IP

ChaChi C2 IP

172.96.189[.]246

IP

ChaChi C2 IP

185.183.96[.]147

IP

ChaChi C2 IP

185.185.27[.]3

IP

ChaChi C2 IP

185.186.245[.]85

IP

ChaChi C2 IP

193.239.85[.]55

IP

ChaChi C2 IP

194.187.249[.]102

IP

ChaChi C2 IP

194.187.249[.]138

IP

ChaChi C2 IP

194.5.249[.]137

IP

ChaChi C2 IP

194.5.249[.]138

IP

ChaChi C2 IP

194.5.249[.]139

IP

ChaChi C2 IP

194.5.249[.]18

IP

ChaChi C2 IP

194.5.249.[]180

IP

ChaChi C2 IP

194.5.250[.]151

IP

ChaChi C2 IP

194.5.250[.]162

IP

ChaChi C2 IP

194.5.250[.]216

IP

ChaChi C2 IP

198.252.100[.]37

IP

ChaChi C2 IP

23.83.133[.]136

IP

ChaChi C2 IP

37.120.140[.]184

IP

ChaChi C2 IP

37.120.140[.]247

IP

ChaChi C2 IP

37.120.145[.]208

IP

ChaChi C2 IP

37.221.113[.]66

IP

ChaChi C2 IP

45.147.228[.]49

IP

ChaChi C2 IP

45.147.229[.]29

IP

ChaChi C2 IP

45.147.230[.]162

IP

ChaChi C2 IP

45.147.230[.]212

IP

ChaChi C2 IP

86.106.20[.]144

IP

ChaChi C2 IP

89.38.225[.]208

IP

ChaChi C2 IP

 

MITRE ATT&CK

Tactic

ID

Name

Description

Execution

T1059/001

Command and Scripting Interpreter: PowerShell

ChaChi - enumerate system and execute commands - C2 Command

T1059/003

Command and Scripting Interpreter: Windows Command Shell

Reverse shell and service deletion

T1569/002

System Services: Service Execution

Used to execute ChaChi once installed

 

Persistence

T1543/003

Create or Modify System Process: Windows Service

ChaChi Installation as a Service

 

Defence Evasion

T1027

Obfuscated Files or Information

ChaChi - Gobfuscated Functions and Strings

 

Discovery

T1057

Process Discovery

ChaChi - Process Enumeration

T1082

System Information Discovery

ChaChi - Computer Name and Username

 

C2

T1572

Protocol Tunnelling

ChaChi - DNS tunnelling for C2

T1071/001

Application Layer Protocol: Web Protocols

ChaChi – HTTP for C2

T1090/002

Proxy: External Proxy

ChaChi – SOCKS5 proxy

 

T1001

Data Obfuscation

ChaChi – Custom C2 encoding

 

T1008

Fallback Channels

ChaChi – DNS primary, HTTP fallback

 

T1573/001

Encrypted Channel: Symmetric Cryptography

ChaChi – XSalsa20+Poly1305 for C2 encryption

 

Exfiltration

T1041

Exfiltration Over C2 Channel

ChaChi

 

Resource Development

T1587/001

Develop Capabilities: Malware

ChaChi Backdoor

T1583/001

Acquire Infrastructure: Domains

ChaChi Domain registration


BlackBerry Assistance

If you’re battling ChaChi GoLang RAT or a similar threat, you’ve come to the right place, regardless of your existing BlackBerry relationship.

The BlackBerry Incident Response team is made up of world-class consultants dedicated to handling response and containment services for a wide range of incidents, including ransomware and Advanced Persistent Threat (APT) cases.

We have a global consulting team standing by to assist you providing around-the-clock support, where required, as well as local assistance. Please contact us here: https://www.blackberry.com/us/en/forms/cylance/handraiser/emergency-incident-response-containment.

The BlackBerry Research & Intelligence Team

About The BlackBerry Research & Intelligence Team

The BlackBerry Research & Intelligence team examines emerging and persistent threats, providing intelligence analysis for the benefit of defenders and the organizations they serve.