StopRansomware: Gunra Ransomware Threat Analysis
Detection stack
- AIDR
- Alert
- ETL
- Query
Summary
Gunra is a ransomware-as-a-service (RaaS) operation that follows a double-extortion model combining data encryption with exfiltration. The threat actors target critical infrastructure, government entities, and a wide range of commercial organizations worldwide. The ransomware is based on leaked Conti source code and has evolved to support both Windows and Linux environments.
Investigation
The FBI and international partners observed Gunra actors exploiting internet-facing vulnerabilities and abusing stolen credentials for initial access. The investigation identified the use of Impacket libraries for lateral movement and multiple open-source tools for data exfiltration. The group also relies on a Tor-based negotiation portal and qTox to communicate with victims.
Mitigation
Organizations should prioritize patching known exploited vulnerabilities in internet-facing systems, especially VPN gateways and RDP infrastructure. Maintaining immutable offline backups and enforcing strict network segmentation are critical for limiting lateral movement. Multi-factor authentication (MFA) should also be enabled across all remote access services.
Response
If Gunra activity is detected, compromised hosts should be isolated immediately while preserving relevant forensic artifacts, including encrypted files and system logs. Threat hunting should begin to determine the scope of the intrusion and review privileged account activity. Organizations should then follow formal eviction procedures to fully contain and remove the adversary from the environment.
Attack Flow
Detections
Possible Impacket Command Line Patterns (via cmdline)
Proof of Value
Create or Delete Shadow Copy via Powershell, CMD or WMI (via cmdline)
Proof of Value
Alternative Remote Access / Management Software (via system)
Proof of Value
Possible Impacket Execution Behaviour (via audit)
Proof of Value
Alternative Remote Access / Management Software (via audit)
Proof of Value
IOCs (HashSha256) to detect: #StopRansomware: Gunra Ransomware
Proof of Value
IOCs (SourceIP) to detect: #StopRansomware: Gunra Ransomware
Proof of Value
IOCs (DestinationIP) to detect: #StopRansomware: Gunra Ransomware
Proof of Value
Gunra Ransomware Account Manipulation and Privilege Escalation Detection [Microsoft Windows Security Event Log]
Proof of Value
Detection of Exploited Vulnerabilities in FortiOS and FortiProxy [Firewall]
Proof of Value
Gunra Ransomware Lateral Movement and Credential Dumping Detection [Windows Process Creation]
Proof of Value
Detection of Gunra Ransomware File System Traversal APIs [Linux Process Creation]
Proof of Value
Simulation Execution
Prerequisite: The Telemetry & Baseline Pre-flight Check must have passed.
Rationale: This section details the precise execution of the adversary technique (TTP) designed to trigger the detection rule. The commands and narrative MUST directly reflect the TTPs identified and aim to generate the exact telemetry expected by the detection logic. Abstract or unrelated examples will lead to misdiagnosis.
-
Attack Narrative & Commands: The adversary’s goal is to prepare for a ransomware deployment. Before encryption can begin, the malware must crawl the file system to build a list of high-value files (documents, databases, etc.). The Gunra ransomware specifically uses the
FindFirstFileWandFindNextFileWAPIs to perform this wide-scale enumeration. We will simulate this by compiling and executing a small C# snippet that explicitly calls these APIs via a DLL import, causing Sysmon to log the API usage in theImageLoadedfield. -
Regression Test Script:
# Save this as TriggerDetection.cs using System; using System.Runtime.InteropServices; using System.IO; class Program { static void Main() { // This simulates the Gunra ransomware's traversal behavior // by forcing the loading of these specific APIs. DirectoryInfo di = new DirectoryInfo(@"C:"); foreach (var file in di.GetFiles()) { // Accessing file properties triggers the traversal APIs string name = file.Name; } Console.WriteLine("Traversal complete."); } } # Compile and Run using csc.exe (built-in to .NET Framework) Add-Type -TypeDefinition @" using System; using System.Runtime.InteropServices; public class Win32 { [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] public static extern bool FindFirstFileW(string lpFileName, out WIN32_FIND_DATA lpFindFileData); [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] public static extern bool FindNextFileW(IntPtr hFindFile, out WIN32_FIND_DATA lpFindFileData); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct WIN32_FIND_DATA { public uint dwFileAttributes; public uint ftCreationTime; public uint ftLastAccessTime; public uint ftLastWriteTime; public uint nFileSizeHigh; public uint nFileSizeLow; public uint dwReserved0; public uint dwReserved1; public uint dwFileIndexHigh; public uint dwFileIndexLow; public uint dwStreamSize; public string cFileName; public string cAlternateDataStream; } } "@ # Execute a small C# script that explicitly calls the functions to ensure string presence in logs $code = @" using System; using System.Runtime.InteropServices; class Program { [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] public static extern bool FindFirstFileW(string lpFileName, out FIND_DATA lpFindFileData); [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] public static extern bool FindNextFileW(IntPtr hFindFile, out FIND_DATA lpFindFileData); [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct FIND_DATA { public uint dwFileAttributes; public uint ftCreationTime; public uint ftLastAccessTime; public uint ftLastWriteTime; public uint nFileSizeHigh; public uint nFileSizeLow; public uint dwReserved0; public uint dwReserved1; public uint dwFileIndexHigh; public uint dwFileIndexLow; public uint dwStreamSize; public string cFileName; public string cAlternateDataStream; } static void Main() { FIND_DATA data; IntPtr handle = IntPtr.Zero; // This triggers the specific strings in the Sysmon ImageLoaded field if (FindFirstFileW("C:\*", out data)) { Console.WriteLine("Found file via FindFirstFileW"); FindNextFileW(handle, out data); } } } "@ $code | Out-File -FilePath "$env:TEMPTriggerDetection.cs" & csc.exe "$env:TEMPTriggerDetection.cs" & "$env:TEMPTriggerDetection.exe" -
Cleanup Commands:
Remove-Item "$env:TEMPTriggerDetection.cs" -ErrorAction SilentlyContinue Remove-Item "$env:TEMPTriggerDetection.exe" -ErrorAction SilentlyContinue