// VMRAY LABS · THREAT RESEARCH

What indicators miss: geo-aware malware and two hidden backdoors

Executive summary

A file hash identifies a file, a domain identifies a server, and a location lookup identifies a service the malware contacted. These indicators do not explain the malware’s next decision, the code behind it, or the data hidden inside the file. Two samples can share an indicator but behave very differently. This post examines that missing context and why it matters for detection.

We examine this through two investigations. In both, the VMRay sandbox recorded the samples’ behaviour during execution. We also used manual reverse engineering to recover what the samples keep hidden.

The first investigation examines a lookup that is easy to misread. When malware asks an IP lookup service for its location, the request alone is often treated as sandbox evasion. It should not be. We studied 726 unique samples that made such a lookup. Only 58 then compared the returned country against an exclusion list and quit on a match. The other 668 looked up their location but did not follow those steps. That gives a gate rate of about 8% for this set of location-aware samples, using our own definition of a gate. A location lookup can mean different things in different samples. Only the behaviour around the request tells them apart.

The second investigation shows what a file hash hides. We examined fifteen files tied to the publicly reported UnsolicitedBooker activity and reverse engineered two backdoors from them: MarsSnake and LuciDoor. The sandbox recorded what they did during execution, but running the samples alone does not print the specific values a defender needs. MarsSnake keeps its configuration and keys encoded and only rebuilds them in memory. LuciDoor is packed inside the LuciLoad loader rather than provided as a separate file.

We wrote small unpackers and decoders to extract those values. Both LuciLoad samples yielded the same hidden LuciDoor DLL. From MarsSnake, we recovered its command-and-control addresses and ports, the key used to scramble its traffic, and the strings hidden from a plain file scan. Defenders need these exact values for precise rules. None appear in the file hash alone.

The regional context comes from public reporting. ESET documented MarsSnake against an international organisation in Saudi Arabia in January 2025 [1]. Positive Technologies later reported MarsSnake and LuciDoor against telecommunications organisations in Central Asia [2]. The location study uses a separate, much larger sample set, unconnected to these campaigns. We deliberately ran it alongside the backdoor work. Both investigations approach the same point from different directions: an indicator alone tells you little until you see what the sample does.

Both investigations lead to the same conclusion. An indicator tells you what to look for. The behaviour recorded by the sandbox, together with the code and data recovered through reverse engineering, explains what it means and what to do about it. Combining this evidence turns an indicator into a detection.

Key judgments

  • A geolocation request alone is not enough evidence of evasion. In our dataset, 58 of 726 unique samples met the country-gating criteria and the remaining 668 did not. This does not prove that they collected only location information or that they used no other checks.
  • Country gating and analysis evasion are separate conclusions. A comparison followed by an exit stops the malware in certain countries. More evidence is needed to show that this was intended to avoid analysis. LuciLoad’s elapsed-time check is a clearer anti-analysis example because it tests whether a requested sleep was shortened.
  • Automated sandbox analysis and reverse engineering together produced practical detection evidence. The VMRay sandbox recorded each sample’s behaviour and network activity. Our unpackers and decoders then recovered hidden data, including the LuciDoor DLL inside two loaders and MarsSnake’s configuration and strings. Exact resource layouts, decoding constants and strings give defenders extra ways to identify related files.
  • MarsSnake and LuciDoor are distinct backdoors linked through reported activity and reused infrastructure [2]. Their different implementations do not establish separate developers, a shared developer or the size of the team behind them.
  • The regional and attribution context comes from the vendors, not from us. ESET reported MarsSnake against an organisation in Saudi Arabia and describes UnsolicitedBooker as China-aligned [1]. The public sources do not report LuciDoor in Saudi Arabia. Our own technical analysis does not identify the operator or its sponsor.

1. Introduction and method

A location-service request can appear in a threat feed without an explanation of the decision that follows it. A loader hash can identify a malicious file without revealing the backdoor inside it. Encoded configuration can contain useful addresses even when a strings scan shows none. Each indicator is real, but it lacks context. We recovered that context through VMRay sandbox runs, manual code analysis and extraction tools we built.

The research produced several useful results. We measured country gating across 726 unique location-aware samples, recovered the same LuciDoor payload from two loaders, and extracted MarsSnake’s C2 addresses and ports. We also reconstructed the key material MarsSnake uses to scramble its traffic and checked exact detection strings against public descriptions. For example, LuciLoad’s hidden window title is OneDriveLaucher in our samples, while public reporting gives it as OneDriveLauncher [2]. This difference matters when a rule relies on an exact match.

We combined two methods. VMRay’s sandbox uses hypervisor-based, agentless monitoring to observe behaviour from outside the virtual machine. We examined its function call and network logs, then manually reverse engineered the samples outside the sandbox. Reading the disassembled and decompiled code helped us explain the behaviour recorded by the sandbox. We also used the code to build our unpackers and decoders. An execution shows the path reached in that environment. Code analysis can reveal other paths and recover data without running every capability.

The geolocation study and the backdoor investigation use different datasets and answer different questions. We did not set out to link them, and nothing connects the geolocation samples to the reported MarsSnake or LuciDoor activity.

2. The measurement: profiling versus gating

We started with one question: “What does malware do with the response to a geolocation lookup?” The malware may then collect data, compare the response against a list of countries, or do nothing further. The lookup alone is not evasion. The action that follows, such as quitting after a country match, can point to evasion. Even then, evasion is not the only possible reason.

We started with 912 VMRay analyses and their recorded function calls and network activity. Of these, 908 contacted a geolocation or IP lookup service. The other four never reached one and were set aside. Removing duplicates left 726 unique samples.

We use two labels of our own for these samples. We call a sample a country gater only when its run showed all three steps:

  1. A geolocation lookup returned country information.
  2. The sample compared the result with at least three country codes.
  3. A matching code led to an exit.

The comparisons used two-letter country codes such as DE, GB and US. We call every other location-aware sample a profiler: it contacted a lookup service but did not take all three steps. The label does not mean that a sample only sent its location to a C2 server or that it had no other checks. Figure 1 explains the distinction.

The location check (identical) GET /json/ → countryCode BOTH DO THIS Profiler ABOUT 92% Records the country and keeps running. Location may go to the C2 with other host detail. The sample carries on. Gater ABOUT 8% Compares the country to a fixed list. On a match, the sample calls ExitProcess. Only this branch is true sandbox evasion.
FIG 1A location lookup, a country gate, and the reason behind the gate each need different evidence. A gate can serve evasion or simple geographic targeting.

The public IP address seen by the service determines the returned location. Routing through a VPN or proxy can therefore change the answer. The gate compares the country code associated with that public IP address, not the machine’s physical location.

Of the 726 unique samples, 58 met the gating criteria and 668 did not. That is a gate rate of about 8%.

A conventional 95% Wilson interval for 58 of 726 is 6.23% to 10.19%. This binomial calculation does not correct for how the dataset was selected or which families it contains. The samples were not drawn at random from all malware, and related builds may not count as independent observations. The interval therefore does not establish a rate for malware as a whole. Figure 2 presents the counts and the dataset they describe.

912 analyses in the dataset 908 looked up their geolocation 726 unique, deduped by hash OF THOSE 726 668 profile only 58 gate + quit Profiling versus gating Only about one in twelve samples exits on the location answer. The rest keep running. GATE RATE 58 / 726 = 7.99% 8% gate 92% profile 95% Wilson interval 6.23% to 10.19%. Binomial only: not corrected for selection or family clustering, so it is not a base rate for malware as a whole. ALL 58 GATERS: ONE FAMILY (TWIZT / PHORPIEX) Byte-identical ten-country Western exclusion list.
FIG 2Dataset selection and the observed country-gating rate.

Figure 3 follows one sample from its request to its exit, using its VMRay function log. The trace shows a request to ip-api.com and a response containing country code DE. The sample compares that code with its exclusion list and calls ExitProcess after a match. The request alone would not explain why execution stopped.

ONE GATER, FROM THE BEHAVIOURAL FUNCTION LOG GEO-GATE · BEHAVIOURAL LOG [0243.303] getaddrinfo(“ip-api.com”, “80”) ; DNS for the geo service [0244.131] connect(208.95.112.1 : 80) ; TCP to ip-api.com [0244.158] send(“GET /json/ HTTP/1.1 …”) [0244.161] recv → 200 OK … countryCode: DE [0244.378] strcmp(“DE”,”US”)→-1 strcmp(“DE”,”SE”)→-1 strcmp(“DE”,”CA”)→-1 [0244.379] strcmp(“DE”,”DE”)→ 0 ; match on the exclusion list [0247.501] ExitProcess(0) ; sample quits, records nothing more A static feed shows only the request. The returned country, the comparison and the exit appear only here.
FIG 3A single sample from request to exit, drawn from its VMRay behavioural function log: request, DE response, matching comparison and exit. Simplified for clarity, not a verbatim export.

All 58 gaters were classified by VMRay as Twizt/Phorpiex. Our analysis recorded the same ten-country exclusion list in each sample. Table 1 lists its members alphabetically.

Table 1. Countries in the exclusion list used by Phorpiex.

CodeCountry
CACanada
CHSwitzerland
DEGermany
GBUnited Kingdom
LILiechtenstein
LULuxembourg
NLNetherlands
NZNew Zealand
SESweden
USUnited States

The repeated list helps group these samples. It does not identify an operator or explain why those countries were selected. Avoiding analysis is one possible reason for a country restriction, but the observed comparisons do not settle that question.

Our criteria also limit the measurement. They require at least three country comparisons and an exit after a match. A one-country gate, a delayed decision or behaviour on a path not reached during analysis may fall outside the classification. The 668 remaining samples cannot be treated as a verified group of malware that only profiles victims.

Vendors and analysts should preserve this distinction. Report a lookup when one is observed. Report a country gate when the response controls an exit. Assign an evasion purpose only when further evidence supports it.

3. The UnsolicitedBooker toolset: MarsSnake and LuciDoor

We examined fifteen files associated with the publicly reported activity: three macro documents, one RAR archive, two MarsSnakeLoader builds, two LuciLoad builds and seven MarsSnake builds. We also examined the LuciDoor DLL recovered from both LuciLoad samples. The file indicators appear in Table 4.

ESET reported attacks against the same international organisation in Saudi Arabia in March 2023, March 2024 and January 2025. Its MarsSnake account covers the January 2025 campaign, which used a Saudia flight-ticket lure. The earlier attacks involved other backdoors [1]. Positive Technologies reported LuciDoor in Kyrgyzstan in September 2025, MarsSnake there in November, and LuciDoor in Tajikistan in January 2026 [2]. These were separate deployments covered by its investigation.

Figure 4 maps the reported delivery routes to the loader and backdoor each one delivers.

CENTRAL ASIAN ROUTE Macro document WMI check, hex payload rebuild MarsSnakeLoader RC4 + zlib → shellcode LOADER MarsSnake x64 backdoor BACKDOOR CHINA ROUTE RAR archive .lnk → FTP script → VBS help.vbs → plasrv.exe renames and runs directly DROP MarsSnake direct, no loader BACKDOOR LINKED IN THE SAME INVESTIGATION The document route also delivered LuciLoad in Sept 2025 and Jan 2026, which unpacks LuciDoor (x86, TLS).
FIG 4Reported document delivery and the archive route, including the loader for each backdoor.

ESET describes UnsolicitedBooker as China-aligned. Positive Technologies describes activity resembling that group and discusses uncertainty about the wider attribution [1,2]. We use the campaign name to identify that reporting context. It is not an independent attribution based on our sample analysis.

Our files contain PE timestamps of 1 August, 6 November and 10 November 2025. These are build metadata, not verified attack dates. Figure 5 keeps the reported campaign dates separate from that metadata.

REPORTED CAMPAIGN DATES Saudi intrusion ESET, earliest point Jan 2025 MarsSnake, Saudi lure Sept 25 – Jan 26 Central Asia telecoms OUR SAMPLE PE TIMESTAMPS — BUILD METADATA, NOT ATTACK DATES 1 Aug 2025 6 & 10 Nov 2025
FIG 5Reported campaign dates, with sample timestamps shown separately.

3.1 Delivery

The document route uses an embedded macro. Where macro execution is permitted, it checks the registry through Windows Management Instrumentation. It then rebuilds a payload from hex text containing xx padding and writes the result with ADODB.Stream.SaveToFile. It waits three seconds before launching the file. The delay alone does not establish an anti-analysis check.

The documents led to different loading chains. Positive Technologies reported LuciLoad in the September 2025 and January 2026 deployments. In November, the document dropped a legitimate, signed Microsoft Plasrv.exe next to a malicious PDH.DLL in a Microsoft\PlayReady folder. When Plasrv.exe ran, Windows loaded the attacker’s PDH.DLL from that folder instead of the genuine system library. This is DLL side-loading. It abuses the search order rather than a flaw in the program. The loaded DLL carried MarsSnakeLoader [2].

The archive route starts with a Chinese-language shortcut about water charges in Chongqing. In the archive we examined, additional files were hidden beneath .__init__ and nested .__MACOS__ directories. The shortcut invokes version.txt. Its ! shell escapes and final bye identify it as an FTP command script rather than an ordinary text document; public reporting describes the same file as a BAT script. The script moves help.log to c:\programdata\help.vbs and runs it. The VBS script then moves and renames plasrv.log to c:\programdata\Oracle\Java\installcache\plasrv.exe and launches it.

We matched plasrv.log to the MarsSnake hash beginning a3f22335, listed in full in Table 4. This route launches the backdoor directly, without a separate MarsSnakeLoader stage. Positive Technologies also describes direct delivery in this archive route [2].

Document metadata provides more clues for grouping files. Positive Technologies reported eastAsia="zh-CN" in Russian-language documents and Generated by Snipaste in embedded-image metadata [2]. Our review also recorded zh-TW in one document. These values may reflect authoring settings or reused templates. They do not prove the author’s location. The archive paths and script contents are stronger clues when combined with the resulting file and process activity.

3.2 The loaders

MarsSnakeLoader and LuciLoad both carry an encoded payload, but use different extraction routines. Recovering the payloads allowed us to inspect the backdoors directly and connect them to the loader files.

MarsSnakeLoader appears as a PDH.DLL proxy and as an executable. It decrypts an embedded block with RC4 and decompresses the result with zlib. In our files, the key is assembled from qio1239djk123sd. and a;13,, producing qio1239djk123sd.a;13,. The parts contain 16 and 5 ASCII bytes, respectively. The decrypted data starts with the zlib header 78 9C and expands into shellcode carrying the 64-bit MarsSnake payload.

The loader maps the payload into memory and prepares its configuration at the OOkupFunction*71N marker before transferring control. This affects extraction because the embedded backdoor’s initial configuration may differ from the one the loader writes. Our unpacker recovered the payload from both loader builds. We examined the configuration values supplied by the loaders as well as those stored in the backdoors. Figure 6 traces the decryption, decompression and configuration write.

ONE PROTECTED BLOCK, REBUILT AT RUN TIME CARRIERLoader PDH.DLL or EXE DECRYPTRC4 qio1239djk123sd.a;13, DECOMPRESSzlib starts 78 9C MAPMarsSnake PE into memory CONFIGwrite at marker CONFIG WRITTEN AT MARKER OOkupFunction*71N The C2 written at run time means the backdoor on disk may hold no address. Both loader and backdoor need inspection: our unpacker replays every step and recovered the payload from both builds.
FIG 6MarsSnakeLoader decryption, decompression and configuration setup.

Configuration can still be recovered from files on disk. Writing it at runtime does not mean the loader contains no C2 data or that every MarsSnake file lacks an encoded configuration. The direct-delivery build is another example of why both the loader and backdoor need inspection.

The PDH.DLL build forwards the genuine Windows library’s exported function names to C:\Windows\System32\pdh.dll. This lets the legitimate program keep using those functions while the malicious loader executes. A check for missing export names would not expose the proxy. Figure 7 distinguishes this side-loading route from the malicious plasrv.exe launched directly by help.vbs.

CENTRAL ASIAN ROUTE · DLL SIDE-LOADING Plasrv.exe signed Microsoft, in PlayReady LEGIT PDH.DLL (malicious) loaded from folder, runs loader PROXY real pdh.dll exports forwarded, Plasrv keeps working CHINA ROUTE · NO SIDE-LOADING help.vbs from the archive, no proxy DLL SCRIPT plasrv.exe (direct) the MarsSnake backdoor itself DROP Same backdoor, two launches side-load hides it; direct skips the proxy
FIG 7A legitimate executable loading a malicious proxy DLL, compared with direct backdoor execution.

Our files contain two useful PDB paths: D:\project\MarsSnake\bin_shellcode\load_http_64.pdb and D:\project\MarsSnake\x64\http\MarsSnake.pdb. These help connect the loader and backdoor builds. ESET’s earlier samples used a different project-root spelling, D:\yu_project\MarsSnake\... [1].

LuciLoad is a 32-bit loader. It records the time with GetTickCount64, calls Sleep(15000), and checks how much time has passed. In our analysis, it exits if less than about 11.25 seconds has passed. This specifically tests whether the requested delay was shortened, which supports an anti-analysis interpretation. The effect depends on how the analysis environment handles sleep and time measurements.

LuciLoad then creates a hidden window through CreateWindowExW. Our samples use the title OneDriveLaucher, with that exact misspelling. Public reporting gives it as OneDriveLauncher [2]. We use the spelling from our own samples for detection, without assuming every variant matches it.

Our unpacker follows four steps:

  1. Read bitmap resource type 2 (RT_BITMAP), ID 129. The payload size is at offset 40 and the encrypted payload starts at offset 44.
  2. Decrypt the payload with RC4 and the key microsoft.
  3. Read the first four decrypted bytes as the uncompressed output size.
  4. Decompress the remaining bytes with LZNT1, reproducing the loader’s RtlDecompressBuffer call with argument 0x102.

The loader resolves the decompression function at runtime. Both samples produced the same 40,960-byte x86 DLL, with a valid PE structure. Its SHA-256 is c6f682eea8405a9bbb1454ac68a056a086b117fea611e7f8492f1f7c6b5c2cc7. We checked the extracted structure and output hash rather than relying on an MZ prefix alone. Figure 8 shows the elapsed-time check, the resource decrypt and the recovery of LuciDoor.

Timing trap GetTickCount64, Sleep(15000): exit if under ~11.25s Disguise hidden window titled OneDriveLaucher (misspelled) CARRIERRT_BITMAP 129 size @40, data @44 DECRYPTRC4 key “microsoft” SIZE PREFIX4-byte LE output length DECOMPLZNT1 0x102 PAYLOADLuciDoor 40,960 B BOTH LUCILOAD BUILDS PRODUCE THE IDENTICAL DLL SHA-256 c6f682ee…5c2cc7 · verified by extracted structure, not the MZ prefix alone
FIG 8LuciLoad checks elapsed time, decrypts its bitmap resource and recovers LuciDoor.

3.3 MarsSnake, the backdoor that hides its strings

We analysed seven 64-bit MarsSnake builds, each approximately 65 to 96 KB. Their C2 settings and protocol strings are encoded in the file. Six builds also reconstruct their traffic key material from constants during execution. One stores the full value as readable text, which allowed us to check the reconstruction.

The recovered value, rYB1oDHVMViTRnaGsFw1TbHJ1z1aZ, is a 29-character ASCII string. MarsSnake uses it to XOR the traffic sent to its C2 server and as the basis for its AES key.

MarsSnake rebuilds the 29-character value in memory from fixed numbers compiled into the code. One is the constant 0x4D2BE561B84C932E. In the six obfuscated builds, it is stored as two four-byte halves. A rule that expects all eight bytes together could miss those files. The value rebuilt in memory therefore differs from the pattern visible to a file scanner. Figure 9 shows the stored constants and a worked string-decoding example.

ON DISK Key material for the body XOR and AES is not stored as text. A thread-safe initialiser builds it in memory from constants. CONSTANT 0x4D2BE561B84C932E stored as 0x4D2BE561 · 0xB84C932E A rule expecting all eight bytes together could miss these files. EXECUTE IN MEMORY The key materialises. Strings decode on first use with a rolling 8-byte key: plain[i] = enc[i] XOR ((key64 >> (8*i)) & 0xFF) Recovered value (29 chars): rYB1oDHVMViTRnaGsFw1TbHJ1z1aZ Unused arithmetic loops run before the real calls.
FIG 9MarsSnake’s stored constants and an example of string decoding.

Other strings use a repeating eight-byte XOR key. The decoder selects bytes from the key in little-endian order:

String decode · little-endian key select
plain[i] = enc[i] XOR ((key64 >> (8 * (i & 7))) & 0xFF)

Two keys recur across all seven builds. 0x2113E7E35DF5010D decodes the completion marker &@&DWJ@*&!@(@#&*(@$&^. 0x7DBD49499DF19131 decodes iphlpapi.dll. MarsSnake loads the library and resolves functions at runtime. Those dynamically resolved functions are therefore absent from its normal import table. The decoder exposes useful strings even when a recorded run has not reached the routines that use them.

The C2 configuration follows the 17-byte marker OOkupFunction*71N. The marker also supplies the repeating XOR key:

Config decode · marker as repeating key
cfg[i] ^= marker[i % 17]

After decoding, the configuration fields contain plain-text IPv4 addresses and ports. Across the examined files, we recovered 81.70.28[.]71:8000, 93.157.106[.]75:80 and 5.181.1[.]153:80. Positive Technologies had already reported these addresses [2]. Our decode adds the associated ports and the exact configuration marker. Figure 10 works through the decode and lists the three recovered address and port pairs.

The C2 address sits in a config block XOR-keyed with the 17-byte marker. C2 ADDRESS FIELD (ONE BYTE PER COLUMN) on disk 77 7E 45 42 40 68 47 56 4D 43 58 marker 4F 4F 6B 75 70 46 75 6E 63 74 69 RECOVERED ENDPOINTS 81.70.28[.]71 : 8000 93.157.106[.]75 : 80 5.181.1[.]153 : 80 WHAT THE DECODE ADDS Positive Technologies reported the addresses. Our extractor recovers all three, plus the ports and the exact marker OOkupFunction*71N.
FIG 10A worked configuration decode and the three recovered address and port pairs.

The marker, RC4 key and completion string we recovered also differ from the versions in public reports. We use the values from our own samples for literal matching. Such differences should be checked against the sample bytes before they are treated as errors.

After the handshake, MarsSnake uses a message-type byte at offset 4 to select the command handler. Our code analysis identified the eight commands described by Positive Technologies: single-command execution, a reverse shell, file transfer in both directions, drive enumeration, directory listing, heartbeat and connection termination [2]. The code uses threaded handlers. Message types 5, 6, 7, 9 and 10 reach a completion-marker check that determines whether the loop continues. Figure 11 lists the command identifiers and their functions.

After the handshake, a message-type byte at offset 4 selects one handler, each in its own thread. 1one cmd.exe command 2reverse shell (piped) 3receive a file 4upload a file 8list drives and type 12directory listing 13heartbeat 11terminate thread Message types 5, 6, 7, 9 and 10 reach a completion-marker check: continue the loop, or end it.
FIG 11MarsSnake command identifiers and their functions.

The reverse shell connects a hidden cmd.exe to pipes using CreatePipe, PeekNamedPipe and CreateProcessW. It clears the console quick-edit flag, which can otherwise pause console interaction when text is selected. MarsSnake also derives a host identifier from the computer name, local IP and username, consistent with the method described publicly [2].

MarsSnake’s AES implementation is compiled into the program. The examined imports do not include CryptoAPI or BCrypt, and the communication routine uses WS2_32 sockets. It XORs the message body with the 29-character value, then encrypts the result with AES-128-ECB. The HTTP request is POST /eg.js?t=<unix>. HTTP headers remain outside TLS, while the application body is encrypted.

The client sends the handshake value dsalsjd89w21dcx9cwad@ and checks the response for asdas290e/cz/x213/.14. It decodes these strings for use during execution. Figure 12 shows this exchange separately from the message-protection steps.

HANDSHAKE Clientinitiates the connection HELLO client sends dsalsjd89w21dcx9cwad@ must return asdas290e/cz/x213/.14 Serveraccepts only the right reply MESSAGE PROTECTION PLAINTEXTmessage body commands, files, replies STEP 1 · XOR WHOLE BODY29-char key rYB1oDHVMViTRnaGsFw1TbHJ1z1aZ STEP 2 · AES-128-ECBcompiled in, no CryptoAPI no BCrypt · no IV (ECB mode) POST /eg.js?t=<unix> · WS2_32 sockets · HTTP headers outside TLS, application body encrypted
FIG 12MarsSnake handshake and message protection: body XOR, AES-128-ECB and HTTP transport.

3.4 LuciDoor, a separate backdoor that uses TLS

Recovering LuciDoor exposes strings hidden inside LuciLoad’s encrypted resource. The DLL contains readable request paths, proxy strings and OneDrive-related names. These can be used in file scans after unpacking, although they are not directly readable in the encrypted payload.

When its configuration enables persistence, LuciDoor creates a scheduled task that launches LuciLoad at logon. Positive Technologies reported the name OneDrive Launcher and author Microsoft [2]. Our analysis recorded the task under \Microsoft\, with a ten-second delay (PT10S). The executable is disguised as OneDriveLauncher.exe. Its destination depends on privileges, with %ProgramData%\Microsoft OneDrive\setup\ used in the administrator path. The task’s target and related process activity help distinguish it from legitimate software.

The C2 worker disables WoW64 file-system redirection and uses Schannel through the Windows Security Support Provider Interface. It loads Secur32.dll and obtains the interface through InitSecurityInterfaceA. It uses QueryContextAttributes to prepare TLS buffers. The backdoor’s networking code uses the TLS implementation provided by Windows.

LuciDoor first tries a direct connection. If that fails, it reads the configured Windows proxy and tries HTTP CONNECT, SOCKS5 and SOCKS4. If these attempts fail or no proxy is configured, it examines the host’s active TCP connections for possible proxy endpoints. It then repeats the proxy methods [2]. GetTcpTable retrieves the host’s IPv4 TCP table, not just LuciDoor’s own connections [3]. Figure 13 shows the connection selection and proxy fallback order.

TLS LuciDoor C2 thread disables WoW64 redirect loads Secur32.dll, InitSecurityInterfaceA own Schannel TLS, not WinINet 1Directconnect to :443 2System proxyregistry 3Active TCP hostsCONNECT 4SOCKS 5 / 4Basic auth Tried in turn until one reaches the C2. GetTcpTable reads the whole IPv4 table, not just its own. HTTPS request POST /sys/index.jsp UA: Firefox rv:72.0 chained XOR, one-byte checksum from the encoded header seeds body C2 button.gdakdbysw[.]xyz : 443 · persistence \Microsoft\OneDrive Launcher, author Microsoft, PT10S
FIG 13LuciDoor’s connection selection and proxy fallback order.

The readable string Proxy-Authorization: Basic %s belongs to HTTP proxy authentication, not SOCKS. Proxy negotiation and the TLS-protected application exchange are separate stages. Once established, Schannel protects the application traffic. This does not mean that every earlier proxy-negotiation message is inside TLS.

The recovered configuration includes button.gdakdbysw[.]xyz:443. Positive Technologies reported using a PolarSSL-related TLS fingerprint to identify a compromised MikroTik router serving as C2 infrastructure [2]. This is historical reporting about the server. It does not mean that LuciDoor implements PolarSSL. The certificate description alone is also not a unique indicator.

LuciDoor sends requests to /sys/index.jsp with the User-Agent recorded in Table 6. Inside the TLS session, messages contain RandomSeed, MsgType, MsgMarker and Payload. The protocol uses chained XOR. It also derives a one-byte value from the encoded header to initialise payload encoding. This obfuscates the application data separately from TLS protection [2]. Figure 14 lists the commands and message-stage values.

Inside the TLS session every message is {RandomSeed, MsgType, MsgMarker, Payload}. MsgType selects the action. SHELL SESSION 12start a cmd.exe shell 13send input to the shell 14end the shell session FILE TRANSFER 15start file exfiltration 16request the next part 17/18receive / write a block CONSOLE 61Lucida Console, UTF-8 MsgMarker signals the stage: 0 done · 1 more blocks · 2 error Command 61 (Lucida Console) is the setting Positive Technologies says inspired the name LuciDoor.
FIG 14LuciDoor commands and message-stage values.

The command set covers a shell session, staged file transfers and console setup. Command 61 selects Lucida Console and UTF-8 output. Positive Technologies states that this font setting inspired the name LuciDoor [2]. The backdoor also collects the username, computer name, system architecture, language and process integrity information. We identified these capabilities through code analysis.

3.5 How the two backdoors are linked and detected

The backdoors share reported infrastructure but differ in implementation. Positive Technologies connected a LuciDoor deployment to an IP previously used by MarsSnake [2]. Table 2 summarises the technical differences in the builds we examined.

Table 2. MarsSnake and LuciDoor in the analysed samples.

PropertyMarsSnakeLuciDoor
Architecture64-bit32-bit
TransportHTTP through sockets; encrypted application bodyTLS through Windows Schannel and SSPI
Request/eg.js?t=<unix>/sys/index.jsp
StringsImportant values encoded or reconstructedMany useful strings readable in the recovered DLL
Message protectionXOR followed by AES-128-ECBChained XOR inside TLS
ConfigurationXOR-protected fields; loader may replace themRC4-protected configuration passed by LuciLoad
Proxy handlingNo proxy routine identified in the examined codeDirect, configured proxy, then candidate proxies from TCP connections
Launch and persistenceSide-loading or direct execution; persistence is not established by the launch method aloneIn-memory payload loading; optional task launches LuciLoad at logon

Table 3 summarises the tools we built and what each one recovered or verified.

Table 3. Tools developed during the research and recorded checks.

ToolResult and check
MarsSnake configuration extractorExamined seven backdoors and both loaders; recovered the three address and port pairs in Table 5.
MarsSnakeLoader unpackerRC4 decryption and zlib decompression succeeded on both loader builds.
MarsSnake string decoderReproduced the completion marker using the recurring eight-byte XOR key.
LuciLoad unpackerBoth loaders produced the same 40,960-byte DLL with the SHA-256 in Table 4.

Figure 15 compares the two backdoors side by side.

Two technically different backdoors linked to the same reported activity. They differ on almost every detail. MARSSNAKE LUCIDOOR ARCHITECTUREx64x86TRANSPORTraw WinSock, plaintext HTTPown Schannel / SSPI TLSREQUESTPOST /eg.jsPOST /sys/index.jspSTRINGSobfuscated, runtime-decodedcleartext in unpacked DLLCRYPTOGRAPHYcustom AES-128 + body XORchained XOR + checksumCONFIGURATIONmarker XOR blockRC4 block in the loaderPROXY SUPPORTnonedirect / system / active connectionsPERSISTENCEnot established by launchscheduled task, OneDrive Launcher
FIG 15Comparison of the two recovered backdoors.

The features that survive obfuscation make the best rules. These include MarsSnake’s configuration marker and recurring decoding keys, LuciLoad’s resource layout and exact window title, and LuciDoor’s readable request and task strings. Common strings such as microsoft or Lucida Console need additional conditions. A rule must also match the bytes as stored in the file, including split constants and encoded bytes. Section 6.4 gives the resulting rules.

We tested those rules against the analysed files and a clean corpus. Every sample matched the correct family rule, with no cross-family collisions. There were no matches across C:\Windows\System32, C:\Windows\SysWOW64 and C:\Program Files. This result is limited to that clean-software corpus. It is not a measured false-positive rate for every environment, so the rules still need tuning against local telemetry before deployment.

Behavioural detections should connect task creation, file paths and module loading. Event ID 4698 can record scheduled-task creation when the required auditing is enabled [4]. A task created through COM does not require a schtasks.exe process. For the archive route, inspect ftp.exe -s alongside the script file. Process command lines alone do not reveal the ! commands inside that file.

3.6 Diamond Model summary

Figure 16 summarises the reported actor, capabilities, infrastructure and victims. It combines several events and should be read as a campaign overview. ESET’s attribution and the vendors’ victim reporting remain explicitly sourced. The unrelated geolocation dataset is excluded from this model.

Diamond Model UnsolicitedBooker ADVERSARY UnsolicitedBooker, China-aligned per ESET, not confirmed here; our analysis is technical only CAPABILITY MarsSnake, LuciDoor, two loaders, macros INFRASTRUCTURE 81.70.28[.]71, 5.181.1[.]153 button.gdakdbysw[.]xyz VICTIM Telecoms, Central Asia (Positive Technologies); earlier international org in Saudi Arabia (ESET) A campaign overview combining several reported events. Attribution and victim context remain vendor-sourced.
FIG 16Diamond Model overview of the publicly reported backdoor activity.

4. What this shows

Each part of the work added information that an indicator does not carry on its own. Following the country responses showed why some samples exit. Starting from a MarsSnake file hash, we recovered its hidden configuration and protocol values. These are the addresses, ports and keys a defender would otherwise have to capture live or miss. Unpacking two LuciLoad files produced the same LuciDoor DLL, which the loader’s own hash does not reveal. Figure 17 pairs each starting indicator with the evidence the analysis added.

WHAT FEEDS SEE a macro document a Microsoft-looking loader a backdoor in an image resource a browser User-Agent Each is real. Several carry no reputation at all. THE OBSERVATION GAP deeper analysis crosses it WHAT WE RECOVERED the ten-country exit list MarsSnake runtime-only protocol LuciDoor’s TLS stack, unpacked C2 config behind the marker Each is malicious. All were largely unseen before. The UnsolicitedBooker toolset and the geolocation dataset are independent, run alongside to make the same point.
FIG 17The starting indicator for each investigation and the extra evidence we added to it.

Both methods mattered. A sandbox run showed that an exit occurred under a particular condition. A decoder recovered strings without running the whole backdoor. Keeping the trace, decoding method and extracted output with the indicator makes the finding easy to check and reuse.

5. Conclusion and defender guidance

The investigation recovered what the starting indicators left out. We explained why a sample exited after a location check and recovered MarsSnake’s hidden configuration and traffic values, along with the DLL that LuciLoad unpacks. The geolocation measurement also provides a separate lesson: a confirmed country gate is not the same as proof of evasion.

For Middle Eastern defenders, the Saudi MarsSnake campaign provides direct regional context [1]. The public sources place LuciDoor in Central Asia rather than the Middle East. Our technical findings do not establish regional targeting either way.

Investigations should preserve five kinds of evidence:

  • The location request, returned country, comparison and resulting action.
  • The relationship between the initial file, loader and extracted payload.
  • Configuration fields and exact strings in their stored and decoded forms.
  • Task creation, module loading and file activity tied to the responsible process.
  • Network destinations interpreted alongside host evidence and protocol visibility.

MarsSnake’s HTTP metadata may expose the request path even though the body is encrypted. LuciDoor’s request path is inside TLS, so visibility depends on where it is inspected. A timeout or early exit also needs context. Record the last execution path reached and any unfinished delay or extraction stage before deciding whether to extend the run or continue manual analysis.

6. Indicators of compromise

The tables identify values recovered from samples and context from public reporting. Addresses are defanged. Complete hashes support exact matching. Strings, paths and partial hashes are investigation clues that need supporting evidence. The legitimate service ip-api.com appears in the separate geolocation study; it is not malicious infrastructure or evidence linking the datasets.

6.1 Files (SHA-256)

Table 4. The fifteen analysed files and the recovered LuciDoor DLL (SHA-256).

RoleSHA-256
MarsSnake3aa78ea358b2a6f92c76ff040eb28ae4dfb82c96809c373b415353328a0b3679
MarsSnake (archive route, plasrv.log drop)a3f223350e03fb7ae6ac4ddf170a94d40da0a525375b764d361a033af5ea15e8
MarsSnake1039ef72c27b0a92263cd9837ba3d47abe876dabdea64ac07cfdcb663be8e312
MarsSnake47d8aa9b806fab9bb4545bff8e5096989243984ac9f45e591fb7fa752fa79644
MarsSnakeccbba80a602caf38e34fddfffbf8ea6bfeb31813fecda107a4abd76cb2ffcdac
MarsSnakebe7e19eabcf67de1306dbdcafc6ca93697187027be54f9d5b1e682b187831aa9
MarsSnake (stores the full 29-character value as readable text)6a8e969a26885f859e594870ca56014f87b37bcffee70441dc6799e9894999fd
MarsSnakeLoader (PDH.DLL proxy, side-loaded by a legitimate Plasrv.exe)01f28cefdcf3940c19efd7a0446aa0e56c56bc7c955774c94d6d469fca627a4e
MarsSnakeLoader (EXE)87619f23611dda86bb58c845c7824f34c76e9d270f624e5bb2c1fd8ab96d750f
LuciLoad54c993140dd490bb44f4cfb31612dc2c13bbf8bfaac8a0ca2ffaa2e20d553074
LuciLoad469e1e62b324575950f3237d37f81567bc55476e48a2a1bd0d31d8b22ff09e9b
LuciDoor (unpacked, 40,960-byte x86 DLL)c6f682eea8405a9bbb1454ac68a056a086b117fea611e7f8492f1f7c6b5c2cc7
Documente6a28b3833384018bad60043c82bb4cfcce86a3418ece86ea0d71c7aac9ca22b
Documentb3f91970f6b25f0f24da2b4ca488e8a484847b0eb0e13ffde982f1740de5f19c
Documentf4243a95a7c81130eb257a1f1f63fb744dd6d613b57e69ccd166ce7dfaddbb56
Chinese-language archive (RAR, carries the .lnk)3c9e76eee8c813e2de16640504118550b18b21e4f951df47ef8914bb5b7a031b

The partial hash 725d7c51 is only the beginning of a reported hash, so it cannot be used for an exact SHA-256 match.

6.2 Network

Table 5. Recovered endpoints and historical network indicators.

IndicatorRole
81.70.28[.]71:8000MarsSnake C2, archive route (recovered from the configuration).
93.157.106[.]75:80MarsSnake C2 recovered from the configuration; Positive Technologies also reported reuse of this IP by LuciDoor in another attack.
5.181.1[.]153:80MarsSnake C2 (recovered from the configuration).
button.gdakdbysw[.]xyz:443LuciDoor C2. Historical C2 reported by Positive Technologies; its router and TLS-fingerprint findings are source-attributed, not a current infrastructure check [2].
mail.ru.cdhgwnjjcw[.]xyzDelivery lookalike, impersonates mail.ru [2].
contact.decenttoy[.]topSaudi MarsSnake campaign C2, January 2025, per ESET [1].

Our extractor recovered the MarsSnake address and port pairs during the research. The addresses were also reported by Positive Technologies [2]. The Saudi domain is historical context from ESET [1].

6.3 Host and behaviour

Table 6. Host, code and behaviour indicators.

ArtefactValue
MarsSnake configuration markerOOkupFunction*71N (17 bytes; MarsSnake uses the marker as the repeating XOR key for the configuration that follows it).
MarsSnake 29-character value (message-body XOR and AES-key source)rYB1oDHVMViTRnaGsFw1TbHJ1z1aZ
Constant used to build the hidden value0x4D2BE561B84C932E (stored as two four-byte parts in six of the seven builds).
MarsSnake keys used to decode strings0x2113E7E35DF5010D, 0x7DBD49499DF19131 (stored in all seven builds).
MarsSnake completion marker&@&DWJ@*&!@(@#&*(@$&^
MarsSnake request pathPOST /eg.js
MarsSnake User-AgentMozilla/5.0 (Windows NT 10.0; ) AppleWebKit/537.36 (KHTML, Gecko) Chrome/137.0.0.0 Edg/137.0.0.0
MarsSnake handshake tokensdsalsjd89w21dcx9cwad@, asdas290e/cz/x213/.14
MarsSnake PDBD:\project\MarsSnake\x64\http\MarsSnake.pdb
MarsSnakeLoader PDBD:\project\MarsSnake\bin_shellcode\load_http_64.pdb
MarsSnakeLoader RC4 keyqio1239djk123sd.a;13, (followed by zlib decompression).
LuciLoad RC4 keymicrosoft (followed by a four-byte size value and LZNT1 decompression through RtlDecompressBuffer).
LuciLoad payload resourceBitmap resource type 2, ID 129.
LuciLoad hidden window titleOneDriveLaucher (misspelled in the binary; recovered in our analysis; public reporting uses OneDriveLauncher [2]).
LuciDoor scheduled task\Microsoft\OneDrive Launcher (author Microsoft, logon trigger, PT10S delay).
LuciDoor masqueradeOneDriveLauncher.exe; administrator path %ProgramData%\Microsoft OneDrive\setup\; standard-user path is based on %AppData% [2].
LuciDoor requestPOST /sys/index.jsp, User-Agent Mozilla/5.0 (compatible; Windows NT; rv:72.0) Gecko/20100101 Firefox.
Delivery drop path (archive route)c:\programdata\Oracle\Java\installcache\plasrv.exe
Delivery script signatureFTP script version.txt: lines begin with ! to escape to the shell, ends with bye (the FTPlnk_phishing builder, per Positive Technologies).
Delivery archive nestingHidden .__init__ directory that nests several .__MACOS__ folders, disguised as macOS metadata (recovered from the archive in our analysis).
Document-language clueword/settings.xml contains eastAsia=”zh-CN” and our analysis also recorded zh-TW; these settings occur in Russian-language documents and do not establish author location.
Document metadata clueGenerated by Snipaste, embedded-image metadata reported by Positive Technologies [2].

Rules that search for readable strings can miss the encoded protocol values in these MarsSnake files. The configuration marker, decoding keys and related code patterns provide alternatives. Task and file-path matches should be checked against the responsible process and file identity.

6.4 Detection rules (YARA)

These rules cover the four backdoor and loader families and provide a hunting aid for the geolocation gaters. The detection patterns come from the obfuscation layer, configuration marker, hardcoded keys, misspelled window title and cleartext request paths. They do not rely on the runtime protocol strings that MarsSnake rebuilds only during execution.

Every analysed sample matched its family rule with no cross-family collisions. Recursive scans of a clean Windows and Program Files corpus produced no matches. LuciDoor ships packed inside LuciLoad, so its rule matches the unpacked payload or a memory image. The gater rules are for hunting rather than precise detection.

YARA · MarsSnake backdoor
rule UnsolicitedBooker_MarsSnake_Backdoor
{
    strings:
        $marker = "OOkupFunction*71N" ascii
        $xor1 = { 0D 01 F5 5D E3 E7 13 21 }
        $xor2 = { 31 91 F1 9D 49 49 BD 7D }
    condition:
        uint16(0) == 0x5A4D and $marker and $xor1 and $xor2
}
YARA · MarsSnakeLoader
rule UnsolicitedBooker_MarsSnakeLoader
{
    strings:
        $rc4 = "qio1239djk123sd." ascii
        $marker = "OOkupFunction*71N" ascii
    condition:
        uint16(0) == 0x5A4D and $rc4 and $marker
}
YARA · LuciLoad
rule UnsolicitedBooker_LuciLoad
{
    strings:
        $misspell = "OneDriveLaucher" wide
        $rc4 = "microsoft" ascii
    condition:
        uint16(0) == 0x5A4D and $misspell and $rc4
}
YARA · LuciDoor backdoor (unpacked payload, not the LuciLoad file)
rule UnsolicitedBooker_LuciDoor_Backdoor
{
    strings:
        $uri = "/sys/index.jsp" ascii
        $ua = "rv:72.0" ascii
        $task = "OneDrive Launcher" wide
        $exe = "OneDriveLauncher.exe" wide
        $font = "Lucida Console" wide
    condition:
        $uri and ($ua or 2 of ($task, $exe, $font))
}
YARA · Configuration-marker sweep across the chain
rule UnsolicitedBooker_MarsSnake_ConfigMarker_Generic
{
    strings:
        $marker = "OOkupFunction*71N" ascii
    condition:
        $marker
}
YARA · Geolocation lookup, Twizt/Phorpiex (hunting)
rule geogate_ipapi_country_lookup
{
    strings:
        $ipapi   = "ip-api.com" ascii wide nocase
        $json    = "GET /json/" ascii wide nocase
        $cc      = "countryCode" ascii wide nocase
        $icanhaz = "icanhazip" ascii wide nocase
        $ipinfo  = "ipinfo.io" ascii wide nocase
    condition:
        $cc and (2 of ($ipapi, $json, $icanhaz, $ipinfo))
}
YARA · Western country-code list, Twizt/Phorpiex (hunting)
rule geogate_west_excluding_country_list
{
    strings:
        $geo1 = "ip-api" ascii wide nocase
        $geo2 = "countryCode" ascii wide nocase
        $geo3 = "icanhazip" ascii wide nocase
        $us = "\"US\"" ascii wide
        $se = "\"SE\"" ascii wide
        $ca = "\"CA\"" ascii wide
        $ch = "\"CH\"" ascii wide
        $gb = "\"GB\"" ascii wide
        $li = "\"LI\"" ascii wide
        $nl = "\"NL\"" ascii wide
        $lu = "\"LU\"" ascii wide
        $nz = "\"NZ\"" ascii wide
        $de = "\"DE\"" ascii wide
    condition:
        1 of ($geo*) and 6 of ($us, $se, $ca, $ch, $gb, $li, $nl, $lu, $nz, $de)
}

7. Abbreviations

  • ADODB ActiveX Data Objects.
  • AES Advanced Encryption Standard; ECB Electronic Codebook mode.
  • C2 command and control.
  • COM Component Object Model.
  • DLL dynamic-link library; PE Portable Executable.
  • FTP File Transfer Protocol; HTTP Hypertext Transfer Protocol.
  • TLS Transport Layer Security.
  • IOC indicator of compromise.
  • LZNT1 a Windows compression format.
  • MZ the signature at the start of a PE file.
  • PDB program database containing debugging information.
  • RC4 a stream cipher; XOR exclusive OR.
  • Schannel Windows Secure Channel; SSPI Security Support Provider Interface.
  • SHA-256 Secure Hash Algorithm, 256-bit.
  • TCP Transmission Control Protocol.
  • VBS VBScript.
  • WoW64 Windows 32-bit on Windows 64-bit.
  • YARA a pattern-matching tool.

8. References

  1. ESET Research. ESET APT Activity Report Q4 2024 to Q1 2025, pages 8 and 9. Earlier Saudi intrusions and the January 2025 MarsSnake campaign. web-assets.esetstatic.com
  2. Positive Technologies Expert Security Center. Poisonous Mars, or how LuciDoor knocks on the doors of the CIS. 24 February 2026. Campaign context, loader and backdoor analysis, and historical infrastructure.
  3. Microsoft. GetTcpTable function. IPv4 TCP table scope.
  4. Microsoft. Event 4698: A scheduled task was created. Task-creation auditing.

Hasan Mevzi

Hasan Mevzi is a Cyber Threat Intelligence Analyst at VMRay, where he researches malware and the adversaries behind it, producing intelligence that helps organizations detect and defend against emerging threats. Before joining VMRay, he spent several years in threat intelligence, tracking advanced persistent threats and cybercriminal groups, analyzing their tactics, techniques and procedures, and investigating the infrastructure and identities behind them.