In June 2025, threat actors carried out a strategic web compromise by replacing the legitimate link, tibetfund.org/90thbirthday, on a compromised webpage with a malicious link. The original link directed users to a page inviting members of the Tibetan community to send greetings to the Dalai Lama, but the malicious link redirected them to a fraudulent page hosted at thedalailama90.niccenter[.]net. This fake page was designed to closely mimic the original tibetfund.org site.
The figure below compares the legitimate webpage and the malicious replica created by the threat actor.

Figure 1: A side-by-side comparison of the legitimate Tibetan webpage and the malicious replica created by the threat actor.
The malicious webpage includes an option to download an encrypted chat application, designed to lure the targeted user to connect with other members of the Tibetan community under the pretense of secure communication. Clicking on this “chat” option redirects users to tbelement.niccenter[.]net, where they are prompted to download a backdoored version of Element, a popular open-source encrypted chat application.
The figure below shows the webpage created by the threat actor which impersonates the Element messaging application to lure users.

Figure 2: Webpage crafted by threat actor to distribute a backdoored version of the Element messaging application.
The webpage also contains JavaScript code designed to collect the visitor’s IP address and user-agent information. Using WebRTC, the malicious webpage retrieves the user’s IP address and then sends the information collected via an HTTP POST request to save_ip.php, a PHP script hosted on the same server.
The figure below shows the JavaScript code responsible for this action.

Figure 3: The JavaScript code on the webpage used to collect the user's IP address and user-agent information.
When the user clicks the “Download” button on the webpage shown in Figure 2, a ZIP archive is downloaded from the following URL: https://tbelement.niccenter[.]net/Download/TBElement.zip.
TBElement.zip contains multiple components related to the legitimate messaging application, Element. However, the legitimate DLL, ffmpeg.dll, has been replaced with a malicious DLL. Since the legitimate, digitally signed file Element.exe is vulnerable to DLL sideloading, it automatically loads the malicious ffmpeg.dll when it runs.
The figure below shows the multiple stages involved in the attack chain.

Figure 4: Multi-stage attack chain for Operation GhostChat.
The technical analysis below describes each stage of the attack chain and how GhostChat orchestrates command-and-control (C2) communication.
The ffmpeg.dll file is a stage 1 loader that loads embedded shellcode, injects it into a target process, and executes it. In addition, ffmpeg.dll creates persistence on the compromised machine by adding a Windows registry value.
The table below describes the key functionalities of the ffmpeg.dll file.
|
Capability |
Description |
|---|---|
|
API resolution |
API names are stored as plain text in the
binary, with no hashing algorithms used. To resolve API
addresses, the export directory of the loaded module is
scanned and compared against the API names. The threat actors use less common Windows native APIs like Nt* and Rtl*, likely to evade detection by EDR solutions that focus on monitoring user-mode APIs for suspicious activity. |
|
Map ntdll from disk |
The stage 1 shellcode loader uses a technique
to bypass potential user-mode API hooks or memory
breakpoints in ntdll.dll. It achieves this by loading a
fresh copy of ntdll.dll from disk and mapping it into memory.
Here’s how the process works:
This process ensures that any API hooks or modifications added by endpoint security solutions in the user-mode ntdll.dll are overwritten. |
|
Code injection |
The stage 1 shellcode loader uses shared
memory section-based code injection to inject 32-bit
shellcode into a legitimate Windows process, ImagingDevices.exe.
The technique relies on low-level APIs to minimize detection
by security solutions. The steps are as follows:
This method stealthily injects the shellcode into the target process. |
|
Registry persistence |
To achieve persistence, the malware adds a
registry value under the path:
|
Table 1: Key capabilities of the ffmpeg.dll file.
The stage 2 shellcode contains an executable compressed with NRV2D, which is one of the compression algorithms supported by the popular UPX packer. To evade detection, the executable’s PE headers have their MZ and PE magic bytes replaced with 0xd and 0xa.
The shellcode allocates memory with PAGE_EXECUTE_READWRITE permissions via VirtualAlloc, reflectively loads the stage 3 executable into this memory region, and then executes it starting at its entry point.
The stage 3 executable is a variant of Ghost RAT. Its embedded configuration is encrypted with a custom algorithm resembling RC4 but modified significantly. This implementation adds bitwise operations, and its Key Scheduling Algorithm (KSA) is altered so the provided key does not affect encryption or decryption. Python code to decrypt the configuration is available in our GitHub repository.
Ghost RAT communicates with its C2 server at 104.234.15[.]90:19999 using a TCP binary protocol. This variant features a custom packet header that uses "KuGou" instead of the usual "Gh0st" and encrypts its traffic using the same RC4-like algorithm used for the configuration encryption.
Malicious functionality is largely implemented in the exported functions of a
plugin DLL named config.dll.
This DLL is downloaded from the C2 server and stored on disk at C:\Users\Public\Documents\config.dll.
To evade static AV scans, the DLL is XOR-encoded with a one-byte key (0x15) and
decoded only upon being loaded by the malware.
As the exact DLL couldn’t be retrieved from the C2 server, its functionality was derived by analyzing a KuGou variant DLL (MD5: 7b9a808987d135e381f93084796fd7c1) and comparing it with the Ghost RAT’s source code.
A table outlining the C2 commands supported by this variant is shown below.
|
Command ID |
Functionality |
Source code class |
|---|---|---|
|
0x0 |
Sets a flag to indicate a successful connection to the C2. |
CKernelManager |
|
0x1 |
Executes the |
CFileManager |
|
0x2 |
Executes the |
CScreenManager |
|
0x3 |
Executes the |
CVideoManager |
|
0x4 |
Executes the |
CKeyboardManager |
|
0x5 |
Executes the |
CAudioManager |
|
0x6 |
Executes the |
CSystemManager |
|
0x7 |
Executes the |
CShellManager |
|
0x8 |
Retrieves |
N/A |
|
0x9 |
Terminates itself. |
N/A |
|
0xD |
Sets the |
N/A |
|
0xF |
Sets the |
N/A |
|
0x13 |
Executes the |
N/A |
|
0x14 |
Sends the plugin DLL path hardcoded in the
sample |
N/A |
|
0x15 |
Executes |
CSysInfo |
|
0x16 |
Executes the |
CSerManager |
|
0x17 |
Executes the |
CRegistry |
Table 2: List of commands supported by the KuGou variant of Ghost RAT.