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.

SHA256Description
2b069dcde43b874441f66d8888dcf6c24b451d648c8c265dffb81c7dffafd667Encrypted NailaoLocker
ee5fc8c8b3a9f7412655da01eb27a8959c82732988c0de593c1c90afeda1ef55NailaoLocker

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.

  1. Unload and delete NailaoLoader
  2. Create a mutex (name: Global\lockv7)
  3. Decode an encoded data region
  4. Create a log file
  5. 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.

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**
  • 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**

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**

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.

TypeExclusions
DriveA:\ , B:\ 6 , W:\
FolderBoot , Windows , Program Files , Program Files (x86) , ProgramData , AppData , Application Data
Fileboot.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:

  1. Generate 32 random bytes for an AES key and 16 random bytes for the initialization vector (IV).
  1. Encrypt the AES key and IV with a hardcoded RSA public key.
  1. Prepare for encryption with AES-256-CBC.
  1. Read the first 0x10000 (65,536) bytes of the file.
  2. Overwrite the data range mentioned in step 4 with the file size and the original data encrypted with AES-256-CBC.
  1. Writes a footer to the end of the file containing various information such as the encrypted AES key and IV.
  1. Add .locked to the end of the file name.
  2. Call the SetFileTime function to change the $SI timestamp of the file to match that of the original file.
  3. 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.

Figure 12: API hooking

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\lockedv38. 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.

NameSHA256Compilation Timestamp
NailaoLocker v3c7e5cd90da79d40818d6e781c9204e95d1b2a0973b0413282e82d2c125776e9b2024-08-18 08:43:20 (UTC)
NailaoLocker v7ee5fc8c8b3a9f7412655da01eb27a8959c82732988c0de593c1c90afeda1ef552024-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.dll9. 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.

Appendix A: Structure of encoded data region↩︎

OffsetDescriptionValue in the analyzed sample
0x0000Execution mode (0 = Encryption , 1 = Decryption)0
0x0004A drive encryption setting (0 = Encrypt , 1 = Do not encrypt)1
0x0008B drive encryption setting (0 = Encrypt , 1 = Do not encrypt)1
0x000CC drive encryption setting (0 = Encrypt , 1 = Do not encrypt)0
0x0010D drive encryption setting (0 = Encrypt , 1 = Do not encrypt)0
0x0014Log file setting (0 = Do not create , 1 = Create)1
0x0018Ransom note autorun setting (0 = Disabled , 1 = Enabled)0
0x001CUnknown (not used)1
0x0020File name of the ransom noteOmit
0x0220Process name to be executed (Optional)Empty
0x1420RSA public or private key size0x5B
0x1424RSA public or private key (maximum 0x70 bytes)Omit
0x1494Unknown (not used)0
0x1824Size of the ransom note0x98A
0x1828Contents of the threatening letterOmit

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)
  1. https://www.orangecyberdefense.com/global/blog/cert-news/meet-nailaolocker-a-ransomware-distributed-in-europe-by-shadowpad-and-plugx-backdoors ↩︎
  2. https://www.trendmicro.com/en_us/research/25/b/updated-shadowpad-malware-leads-to-ransomware-deployment.html ↩︎
  3. Also known as Remote Access Trojan or Remote Administration Tool. It allows the remote access from attacker to infected machine. ↩︎
  4. Creation of a log file depends on the configuration value in the encoded data region mentioned above. ↩︎
  5. It says Excute not Execute , but this is typo of malware developer. ↩︎
  6. 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. ↩︎
  7. SHA256: 27b313243daf145c9105f5372e01f1cea74c62697195c1a21c660be5f7ee788c ↩︎
  8. The magic numbers in the footers of the encrypted files b'LV7\x00'also support this fact. ↩︎
  9. A similar detection evasion technique is implemented in Winnti Loader. For details, 
    please check RevivalStone:Winnti Groupによる日本組織を狙った攻撃キャンペーン | LAC WATCH (Japanese article). ↩︎

Share