AsyncRAT is an open source remote access tool that is commonly used by threat actors for file exfiltration and remote desktop control. Threat actors use script injectors and phishing attachments to deliver AsyncRAT to victim endpoints across numerous campaigns. AsyncRAT has consistently ranked among the top 10 malware trends on Any.run for several months. BleepingComputer reported an 11 month long campaign targeting US infrastructures where the attackers employed multiple loader samples and numerous domains to distribute the AsyncRAT malware.

AsyncRAT was first published on GitHub in January 2019 as an open source remote administration tool. It is designed to remotely monitor and control other computers through its client-server architecture that allows for multiple simultaneous connections. It encrypts command and control (C2) communications and has a variety of features to aid remote administration activities.

Some of its features are keylogging, audio and video recording, system information retrieval, remote desktop control, password recovery, remote shell, and payload injection. The open source nature of the tool allows threat actors to modify it to suit their malicious objectives, leading to multiple variants. The latest variants of AsyncRAT are designed to bypass security defenses with specially crafted BAT loaders.

In this blog post, we explore the behavior of multiple variants of AsyncRAT on a Windows endpoint, and demonstrate how to detect its activities with Wazuh.

Behavioral analysis

AsycRAT as a remote desktop tool

  • AsyncRAT GUI allows threat actors to control the infected machine. 
  • Attackers connect to the server via asynchronous TCP sockets, which allow for numerous simultaneous connections without disruption.
  • An attacker can monitor the victim’s activity in real time by issuing instructions to the AsyncRAT client to take screenshots of the desktop and upload them to the C2 server.
  • AsyncRAT captures the screenshots using the .NET Framework libraries in Windows and converts them to a byte array before sending to the C2 server.

AsyncRAT as a keylogger

  • The AsyncRAT client uses LimeLogger’s APIs to periodically record and send keystrokes from the target to the C2 server.
  • AsyncRAT uses the SetWindowsHookEx function in the Windows API to monitor system message traffic and retrieve specific types of keystrokes.
  • The SetHook and unsetHook functions are used to install and uninstall the keyboard hook by calling SetWindowsHookEx with the LowLevelKeyboardProc delegate.

AsyncRAT as a process manager

  • AsyncRAT uses the System.Diagnostics namespace in the .NET Framework to interact with system processes, retrieving a list of running processes.
  • AsyncRAT initiates a new process by using the Process.Start method.
  • AsyncRAT uses the System.Diagnostics.Process class in the .NET Framework to execute shell commands, starting a new instance of cmd.exe with the shell command as a parameter.

Persistence

  • The client checks if its code has administrative privileges and if so, adds Windows Scheduled Tasks using SchTasks.exe with highest runlevel privileges to execute its copy in appdata. In the absence of administrative privileges, AsyncRAT will use the Registry Run Key HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run for persistence.
  • It changes the privileges of its process tokens with the SeDebugPrivilege token in order to obtain more control over other processes.
  • AsyncRAT will decrypt its AES-encrypted configuration data, which includes the port number and C2 IP address  to be used for C2 connection.
  • AsyncRAT can download more payloads from pastebin by using the WebClient.DownloadString API. 

Analyzed IoC file

Hash typeValue
MD519e6c35edf4a0d80e5317764b621bfac
SHA2561742b48fad9814441ee7726009a0e375757134dcc872f88ed584b6a2099c7473

Infrastructure

To demonstrate the detection of AsyncRAT with Wazuh, we use the following infrastructure.

  • A pre-built ready-to-use Wazuh OVA 4.7.2 Follow this guide to download the virtual machine.
  • A Windows 10 endpoint with Wazuh agent 4.7.2 installed. We call this the victim endpoint. Refer to the following installation guide to install the Wazuh agent. 

Wazuh detection 

We use the following techniques to detect the AsyncRAT behavior on a compromised Windows endpoint.

  • We use Sysmon to monitor system events and create rules on the Wazuh server to detect the behavior of AsyncRAT on the monitored endpoint.
  • Performing file signature scanning using VirusTotal integration with Wazuh.
  • Removing malicious files using the Wazuh active response module.

Configuration

Perform the following steps to configure Sysmon on the monitored endpoint, and forward logs in the Sysmon event channel to the Wazuh server for analysis.

Windows endpoint

1. Download Sysmon from the Microsoft Sysinternals page.

2. Extract the compressed Sysmon file to your preferred location. 

3. Download the Sysmon configuration file – sysmonconfig.xml using PowerShell. Replace <SYSMON_EXECUTABLE_PATH> with the path to your Sysmon executable.

> wget -Uri https://wazuh.com/resources/blog/emulation-of-attack-techniques-and-detection-with-wazuh/sysmonconfig.xml -OutFile <SYSMON_EXECUTABLE_PATH>\sysmonconfig.xml

4. Switch to the directory with the Sysmon executable. Run the command below to install and start Sysmon using PowerShell with Administrator privileges:

> .\Sysmon64.exe -accepteula -i sysmonconfig.xml

5. Add the following configuration within the <ossec_config> block of the C:\Program Files (x86)\ossec-agent\ossec.conf file to forward Sysmon events to the Wazuh server:

<localfile>
  <location>Microsoft-Windows-Sysmon/Operational</location>
  <log_format>eventchannel</log_format>
</localfile>

6. Restart the Wazuh agent to apply the configuration changes on the same terminal:

> Restart-Service -Name wazuh

Wazuh server

In this section, we create rules to detect AsyncRAT behavior on the monitored endpoint. 

1. Add the rules below to the /var/ossec/etc/rules/local_rules.xml file on the Wazuh server:

<group name="asyncrat,">

<!-- AsyncRAT execution -->
<rule id="100401" level="12">
    <if_sid>61603</if_sid>
    <field name="win.eventdata.Image" type="pcre2">\.exe</field>
    <field name="win.eventdata.OriginalFileName" type="pcre2">Stub\.exe</field>
    <description>AsyncRAT executed.</description>
    <mitre>
        <id>T1204</id>
    </mitre>
</rule>

<!-- DLL process injection -->
<rule id="100402" level="12">
    <if_sid>61609</if_sid>
    <field name="win.eventdata.Image" type="pcre2">.*\.exe</field>
    <field name="win.eventdata.ImageLoaded" type="pcre2">(?i)[c-z]:\\\\Windows\\\\SysWOW64\\\\mscoree\.dll</field>
    <description>Potential AsyncRAT activity detected: Process $(win.eventdata.ImageLoaded) is injected on $(win.system.computer).</description>
    <mitre>
        <id>T1055.001</id>
    </mitre>
</rule>

<rule id="100403" level="12">
    <if_sid>61609</if_sid>
    <field name="win.eventdata.Image" type="pcre2">.*\.exe</field>
    <field name="win.eventdata.ImageLoaded" type="pcre2">(?i)[c-z]:\\\\Windows\\\\Microsoft\.NET\\\\Framework\\\\v4\.0\.30319\\\\mscoreei\.dll</field>
    <description>Potential AsyncRAT activity detected: Process$(win.eventdata.ImageLoaded) is injected on $(win.system.computer).</description>
    <mitre>
        <id>T1055.001</id>
    </mitre>
</rule>

<rule id="100404" level="12">
    <if_sid>61609</if_sid>
    <field name="win.eventdata.Image" type="pcre2">.*\.exe</field>
    <field name="win.eventdata.ImageLoaded" type="pcre2">(?i)[c-z]:\\\\Windows\\\\Microsoft\.NET\\\\Framework\\\\v4\.0\.30319\\\\clrjit\.dll</field>
    <description>Potential AsyncRAT activity detected: Process $(win.eventdata.ImageLoaded) is injected on $(win.system.computer).</description>
    <mitre>
        <id>T1055.001</id>
    </mitre>
</rule>

<!-- Registry creation for persistent -->
<rule id="100405" level="15">
    <if_sid>61614</if_sid>
    <field name="win.eventdata.EventType" type="pcre2">^CreateKey$</field>
    <field name="win.eventdata.Image" type="pcre2">(?i)[c-z]:\\\\Windows\\\\System32\\\\svchost\.exe</field>
    <field name="win.eventdata.TargetObject" type="pcre2">HKLM\\\\System\\\\CurrentControlSet\\\\Services\\\\[A-Za-z0-9]+</field>
    <description>Suspicious registry key creation detected on $(win.system.computer).</description>
    <mitre>
        <id>T1543</id>
    </mitre>
</rule>

</group>

Where:

  • Rule ID 100401 is triggered when AsyncRAT is executed on the Windows endpoint.
  • Rule ID 100402 detects when AsyncRAT injects DLL process mscoree.dll into C:\Windows\Microsoft.NET\Framework\v4.0.30319\
  • Rule ID 100403 detects when AsyncRAT injects DLL process mscoreei.dll into C:\Windows\Microsoft.NET\Framework\v4.0.30319\
  • Rule ID 100404 detects when AsyncRAT injects DLL process clrjit.dll into C:\Windows\Microsoft.NET\Framework\v4.0.30319\
  • Rule ID 100405 detects when AsyncRAT creates registry keys on the Windows endpoint.

2. Restart the Wazuh manager for the changes to take effect:

# systemctl restart wazuh-manager

Detection results

From the Agents tab in your Wazuh dashboard, select the Windows endpoint and navigate to the Security events tab to view the generated alerts.

The screenshot below shows the alerts generated on the Wazuh dashboard when the AsyncRAT is executed on the victim endpoint.

AsyncRAT security events

VirusTotal integration

VirusTotal aggregates antivirus products and online scan engines, offering an API that can be queried using URLs, IP addresses, domains, or file hashes to detect security threats. You can configure Wazuh to automatically send requests to the VirusTotal API with the hashes of files created or modified on the monitored endpoint.

For this integration, we configure the Wazuh File Integrity Monitoring module and VirusTotal to detect and scan files that are added or modified on specific directories on the Windows endpoint. Additionally, we configure the Wazuh active response module to remove the files identified as malicious by VirusTotal.

Windows endpoint

1. Add the following configuration to the “C:\Program Files (x86)\ossec-agent\ossec.conf” file to monitor the intrusion of the AsyncRAT file. In this blog post, we configure the FIM module to monitor the Downloads folder for all users:

<syscheck>
  <directories check_all="yes" realtime="yes">C:\Users\*\Downloads</directories>
</syscheck>

2. Restart the agent to apply the changes by running the following PowerShell command as an administrator:

> Restart-Service -Name wazuh
Active response Python script configuration

We create an active response script to remove any variant of AsyncRAT immediately VirusTotal identifies it as a threat.

1. Create an active response script remove-threat.py on the Windows endpoint with the following content:

#!/usr/bin/python3
# Copyright (C) 2015-2022, Wazuh Inc.
# All rights reserved.
 
import os
import sys
import json
import datetime
 
if os.name == 'nt':
    LOG_FILE = "C:\\Program Files (x86)\\ossec-agent\\active-response\\active-responses.log"
else:
    LOG_FILE = "/var/ossec/logs/active-responses.log"
 
ADD_COMMAND = 0
DELETE_COMMAND = 1
CONTINUE_COMMAND = 2
ABORT_COMMAND = 3
 
OS_SUCCESS = 0
OS_INVALID = -1
 
class message:
    def __init__(self):
        self.alert = ""
        self.command = 0
 
def write_debug_file(ar_name, msg):
    with open(LOG_FILE, mode="a") as log_file:
        log_file.write(str(datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S')) + " " + ar_name + ": " + msg +"\n")
 
def setup_and_check_message(argv):
 
    # get alert from stdin
    input_str = ""
    for line in sys.stdin:
        input_str = line
        break
 
 
    try:
        data = json.loads(input_str)
    except ValueError:
        write_debug_file(argv[0], 'Decoding JSON has failed, invalid input format')
        message.command = OS_INVALID
        return message
 
    message.alert = data
 
    command = data.get("command")
 
    if command == "add":
        message.command = ADD_COMMAND
    elif command == "delete":
        message.command = DELETE_COMMAND
    else:
        message.command = OS_INVALID
        write_debug_file(argv[0], 'Not valid command: ' + command)
 
    return message
 
 
def send_keys_and_check_message(argv, keys):
 
    # build and send message with keys
    keys_msg = json.dumps({"version": 1,"origin":{"name": argv[0],"module":"active-response"},"command":"check_keys","parameters":{"keys":keys}})
 
    write_debug_file(argv[0], keys_msg)
 
    print(keys_msg)
    sys.stdout.flush()
 
    # read the response of previous message
    input_str = ""
    while True:
        line = sys.stdin.readline()
        if line:
            input_str = line
            break
 
    # write_debug_file(argv[0], input_str)
 
    try:
        data = json.loads(input_str)
    except ValueError:
        write_debug_file(argv[0], 'Decoding JSON has failed, invalid input format')
        return message
 
    action = data.get("command")
 
    if "continue" == action:
        ret = CONTINUE_COMMAND
    elif "abort" == action:
        ret = ABORT_COMMAND
    else:
        ret = OS_INVALID
        write_debug_file(argv[0], "Invalid value of 'command'")
 
    return ret
 
def main(argv):
 
    write_debug_file(argv[0], "Started")
 
    # validate json and get command
    msg = setup_and_check_message(argv)
 
    if msg.command < 0:
        sys.exit(OS_INVALID)
 
    if msg.command == ADD_COMMAND:
        alert = msg.alert["parameters"]["alert"]
        keys = [alert["rule"]["id"]]
        action = send_keys_and_check_message(argv, keys)
 
        # if necessary, abort execution
        if action != CONTINUE_COMMAND:
 
            if action == ABORT_COMMAND:
                write_debug_file(argv[0], "Aborted")
                sys.exit(OS_SUCCESS)
            else:
                write_debug_file(argv[0], "Invalid command")
                sys.exit(OS_INVALID)
 
        try:
            os.remove(msg.alert["parameters"]["alert"]["data"]["virustotal"]["source"]["file"])
            write_debug_file(argv[0], json.dumps(msg.alert) + " Successfully removed threat")
        except OSError as error:
            write_debug_file(argv[0], json.dumps(msg.alert) + "Error removing threat")
           
       
    else:
        write_debug_file(argv[0], "Invalid command")
 
    write_debug_file(argv[0], "Ended")
 
    sys.exit(OS_SUCCESS)
 
if __name__ == "__main__":
    main(sys.argv)

The os.remove() function in the active response Python script handles the removal of the malicious file:

os.remove(msg.alert["parameters"]["alert"]["data"]["virustotal"]["source"]["file"])

2. Download Python and run the installer. This works with Python 3.8.7 or later (with pip pre-installed). Then, select the following checkboxes during installation:

  • Use admin privileges when installing Python.
  • Add Python.exe to PATH.

Note: This step is optional if you already have python installed on your system.

3. Run the following command with administrative privilege to install Pyinstaller using PowerShell:

> pip install -U pyinstaller

4. Convert the Python script remove-threat.py to an executable file with the following command:

> pyinstaller -F remove-threat.py

5. Move the executable file remove-threat.exe from the \dist folder under your current working directory to the C:\Program Files (x86)\ossec-agent\active-response\bin folder.

6. Restart the agent to apply the changes by running the following PowerShell command as an administrator:

> Restart-Service -Name wazuh

Wazuh server

1. Append the configuration below to the /var/ossec/etc/ossec.conf  file to scan the files with VirusTotal:

<ossec_config>
  <integration>
    <name>virustotal</name>
    <api_key><API_KEY></api_key> <!-- Replace with your VirusTotal API key -->
    <rule_id>554,550</rule_id>
    <alert_format>json</alert_format>
  </integration>
</ossec_config>

Replace the <API_KEY> variable with your VirusTotal API key. The FIM rule IDs 554 and 550 detect file addition and modification events respectively.

Active response configuration

1. Append the following configuration to the /var/ossec/etc/ossec.conf file:

<ossec_config>
    <command>
        <name>remove-threat</name>
        <executable>remove-threat.exe</executable>
        <timeout_allowed>no</timeout_allowed>
    </command>

    <active-response>
        <disabled>no</disabled>
        <command>remove-threat</command>
        <location>local</location>
        <rules_id>87105</rules_id>
    </active-response>
</ossec_config>

2. Add the following rules to the /var/ossec/etc/rules/local_rules.xml file to generate alerts when the active response module successfully removes the malicious files or not.

<group name="virustotal,">
  <rule id="110006" level="12">
    <if_sid>657</if_sid>
    <match>Successfully removed threat</match>
    <description>$(parameters.program) removed threat located at $(parameters.alert.data.virustotal.source.file)</description>
  </rule>

  <rule id="110007" level="12">
    <if_sid>657</if_sid>
    <match>Error removing threat</match>
    <description>Error removing threat located at $(parameters.alert.data.virustotal.source.file)</description>
  </rule>
</group>

Where:

  • Rule ID 110006 generates an alert when the active response module successfully removes the threat.
  • Rule ID 110007 generates an alert when the active response module fails to remove the threat.

3. Restart the Wazuh manager to apply configuration changes:

$ sudo systemctl restart wazuh-manager

Visualize results

We download a variant of AsyncRAT on the Windows endpoint’s download folder to test the configuration. As shown in the screenshot below, the Wazuh FIM module detects the addition of a file on the system. This file was subsequently scanned by VirusTotal and identified as malicious, prompting the Wazuh active response module to remove the threat from the system.

AsyncRAT

Conclusion

AsyncRAT is a versatile tool used by attackers to gain foothold, steal data, and deploy more malware on targets, either in its original or modified form. We recommend maintaining total visibility of your Windows endpoints to detect any suspicious activity and take action before it escalates. Wazuh is a free, open-source SIEM and XDR solution that offers visibility to monitored endpoints and can be configured to detect and respond to suspicious behavior.

In this blog post, we demonstrated how to detect AsyncRAT activities with Wazuh. We used Sysmon to augment logs from the victim endpoint and created rules to detect suspicious activities associated with different variants of the malware. We also combined VirusTotal with Wazuh Active response module to scan and remove malicious files from the victim endpoint.

To learn more about Wazuh capabilities, check out our documentation, blog posts, and our community for support and updates.

Reference