AnyDesk Clone Drops .NET Loader with AES Encrypted Payload and AV Evasion Delivering Phemedrone Stealer

On June 16, 2025, a suspicious domain impersonating AnyDesk — anydeske[.]icu — was reported on Twitter. The site served what appeared to be a legitimate remote access tool but actually delivered a malicious .NET loader. Further investigation revealed that the loader employed AES decryption, anti-analysis junk code, and evasion techniques to ultimately deliver Phemedrone Stealer

Attack Chain Overview

The attack chain leverages a multi-stage infection strategy starting from a deceptive website and ending with the deployment of the Phemedrone Stealer. Each phase of the chain incorporates layers of obfuscation, encryption, and defense evasion.

1. Initial Access

  • Victim is lured to anydeske[.]icu, a fake AnyDesk website.

  • They download a file named setup.exe — a .NET loader, disguised as a legitimate installer.

2. Loader Execution & Obfuscation

  • Upon execution, the loader:

    • Runs silently with no GUI.

    • It immediately begins performing meaningless mathematical calculations and other junk code routines designed to delay execution and evade sandbox timeouts.

    • Expects a command-line argument containing an AES-encrypted URL of the next-stage payload).

    • Decrypts this url using a derived AES key and IV (via PBKDF2 and AES-CBC).

    • Downloads the actual payload (second stage) to the victim’s %TEMP% directory.

3. Defense Evasion

  • Before executing the payload, the loader:

    • Adds Defender exclusions using repeated PowerShell commands

    • These exclusions reduce the chance of detection when the final payload is written and executed.

4. Payload Delivery & Execution

  • The decrypted URL points to a remote payload (EXE)

  • The loader downloads the file to %TEMP% and runs it with Process.Start().

  • This file is identified as Phemedrone Stealer, a credential- and data-exfiltration malware.

Initial Vector: Fake AnyDesk Website

The infection chain begins with a malicious website impersonating AnyDesk, a popular remote desktop software. The domain anydeske[.]icu was designed to deceive users into believing they were downloading a legitimate installer. Instead, the site served a .NET-based loader malware posing as the setup executable.

Phishing website impersonates AnyDesk

While the .NET loader itself does not contain any hardcoded URLs or payload references, it includes logic to decrypt AES-encrypted data passed as a command-line argument. The malware derives a 256-bit AES key using Rfc2898DeriveBytes (PBKDF2) and decrypts the input using AES-CBC.

Since the delivery site is currently offline, the original encrypted blob and decryption key are unavailable, but the structure of the code confirms the loader was designed to operate only when invoked with external encrypted data — an evasive technique to hide infrastructure from static analysis.

The loader is a lightweight .NET binary built to run quietly, decrypt external input, and execute its payload. Its structure is minimal but intentional: async entry, junk operations, and AES routines are all used to hide the actual behavior.

Hidden Control Flow via Async State Machine

The loader begins execution through a compiler-generated asynchronous state machine (Program.<Main>d__2), a structure created by the C# compiler to handle async methods. This technique allows the malware to execute tasks like downloading or sleeping without blocking the main thread, while also introducing obfuscation. The resulting control flow appears fragmented and cluttered, complicating static analysis and making the execution path less immediately clear to analysts.

Anti-Analysis and Obfuscation Techniques

The loader contains multiple methods designed to slow down analysis, evade detection, and waste time during sandbox execution. by simulating computation or generating useless code paths. These routines do not affect execution or payload delivery but serve to evade sandboxes and slow down debugging

GenerateJunkCodeFunction()

This method randomly constructs fake C-style function signatures and bodies using calls like GenerateRandomName() and GenerateRandomNumber(). The loop composes multiple randomized lines, including variable declarations, dummy arithmetic, conditions, loops, and return statements.

This logic isn’t compiled or executed.

PerformJunkCalculations()

This method performs a high-volume, floating-point math loop involving:

  • Math.Sin

  • Math.Cos

  • Math.Sqrt

The loop executes up to 10,000 iterations, depending on a random value. Every 1000 iterations, it reprocesses the calculation through a square root.

PerformJunkCalculations() method

ExecuteObfuscatedOperations()

This is the central dispatcher for junk operations. It runs a loop for a specified number of seconds, calling one of several predefined methods in rotation. It also repeatedly invokes AddFoldersToDefenderExclusions() to evade AV monitoring.

  • Rotates through ObfuscatedOperation1() to ObfuscatedOperation6() every few milliseconds

  • Adds AV exclusions at random intervals

  • Sleeps for 10–50ms between calls to throttle behavior and prolong runtime

ObfuscatedOperation1() to ObfuscatedOperation6() methods are self-contained, meaningless logic intended to create system noise.

ObfuscatedOperation1()

This method allocates a 1KB buffer and fills it with random bytes using Random().NextBytes(). It then creates a new AES encryption context with Aes.Create() and generates a fresh encryption key and IV using aes.GenerateKey() and aes.GenerateIV().

Methods responsible for AES key and IV generation

The buffer is encrypted using CreateEncryptor() and TransformFinalBlock(), and the result is discarded. The encrypted data has no functional use.

ObfuscatedOperation1() method

this routine simply exists to trigger cryptographic API usage, mimic “real” encryption activity and add complexity and delay for behavioral engines or sandboxes

ObfuscatedOperation2()

This routine generates a random alphanumeric string of 100 characters and computes its SHA256 hash using SHA256.Create() followed by ComputeHash(). The resulting hash is converted into a hexadecimal string using BitConverter.ToString() and a Replace() operation, but this output is never used. Like Operation1, the purpose is to invoke cryptographic functions

ObfuscatedOperation2() method

ObfuscatedOperation3()

This method performs repeated trigonometric calculations in a loop: for 1000 iterations, it computes the sum of Math.Sin(i) * Math.Cos(i) divided by Math.Tan(i + 0.1) + 0.1. The values are accumulated into a local variable and discarded. 

ObfuscatedOperation3() method

ObfuscatedOperation4()

This operation constructs a large string using Base64-encoded GUIDs. It creates 100 GUIDs via Guid.NewGuid(), converts each to a Base64 string, and appends them to a StringBuilder. The resulting string is then mutated with character replacements (e.g., replacing A with Z, a with z). The final output string is not stored or used.

ObfuscatedOperation4() method

ObfuscatedOperation5()

This method performs temporary file I/O. It generates a temp file path using Path.GetTempFileName(), writes a randomly generated 1000-character string into it using File.WriteAllText(), reads it back using File.ReadAllText(), and then deletes the file. It mimics the behavior of programs performing temp-file-based operations, but the data involved is meaningless.

ObfuscatedOperation5() method

Meaningless temp files created during execution:

Dropped Files section in VT

ObfuscatedOperation6()

In this method, the loader generates a list of 1000 random integers between 0 and 9999 using Random().Next(10000). It then sorts the list, reverses it, and filters out all values that are divisible by 3 using a LINQ where clause. The filtered list is stored locally and not used elsewhere. This method is a classic case of memory churn: it exercises list sorting, reversal, and filtering logic, all of which appear behaviorally legitimate but contribute nothing to the malware’s functionality.

ObfuscatedOperation6() method

Disabling Windows Defender via PowerShell

Next the loader disables Windows Defender’s scanning in specific system directories by adding them to Defender’s exclusion list. It begins by retrieving the path to the system’s CommonApplicationData directory (C:\ProgramData) via Environment.GetFolderPath(). The exclusion command is constructed in an intentionally obfuscated way: the string "Add-MpPreference" is assembled character by character, and the argument "-ExclusionPath" is also dynamically built using Convert.ToChar() for each letter.

Building the PowerShell Command "Add-MpPreference" and "-ExclusionPath"

Once the components are constructed, the final PowerShell command is composed and Base64-encoded then decoded

The resulting PowerShell command is (after executing ExecutePowerShellCommand() method):

				
					"powershell.exe" -Command "Add-MpPreference -ExclusionPath "C:\ProgramData""

				
			

Then the loader defines a hardcoded byte array (array3) that also decodes to the same Add-MpPreference command, but this time targeting the $env:TEMP folder. This ensures the malware excludes both the ProgramData and TEMP directories from Defender scanning.

Building the PowerShell Command "Add-MpPreference -ExclusionPath $env:TEMP"
Constructing command with CyberChef

Like the previous command, the string is Base64-encoded/decoded before use.

The resulting PowerShell command is (after executing ExecutePowerShellCommand() method):

				
					"powershell.exe" -Command "Add-MpPreference -ExclusionPath $env:TEMP"
				
			

At the end of the method, both commands are executed using an internal helper: Program.ExecutePowerShellCommand(), which launches powershell.exe with elevated permissions.

Privilege-Escalated, Silent Command Execution via PowerShell

Next it executes PowerShell commands on the victim system with elevated privileges.

It constructs a ProcessStartInfo object configured to launch powershell.exe with the provided command string passed via the -Command argument with parameters:

  • CreateNoWindow = true ensures that no PowerShell window appears on the screen.

  • UseShellExecute = false disables shell-level execution to allow for input/output redirection.

  • RedirectStandardOutput and RedirectStandardError are enabled to capture any response (although not read in this case).

  • Verb = "runas" forces the process to run with administrator privileges, triggering UAC elevation if required.

Once the process is configured, it is started and allowed to run for up to 5 seconds via WaitForExit(5000).

ExecutePowerShellCommand() method

This silently executes PowerShell commands with elevated privileges, primarily to add Defender exclusions, without showing a window or triggering visible output.

Payload URL Decryption

The loader implements a custom AES-CBC decryption routine to extract the actual payload URL from an externally supplied encrypted blob. This design choice moves sensitive infrastructure (download URLs) outside the binary, forcing analysts to obtain the original command-line arguments or staging source to reconstruct the full execution flow.

DecryptUrl() method

The method accepts two parameters:

  • encryptedData: a byte array containing the encrypted content (URL).

  • key: a 32-byte AES key derived from the first 16 bytes of encryptedData

The first 16 bytes of encryptedData are extracted into a separate array and used as the AES IV. The remaining bytes are treated as ciphertext.

The AES key is generated using GenerateSecureKey() method:

In the GenerateSecureKey() method, the loader uses PBKDF2 via Rfc2898DeriveBytes to derive a 256-bit AES key from a password. The key derivation process is based on three inputs:

  • Password: likely passed as a command-line argument or dynamically fetched (not present in the static binary).

  • Salt: the static string "SaltValueForUrlDecryption" is hardcoded in the sample.

  • Iterations: 10,000 rounds of HMAC are used to slow down brute-force attempts.

The result is a 32-byte AES key suitable for AES-256 encryption, which is later used to decrypt the payload URL.

Payload Download, Validation, and Execution

Once the loader has decrypted the payload URL, it proceeds to download the next-stage binary (in this case, Phemedrone Stealer).

This phase is handled in three steps: downloading the binary from a remote location, validating that the file is executable, and launching it.

DownloadFileWithProgressAsync is responsible for retrieving the payload from the remote server. It accepts two parameters: the URL to download from, and the full file path where the payload should be saved.

DownloadFileWithProgressAsync() method

Before execution, the downloaded file is passed through ValidateDownloadedFile  method to avoid crashing or executing a corrupt payload. This method performs three main checks:

  1. Existence Check – Verifies that the file exists at the specified path.

  2. Size Check – Ensures the file is not empty (Length > 0).

  3. PE Header Check – Reads the first two bytes to confirm that they match the standard MZ signature of a valid Windows PE file.

If any check fails, the function returns false and terminates execution.

ValidateDownloadedFile() method

Once the file passes validation, the loader executes it using Process.Start(), with UseShellExecute = true. This launches the binary in a separate process.

RunDownloadedFile() method

Conclusion

This campaign uses a malicious AnyDesk lookalike website to distribute a custom .NET loader designed to stealthily retrieve and execute the Phemedrone Stealer. The loader employs AES-encrypted arguments, PowerShell-based AV evasion, and a variety of junk and obfuscated operations to delay dynamic analysis and mislead reverse engineers.

Notably, the loader adds its working directory to Windows Defender exclusions, helping the second-stage payload persist without interference. The use of PBKDF2 key derivation with a hardcoded salt to decrypt the download URL indicates a moderate level of obfuscation, requiring knowledge of both the password and binary logic to retrieve the payload.

The final payload, Phemedrone Stealer, is delivered via Process.Start() as an external executable, completing a simple yet effective infection chain.

IOCs

				
					.Net loader: 
    - b1edc65392305bb7062c86930baae32ead04731e9dbd806ab6a5c382e9e52e3f
Phemedrone Stealer:
    - 29c5fe838dbcf78b8e6c77c60cd8a2e6c19515b6cd986e11d3b3e4af5fe61c73
AnyDesk Clone Domain:
    - anydeske[.]icu
Contacted IP Addresses:
    - 45.145.7[.]134
    - 216.74.123[.]49:50643
Contacted URLs:
    - https://pastebin[.]com/raw/YwvHhwUk
    - https://pastebin[.]com/raw/WrgrtxSu
    - http://45.145.7[.]134/hook/upgrade.php
    - http://45.145.7[.]134/ups/Snup.bat

				
			

MITRE ATT&CK

Initial Access

  • User Execution: Malicious File – [T1204.002]

Execution

  • Command and Scripting Interpreter: PowerShell – [T1059.001]

Defense Evasion

  • Obfuscated Files or Information – [T1027]
  • Modify System Configuration: Windows Defender Exclusions – [T1562.001]
  • Signed Binary Proxy Execution: PowerShell – [T1216.001]
  • Deobfuscate/Decode Files or Information – [T1140]
  • Command-Line Interface with Encrypted Parameters – [T1059.003]
Keep reading

Summary Recently identified previously undetected Kimsuky (also known as Black Banshee) infrastructure through advanced pivoting techniques. Using HTTP header analysis,

A recently observed phishing campaign impersonating Egypt Post (البريد المصري) has been attributed to the Smishing Triad, a well-documented cybercriminal

Introduction FleshStealer is a sophisticated, modular, and obfuscated .NET-based information-stealing malware designed for comprehensive data exfiltration from Windows systems. Its

Table of Contents

Check your darknet exposure

Get Your Free Report