In June 2025, a new subdomain, hhthedalailama90.niccenter[.]net was used by the threat actor to distribute a malicious application masquerading as a "special prayer check-in" software.
The malicious binary hosted at the URL http://hhthedalailama90.niccenter[.]net/DalaiLamaCheckin.exe is an application built with the PyQT5 framework and the Python data visualization library, Folium, and packaged as an executable using PyInstaller.
The binary displays a graphical user interface (GUI) to the
targeted user, prompting them to check in by entering their username and email
address. In addition, the GUI also displays an interactive map showing other
users who have checked in, thereby adding legitimacy to the social engineering
process. In the background, malicious activities are carried out.
The figure below shows the graphical user interface (GUI)
displayed to the victim upon execution of DalaiLamaCheckin.exe.

Figure 5: Graphical user interface (GUI) displayed upon execution of DalaiLamaCheckin.exe.
The table below describes the key capabilities of this binary.
|
Capability |
Description |
|---|---|
|
Directory creation |
Creates a directory in the path: |
|
DLL sideloading infection chain |
Copies the following components to the specified directory for the next stage of the infection chain:
|
|
Persistence |
Establishes persistence by creating a Windows
shortcut file, Birthday
Reminder.lnk,
in the STARTUP directory. The shortcut’s target path points
to VLC.exe in the |
|
PyQT5 check-in dialog and API integration |
Displays a GUI created with PyQT5, prompting the target to check in. The dialog prompts the user to enter their username and email address. Upon check-in, an HTTP GET request is sent to 104.234.15[.]90:59999/api/checkins with the custom HTTP header X-API-KEY: m1baby007. |
|
Folium-based data visualization |
Utilizes the Python visualization library,
Folium, to download check-in data from
104.234.15[.]90:59999/api/checkins. The data is parsed to
extract usernames and locations, then used to generate a map
file named |
Table 3: The key capabilities of the PhantomPrayers binary.
This information is captured at the server's end in the following JSON format.
{
"username": "",
"lat": "",
"lon": "",
"location": "",
"timestamp": "",
"ip": "",
"email": ""
}
The check-in data downloaded from the server is available in our GitHub repository. It appears that most of these entries were fabricated by the threat actor as the IP addresses captured for most of the usernames belong to hosting providers instead of ISPs.
Below is the configuration present inside the PyInstaller decompiled code.
BACKEND_URL = 'http://104.234.15.90:59999/api'
CHECKIN_URL = f'{BACKEND_URL}/checkin'
CHECKINS_URL = f'{BACKEND_URL}/checkins'
API_KEY = 'm1baby007..'
API_HEADERS = {'X-API-KEY': API_KEY}
BIRTHDAY_VENUE_COORDS = [32.232513887581284, 76.32422089040426]
MAP_HTML_FILE = os.path.join(tempfile.gettempdir(), 'map.html')
APP_NAME_IN_APPDATA = 'DalaiLamaBirthdayCheckin'
The PhantomPrayers attack chain closely resembles the Operation GhostChat attack, with the notable exception that the stage 2 loader shellcode is encrypted and stored in an external file .tmp instead of being embedded within stage 1. The PhantomPrayers attack chain is shown in the figure below.

Figure 6: Multi-stage attack chain for Operation PhantomPrayers.
When VLC.exe is executed, it sideloads the malicious libvlc.dll from the same directory. The stage 1 loader code resides in the libvlc_new exported function, which decrypts and executes the next-stage shellcode stored in the .tmp file within the directory.
The shellcode in the .tmp file is encrypted with two layers:
Layer 1: RC4 encryption using a hardcoded 16-byte key and initialization vector (IV).
Layer 2: AES-128 (CBC mode) encryption, with the same 16-byte key and IV.
The decryption code is provided below.
from Crypto.Cipher import ARC4
from Crypto.Cipher import AES
with open(".tmp", "rb") as f:
encrypted_shellcode = f.read()
rc4_key = b'\x0F\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F'
rc4_cipher = ARC4.new(rc4_key)
rc4_decrypted = rc4_cipher.decrypt(encrypted_shellcode)
aes_key = b'\x01\x02\x03\x09\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F'
aes_iv = b'\x01\x02\x03\x09\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F'
aes_cipher = AES.new(aes_key, AES.MODE_CBC, aes_iv)
rc4_decrypted = rc4_decrypted + b"\x00"
decrypted_shellcode = aes_cipher.decrypt(rc4_decrypted)
with open("decrypted_shellcode.bin", "wb") as f:
f.write(decrypted_shellcode)
This shellcode, similar to the one used in the Operation GhostChat infection chain, is designed solely to decompress an embedded executable, load it into memory, and execute it.
The final payload is a 32-bit executable and a variant of the PhantomNet backdoor. The final payload’s embedded configuration is XOR-encoded with a hardcoded 10-byte key (6B B2 95 27 66 66 74 6B A1 86) and includes the C2 server 45.154.12[.]93 and port 2233 as strings. While this sample uses TCP for C2 communication, it can also be configured for HTTPS communication. C2 traffic is secured using AES encryption with a key derived from a string in the configuration.
PhantomNet can be set to operate only during specific hours or days, but this capability is not enabled in the current sample. The backdoor relies on plugin DLLs delivered from the C2 server to carry out actions on the infected system.
Since this sample's commands and functionality match those reported by ESET researchers in the 2020 Operation SignSight campaign, we will not provide further details on the malware.