By Vanja Svajcer.
- Group TA505 has been active for at least seven years, making wide-ranging connections with other threat actors involved in ransomware, stealing credit card numbers and exfiltrating data. One of the common tools in TA505's arsenal is ServHelper. In mid-June, Cisco Talos detected an increase in ServHelper's activity. We investigated the activity and discovered a set of intertwined malware families and TTPs.
- We found that ServHelper is being installed onto the targeted systems using several different mechanisms, ranging from fake installers for popular software to using other malware families such as Raccoon and Amadey as the installation proxies.
- This threat demonstrates several techniques of the MITRE ATT&CK framework, most notably Scripting - T1064, PowerShell - T1059.001, Process Injection - T1055, Non-Standard Port - T1571, Remote Access Software - T1219, Input Capture - T1056, Obfuscated Files or Information - T1027, Ingress Tool Transfer - T1105, and Registry Run Keys/Startup Folder - T1547.001.
What's new? Although ServHelper has existed since at least early 2019, we detected the use of other malware families to install it. The installation comes as a GoLang dropper, .NET dropper or PowerShell script. Its activity is generally linked to Group TA505, but we cannot be certain that they are the exclusive users of this RAT.
ServHelper will also sometimes install a module that includes either Monero or Ethereum cryptocurrency mining tools.
How did it work? One path for infection starts with the compromise of a legitimate site that hosts cryptographically signed MSI installers. These install popular software such as Discord. However, they also launch a variant of the Raccoon stealer, which downloads and installs a ServHelper RAT if instructed by the command and control (C2) server.
Attackers also deploy the ServHelper RAT with a variant of the Amadey malware which gets a full command line from the server to install an initial PowerShell downloader component for ServHelper.
ServHelper includes the functionality to remotely control the infected system, log keystrokes, exfiltrate users' confidential data, launch RDP sessions, install cryptomining software and install the NetSupport remote access tool.
So what? Although many threat actors, such as TA505 or its associated groups — to which we attribute these campaigns with moderate confidence — have been affected by the arrests of several CLOP members in Ukraine, they continued to operate using a different set of tools. These attacks are geared toward taking control over the infected systems and stealing confidential data which the group will likely leverage for financial gain later on.
Users need to make sure they install software only from trusted sources. Even if installers are signed with a valid certificate, that does not mean that the functionality is legitimate.
Introduction This investigation started as a single and simple call to an IP address hosting a PowerShell script found in Cisco Secure product telemetry. Initially, while looking at the code, we thought it is just one of many cryptomining malware campaigns.
However, we realized soon that the main payload is a variant of a ServHelper backdoor. The usage of the tool is generally linked with the activity of the threat group TA505. TA505 is a crimeware-focused group active since at least 2014. They are mostly known for their usage of the Dridex and CLOP ransomware families in their campaigns. There are some theories that CLOP ransomware gang members, arrested in Ukraine in June 2021, originated from the group TA505.
What started as an investigation into an Ethereum cryptominer, turned out to be a never-ending whirlwind of different malware families. Apart from the usual suspects, often attributed to TA505, such as the Raccoon stealer and Amadey stealer/loader, we have encountered a couple of newer techniques from this group. TA505 now uses an MSI installer signed with a valid certificate and a GoLang go-clr-based dropper that can load a .NET assembly from memory.
Initial discovery While looking at the daily report of suspicious command lines, we encountered a call to a PowerShell script hosted at the IP address 188.8.131.52.
Initial command in product telemetry.
The downloaded script was a simple PowerShell script to download additional scripts and launch a VBScript file, "start.vbs." We first assumed this was another cryptocurrency miner, but we decided to analyze the scripts because, as a cryptocurrency miner, it was not immediately familiar.
Downloaded PowerShell script, "bi.ps1."
Start.vbs is a simple driver that seems to check for the size of the System Management BIOS memory to avoid executing within virtual machines, and then launches the script "ready.ps1."
Start.vbs first checks for the amount of SMBIOS memory before it launches the initial loader.
Before executing the next stage, ready.ps1 decodes a base64-encoded string to reveal a tool for disabling the Microsoft AMSI interface, which is often used by anti-malware software for scanning the content of obfuscated PowerShell, VBA, VBS and scripts written in other Microsoft scripting languages. Once AMSI is disabled, ready.ps1 launches the next stage, which is the main PowerShell loader, resolve-domain.ps1.
AMSI bypass in ready.ps1.
The AMSI bypass first loads the amsi.dll library and then gets the address of the function AmsiScanBuffer. The first six bytes of the function are patched with 2 x86 instructions "MOV EAX,80070057;RET" to return the value 0x80070057 (INVALID ARG) to the caller so that it seems as if the scan has failed.
Main PowerShell loader The loader starts with a function for decrypting the content of a variable containing the real PowerShell code of the loader. The function derives a TripleDES password from the parameters submitted to the function call.
TripleDES is used to decrypt the actual PowerShell loader.
When decrypted, the main loader contains several base64-encoded buffers and a logic to drop and load files decoded from those buffers. Before it's dropped to disc, the buffers need to be decrypted using a simple byte XOR scheme with a fixed seven-byte XOR key.
The main loader needs to deobfuscate the file content after Base64 decoding.
The loader will, depending on the characteristics of the system, attempt to drop the payloads into the following locations:
These locations are a telltale sign of ServHelper infection, a RAT that's been active since at least early 2019.
While reading the deobfuscated PowerShell script we noticed the download and execution of another URL: hxxp://45[.]61[.]136[.]223/get/m5.php. The call to this URL will be executed only if the amount of memory in the graphics card is larger than 4MB, which may be a way to evade some virtual machines or just a check for a machine with sufficient capacity to download the module, which is used for cryptocurrency mining.
Cryptomining module m5.php The cryptomining module hosted on hxxp://45[.]61[.]136[.]223/get/m5.php is what prompted us to initially assume that the final payload of the campaign is just a cryptominer and not confidential information stealing and remote control of the infected systems which may be attributed, based on the known TTPs, to Group TA505.
m5.php will only be downloaded if the size of the video controller memory is larger than 4MB.
The m5 is lightly obfuscated, first by adding a decimal 92 to each of the characters and then by base64 encoding it. The script creates another PowerShell script in the C:\Windows\system32\update-request.ps1. The update-request module will be launched through a UAC bypass attempt which abuses a scheduled task \Microsoft\Windows\DiskCleanup\SilentCleanup by modifying the registry value HKCU:\Environment\windir to contain the call to the modified slmgr.vbs script containing the call to launch update-request.ps1.
UAC bypass to launch update-request.ps1.
Update-request.ps1 is obfuscated in a similarly simple manner to m5.php content. The script contains another layer of obfuscation with TripleDES similar to the one seen in resolve-domain.ps1. An interesting fact is that the decrypting function has a name decra, which is the same name as an export of a ServHelper service loader, which will be described a bit later.
Once decoded, update-request contains instructions to download and run cryptomining software. In some previous instances, ServHelper installations were linked to Monero mining but in this campaign, a choice is made between mining Monero with XMRig and Ethereum. Ethermine and its configuration file are downloaded if Ethereum is the chosen miner.
The Ethminer payload is saved into the drive as C:\windows\system32\mui_pack_es.json as a base64-encoded file, which is also encrypted using XOR with the byte-based key "Asfianweiw". The Monero mining XMRig payload may be downloaded into C:\windows\system32\mui_pack.json and decrypted before loading into memory using the same method. This tactic is likely designed to avoid the detection of PE files by anti-malware software.
The mining payloads will only exist in the memory as PE modules and it will be loaded by injecting them reflectively into the legitimate process c:\windows\system32\msiexec.exe. The method to hollow msiexec seems to be a PowerShell port of the C++ RunPE process hollowing project. It loads an embedded base64-encoded custom .NET assembly which is simply used as a trampoline to avoid having to import all the required functions from the kernel32.dll module.
Looking at the Ethereum payouts for the address 0x12420E4083F1E37b91AFA0E054682d049F9505C6 at the blockchain explorer on ethermine.org, we can see that the pool of miners with this address earned just over 17 Ethereums over the period of fewer than four months, which at the time of writing this post is worth slightly more than $33,000 USD.
Ethermine payouts to the address associated with the TA505 ServHelper campaigns.
ServHelper installation In this campaign, the PowerShell loader resolve-domain.ps1 is responsible for dropping and installing the ServHelper payload. In this case, the main loader is downloaded from a website, but in some other cases, the main PowerShell loader is dropped by an executable dropper.
The PowerShell loader uses the same SilentCleanup UAC bypass seen in the mining module to execute the registry. The file system can change without the UAC prompt.
The loading of ServHelper consists of two main DLL modules combined with helper modules to allow communication over RDP. The PowerShell module changes the registry keys related to the Windows service Terminal Server. The Terminal Server service is changed so that it listens on a non-default TCP port 7201 instead of the default port 3389. A new Remote Desktop service Termservice is created and its ServiceDLL value is set to point into the ServHelper DLL loader C:\Windows\branding\mediasrv.png.
The loader DLL mediasrv.png is packed with UPX and employs a simple XOR decryption of strings that are dynamically constructed in memory. The loader is a service DLL with the ServiceMain function containing the ability to load the main ServHelper DLL module from C:\Windows\branding\mediasvc.png.
The mediasrv.png contains the usual exports for a svchost-based service DLL, such as ServiceMain, SvcHostPushServiceGlobals and an additional export decra, which seems to be used for decryption. SvcHostPushServiceGlobals seems to be used to load the standard Remote Desktop DLL termserv.dll and loads an RDPWrapper configuration from the dropped file C:\Windows\branding\wupsvc.jpg. Some earlier analyses indicate that the first stage of the ServHelper DLL loader is in fact a modified variant of RDPWrapper which allows for remote concurrent RDP sessions on the host. This would also explain the loading of the RDPWrap configuration file.
Modified RDPWrap DLL first decrypts the name and then loads the main ServHelper module.
The main ServHelper RAT module is written in Delphi using the compilation to native code. It uses a modified Vigneres cipher to encrypt and decrypt the strings used in the file. We used IDAPython to create a simple script for decoding the strings and assigned a function key to patch the strings back into an IDA database file. We'll share this script at the bottom of this post.
The ServHelper module contains typical backdoor functionality. It launches many threads, some for tunneling the traffic over OpenSSH (which may be downloaded from a C2 server) tunnel and some as a main command processing loop, which for the sample under analysis, accepts the following commands:
- socks Although the hijack and keylogging commands are accepted by the RAT, it seems like they are not implemented by the variant. From the analysed code, it seems that, for example, the hijack functionality should be implemented by one of the DLL exports, gusiezo3. However, this functionality actually enters an infinite sleep loop. Other researchers have previously described the other functions in depth.
Gusiezo3 export is supposed to handle the command hijack but it simply enters an infinite loop.
This is similar to other exports, like euefnaiw, which should handle keylogging and hitit, but no functionality is implemented.
The C2 domain name for this sample is "novacation.cn." While searching for other related samples, we discovered another dropper written in GoLang.
GoLang go-clr dropper The dropper uses the go-clr loader, which allows a GoLang executable to load a .NET assembly from memory or from the disk. The dropper extracts a base64-encoded buffer from its own rdate section, decompresses the buffer using gzip deflate, and loads the .NET ServHelper dropper into memory to execute it. The base64 buffer is corrupt to avoid automatic extraction by anti-malware software. It automatically replaces itself before it is base64 decoded and decompressed.
Gzip buffer is corrected before it is base64 decoded into a binary buffer containing a .NET assembly.
The loaded assembly is a usual dropper for ServHelper. It extracts the PowerShell loader components for the ServHelper into the temporary files folder and runs ready.ps1, which launches the infection as described above.
.NET ServHelper dropper drops and executes the PowerShell loader components.
As with every investigation, we tried to find similar files and their locations on the internet and found that GoLang droppers are downloaded and installed as a consequence of running a group of MSI installer packages signed with a valid certificate and not detected by any antimalware software. The installers purport to be MSI files that install various applications, including a video editor, a wiki program and Discord.
MSI installer downloaders The certificate belongs to a Russian company SGP-GEOLOGIYA, OOO. The first sample has been submitted to VirusTotal on May 2 and again on July 15.
Malicious MSI installers signed by "SGP-GEOLOGIYA, OOO" are not detected.
The MSI installer file is created with a trial version of Advanced Installer. Files created with Advanced Installer contain a parser aipackagechainer.exe used to parse the package and communicate to msiexec.exe to download and run prerequisites. the AI_PreRequisite table contains a URL hxxp://91[.]212[.]150[.]205/filename.exe that points to an executable file that the installer downloads and runs.
MSI installer will download and run files from any URL specified in the AI_PreRequisite table.
However, the URL of the GoLang ServHelper dropper, referenced as being downloaded by the MSI installer, is hxxp://91[.]212[.]150[.]205/al.exe and there is no reference to it in the MSI installation prerequisites. A logical assumption is that the filename.exe is a downloader of the ServHelper dropper.
Raccoon and Amadey stealers entering the ServHelper play The sample filename.exe, (SHA256 7516b2271e4a887156d52f661cdfc561fded62338a72b56f50bf188c2f5f222a), downloaded by the MSI installer is a variant of the Raccoon information stealing malware. Raccoon is a stealer that attempts to find and exfiltrate information that can be used by the attacker to gain financial benefits, such as user credentials, cookies, cryptocurrency wallet details and credit card numbers.
The sample we analysed, referenced by the MSI installer, communicates with a C2 server hosted on 34[.]76[.]8[.]115.
Raccoon uses HTTP for communication with the C2 server. The data submitted and received is encrypted with RC4 using an encryption key hardcoded within the body of the stealer. When run for the first time, the Raccoon executable sends a POST request to the C2 server. The request contains the basic information about the bot, such as a unique bot identifier, username, configuration identifier and the format of data expected and the C2 server responds with the configuration in a format specified by the bot, usually JSON.
The RC4 passphrase and all other Raccoon strings are encrypted with a simple XOR scheme.
The analysed sample RC4 passphrase was "$Z2s`ten\@bE9vzR". We used it to decrypt the response sent back to the bot from the C2 server. Then, we obtained the JSON configuration, which shows that the C2 instructs the bot to download the GoLang ServHelper dropper.
Decrypted Raccoon configuration to download the ServHelper GoLang dropper.
However, Raccoon is not the only family used to install ServHelper together with executing its information stealing objective. Another stealer family samples, variants of Amadey are also instructed by its C2 server to download ServHelper samples. This is done in a slightly different manner. The Amadey loader receives a PowerShell command line from its C2 server and executes it to download and install ServHelper samples in its PowerShell form. The usage of Amadey is also linked to group TA505.
The sample with SHA256 baad7552e8fc0461babc0293f7a3191509b347596d9ca8d2a82560992ff2c48e, apart from it screen capture and credential dumping plugins receives from the C2 server 157[.]90[.]24[.]103 the command which decodes to the same IP address we initially observed in our telemetry: 94[.]158[.]245[.]88.
Amadey C2 instructs the bot to download and run a ServHelper PowerShell installer.
However, the pattern is similar: An information-stealing malware variant is instructed by its C2 server to download and install ServHelper.
Conclusion In this post we documented activities that may be attributed with moderate confidence to the threat group TA505 or a related group. The activities include several malware families geared toward stealing and exfiltrating confidential data.
All documented families as well as signed MSI installers are used to download and run ServHelper - a RAT with different TTPs, such as usage of GoLang, .NET framework, PowerShell and Delphi.
Malware families in modules observed in these campaigns.
Users need to make sure they install software only from trusted sources. Even if installers are signed with a valid certificate that does not mean that the functionality is legitimate. The question of storage of confidential data is also important as passwords and credit card numbers are sometimes stored in insecure storage facilities such as sqlite databases, which are easy targets for criminals. Session cookies can also be used for hijacking accounts and they have a value for attackers.
It is very likely that we will see groupe similar to TA505 adapting these tools in the future as the detection for them improves.
Coverage Ways our customers can detect and block this threat are listed below.
Cisco Secure Web Appliance web scanning prevents access to malicious websites and detects malware used in these attacks.
Cisco Secure Malware Analytics helps identify malicious binaries and build protection into all Cisco Security products.
Cisco Umbrella, our secure internet gateway (SIG), blocks users from connecting to malicious domains, IPs, and URLs, whether users are on or off the corporate network.
Additional protections with context to your specific environment and threat data are available from the Cisco Secure Firewall Management Center.
Open Source Snort Subscriber Rule Set customers can stay up to date by downloading the latest rule pack available for purchase on Snort.org.
The following SIDs have been released to detect this threat: 57975.
The following ClamAV signatures have been released to detect this threat as well as tools and malware related to these campaigns:
- Win.Trojan.ServHelper-9883867 Cisco Secure Endpoint (AMP) users can use Orbital Advanced Search to run complex OSqueries to see if their endpoints are infected with this specific threat. For specific OSqueries on this threat, click here, here, here and here.
45[.]61[.]137[.]91 - C2 IP
91[.]212[.]150[.]205 - hosting a GoClr dropper variant
193[.]150[.]70[.]5 - hosting a GoClr dropper variant
94[.]158[.]245[.]88 - hosting original attack seen in the telemetry
93[.]157[.]63[.]171 - hosting Raccoon and a GoClr dropper variant
www[.]novacation[.]cn - C2 from the samples 1 and 2 of ServHelper
dssagrgbe3irggg[.]xyz - C2 alternative from ServHelper
dsgiutugagb[.]cn - C2 alternative from ServHelper sample1
asfggagsa3[.]xyz - C2 alternative from an earlier sample - sample2
sagbbrrww2[.]cn - C2 alternative from sample 2
asdjausg[.]cn - C2 from a newer dropper
telete[.]in - Raccoon C2
C2 Domain's IP addresses, changing frequently
185[.]163[.]45[.]103 - July 4, 2021 to July 15, 2021
206[.]188[.]197[.]221 - July 2, 2021 to July 4, 2021
206[.]188[.]196[.]143 - July 1, 2021 to July 2, 2021
46[.]17[.]96[.]8 - June 29, 2021 to July 1, 2021
45[.]61[.]137[.]91 - June 27, 2021 to June 29, 2021
hxxp://94[.]158[.]245[.]88/bi.ps1 - initial investigation point, also hosting Powershell versions of droppers without .NET and without GoClr
hxxp://ww16[.]enroter1984[.]cn/bif/b.php - C2 (enroter1984.cn from at least November 2020)
hxxp://bromide[.]xyz/ssh.zip - hosts OpenSSH Zip use to tunnel the traffic
hxxp://94[.]158[.]245[.]88/cap/Get-Content.ps1 - earlier campaign, Feb 2021
hxxp://94[.]158[.]245[.]88/drc.ps1 - downloaded by Amadey
hxxp://94[.]158[.]245[.]88/cap/ready.ps1 - campaign March 2021
hxxp://45[.]61[.]136[.]223/get/m5.php - Cryptomining portion
hxxp://beautyiconltd[.]cn/ethged.txt - Ethminer
hxxp://beautyiconltd[.]cn/ethcnf.txt - Ethminer configuration
hxxp://beautyiconltd[.]cn/rigged.txt - xmrig for Monero mining
hxxp://beautyiconltd[.]cn/cnf.txt - xmrig configuration
45732f9c8b3e853484464d5748a8879a7095dc0c1c08e66854d350254c38bb42 - mediasrv.png
a2b0ef2413399dbdb01de3a0d2dd310ba127bbfdad09352fecb8444d88a05662 - mediasvc.png
02390b9368add3c496f779db617d19171379b36f1d79c0fa4ab3a07afc7c3e46 - wupsvc.jpg config file
9c7fc1304f9dada69594f64d230cb20ce3c1f83a41ca0e27b6274361941b3c67 - PowerShell dropper Get_Content.ps1
74333b02f97c1fbf44592463210a6962f1601ab91a4e28d037756b9804c5b2a0 - drc.ps1
5b6b7899dd459fa0bb234a0b102af91f4ee412abf36b1c54d1253ae59dda6ee2 - ready.ps1
9520067abc34ce8a4b7931256e4ca15f889ef61750ca8042f60f826cb6cb2ac9 - ready.ps1
f00f8b0d2602fc2e8bcf5899377f6a23beae9ea9df2c0a3c4e9aad4cae2ef522 - Get-Content.ps1
b65273062c9be6bfc6343438e51d7f68aaecf8382ae1373ff1b3adfacff1fd5d - Get-Content.ps1 earlier variant
0d650a1ab25e820a8bcd2b49144daef20439c931d5bbd5b547c65511aab6d334 - Get-Content.ps1
5d4a0661cfb3cca59acd8a9fa433ec2c48d686da36f3890b73e7b9f37c60e980 - start.vbs
a1351912f8ffeeb5ebe2eb8abf45e50a52b67f82328090ad4b1ba89f30106e00 - start.vbs
7a9fae49143829692253d09fa7c66f6c2809d29cff52734567db688c91a01924 - bi.ps1
20eb050c3c94f134ca7c812c712deb45870f6952086608a11d4d4e78ca3c8ff6 - mediasrv.png
ffcdccdae62c13b61f32d6fa0ad73ddbfda89d0e4fcab3bf074003ca73d522a5 - mediasvc.png
4390543ecc7f39f0dcf6db2816edaaa6b64f720263c401c108f18df291241cb5 - wupsvc.jpg
1f2f7c7e0ad496e8991e4495b8830961314baee109fb7e0d15d2c3dc0857ef0b - update-request.ps1
42c277ada9c6f8ddcd6211e4792a8df1fa0d0ad8cbb867eee1a431cc1b79834d - mae.ps1
PowerShell mining loader
0b25a462efbb3c5459febae122e434f4a6ec6d2dbfacf03e4537e437f91c5dcc - m5.php
Amadey samples downloading ServHelper from hxxp://94[.]158[.]245[.]88/cap/
GoCLR droppers for ServHelper (some samples downloaded by Raccoon)
Raccoon samples downloading ServHelper
.NET ServHelper dropper
IDAPython script to deobfuscate ServHelper strings using Vigneres cypher
import sysimport idaapiimport idcimport ida_bytesimport ida_exprimport ida_kernwin#Load this Python script into IDAPro. To run it, position the cursor at the screen address of the string to deobfuscate and press the F2 key.def getString(ea): # We get the item-head because the `GetStringType` function only works on the head of an item. string_type = idc.get_str_type(idaapi.get_item_head(ea)) string_content = idc.get_strlit_contents(ea, strtype=string_type) return string_content,string_type # Python code to implement Vigenere Cipher as implemented in the Delphi code at# https://stackoverflow.com/questions/6800326/how-to-crypt-or-hide-a-string-in-delphi-exe/6801163# This algorithm was implemented in ServHelper malware # Generate the key stream from the keyworddef generateKey(string, key): key = list(key) if len(string) == len(key): return(key) else: for i in range(len(string) - len(key)): key.append(key[i % len(key)]) return("" . join(key)) # Decrypt the original text, skip non-alphabet characters def originalText(cipher_text, key): orig_text =  for i in range(len(cipher_text)): if (ord(cipher_text[i]) >= ord('A') and ord(cipher_text[i]) <= ord('Z')): x = (ord(cipher_text[i]) - ord(key[i]) + 26) % 26 x += ord('A') orig_text.append(chr(x)) elif (ord(cipher_text[i]) >= ord('a') and ord(cipher_text[i]) <= ord('z')): x = (ord(cipher_text[i].upper()) - ord(key[i]) + 26) % 26 x += ord('a') orig_text.append(chr(x)) else: orig_text.append(cipher_text[i]) return("" . join(orig_text)) def patchString(strng): """Patch a decrypted utf-16le encoded string back to IDAPro""" ida_bytes.patch_bytes(idc.get_screen_ea(), strng.encode('utf-16le')) def decryptString(keyword = 'WBORRHOS'): #change the keyword to a string appropriate for the sample under analysis kemi,strtype=getString(idc.get_screen_ea()) strkemi=str(kemi,'utf-8') key= generateKey(strkemi,keyword) decrypted=originalText(strkemi,key) patchString(decrypted) #Make sure what was patched is defined as a string literal ida_bytes.create_strlit(idc.get_screen_ea(),ida_bytes.get_item_size(idc.get_screen_ea()),strtype) def key_decrypt(): decryptString( 'WBORRHOS') #Assign the decryption function to the function key F2ida_kernwin.add_hotkey('F2', key_decrypt)