noCry: Windows Ransomware Technical Review
Translated from Azerbaijani. Translation errors may exist!
NoCry is a ransomware variant developed with .NET, featuring advanced encryption and obfuscation mechanisms.
Static Analysis
We only have one exe file
To learn about the programming language, IDE, and packers used in the ransomware program, we load it into the DIE application.
During static analysis performed with Die (Detect It Easy), it was discovered that the file was written in Visual Basic and implements anti-analysis mechanisms. Specifically, the program attempts to protect itself with Anti-debug, Anti-Sandboxie, and Anti-VM techniques.
Let’s continue the analysis and get the hash values.
1
2
3
MD5: 00c127d803d89f32024afdcff3903162
SHA1: 6ed4558be1130499456aaef9a717e6517c45406a
SHA256: 8c922fb6caaa11a681987a59d3dac34fb0c10d75753217dde72fa845022b7b8f
In the first stage of analysis, I will examine the file using IDA Pro. The reason is that IDA is very powerful in showing the overall structure of the program, the interactions between functions, and potential code flow.
From here we can see that: _CorExeMain address is marked as the external entry point in the EXE file, and the program will be executed through CLR (Common Language Runtime).
In IDA Pro analysis, only one function named Start appears in the Functions list.
This is normal because the file is .NET-based and IDA Pro doesn’t recognize managed code as native functions. Therefore, the main logic parts of the program are not visible in IDA, and the real code structure can be seen with dnSpy, which we’ll get to later. Going down, we don’t encounter actual code. Instead, string metadata belonging to the .NET project is visible. Here, values like db, dw, and align are shown.
This is normal because: There is no native assembly, the code is managed by CLR, and IDA Pro shows these parts as data.
The strings here belong to methods, UI components, and API requests inside the program. During analysis, we encounter UI Form components and functions like SystemParametersInfoA.
(I knew before taking this screenshot that the malware was written in 2020, not 2025…) SystemParametersInfoA is an API that allows changing Windows system parameters. It’s also used by normal programs, but malware can use it for malicious purposes. Below are some examples.
Changing the desktop wallpaper
1
SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, "C:\\path\\msg.bmp", SPIF_UPDATEINIFILE | SPIF_SENDWININICHANGE);
Attempting to block the screen
1
SystemParametersInfoA(SPI_SETSCREENSAVEACTIVE, FALSE, NULL, 0);
As I mentioned, there isn’t much to look at with IDA Pro. Finally, let’s look at the screenshot showing that the ransomware uses mscoree.dll at runtime.
The shown PE Debug Directory structure indicates which PDB file NoCry ransomware used during build and that it’s executed by .NET CLR. The entry point jumps to the _CorExeMain function and is directed to the CLR host. I think it’s time to use dnSpy as a tool.
Before continuing the analysis process with dnSpy, we will load the exe file into the .NET Reactor Slayer tool. The purpose of this step is to detect obfuscated strings and increase code readability. The tool automatically deobfuscates strings hidden or encrypted by .NET Reactor.
Now dnSpy can be used.
We see Assembly info and namespaces, the most important of which are the namespaces. This is the real “brain” of the program. {} NoCry is the main namespace and all functional parts of the program are here. Let’s look at the most important modules and code. Let’s examine the code of the Anti module coming from {} NoCry.
Emulator() — Emulator Detection
1
2
3
4
long ticks = DateTime.Now.Ticks;
Thread.Sleep(10);
if (DateTime.Now.Ticks - ticks < 10)
return true;
This function determines whether the program is running in a real Windows environment by measuring time delay. If the delay is less than normal, the program thinks it’s an emulator.
DetectVirtualMachine() — VM Detection
1
2
3
4
5
6
7
8
9
10
11
public static bool DetectVirtualMachine()
{
foreach (ManagementBaseObject managementBaseObject in managementObjectCollection)
{
string text = managementBaseObject["Manufacturer"].ToString().ToLower();
if ((Operators.CompareString(text, "microsoft corporation", false) == 0 && managementBaseObject["Model"].ToString().ToUpperInvariant().Contains("VIRTUAL")) || text.Contains("vmware") || Operators.CompareString(managementBaseObject["Model"].ToString(), "VirtualBox", false) == 0)
{
return true;
}
//Some parts are cut because the code is long!
This function gets the computer manufacturer and model name via WMI. If the system is running on a virtual machine like VirtualBox or VMware, it detects it and returns true.
DetectDebugger() — Debugger Detection
1
2
[DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
private static extern bool CheckRemoteDebuggerPresent(IntPtr hProcess, ref bool isDebuggerPresent);
Detects via API whether a debugger is attached to the process.
DetectSandboxie() — Sandbox Detection
1
2
3
4
public static bool DetectSandboxie()
{
return Anti.GetModuleHandle("SbieDll.dll").ToInt32() != 0;
}
This function checks for the presence of Sandboxie DLL to detect the Sandboxie sandbox environment.
The encryption process of our files takes place under the check module:
- AES_Encrypt()
This function encrypts the given text using AES encryption and returns it in Base64 format. The key is formed based on MD5 hash and works in ECB (Electronic Codebook) mode.
- AES_Decrypt()
This function checks whether the given cipher is decrypted correctly. If the decryption process is successful, it returns true, otherwise false. I think this method can be used to test the correctness of the cipher within the ransomware. Another module is del.
del Module’s Function: Complete Cleanup
The StandardModule class named del is a structure found in .NET (Visual Basic) based programs and performs cleanup (delete/self-destruct) operations.
Deleting originals of encrypted files.
1
2
3
4
5
6
7
8
9
List<string>.Enumerator enumerator = Form4.listenc.GetEnumerator();
while (enumerator.MoveNext())
{
string text = enumerator.Current;
if (File.Exists(text))
{
File.Delete(text);
}
}
Interaction.SaveSetting(): This is a function used in Visual Basic to write data to the Windows Registry.
While the ransomware is running, it stores some status information in the Registry. These lines reset all those values (“P”, “H”, “M”, “S”, “X”, “D”, “T”, “G”, “F”, “C”, etc.) to “0”.
1
string text3 = Path.GetTempPath() + "del.vbs";
Creates a vbs script in the Temp folder (C:\Users...\AppData\Local\Temp\del.vbs).
The del.vbs script starts immediately after the NoCry.exe process closes and deletes both the main location of the program and its copy in the Startup folder. This is a classic “Self-Delete” technique that cleans itself when the process is no longer running.
There are Form1, Form2, Form3, etc. namespaces inside the malware. I will look at each one individually and write down the most important code and functions below.
In the Form1_Load method, the timer is started with this.Timer1.Start().
Since Timer1.Interval = 1000, this is executed every 1 second. The Timer1_Tick method decrements the hour, minute, and second variables every second. These values are displayed in Label9 (hour) and Label7 (minute) on the window. Timer values are saved in the Registry (Interaction.SaveSetting) every time they change. This ensures that the Timer continues from where it left off even when the computer is turned off and on.
If the countdown reaches zero (this.hour == 0.0 & this.minute == 0.0)
The del.del() method is called. If you remember, I wrote about this above, it starts the self-deletion operation and most likely destroys the files beyond recovery.
Form2 is the window where the victim enters the Decryption key and attempts to retrieve their files, Form3 is the classic ransomware window used by the hacker to communicate with the victim. I won’t write anything about these. Form4 is the window that displays the list of encrypted files used by the Ransomware. The main purpose of this window is to convince the victim that their files are actually encrypted. Let’s look at the module named Modul1.
This module is where the program starts, Anti-Analysis checks are performed, the AES encryption key is prepared, files are encrypted, ransom notes are prepared, and information is sent to the hacker.
startup method: If the configuration allows, it copies the hacker’s file to the Windows Startup folder. This ensures that the ransomware restarts when the system is rebooted.
Module1.HWID() This collects system information such as CPU ID, BIOS serial number, and Motherboard serial number, and creates an MD5 Hash from them.
1
2
3
4
5
6
7
8
9
10
if (!text3.EndsWith("Bin"))
// ...
if (!text3.EndsWith("indows"))
if (!text3.EndsWith("tings"))
if (!text3.EndsWith("System Volume Information"))
// ...
// Program Files folders are excluded
if (!text3.EndsWith("rogram Files (x86)"))
if (!text3.EndsWith("rogram Files"))
// ...
The ransomware excludes folders that are critical to the Windows operating system from encryption. This prevents the system from crashing so the victim can pay the ransom.
EncryptOrDecryptFile Opens the file, encrypts it using Module1.CryptoAction.ActionEncrypt, and deletes the original file (fileInfo.Delete())
The .NoCry extension is added to the encrypted file along with St.exs. I placed the namespaces screenshot below again so you don’t forget.
Finally, let’s look at the NewWebhook and ST modules. Immediately after the encryption process is complete, it sends to the hacker using the “Discord Webhook URL”.
1
2
public static string webhookk = St.webhook;
//Stores the Webhook URL where the data should be sent, this is taken from the St configuration class.
This method is called by the Module1.sends method and is used to transmit the victim’s complete information package. MultipartFormDataContent This is a standard web format that allows sending both text and screenshots in the same HTTP request. When this request is successfully completed, the hacker receives all the details about the victim and the Decryption key in the Discord channel.
The ransomware gets some of the values we wrote above from inside the St module here.
Dynamic Analysis
Now let’s run the Ransomware and perform dynamic analysis, let’s see what we can learn during dynamic analysis.
There are no child processes.
The code dumped from RAM is the same as the code we looked at in dnSpy, there is no difference in this part. Therefore, it’s not worth performing Dynamic analysis.
The appearance of the Ransomware is in this format
We must write the key given to us by the hacker here. If we write it wrong 3 times, all our files will be deleted.
IOC
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
The following indicators can be used to confirm NoCry Ransomware infection and clean the system.
Unique signatures of the malicious file:
MD5: 00c127d803d89f32024afdcff3903162
SHA1: 6ed4558be1130499456aaef9a717e6517c45406a
SHA256: 8c922fb6caaa11a681987a59d3dac34fb0c10d75753217dde72fa845022b7b8f
Malware's external connections:
C2 Channel: https://discord.com/api/webhooks/816008354065416215/oYSubP4bdGoy9bWfFabwIi4Vc9A_utG5BOlFFIFXRUj8WtL8i98RhbtRyQkOk6EG91-t
IP Query: http://ip-api.com/csv/?fields=country,query
User-Agent: Standard .NET HttpClient or WebClient agent headers.
Files created or modified on the system:
Temp Files (%TEMP%):
%TEMP%\del.vbs
%TEMP%\Cry.img
%TEMP%\[Username]-screenshot.jpg
Startup:
%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\[RandomName].exe (Copied file for persistence).
HOW_TO_DECRYPT.html (or name from Resources.html).
Keys used by the malware to save its own state:
Path: HKCU\Software\VB and VBA Program Settings\[ProgramName]\Setting
Parameters (Keys):
"F" –
"H", "M", "S" –
"P", "X"
"T"
"G"
Behavioral Indicators
WMI Activity: Win32_Processor, Win32_BIOS, Win32_BaseBoard queries
Shadow Copies: Calling the SRRemoveRestorePoint function or vssadmin commands.
Desktop Modification: Sudden change of wallpaper.
Mitre Technique ID
1
2
3
4
5
6
7
8
9
10
T1059.005 Command and Scripting Interpreter
T1547.001 Boot or Logon Autostart Execution
T1497 Virtualization/Sandbox Evasion
T1486 Data Encrypted for Impact
T1490 Inhibit System Recovery
T1082 System Information Discovery
T1113 Screen Capture
T1102 Web Service
T1491 Defacement
T1070.004 Indicator Removal
Yara Rule
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
rule Ransomware_NoCry_NET
{
meta:
description = "Improved detection for NoCry .NET ransomware variants (reduce FP)"
author = "rafok2v9c"
date = "2025-12-04"
reference = "Internal Analysis"
threat_level = "High"
category = "Ransomware"
strings:
// Namespace / module identifiers (likely wide UTF-16 in .NET)
$s_nocry1 = "NoCry.My" wide
$s_nocry_res = "NoCry.My.Resources" wide
$s_newwebhook = "NewWebhook" wide
// Crypto / key derivation / functions (Rijndael must be present)
$c_rij = "RijndaelManaged" wide
$c_sha512 = "SHA512Managed" wide
$c_encrypt_method = "EncryptOrDecryptFile" wide
$c_check_aes = "check.AES_Decrypt" wide
// WMI / HWID queries (wide)
$w_cpu = "Win32_Processor" wide
$w_bios = "Win32_BIOS" wide
$w_base = "Win32_BaseBoard" wide
$w_gpu = "Win32_VideoController" wide
// Web / exfil / screenshot markers (ascii/wide as appropriate)
$net_multipart = "MultipartFormDataContent" wide
$net_sendinfo = "SendSysInfo" wide
$net_screenshot = "-screenshot.jpg" ascii wide
// look for discord webhook path (common C2 for this sample)
$discord1 = "discord.com/api/816008354065416215" ascii nocase
$discord2 = "discordapp.com/api/816008354065416215" ascii nocase
// Destructive / anti-analysis markers
$d_delvbs = "del.vbs" ascii
$d_spi = "SystemParametersInfoA" ascii
$d_restore = "DeleteRestorePoints" wide
condition:
uint16(0) == 0x5A4D and
(
// HIGH CONFIDENCE: specific namespace + Rijndael + discord webhook-ish
($s_nocry1 or $s_nocry_res) and $c_rij and (any of ($discord*))
or
// Behavioral signature: HWID/WMI + destructive + ransom-string
(2 of ($w_*) and 1 of ($d_*) and 1 of ($msg_*))
or
// Generic but stricter: Rijndael + encrypt method + multipart exfil
$c_rij and $c_encrypt_method and $net_multipart
)
}
CONCLUSION
NoCry Ransomware is malicious software built on .NET (VB.NET) with a modular structure, designed for “Ransomware-as-a-Service” (RaaS) or individual use. Code analysis revealed the following key features:
Technology: Uses .NET Framework (Windows Forms). Obfuscation is applied to make the code harder to read, but it can be decompiled.
Encryption: Uses standard AES-256 algorithm (RijndaelManaged). The Key and IV are derived from the user’s HWID (Hardware ID) and SHA-512 hash of random strings. This shows that a unique key is created for each victim, not a “Static Key”.
C2 and Data Exfiltration: Instead of a traditional C2 server, it uses Discord Webhooks (NewWebhook class) to steal data (Key, ID, Screenshot, IP).
Persistence and Destruction: Copies itself to the Startup folder, deletes Windows Restore Points (DeleteRestorePoints), changes the desktop wallpaper, and after finishing its work, destroys itself with the del.vbs script to remove traces.
Anti-Analysis: Uses the Anti class to detect virtual machines, Sandboxes, and debuggers (however, these checks can be bypassed in some configurations).



























