Technical Analysis of NailaoLocker Ransomware

This is the English version of the Japanese article “ランサムウェアNailaoLockerの調査“.
In February 2025, several cybersecurity vendors published a report about a ransomware named NailaoLocker12.
Compared to other ransomware attacks, NailaoLocker was special because it was deployed along with malware (RAT3) such as PlugX and ShadowPad. PlugX and ShadowPad is mainly used for cyber espionage purposes, by threat actors with nation-state background. As in this case, deploying ransomware after the usage of those malwares have almost never been reported.
This article will share the findings from the technical analysis of the NailaoLocker.
Sample
File indicators of analyzed samples are as follows.
SHA256 | Description |
---|---|
2b069dcde43b874441f66d8888dcf6c24b451d648c8c265dffb81c7dffafd667 | Encrypted NailaoLocker |
ee5fc8c8b3a9f7412655da01eb27a8959c82732988c0de593c1c90afeda1ef55 | NailaoLocker |
NailaoLocker exists on the file system in an encrypted state, and will be decrypted in memory by the loader (NailaoLoader) before execution. The following Python script can statically decrypt the encrypted NailaoLocker sample listed in the table above. This article does not provide a detailed analysis of the decrypted NailaoLoader sample. However, if you’re interested, you can analyze it yourself by decrypting the sample using this script.
import ctypes
with open('**Encrypted NailaoLocker**', 'rb') as dat_file:
dat = bytearray(dat_file.read())
for i in range(len(dat)):
tmp = ctypes.c_uint8(dat[i] + 75).value
tmp ^= 0x3F
tmp = ctypes.c_uint8(tmp - 75).value
dat[i] = tmp
with open('**Output File**', 'wb') as result_file:
result_file.write(dat)
Code language: JavaScript (javascript)
Procedure of NailaoLocker
NailaoLocker encrypts files on an infected machine by following the procedure below. Note that the mutex name varies depending on the NailaoLocker version, as detailed in a later section.
- Unload and delete NailaoLoader
- Create a mutex (name:
Global\lockv7
) - Decode an encoded data region
- Create a log file
- Encrypt files and create ransom note
Encoded data region
Specific data in NailaoLocker, including the file name and content of the ransom note, the RSA public key, and various configuration values, is encoded using a single-byte XOR with the key 0x3F. In the analyzed sample, the data region from offset 0x26D700 to 0x27132C in the executable binary was encoded.

During NailaoLocker execution, the data is decoded as needed.

For the structure of the encoded data region, please see Appendix A at the end of the article.
Log file
NailaoLocker will create and write a log file on %ProgramData%\lock.log
during operations such as file encryption4. The following is the format of the log lines output by NailaoLocker.
- When encrypting a file
- On success:
OK Encrypt [**Target File Path**]
- On failure:
*** Encrypt [**Target File Path**] error with code **Error Code**
- On success:
- When decrypting a file (details described in later section)
- On success:
OK Decrypt [**Target File Path**]
- On failure:
*** Decrypt [**Target File Path**] error with code **Error Code**
- On success:

Though this was not enabled in the analyzed sample, NailaoLocker also had the function to execute an arbitrary process when it is executed. When an arbitrary process was executed, NailaoLocker outputs the following log line.
- When executing a process5
- On success:
OK Excute [**Process Name**] OK
- On failure:
*** Excute [**Process Name**] error with code **Error Code**
- On success:
Investigating this log file is useful for checking what kind of action was performed by NailaoLocker. If you suspect you may be infected with NailaoLocker, it is a good idea to check it.
Exclusions
The following drives, folders, and files are excluded from file encryption done by NailaoLocker.
Type | Exclusions |
---|---|
Drive | A:\ , B:\ 6 , W:\ |
Folder | Boot , Windows , Program Files , Program Files (x86) , ProgramData , AppData , Application Data |
File | boot.ini , *.exe , *.dll , *.sys |
File Encryption
NailaoLocker uses statically linked OpenSSL 3.3.2 library functions to encrypt files. The encryption flow is as follows:
- Generate 32 random bytes for an AES key and 16 random bytes for the initialization vector (IV).

- Encrypt the AES key and IV with a hardcoded RSA public key.

- Prepare for encryption with AES-256-CBC.

- Read the first 0x10000 (65,536) bytes of the file.
- Overwrite the data range mentioned in step 4 with the file size and the original data encrypted with AES-256-CBC.

- Writes a footer to the end of the file containing various information such as the encrypted AES key and IV.

- Add
.locked
to the end of the file name. - Call the
SetFileTime
function to change the $SI timestamp of the file to match that of the original file. - Repeat the steps above for each file to be encrypted.
Partial Data Encryption
When encrypting a file larger than 0x10000 (65,536) bytes, only the first 0x10000 bytes are encrypted, while the rest of the data remains in plaintext. This technique is also frequently observed in other ransomware cases, where only a part of a file — often at the beginning, including the header — is encrypted to reduce the time required to encrypt large files.

Ransom Note
NailaoLocker creates a ransom note in the same folder as the encrypted files. The ransom note appears to be derived from Kodex Ransomware’s note, as indicated by the HTML comments it contains.

Although this function was not enabled in the analyzed sample, NailaoLocker is capable of creating a ransom note in the %ALLUSERSPROFILE%
folder and modifying the {HKLM|HKCU}\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
registry key to ensure it executes automatically upon system startup.
File Decryption
We confirmed that NailaoLocker can also act as a decryptor, depending on its configuration values. This sample also includes a function for decrypting files. Although the RSA public key is stored in this location and the encryption routine is called in this sample, if the RSA private key were placed there and the decryption routine were invoked with the aforementioned configuration, the sample would behave as a decryptor.

This suggests that the intended operation would involve providing (or an attacker executes) a decryptor version of NailaoLocker that includes the RSA private key to users who paid the ransom.
However, the Bitcoin address included in the ransom note shows no record of any transactions, suggesting that no users paid the ransom.
Anti-detection by API hooking
NailaoLocker performs API hooking on the GetModuleHandleExW
function immediately after its execution. If GetModuleHandleExW
has already been hooked via a JMP instruction, NailaoLocker overwrites 12 bytes of instructions starting from the jump destination address and redirects execution to the function shown in Figure 13. This technique is likely intended to make detection by EDRs more difficult, thereby ensuring that file encryption is performed without interference.


v3 and v7
The analyzed sample creates a Mutex named Global\lockv7
during execution. The string ‘v7’ at the end of the mutex name is believed to indicate the version of NailaoLocker.This is supported by the fact that another in-the-wild NailaoLocker sample7 creates a mutex named Global\lockedv3
8. Therefore, the sample mentioned in Footnote 7 can be identified as NailaoLocker v3, and the sample analyzed in this article as NailaoLocker v7.

Comparing the compilation timestamps of the NailaoLocker v3 and v7 samples reveals a difference of only about two months. If the compilation timestamps have not been tampered with, it is likely that NailaoLocker is being actively maintained and improved.
Name | SHA256 | Compilation Timestamp |
---|---|---|
NailaoLocker v3 | c7e5cd90da79d40818d6e781c9204e95d1b2a0973b0413282e82d2c125776e9b | 2024-08-18 08:43:20 (UTC) |
NailaoLocker v7 | ee5fc8c8b3a9f7412655da01eb27a8959c82732988c0de593c1c90afeda1ef55 | 2024-10-19 08:02:47 (UTC) |
The most significant difference between the NailaoLocker v3 and v7 samples lies in the encryption and decryption routines they implement. The NailaoLocker v7 sample uses the library functions from a statically linked OpenSSL, whereas the NailaoLocker v3 sample uses CNG APIs, which are part of the Win32 API.
The reason for this change is likely to prevent detection by antivirus products and to increase the burden on malware analysts.

The NailaoLocker v3 sample also employs a unique detection evasion technique that loads bcrypt.dll, which contains the CNG APIs, from an alternative path by copying it as %temp%\locked.dll
9. This is because some antivirus and EDR products detect ransomware by monitoring the loading of the DLL.

This technique was not implemented in NailaoLocker v7, likely because it uses statically linked OpenSSL rather than dynamically loading bcrypt.dll.
In addition to this, the NailaoLocker v7 sample includes many improvements over the v3 sample, such as multi-threaded file encryption and enhanced log file information output.
Conclusion
At this moment, NailaoLocker is still in its infancy. It encrypts files more slowly than other ransomware, such as LockBit, and lacks a recovery function if the infected device shuts down during encryption, making it inferior to modern ransomware.
However, since development may still be underway, it may become even more difficult to detect and may gain more advanced functionality in the future. At least based on publicly available information, there have been no reports of attacks targeting Japanese companies or organizations so far, but continued vigilance is still necessary.
Please check Appendix B for a YARA rule that can detect the encrypted NailaoLocker file.
Appendix A: Structure of encoded data region↩︎
Offset | Description | Value in the analyzed sample |
---|---|---|
0x0000 | Execution mode (0 = Encryption , 1 = Decryption) | 0 |
0x0004 | A drive encryption setting (0 = Encrypt , 1 = Do not encrypt) | 1 |
0x0008 | B drive encryption setting (0 = Encrypt , 1 = Do not encrypt) | 1 |
0x000C | C drive encryption setting (0 = Encrypt , 1 = Do not encrypt) | 0 |
0x0010 | D drive encryption setting (0 = Encrypt , 1 = Do not encrypt) | 0 |
0x0014 | Log file setting (0 = Do not create , 1 = Create) | 1 |
0x0018 | Ransom note autorun setting (0 = Disabled , 1 = Enabled) | 0 |
0x001C | Unknown (not used) | 1 |
0x0020 | File name of the ransom note | Omit |
0x0220 | Process name to be executed (Optional) | Empty |
0x1420 | RSA public or private key size | 0x5B |
0x1424 | RSA public or private key (maximum 0x70 bytes) | Omit |
0x1494 | Unknown (not used) | 0 |
0x1824 | Size of the ransom note | 0x98A |
0x1828 | Contents of the threatening letter | Omit |
Appendix B: YARA Rule↩︎
rule ENC_NailaoLocker_Ransomware {
meta:
description = "Detects encrypted NailaoLocker ransomware payload"
author = "Internet Initiative Japan Inc."
hash1 = "a2e937d0b9d5afa5b638cd511807e0fcb44ec81b354e2cf0c406f19e5564e54e"
hash2 = "2b069dcde43b874441f66d8888dcf6c24b451d648c8c265dffb81c7dffafd667"
hash3 = "27b313243daf145c9105f5372e01f1cea74c62697195c1a21c660be5f7ee788c"
strings:
$rule1 = { 52 29 6F 29 4D 29 29 }
$rule2 = { 04 29 59 29 37 29 3A 29 42 29 37 29 48 29 3C 29 65 29 48 29 35 29 48 29 04 29 4D 29 3D 29 3A 29 46 29 3E 29 FB 29 3D 29 3A 29 42 29 29 }
condition:
uint16(0) == 0x4F5C and
all of ($rule*)
}
Code language: plaintext (plaintext)
- https://www.orangecyberdefense.com/global/blog/cert-news/meet-nailaolocker-a-ransomware-distributed-in-europe-by-shadowpad-and-plugx-backdoors ↩︎
- https://www.trendmicro.com/en_us/research/25/b/updated-shadowpad-malware-leads-to-ransomware-deployment.html ↩︎
- Also known as Remote Access Trojan or Remote Administration Tool. It allows the remote access from attacker to infected machine. ↩︎
- Creation of a log file depends on the configuration value in the encoded data region mentioned above. ↩︎
- It says
Excute
notExecute
, but this is typo of malware developer. ↩︎ - It depends on the settings in the encoded data region. In this sample, the files in drive A and drive B were set not to be encrypted. ↩︎
- SHA256: 27b313243daf145c9105f5372e01f1cea74c62697195c1a21c660be5f7ee788c ↩︎
- The magic numbers in the footers of the encrypted files
b'LV7\x00'
also support this fact. ↩︎ - A similar detection evasion technique is implemented in Winnti Loader. For details,
please check RevivalStone:Winnti Groupによる日本組織を狙った攻撃キャンペーン | LAC WATCH (Japanese article). ↩︎