LucidRook: Rust & Lua Stagers in UAT-10362's Taiwan Campaigns
Just saw a report on a new cluster, UAT-10362, targeting Taiwanese NGOs and universities. They're deploying a stager called LucidRook, and the architecture is fascinating.
Instead of the usual PowerShell or C#, this threat actor is using a Rust-compiled DLL that embeds a full Lua interpreter. Why does this matter? Rust makes static analysis a nightmare due to its complex standard library and lack of recognizable C-style patterns, while embedding Lua allows them to run modular scripts directly from memory without dropping a .lua file to disk.
Since the entry vector is spear-phishing, likely abusing Office macros or LNK files, we need to hunt for the side-loading of these unsigned DLLs.
Here is a YARA rule to help identify the Lua magic bytes (1B 4C 75 61) inside PE files, which is a strong indicator of this technique:
yara rule LucidRook_Lua_Embedded { meta: description = "Detects Lua interpreter embedded in PE files" author = "SecurityArsenal" strings: $mz = { 4D 5A } $lua = { 1B 4C 75 61 } // Lua header $rust = "alloc::" // Common Rust string in debug/standard builds condition: $mz at 0 and $lua in (1000..filesize) and $rust }
The use of an embedded interpreter suggests they are planning for long-term persistence with flexible plugins. Has anyone started seeing more scriptable interpreters like Lua or Python embedded in loaders lately?
Great share. I've been noticing a slow shift away from PowerShell for initial access because EDRs have tightened the screws on AMSI and Script Block Logging. Moving the logic into a compiled Rust binary with an embedded Lua engine effectively renders those script logs useless. The Lua bytecode runs entirely within the process's memory space. I'd recommend also checking for imports of luaL_loadbuffer or lua_pcall in the Import Address Table if you have the binaries.
This hits close to home. We run a small NGO support group and see these "academic" spear-phishing attempts constantly. The Rust angle is particularly nasty because the resulting binaries are often larger and have higher entropy, which sometimes triggers false positives on heuristic scanners but can also be tuned to blend in with legitimate software build artifacts. I'm pushing for application whitelisting (AppLocker) to stop these unsigned DLLs from loading in the first place.
Just wanted to add that for organizations using Sentinel or Splunk, you can pivot on the file size. These Rust-Lua DLLs are going to be larger than your average shellcode loader (often >1MB) because of the embedded interpreter and standard library. Hunting for "Large Unsigned DLLs" loading from C:\Users\Public\ or AppData via rundll32.exe usually catches these stagers. Good YARA rule, definitely adding that to our repo.
Verified Access Required
To maintain the integrity of our intelligence feeds, only verified partners and security professionals can post replies.
Request Access