Executive summary
Sample: 8dd7d6472771db5b82cfc87adcb03b303fcd8f16462700ce6ff63f3d935348d9
LotusLite is a 32-bit Windows DLL that operates as a persistent remote access trojan. It presents forged Microsoft WPS Office metadata, installs under C:\ProgramData\WKwpsOffice2\, creates an HKCU\Software\Microsoft\Windows\CurrentVersion\Run\AwpOn persistence value, and relaunches its installed payload with the command-line flag --DMLA.
The implant communicates with a hardcoded command-and-control server at 103[.]79[.]77[.]181:443 through WinHTTP. HTTPS carries a custom binary protocol identified by the four-byte magic B2 EB CF DF. Recovered command handlers provide an interactive cmd.exe shell, directory enumeration, file creation and chunked file writes, file-status checks, loop termination, and adjustable polling delays. The initial beacon includes the victim computer name and username.
LotusLite keeps its static import surface small by dynamically resolving nearly every non-KERNEL32 API. API names are XOR-decoded with the repeating five-byte key Credt and then reversed; the C2 address is reconstructed through a separate XOR operation over two embedded byte arrays. Thirty exports create noise around the real control path, which is reached through Bankofchinaunionpaycard and its aliases.
The strongest defensive anchors are the installed path, AwpOn Run value, --DMLA flag, encoded C2 arrays, unusual WinHTTP headers, protocol magic, and shell/file-management behavior. Delivery, unresolved command IDs, and several implementation details remain open questions.
This depth of evidence is what Embusa /analyst is designed to produce from an unknown sample: a verifiable technical narrative, clear confidence boundaries, and detection-ready outputs without requiring the binary to reach the public internet.
Scope and analysis method
The analyzed artifact is a 351,232-byte PE32 DLL with SHA-256 8dd7d6472771db5b82cfc87adcb03b303fcd8f16462700ce6ff63f3d935348d9. The findings below come from PE inspection, decompilation, call-graph review, raw-byte verification, and reconstruction of the malware's decoding routines.
For readability, this article uses LotusLite as the working name for the sample. Conclusions marked as observed are directly supported by code or binary data. Predicted behavior is called out where the available evidence does not prove the final operating state.
Attribution context
LotusLite variants have been publicly linked by external researchers to Mustang Panda, also tracked as Earth Preta and Twill Typhoon. This sample-specific analysis does not independently establish attribution, and its technical findings should be evaluated separately from actor claims.
Format PE32 DLL, Intel i386 Size 351,232 bytes Image base 0x10000000 Entry point 0x1000C7FE Compile time 2026-04-27 06:34:37 UTC Sections .text entropy 6.665; no packing indicated Imports KERNEL32.DLL, USER32.DLL Protections DEP/NX compatible; dynamic base enabled Exports 30, with extensive aliasing and decoy stubs
Masquerading and export-table noise
The version resource claims the company name "Microsoft Office Software Co.,Ltd", product name "Microsoft WPS Office", file description "Microsoft Office", and original filename kwpswndwg.dwgQ. These values conflict with the code and behavior and should be treated as forged metadata.
Most of the DLL's thirty exports are distractions. They display short message boxes and frequently terminate the process. Several names imitate QR APIs, banking-related functions, or generic program entry points. The meaningful path is the export Bankofchinaunionpaycard, ordinal 7, which shares its address with FreeMain_Exit and MddBootstrapInitialize2. Each alias jumps directly to FUN_10005690, the main orchestration routine.
DLL entry @ 0x1000C7FE
-> CRT DLL initialization
-> global constructors
-> FUN_10002620 decodes the C2 address
Bankofchinaunionpaycard / FreeMain_Exit / MddBootstrapInitialize2
-> JMP FUN_10005690
-> check current execution path
-> install and persist, or
-> enter C2 mode when --DMLA is presentInstallation and persistence
The main routine compares the current execution location with the hardcoded installation directory. When the DLL is running elsewhere, FUN_10005220 creates C:\ProgramData\WKwpsOffice2\ and copies the payload and a referenced Microsoft.WindowsAppRuntime.Bootstrap.dll into that directory. The code references an installed executable named WKwpsOffice.exe; whether this executable is a renamed copy of the sample or a companion artifact cannot be proven from the DLL alone.
Installation is concealed with a decoy dialog titled "Error: The Pdf file is corrupted." The message asks the user to restart the computer or contact the "original author," creating a plausible failure state while persistence is established.
Persistence is implemented in FUN_100016D0. The function loads shlwapi.dll, resolves SHSetValueA dynamically, and writes a per-user Run value. Because the key is under HKCU and the installation occurs in ProgramData, the observed path does not inherently require administrative privileges.
Key HKCU\Software\Microsoft\Windows\CurrentVersion\Run Value AwpOn Type REG_SZ Data "C:\ProgramData\WKwpsOffice2\WKwpsOffice.exe" --DMLA
Dynamic API resolution and string obfuscation
The static import table exposes only KERNEL32 and USER32. The remaining libraries and API names are recovered at runtime. FUN_10001490 XORs each encoded byte with key[i % 5] using the ASCII key Credt, then reverses the full decoded buffer. Library loading proceeds through LdrLoadDll and function lookup uses PE export parsing, reducing useful evidence in the import table.
key = 43 72 65 64 74 // "Credt"
for i in range(encoded_length):
decoded[i] = encoded[i] ^ key[i % 5]
reverse(decoded)Recovered APIs describe the implant's behavior even before the command dispatcher is examined:
ntdll LdrLoadDll, RtlInitUnicodeString kernel32 CreatePipe, CreateProcessA, TerminateProcess kernel32 WriteFile, CopyFileA, GetFileAttributesA kernel32 GetComputerNameA, FindFirstFileA, FindNextFileA advapi32 GetUserNameA shlwapi SHSetValueA shell32 CommandLineToArgvW winhttp WinHttpOpen, WinHttpConnect, WinHttpOpenRequest winhttp WinHttpAddRequestHeaders, WinHttpSetTimeouts winhttp WinHttpSetOption, WinHttpSendRequest winhttp WinHttpReceiveResponse, WinHttpQueryDataAvailable winhttp WinHttpReadData, WinHttpCloseHandle
C2 address recovery
The C2 server is not stored as a plaintext string. During CRT initialization, FUN_10002620 XORs a 16-byte array, indexed modulo its length, with a 13-byte array. The resulting thirteen characters are appended to a global string one byte at a time.
array_1 51 a5 11 c0 4d 89 22 9d c7 25 68 b9 ef 7f 28 51 array_2 60 95 22 ee 7a b0 0c aa f0 0b 59 81 de array_1[i % 16] XOR array_2[i] -> 31 30 33 2e 37 39 2e 37 37 2e 31 38 31 -> 103[.]79[.]77[.]181
HTTPS transport
The transport routine at FUN_10003C00 uses WinHTTP to send binary messages in HTTPS POST bodies. It opens a session, applies 120-second resolve/connect/send/receive timeouts, connects to the decoded IP on TCP 443, and creates a secure POST request. Before sending, it relaxes certificate validation through WINHTTP_OPTION_SECURITY_FLAGS, allowing the implant to continue despite selected certificate errors.
The request includes a Chrome-like user agent with unusual spacing and a fixed cookie. These are useful hunting features, but neither should be used alone: the cookie value can occur in legitimate Azure AD B2C traffic.
Destination 103[.]79[.]77[.]181:443
Method POST
URI unresolved; likely / when the global path is empty
User-Agent Mozilla / 5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit / 537.36 (KHTML, like Gecko)
Chrome / 147.0.7727.102 Safari / 537.36
Cookie JSESSIONID=x-ms-cpim-geo
Body custom binary protocolBefore the main command loop, the code also issues a connectivity request to https://www.google[.]com/. The surrounding control flow suggests that this is an internet-availability check.
Binary C2 protocol
The dispatcher in FUN_100045E0 expects a compact binary frame. The magic value appears on the wire as B2 EB CF DF, followed by a signed 32-bit command ID, an unsigned 32-bit payload length, and the indicated number of payload bytes.
offset size field 0x00 4 magic B2 EB CF DF 0x04 4 command signed int32 0x08 4 length uint32 0x0C n payload byte[length]
The first beacon includes the local computer name and current username, obtained through GetComputerNameA and GetUserNameA. Responses are read incrementally with WinHttpQueryDataAvailable and WinHttpReadData, then passed to the command dispatcher.
Recovered command set
The implemented handlers give the operator an interactive shell plus basic file-system control. Command 10 creates the shell process and pipes; command 1 subsequently writes operator-supplied data to the shell's standard input. Output is read from the anonymous pipe, buffered, and returned through the C2 channel.
ID Handler Recovered behavior
0x01 FUN_10002E80 Write data to cmd.exe stdin
0x03 FUN_10003440 Enumerate a directory
0x06 local flag Exit or suspend the C2 loop
0x0A FUN_10002A20 Create pipes and start cmd.exe
0x0B FUN_10002D50 Terminate shell and clean up handles
0x0D fopen("wb") Create or truncate a file
0x0E fopen("ab") Append a received file chunk
0x0F FUN_100061A0 Query and report file statusCommands 2, 4, 5, 7, 8, 9, and 12 are not resolved by the available decompilation. Some paths may be unimplemented, may fall through to defaults, or may require additional runtime state. They should not be assigned capabilities without further evidence.
Polling behavior is adaptive. The loop uses a 500 ms default delay, with observed paths that adjust the interval to 2,000 ms or 20 ms according to recent activity. This gives the operator faster interaction during an active session while reducing traffic when the implant is idle.
Capability and ATT&CK mapping
The recovered code supports the following practical defensive mapping. The mapping describes behavior in this sample; it does not imply anything about the operator behind it.
T1059.003 Windows Command Shell
CreateProcessA launches cmd.exe with redirected pipes
T1547.001 Registry Run Keys / Startup Folder
HKCU Run value AwpOn relaunches WKwpsOffice.exe --DMLA
T1071.001 Web Protocols
WinHTTP carries a custom binary protocol over HTTPS
T1036 Masquerading
Forged WPS Office version metadata and fake PDF error
T1027 Obfuscated Files or Information
XOR-and-reverse API strings and XOR-encoded C2 address
T1082 System Information Discovery
Collects the victim computer name
T1033 System Owner/User Discovery
Collects the current usernameIndicators of compromise
SHA-256 8dd7d6472771db5b82cfc87adcb03b303fcd8f16462700ce6ff63f3d935348d9 SHA-1 eb352c7f82a6987aaa5f3cad51e4c458970f5600 MD5 ef5b753e5a2118d18c5e809c3d159a35 C2 103[.]79[.]77[.]181:443 Path C:\ProgramData\WKwpsOffice2\ File C:\ProgramData\WKwpsOffice2\WKwpsOffice.exe File Microsoft.WindowsAppRuntime.Bootstrap.dll Run key HKCU\Software\Microsoft\Windows\CurrentVersion\Run\AwpOn Flag --DMLA Magic B2 EB CF DF Cookie JSESSIONID=x-ms-cpim-geo
Detection engineering
The most durable detection combines implementation-specific bytes with behavior. Hash and IP matches are high confidence but easy to rotate. The installation path, Run value, command-line flag, encoded arrays, export names, and shell ancestry provide stronger coverage across minor rebuilds.
rule LotusLite_Windows_RAT
{
meta:
description = "Detects the analyzed LotusLite Windows RAT"
strings:
$export_1 = "Bankofchinaunionpaycard" ascii
$export_2 = "Mr47kdr74cQpW9PZtBmepgqcStP98uKBwv7E" ascii
$install = "WKwpsOffice2" ascii wide
$flag = "--DMLA" ascii wide
$key = { 43 72 65 64 74 }
$c2_a = { 51 A5 11 C0 4D 89 22 9D C7 25 68 B9 EF 7F 28 51 }
$c2_b = { 60 95 22 EE 7A B0 0C AA F0 0B 59 81 DE }
condition:
uint16(0) == 0x5A4D and
4 of ($export_*, $install, $flag, $key, $c2_*)
}title: LotusLite Run Key Persistence
status: experimental
logsource:
product: windows
category: registry_set
detection:
selection:
TargetObject|endswith: '\Software\Microsoft\Windows\CurrentVersion\Run\AwpOn'
Details|contains|all:
- 'WKwpsOffice.exe'
- '--DMLA'
condition: selection
level: highEndpoint hunting should also look for cmd.exe spawned by WKwpsOffice.exe or by any process executing from the installation directory, especially when followed by outbound TCP 443 traffic to a raw IP. File creation in the same directory and registry modification events provide useful corroboration.
alert tls $HOME_NET any -> 103.79.77.181 443 (msg:"LotusLite C2 destination"; flow:to_server,established; sid:42001601; rev:1;) # With TLS decryption or equivalent endpoint visibility, # inspect POST bodies for: B2 EB CF DF at frame offset 0.
Useful Windows telemetry includes process creation, registry value changes, file creation, and outbound connection records. In Sysmon terms, prioritize Event IDs 1, 13, 11, and 3. Treat the cookie as supporting evidence rather than a verdict because it can appear in legitimate identity traffic.
Open technical questions
The available artifact begins after delivery, so the infection vector is unknown. The forged Office metadata and fake PDF error are consistent with a document or installer lure, but that remains an inference.
The request-path global used by WinHttpOpenRequest was not initialized in the reviewed code. It may remain empty and therefore resolve to /, but the exact URI remains unresolved. The semantics of unresolved command IDs also require additional code coverage.
The role of Microsoft.WindowsAppRuntime.Bootstrap.dll is not settled. It could be a legitimate dependency, a renamed component, or part of a sideloading arrangement. Likewise, the exact relationship between the analyzed DLL and the installed WKwpsOffice.exe cannot be proven without the additional dropped artifacts.
Memory snapshots were consistent with the on-disk image and did not expose additional runtime-only configuration. Open questions include the exact process launch arguments, installed file set, certificate-error behavior, URI path, beacon serialization, and unresolved protocol commands.
Defensive priorities
For immediate response, block the C2 address, search endpoints for the installation directory and Run value, isolate systems that launched WKwpsOffice.exe --DMLA, and review child-process and network activity around those executions. A positive finding should trigger credential and incident-scope review because the implant exposes an interactive shell and file-transfer channel.
For durable coverage, deploy the YARA logic against file stores and endpoint scans, monitor the registry and process chain, and retain network detections as corroboration. The combination of encoded configuration bytes and host behavior is substantially harder to evade than any single hash, filename, or IP address.