About this post: Thanks to MalwareHunterTeam for flagging this new payload. This analysis and write-up were produced by Claude (Opus 5.5), working as an agent in Claude Code on a REMnux analysis VM. Tools used: Malcat, Ghidra, capstone, capa, a sandboxed Wine environment, and ANY.RUN.
TL;DR
A file called Microsoft-Teams-2026-5.30.1-latest-win-x64.msi is not Microsoft Teams. It is an EV-signed Windows Installer package. It quietly installs a genuine, validly signed copy of the calibre e-book reader, together with a handful of attacker files that ride along with it. Once calibre starts, those files wait about 62 seconds and then unpack a three-stage chain. That chain ends with a remote access trojan running in memory.
- Lure: a “Microsoft Teams” filename on an MSI whose own metadata says “Advanced eBook Reader”.
- Signing: the MSI carries an EV code-signing certificate issued to “Lway Firmware” (Sectigo, serial
34d898fa7a8ca1ec63fcf8fb76874ad3). - Trick: DLL side-loading through a real, signed
calibre.exe, with the next stage hidden inside a real-looking SQLite database. - Patience: a hard-coded 62-second wait before anything malicious runs, which is longer than many quick sandbox runs.
- Payload: the BabaDeda loader, which unpacks the CNCMachineRMS RAT (v1.6.6). It persists with a Run key and a scheduled task, both named “Calibre”, and is configured to talk to
wizardexpensive[.]comand96.62.218[.]59.

But it’s signed!
Code signing is a digital seal: it tells Windows which company published a file and that nobody has changed it since. An EV (“Extended Validation”) certificate is the premium version. The publisher has to pass a stricter identity check, and such files usually trigger fewer warnings.
This MSI is signed with an EV certificate issued to “Lway Firmware”, a company registered in Finland. It was signed on 21 October 2026, about five weeks after the certificate was issued. The certificate has nothing to do with Microsoft or with Teams. A recently issued certificate used to sign a package pretending to be someone else’s product is a pattern we see again and again with signed malware. This certificate has been reported to the CA and added to the CertGraveyard.
There is a second signature in the story, and that one is real. The calibre.exe in the package is the genuine calibre launcher, signed by its developer, Kovid Goyal. The attackers did not touch it. They need it to be trusted.
Step 1: borrow a trusted program
The MSI is a standard WiX package. It installs per user to %LOCALAPPDATA%\Programs\Advanced eBook Reader\, hides itself from “Programs and Features”, and starts calibre.exe as soon as the install finishes. No administrator prompt is needed.
Programs load helper libraries (DLLs) from their own folder. DLL side-loading abuses that habit: put a malicious DLL where a trusted program expects its own, and the trusted program runs the attacker’s code for you. Think of it as swapping one ingredient in a sealed recipe kit. The box and its seal are genuine, but one jar inside isn’t.
Here the swapped jar is calibre-launcher.dll. Compared with the real one, it is unsigned, its company name has been changed, and it has one extra import: a function called ModelPackageSet from j2Json.dll. Nothing in calibre ever calls that function. The import is only there so that Windows loads j2Json.dll as soon as calibre starts.
Step 2: wait a minute, then dig through a database
j2Json.dll is the first-stage loader. It uses two helper DLLs that also came in the package, PuResources.dll and SonitusFXSurround.dll. All three carry version information copied from unrelated software and are padded with large amounts of drawing code that does nothing useful. That filler is there to bore analysts and confuse automated tools.
The loader then does the following:
- It opens
corenative.dat. This is a perfectly valid SQLite database full of engineering fit tables. Starting at offset0x31bf3, however, it also holds 341,491 bytes of scrambled code. - It waits 62 seconds, using a wait on an event that is never triggered. This is a simple way to outlast sandboxes that only watch a program for a minute.
- It unscrambles the bytes with a rolling XOR, copies them into memory that is allowed to run code, and starts them with a Windows callback,
EnumSystemCodePagesW. That API normally lists the system’s code pages; here it is just used to jump into shellcode, raw machine code with no file around it.
Meanwhile, calibre itself fails: the bundled launcher cannot find the Python library it expects and shows an error box. That box keeps the process alive while the loader waits. SonitusFXSurround.dll also contains a thread built to hide the process’s windows for about 80 seconds. We only saw that in the code, though. In our test environment the error box stayed visible.
Step 3: the BabaDeda loader
The shellcode from corenative.dat is the BabaDeda loader. All of its text strings are encrypted and are only assembled on the stack when needed. We decrypted all 124 of them. It checks the CPU vendor string for well-known virtual machines (VMware, VirtualBox, Xen, Hyper-V) and looks for VM services by name.
Next, it looks through the folders of the program’s loaded modules for files ending in .bak, .db, .bin, .dat, .raw or .pak. The one it wants is Generate.bin, an encrypted “storage” container with 1,128 entries. Most entries are small filler values. Two of them matter:
- A small script that waits 2 seconds, adds an HKCU Run value named
Calibre(rewritten every 150 seconds and at shutdown), creates a scheduled task namedCalibre(refreshed every 875 seconds), and then runs the entry calledinput. inputitself, 1.58 MB of shellcode: the final RAT.
It’s a set of nesting dolls: a signed installer, a trusted app, a fake DLL, a database, a container, and finally the payload.
Step 4: CNCMachineRMS, the RAT at the end
The last stage identifies itself through strings such as CNCMachineRMS\tasks and carries version 1.6.6. Its settings sit in encrypted resources, which we decoded. The settings include:
- Gates (servers):
wizardexpensive[.]com:443and96.62.218[.]59:443 - Campaign:
default - Local database:
{localappdata}\FTSuite\ftc.uml - Timers: connect every 598 s, stay connected 93 s, reconnect after failure 61 s, keep-alive 91 s, and sleep 900 s when a VM is detected.
The RAT also embeds its own small script with a VM check. One amusing detail: if the folder C:\Intel exists, it decides it is on a real machine. Otherwise it looks at the hardware and flags systems with less than 6 GB of RAM or fewer than two CPUs.
Its decrypted strings describe a full remote access toolkit:
- remote desktop
- an interactive command shell (cmd.exe or PowerShell)
- a file manager and file search
- camera and microphone access
- downloading and running more payloads (EXE, DLL, MSI, BAT, VBS, PowerShell, ZIP or a link)
- seven different autorun methods, including a scheduled task that runs as SYSTEM at logon
- creating local user accounts and adding them to groups
- profiling the host and its antivirus through WMI
- DNS-over-HTTPS lookups through Cloudflare, Google and Quad9, which keeps its domain lookups out of plain DNS logs
These capabilities come from strings, not from watching the RAT operate. Treat them as what the tool can do, not a record of what it did.
Where this fits
This RAT is not new. LevelBlue SpiderLabs first documented it, and gave it the name CNCMachineRMS, in August 2026. Their sample arrived through a ClickFix lure and hid behind a signed IBM SPSS program. A few days later, marsomx described a build that used ESET SysInspector instead. Both builds used different callbacks, file names, campaign names and servers from this one. The storage format, the loader script, the key names in the RAT’s settings and almost identical timers are the same. This sample looks like a fresh build of the same kit, with a new disguise and new infrastructure.
What the local analysis couldn’t reach
- No live traffic. We stayed offline and never contacted the servers. In our sandboxed test run, stage 2 started right on schedule after 62 seconds, but the process crashed about 3 seconds later, before persistence or any connection attempt. We don’t know why it crashed, and we treat it as a limit of the test environment.
- The public sandbox stopped too early. In a 60-second ANY.RUN run, calibre exited after about 52 seconds, before the 62-second wait was over. The payload most likely never ran, which is why that run looks fairly quiet.
- Some settings are still unknown. A few on/off switches (for example “take a screenshot at first launch”) are present, but we did not recover their values. The RAT’s network protocol and command numbers were not mapped either.
Advice
For regular users: get Teams (and any other software) from the vendor’s own site or your company’s software portal. A file name that says “Microsoft Teams” means nothing, and a valid signature only tells you who signed it, not that they are who you expected. If an “installer” shows you an e-book reader error, stop and report it.
For defenders:
- Block the two servers listed below.
- Hunt for an HKCU Run value or a scheduled task named
Calibrethat points into%LOCALAPPDATA%\Programs\Advanced eBook Reader\. - Hunt for
calibre-launcher.dllthat is unsigned or sits next toj2Json.dll, outside a normal calibre install. - Look for files named
task_payload.binunder aCNCMachineRMS\tasks\folder, scheduled tasks created with/SC ONLOGON /RU SYSTEM /RL HIGHEST, and Windows Security events 4720 and 4732 (new local account, added to a group). The strings behind these are in this build, and LevelBlue lists them as indicators for theirs. - Treat files signed with Lway Firmware serial
34d898fa7a8ca1ec63fcf8fb76874ad3as suspect. - When sandboxing installers, run them for at least several minutes. A 62-second wait is enough to empty a one-minute report.
Indicators of compromise
| Type | Value |
|---|---|
| MSI (SHA256) | b74b2bfc895f1205dfb389772b201a8e31b7bc4464ff3c4463b417626ecedb1c |
| calibre-launcher.dll (patched) | 0efb9058385e057821ee5b6a7282bc6c06b16f4c9ad1d51572325181f8e31a29 |
| j2Json.dll | a270ce8c4ab1a4edcc474a24c5fb5fac239c48ec961a63df972ec40f0d6fff77 |
| PuResources.dll | 7eae86c5ae86e0074446782aec858b4bc44bbb2f01342f185ecf5f7e20272857 |
| SonitusFXSurround.dll | 96033083a2da941691fb234bf7bf1737df731e5bc26947e4e23ff89ded6f0042 |
| corenative.dat | 3e87cda06f72dc8408483eb497d894de6fbbd47d365ac4d0e763d7a71d9c1125 |
| Generate.bin | 84190634766ffdd987d8935426b8a65aa409768ab85fd5ed9608f7abda95800c |
| Stage 2, BabaDeda loader (decoded) | 4d7e1145364a12c657973343eb36cad1401fbee385470648b4bbcb8bd4ac4709 |
| Stage 3, CNCMachineRMS (decoded) | d9274c98d7be30e6045e63d3acc190055a3849e2992b7382643c16a5aefa22dc |
| C2 domain | wizardexpensive[.]com:443 |
| C2 IP | 96.62.218[.]59:443 |
| Signer | Lway Firmware, Sectigo Public Code Signing CA EV R36, serial 34d898fa7a8ca1ec63fcf8fb76874ad3 |
| Persistence | HKCU ...\Run value Calibre; scheduled task Calibre |
| Install path | %LOCALAPPDATA%\Programs\Advanced eBook Reader\ |
| RAT data file | %LOCALAPPDATA%\FTSuite\ftc.uml |
Wrapping up
Nothing here is exotic on its own: a borrowed signed program, a fake DLL, a hidden blob, a timer. Stacked together under a fresh EV signature, they make a package that looks harmless at every quick glance. If you find more samples signed with this certificate or talking to these servers, we’d love to hear about it.
Public sandbox run: ANY.RUN task 2b7c55b1. Earlier reporting: LevelBlue SpiderLabs, “CNCMachineRMS: The Undocumented RAT at the End of a BabaDeda Chain” and marsomx, “BabaDeda malware analysis”.