Operation PhantomPrayers

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.

Graphical user interface (GUI) displayed 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: %appdata%\Birthday.

DLL sideloading infection chain

Copies the following components to the specified directory for the next stage of the infection chain:

 

  • Legitimate, digitally signed VLC.exe, which is vulnerable to DLL sideloading.

  • Malicious libvlc.dll, designed to be sideloaded by VLC.exe.

  • .tmp file containing shellcode, which is loaded and executed by libvlc.dll. 

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 %appdata%\Birthday directory, ensuring the malicious application launches automatically at system startup.

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 map.html, which is loaded and presented to the victim. This map is designed to convince the user that others worldwide are using the prayer check-in software.

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.

Multi-stage attack chain for Operation PhantomPrayers.

Figure 6: Multi-stage attack chain for Operation PhantomPrayers.

Stage 1: Shellcode loader

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:

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)


Stage 2: Reflective loader

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.

Stage 3: PhantomNet

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.