Affected Platforms: Microsoft WindowsImpacted Users: Microsoft WindowsImpact: Most files on the compromised machines are encryptedSeverity Level: High
FortiGuard Labs recently ran across NailaoLocker, a ransomware variant targeting Microsoft Windows systems. Like many ransomware families, it uses AES-256-CBC to encrypt user files. What sets it apart is the presence of hard-coded SM2 cryptographic keys and a built-in decryption function—an uncommon combination that raises immediate questions about intent.
The name “Nailao,” which means “cheese” in Chinese, may be more than a naming quirk. This ransomware could represent a rare opportunity: a payload with embedded recoverability. Or it could be bait—a trap laid to mislead victims and security researchers. One victim’s solution may, in this case, be another’s cheese.
Figure 1: Hard-coded SM2 key pairs in ASN.1 DER format
In this blog, we examine NailaoLocker’s complete technical profile, including its execution flow, encryption and decryption routines, and use of SM2 cryptography. We assess whether this variant introduces a genuine threat or exposes an exploitable flaw.
Loading and Execution
Figure 2: DLL side-loading used to decrypt and load NailaoLocker
NailaoLocker is delivered to the target system as a set of three files:
usysdiag.exe – a legitimate executable used for DLL side-loading
sensapi.dll – a malicious DLL loader (referred to as NailaoLoader)
usysdiag.exe.dat – the obfuscated NailaoLocker payload
Execution begins when the attacker triggers usysdiag.exe, which loads the malicious sensapi.dll using a DLL side-loading technique. This DLL decrypts and loads the actual ransomware payload (usysdiag.exe.dat) directly into memory. To minimize forensic traces, NailaoLoader frees its own library from memory and deletes sensapi.dll immediately after execution.
To prevent multiple instances from running simultaneously, NailaoLocker creates a mutex named lockv7.
Figure 3: NailaoLoader frees memory and deletes the DLL
Initialization
After loading, NailaoLocker checks a hard-coded value against the string «XXXX» to determine which mode to activate: encryption or decryption. This variant does not support command-line arguments for mode selection, indicating that the switch is built-in and may be reserved for internal use or testing.
Before execution proceeds, the ransomware performs a series of setup tasks. It launches a console window to display real-time status updates, signaling no intent to conceal its activity. It also creates a log file at %ProgramData%\lock.log, where it records progress throughout the encryption or decryption process.
In encryption mode, the ransomware retrieves the ransom note from its own binary using a simple XOR decoding routine. This note is later dropped into the affected directories.
Figure 4: Console launch and creation of %ProgramData%\lock.log
Multi-Threaded Execution
To optimize performance, NailaoLocker uses a multi-threaded architecture coordinated through Windows I/O Completion Ports (IOCP). This design enables high-throughput encryption or decryption across multiple processor cores.
An I/O Completion Port is initialized by calling CreateIoCompletionPort(). The main thread performs file system traversal and submits target file handles to the IOCP queue. Meanwhile, each worker thread waits for a handle to appear in the queue. When a file is received, the thread proceeds with encryption or decryption as appropriate.
This model decouples file discovery from processing, allowing the ransomware to efficiently scale across available CPU resources.
The GetSystemInfo() function is invoked to determine the number of logical processors available on the system. Using this information, the ransomware creates at least eight worker threads to handle concurrent file operations. This guarantees a baseline level of parallelism, even on lower-core systems.
Figure 5: IOCP setup with CreateIoCompletionPort() and multi-thread creation
In the next section, we examine the two distinct execution modes—encryption and decryption—and provide a detailed analysis of their functionality.
Key Pair Preparation
A distinctive feature of this NailaoLocker variant is its inclusion of a hard-coded SM2 key pair embedded in ASN.1 DER format. These keys are used during both encryption and decryption.
As shown in Figure 1, the embedded key structure contains a public key and a private key. The public key, based on elliptic curve cryptography, includes x and y coordinates that define a point on the SM2 curve. The private key—rarely seen in ransomware samples—is also present, suggesting a potential test build or alternate use case.
Figure 6: Decryption mode extracts embedded SM2 key pair
After extraction, the keys are initialized using the OpenSSL function EVP_PKEY_CTX_new(). Mapping from the hard-coded string “SM2”, the numerical identifier is set to 0x494 and is passed to the encryption function. This is further supported by the presence of the expected curve OID—06 08 2A 81 1C CF 55 01 82 2D—within the ASN.1 structure.
Figure 7: SM2 mapped to ID 0x494 and matching curve OID
Encryption Mode
When running in encryption mode, NailaoLocker performs two primary tasks: identifying target files and encrypting them using AES-256-CBC. It also appends a ransom note to each affected directory.
File Traversal
NailaoLocker begins by enumerating all logical drives on the system. It recursively searches accessible directories for files to encrypt, while deliberately skipping specific system paths and file types to avoid destabilizing the infected host.
Excluded file extensions:
Excluded directories and files:
\Boot
\Windows
\Program Files
\Program Files (x86)
\ProgramData
\AppData
\Application Data
boot.ini
unlock_please_view_this_file.html
Once a target file is identified, its handle is pushed to the IO Completion Port queue for processing by a worker thread. A ransom note is also dropped into each of the enumerated directories.
Figure 8: NailaoLocker ransom note delivered alongside encrypted files
File Encryption, AES Key Generation, and Key Protection
Each file sent to the I/O Completion Port is processed by a worker thread, which executes the encryption routine using a unique AES key and IV.
At the start of each thread, NailaoLocker allocates memory for 38 _OWORD (16-byte) elements. This space is used to store the AES key, IV, their SM2-encrypted versions, and related metadata.
The ransomware uses BCryptGenRandom() to generate a 32-byte AES key and a 16-byte IV for each file:
Figure 9: Per-thread memory allocation for AES keys and metadata
These values are used for file encryption with the AES-256-CBC algorithm. Instead of securing the AES key and IV with RSA, as is common in ransomware, NailaoLocker uses SM2, an elliptic curve cryptographic algorithm. This appears to be the first documented case of SM2 being used to protect symmetric file encryption keys in ransomware.
Figure 10: AES key and IV protected using SM2 encryption
Because SM2 does not produce a fixed-length output, the ransomware stores the sizes of the encrypted AES key and IV in two _WORD fields. The full memory layout includes:
v17(2)+8: AES key (32 bytes) – green
v17(4)+8: AES IV (16 bytes) – orange
v17(5)+8: Encrypted AES key (variable size) – blue
v17(21)+8: Encrypted AES IV (variable size) – pink
v17(37)+8: Size of encrypted AES key (4 bytes) – gray
v17(37)+C: Size of encrypted AES IV (4 bytes) – brown
Figure 11: Memory dump of AES key, IV, and SM2 encrypted version
Encryption Process
For each target file, NailaoLocker appends the .locked extension and sets the file attribute to FILE_ATTRIBUTE_HIDDEN. It then reads up to 0x10000 bytes (64 KB) of data per operation.
The ransomware performs encryption using the AES-256-CBC algorithm through OpenSSL’s EVP interface. The process includes:
EVP_EncryptInit_ex() – Initializes the encryption context using the AES cipher, AES key, and IV (both generated via BCryptGenRandom() (see Figure 9).
EVP_EncryptUpdate() – Encrypts the file content in blocks, supporting streaming.
EVP_EncryptFinal_ex() – Handles any remaining bytes and applies PKCS#7 padding.
The encrypted data replaces the original content.
Figure 12: File encryption routine using OpenSSL AES-256-CBC
To facilitate decryption, the ransomware assigns a LARGE_INTEGER (8 bytes) to hold the original file size. This value is stored in the first 8 bytes of the encrypted file, allowing the decryptor to navigate to the footer containing key material.
Figure 13: The first eight bytes store the original file size
After the encrypted payload, the ransomware appends a structured footer. It begins with a 4-byte marker 47 56 37 00 («LV7») to indicate the start of the encryption key section.
Figure 14: Storing protected file encryption keys at the end of the encrypted file
The original file content was shifted to storing the file size. Also, the encryption padding extends the file size. These bytes are not able to fit in the space before the “LV7” flag and are placed after the encrypted AES key and IV. Following the «LV7» marker, NailaoLocker stores all remaining cryptographic and overflow data in a fixed sequence. This layout is color-coded in Figure 15:
4 bytes: Encrypted AES key size – orange frame
Variable: Encrypted AES key – white frame
4 bytes: Encrypted AES IV size – green frame
Variable: Encrypted AES IV – pink frame
4 bytes: Remaining AES-encrypted data size – yellow frame
Variable: Remaining encrypted data – gray frame
Figure 15: Encrypted file footer with SM2-protected keys and overflow data
Once encryption is complete, NailaoLocker restores the file’s original last edit timestamp and renames it with the .locked extension (if not already applied). It then prints the total encryption duration to the console in the format done (time), where (time) represents the duration of the encryption operation.
Decryption Mode
In decryption mode, the ransomware requires the SM2 private key to reconstruct the AES key and IV, which are stored at the end of each encrypted file. It then traverses each directory to find encrypted files and performs the decryption process to restore them to their original status.
In this section, we will detail the process and validate the correctness of the built-in ASN.1 DER format of the SM2 private key. To initiate decryption mode, we modify the hard-coded value to be the same as «XXXX,» prompting the ransomware to switch modes.
Upon switching to decryption mode, the file traversal function is adjusted to search for files with the «.locked» extension, adding them to the IO Completion Port queue for processing.
Again, at least eight threads are created to accelerate the decryption process.
Key Retrieval
Each thread begins by parsing the footer of the encrypted file. The ransomware locates the «LV7» marker and reads the data that follows:
Encrypted AES key size
Encrypted AES key
Encrypted AES IV size
Encrypted AES IV
The SM2 private key, extracted earlier from the embedded ASN.1 DER block, is used to decrypt both the AES key and IV.
Figure 16: Decryption routine locates and extracts AES key and IV
File Decryption
Once the AES key and IV are recovered, the file content is decrypted using AES-256-CBC via OpenSSL’s EVP interface:
EVP_DecryptInit_ex() initializes the context.
EVP_DecryptUpdate() decrypts the content in blocks.
EVP_DecryptFinal_ex() removes padding and finalizes the output.
Figure 17: AES key and IV decrypted using SM2 and applied via OpenSSL EVP
Unfortunately, in testing, the embedded SM2 private key failed to correctly decrypt the AES key, suggesting the key material may be incomplete or deliberately non-functional. However, FortiGuard analysts confirmed that when the correct AES key and IV are manually supplied—captured during encryption—the decryption function performs as expected and successfully restores the original file contents.
Conclusion
This analysis provides a detailed technical profile of NailaoLocker, a ransomware variant notable for its embedded SM2 key pair and built-in decryption function. Although the embedded SM2 private key is non-functional in practice, testing confirms that the decryption logic operates correctly when supplied with valid AES key material, indicating this may be an in-development strain or internal test build.
The use of the Chinese SM2 cryptographic standard, particularly to protect AES file encryption keys, marks a notable divergence from conventional ransomware practices. FortiGuard Labs will continue to monitor for the further adoption of region-specific algorithms and for signs that NailaoLocker is evolving toward active deployment.
Fortinet Protections
FortiGuard Labs detects the NailaoLocker ransomware samples with the following AV signatures:
W64/Shadowpad.U!tr
W64/Filecoder.SZ!tr
W64/Filecoder.SZ!tr.ransom
FortiEDR, FortiXDR, and FortiDeceptor provide additional protection by detecting anomalous behavior, halting malicious encryption attempts in real time, and diverting ransomware away from production environments.
All protections are continuously updated based on real-time intelligence shared across Fortinet’s global sensor network, partner CERTs, and trusted threat intelligence alliances.
Fortinet recommends all organizations maintain a strong ransomware defense posture that includes:
Regular patching of exposed systems
Network segmentation
Endpoint protection with behavior-based detection
Encrypted backup strategies with offline storage
Employee awareness and phishing-resistant email security
If you feel your organizations has been impacted by NailaoLocker or any other ransomware, our global Incident Response team can assist with detection, containment, remediation, and recovery.
IOCs
NailaoLocker Ransomware (sha256)
1248c4b352b9b1325ef97435bd38b2f02d21e2c6d494a2218ee363d9874b760746f3029fcc7e2a12253c0cc65e5c58b5f1296df1e364878b178027ab26562d6860133376a7c8e051da787187761e596ce9b3d0cfcea21ed8f434992aa7cb8605