September 4, 2026
Busting Remus Stealer: How I Analyzed a 50,000-Download Malware Campaign
I was browsing on Youtube for recently uploaded software crack videos. I know a lot of people in fact LOVE Adobe products, so I searched…

By SevDMG
17 min read
I was browsing on Youtube for recently uploaded software crack videos. I know a lot of people in fact LOVE Adobe products, so I searched for "Free Photoshop Crack 2026". The first video I've encountered walked through how to download it (via link MediaFire) and how to enter the password.
Well… the demo itself showed what looked like a GENUINE Adobe Installer running through its setup, except it wasn't.
It was "too good" to be true, i thought… A fully cracked, up-to-date version of Photoshop, sitting right there on Mediafire, one password away from working perfectly at 0 costs.
So I've set up my analysis environment. A REMNUX-VM for Static analysis and network simulation and FLARE-VM for dynamic analysis. Both isolated on a Host-Only network, no real internet access.
I pointed the preferred DNS on FLARE-VM to the REMnux gateway, so any lookup the malware made would resolve straight back into my sandboxed network. The tool "INetSim" would answer for anything it tried to reach.
The folder contained the following:
No more talking, lets get straight to the analysis, starting with static analysis.
STATIC ANALYSIS
First of all, what I like to see is the contents of the downloaded folder, with 'tree':
The first thing that caught my eye was the 'Photoshop 2026.exe' sitting right next to CSERHelper.dll. Could this be some kind of DLL hijacking setup? Was the executable going to load that DLL on startup and abuse it somehow? I decided to check it out.
Following the good practices of Malware analysis, we should check the digital signature of the files involved. So I used osslsigncode to inspect both files. And… the results were immediately suspicious…
Interestingly, the signature carried a legitimate DigiCert timestamp counter-signature which is clearly a small detail added to make the file look more "official" and reduce some friction with Windows SmartScreen.
But the certificate itself told a very different story:
The Subject and Issuer are identical, a classic self-signed certificate issued by the company called "Bright Signal Industries" that i couldn't find any legitimate trace of. Even more telling was the fact this certificate was created just eight days before it used to sign the binary. No real software vendor operates this way. Legitimate certificates come from an established, trusted CA, not from an entity that appears to exist solely to sign a single file
When osslsigncode tried to validate the certificate chain, it failed (PKCS7):
The DigiCert timestamp was legitimate, but it doesnt matter. A real timestamp on top of a fake certificate is still a fake certificate.
I ran the same check against CSERHelper.dll.
Unlike the "Bright Signal Industries" certificate, this one had everything a real certificate should had: a properly structured Subject (company, state, region — Valve, WA, Bellevue), and an Issuer that's an actual trusted certificate authority, DigiCert.
osslsigncode still reported the overall verification as "Failed", but for a completely different reason:
Error: self-signed certificate in certificate chain
...
Timestamp Server Signature verification: failed
Signature verification: failedError: self-signed certificate in certificate chain
...
Timestamp Server Signature verification: failed
Signature verification: failedThis isn't a forged certificate. Its a simply old and expired one which was valid between 2015 and 2018, signed using infrastructure (Symantec Time Stamping Services) that has since been deprecated and is no longer trusted by modern systems.
TL;DR: 'Photoshop 2026.exe' failed verification because it was never legitimate to begin with. 'CSERHelper' failed verification because it used to be legitimate, and the internet "moved on". Good early hint that the DLL was just legitimate leftover from a real Steam installation.
Moving forward..
Some people like to jump straight into 'strings' and grep with the help of regex to find malicious keywords like: URLs, "http", "cmd.exe", that kind of thing. Its a fair instinct, but modern malware rarely makes it that easy. Anything meaningful tends to be severely encoded, encrypted or resolved dynamically at runtime in memory, so a plain 'strings' pass on a sample like this, mostly returning a noisy output.
Instead, I used 'peframe', which is a structured static analysis tool that parses the PE file itself and surfaces the things that actually matter: PE sections, entropy, imports, embedded signatures, and known-suspicious IOCs.
A few things stood out immediately. The compile timestamp was zeroed out (1970–01–01) which is a deliberate anti-forensics move, since a real compile date can help investigators correlate samples across a campaign. There was also no .rsrc section, which is unusual for a GUI application that's supposed to have icons, dialogs, and version info like a real installer would.
The behavioral flags were even more telling. It had flags like: anti-debugging, thread context manipulation (possibly process-hollowing), XOR-based obfuscation, full networking capability, privilege escalation and registry/token manipulation. None of this belongs in a Photoshop installer.
Then there was .text entropy and the import table:
An entropy of 6.14 in the .text section is elevated for a compile code, not "high" enough to scream "PACKED MALWARE!", but consistent with obfuscated or heavily optimized machine code.
Also, one imported dll, with 39 functions. No user32.dll, no advapi32.dll, nothing you'd expect from a real GUI app. This almost always means the binary is resolving the rest of its APIs dynamically at runtime, via GetProcAddress, specifically to avoid showing up in a static import table where an analyst (or an AV engine) could spot something like "CreateRemoteThread" or "VirtualAllocEx" sitting in plain sight.
At this point, my initial guess was that this was a C/C++ binary. The single file kernel32.dll import with dynamically resolved APIs, combined with the presence of a .symtab section, is a pattern of MinGW/GCC compilation.
Analysing the .exe with FLOSS, we found some interesting stuff:
Hold on, turns out I was wrong. This wasn't a C/C++ compiled binary, it was Go. FLOSS identified the runtime as go(1.18), and scrolling on the extracted strings, I've found:
Go build ID: "q7_McoebLIxcIFH61WvZ/7qKfZ167KrV-d0LJ3tI8/DmWp7qW0d2FT-9kYEbAo/CtV4W1aOJZ7H2nrLcK30"Go build ID: "q7_McoebLIxcIFH61WvZ/7qKfZ167KrV-d0LJ3tI8/DmWp7qW0d2FT-9kYEbAo/CtV4W1aOJZ7H2nrLcK30"A Go binary doesn't need to dynamically import much from Windows DLLs at all, since it implements most of what it needs internally and only calls into kernel32.dll for the handful of raw OS primitives it can't avoid (threads, memory, file, handles). What looked like "deliberately hidden imports" was, at least partly, just how Go binaries are built.
It also explained the .symtab section and the elevated .text entropy. Go binaries are notoriously large and dense, packed with runtime scheduler code, garbage collector logic, and every standard library package the compiler decided to include.
Since it was compiled in Go, lets look for the "main.go" string.
Every Go binary embeds the module path of its main package, and this one is clearly randomized, not a real project name. A second grep against the same string confirmed it runs deeper than just the file path.
Even the module metadata was obfuscated. The function names followed the same pattern, for example main.YSR2iZ7pk, main.j6XgbpDwa, main.dWooVjqN0DQ0Jt which are meaningless, randomized identifiers instead of a readable Go function names. The one symbol left untouched was main.main, the entry point, which by Go convention can't be renamed without breaking the runtime. This build was definetily to defeat hash-based detection.
For a last visual confirmation of this binary, let's use Detect It Easy:
Running the binary through DIE confirmed most of what static analysis had already surfaced, and added some interesting inconsistency worth chasing before moving to dynamic analysis.
Base address: 0000000000400000
Entry point: 0000000000460c00
Sections: 6
Time date stamp: 1970-01-01 00:00:00
Type: PE64, GUI, AMD64, Little Endian
Target OS: Windows 7 (minimum)
Size: 4,046,848 bytes (3.86 MiB)Base address: 0000000000400000
Entry point: 0000000000460c00
Sections: 6
Time date stamp: 1970-01-01 00:00:00
Type: PE64, GUI, AMD64, Little Endian
Target OS: Windows 7 (minimum)
Size: 4,046,848 bytes (3.86 MiB)No packer was detected, no UPX, no VMProtect, no Themida signature. This confirmed something important: There was no "unpacking" step to perform here. What looked like obfuscation was really just how a statically compiled Go binary is built, combined with randomized symbol names.
One detail stood out, though: DIE reported a file size of 3.86 MiB, while peframe had earlier reported 3,671,488 bytes (3.5MiB) for the same file. That's roughly 375 KB of "hidden data", which is a strong hint that this could be the overlay I'd flagged earlier, data appended after the end of the PE structure itself, and a common place for malware to hide encrypted configuration or a second-stage payload.
This discrepancy was worth chasing down before moving into a debugger.
Lets confirm and locate the overlay offset with this python script:
import pefile
pe = pefile.PE("Photoshop 2026.exe")
overlay_offset = pe.get_overlay_data_start_offset()
if overlay_offset:
filesize = len(open("Photoshop 2026.exe", "rb").read())
overlay_size = filesize - overlay_offset
print(f"Overlay starts at offset: 0x{overlay_offset:x} ({overlay_offset})")
print(f"Overlay size: {overlay_size} bytes")
else:
print("No overlay detected")import pefile
pe = pefile.PE("Photoshop 2026.exe")
overlay_offset = pe.get_overlay_data_start_offset()
if overlay_offset:
filesize = len(open("Photoshop 2026.exe", "rb").read())
overlay_size = filesize - overlay_offset
print(f"Overlay starts at offset: 0x{overlay_offset:x} ({overlay_offset})")
print(f"Overlay size: {overlay_size} bytes")
else:
print("No overlay detected")Output:
remnux@remnux:~/Desktop/Samples/Photoshop$ python3 locate_overlay.py
Overlay starts at offset: 0x37e600 (3663360)
Overlay size: 8128 bytesremnux@remnux:~/Desktop/Samples/Photoshop$ python3 locate_overlay.py
Overlay starts at offset: 0x37e600 (3663360)
Overlay size: 8128 bytesThe math checked out -3,663,360 + 8,128 = 3,671,488, exactly matching the file size peframe had reported from the start. That closed the loop on the size discrepancy I'd flagged after running DIE: it turned out to be a quirk in how DIE calculates file size, not evidence of a hidden multi-hundred-kilobyte payload. A dead end, but worth ruling out properly rather than assuming.
The overlay itself was real, though… just much smaller than expected, at 8 KB. Small enough that it was unlikely to be an embedded second-stage executable, but still worth a look. It could easily be a compressed or encrypted configuration blob, so I decided to check what was actually inside it.
Now we extract this overlay to a isolated .bin:
import pefile
pe = pefile.PE("Photoshop 2026.exe")
overlay_offset = pe.get_overlay_data_start_offset()
if overlay_offset:
with open("Photoshop 2026.exe", "rb") as f:
f.seek(overlay_offset)
overlay_data = f.read()
with open("overlay.bin", "wb") as out:
out.write(overlay_data)
print(f"Overlay extracted: {len(overlay_data)} bytes -> overlay.bin")import pefile
pe = pefile.PE("Photoshop 2026.exe")
overlay_offset = pe.get_overlay_data_start_offset()
if overlay_offset:
with open("Photoshop 2026.exe", "rb") as f:
f.seek(overlay_offset)
overlay_data = f.read()
with open("overlay.bin", "wb") as out:
out.write(overlay_data)
print(f"Overlay extracted: {len(overlay_data)} bytes -> overlay.bin")And we inspect for the following:
- Strings (look for something that's not encrypted)
- General .bin Entropy
- Search for signatures of known embed files
- Look for the first bytes in hex (magic bytes can give us a hint)
The mistery didn't last long. binwalk and strings both pointed the same way: Bright Signal Industries, DigiCert Inc, and the same validity dates already seen in osslsigncode.
This wasn't a hidden payload, it was the digital signature itself. Authenticode signatures are physically stored as a PE overlay, so this was just the fake certificate chain sitting exactly where it belongs.
A dead end, but a useful one: no second-stage payload was bundled statically. Whatever came next would have to be fetched at runtime, over the network.
DYNAMIC ANALYSIS
Well… Static Analysis had told me almost everything it could. I knew the entry point had been hunted down to a randomized module name, I knew the digital signature was fake, and i'd ruled out any embedded second-stage payload. But some things simply don't show up in a disassembler, they only exist for a couple milliseconds, in memory, at the moment the malware actually needs them.
The XOR key protecting the C2 configuration was one of those things.
Rather than trying to reconstruct the decryption routine by hand from obfuscated Go assembly, I decided to let the malware do the work for me: attach a debugger, let it run until the moment it decrypts its own configuration, and read the plaintext straight out of memory.
But first of all, let's run the malware in Flare-VM and point the gateway to our REMnux VM.
In FLARE-VM, I ran RegShot to take a snapshot of the current registry keys and their state before execution. I opened Wireshark on REMnux, capturing on the interface facing FLARE-VM, so I wouldn't miss the very first packet. Then I started INetSim, confirming all eight services came up.
In Regshot I set up the following scanning directories:
C:\Users\SandboxedCuhLMAO\AppData\Local;C:\Users\SandboxedCuhLMAO\AppData\Roaming;C:\Users\SandboxedCuhLMAO\AppData\LocalLow;C:\ProgramData;C:\Windows\Temp;C:\Users\SandboxedCuhLMAO\Desktop;C:\Users\SandboxedCuhLMAO\Downloads;C:\Windows\System32;C:\Users\SandboxedCuhLMAO\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
With the baseline captured and the network running, i double-clicked 'Photoshop 2026.exe'.
Our first glance in Wireshark:
The malware tried to reach out to the following domains:
DNS resolution alone doesn't tell the full story. Resolving a domain is just a step one.
Immediately after, the malware issued an HTTP POST request to ethereum-rpc.publicnode.com.
The POST Request is:
{
"jsonrpc": "2.0",
"id": 1,
"method": "eth_call",
"params": [
{
"to": "0x999941b74F6bbc921D5174A5b29911562cd2D7CF",
"data": "0xc2fb26a6"
},
"latest"
]
}{
"jsonrpc": "2.0",
"id": 1,
"method": "eth_call",
"params": [
{
"to": "0x999941b74F6bbc921D5174A5b29911562cd2D7CF",
"data": "0xc2fb26a6"
},
"latest"
]
}JACKPOT!
At first glance this looks like nothing. A simple JSON-RPC call, the kind any Ethereum wallet sends thousands of times a day. That's exactly the point.
The parameter eth_call is a read-only call to a smart-contract: it costs no gas(*1), creates no transaction, and leaves no trace on-chain of who made the request. To any firewall or EDR watching the wire, this traffic is indistinguishable from a legitimate crypto wallet checking a balance.
(*1) gas — It is the transaction fee paid in cryptocurrency to execute code or change data on a blockchain.
The two fields that matter are to and data. The to field is the smart contract address -0x999941b74F6bbc921D5174A5b29911562cd2D7CF which is a piece of immutable infrastructure sitting on the Ethereum mainnet. The data field, 0xc2fb26a6, is the function selector: the first four bytes of the Keccak-256 hash of the function signature, telling the contract exactly which stored value to return.
In other words, the malware isn't hardcoding a C2 domain at all — it's asking a public, immutable smart contract: "what's the current C2 address?" This class of technique is known as a dead drop resolver (DDR): any mechanism where malware fetches its C2 address at runtime from a third-party, attacker-controlled location instead of hardcoding it which is a role once played by Telegram channel bios, paste sites, and GitHub gists, and now increasingly by public smart contracts. The variant seen here, reading a value from an EVM contract via eth_call, is the most common shape of the technique and is what Google's Threat Intelligence team named EtherHiding.
The design gives the operator two things at once. First, takedown resistance: nobody can compel a public blockchain to censor a read, and the operator can re-point every deployed sample by updating a single contract value for a few cents in gas — no new binary, no new domain to burn. Second, traffic blending: because the request goes to the same high-reputation RPC providers that ordinary crypto wallets and dApps use — Infura, Cloudflare, publicnode — this kind of host-only network signature gets lost in a sea of legitimate blockchain traffic.
Netskope's Threat Labs recently mapped this exact pattern across eight unrelated malware families spanning three different chains: Ethereum, Solana, and TON, which suggests this Remus sample isn't running some "easy" infrastructure. It's using infrastructure that's becoming a standard commodity in the malware supply chain. (https://www.netskope.com/blog/blockchain-dead-drop-resolvers-explained)
REGSHOT RESULTS
After letting the sample run through its full execution cycle, a 5-minute sandbox delay, the port probes, the DNS lookups, and the EtherHiding callback, I compared the two RegShot snapshots.
That 733 was the value that caught my attention. In practice, a number that high is rarely all attacker activity but rather Windows itself generating lot of registry noise in response to any new process running (font cache updates, shell icon cache, prefetch data, Defender Telemetry, etc…). The real work was in isolating which of those ~1037 changes were actually made by the malware itself, rather than by Windows reacting to it.
With the help of AI, it filtered the noise from the Process Monitor driver, Regshot itself, Sysinternals tools and left a handful of entries that actually mattered.
Two independent registry artifacts confirmed execution. The first was a UserAssist entry, stored in ROT13 as Windows always does, which decoded to E:\Photoshop 2026\Photoshop 2026.exe, recording that the binary was deliberately launched. The second was an AppCompatFlags entry under Compatibility Assistant\Store with the same path: a separate Windows mechanism that also logs executed binaries independently of the user's own activity logs. On a real victim machine, both would be reliable forensic proof of execution that survives even if the binary itself is deleted.
The bulk of the remaining changes were CryptnetUrlCache entries: dozens of new files in AppData\LocalLow\Microsoft\CryptnetUrlCache, created as Windows attempted to validate the "Bright Signal Industries" certificate chain against revocation lists and OCSP endpoints. It contacted ctldl.windowsupdate.com and ocsp.digicert.com, received INetSim's fake responses, and cached them locally. The cache even included a new root certificate added to HKLM\SOFTWARE\Microsoft\SystemCertificates\AuthRoot the Windows certificate trust store being updated as a side effect of trying to validate a self-signed certificate it had never seen before.
The absence of persistence mechanisms was something really different from other malware I've studied before. No Run key. No RunOnce. No new service. No scheduled task. No files dropped into AppData, Temp or Startup.
This Remus sample never reached its persistence phase, it failed its environment check, made its network callback and exited cleanly before doing anything lasting to the system. On a real machine, without a VM fingerprint triggering that early exit, persistence would almost certainly follow.
CHASING THE XOR KEY
Before running the sample under the debugger (xdbg64), I made sure ScyllaHide was fully configured where every category should be enabled:
- Debugger Hiding;
- DRX Protection
- Timing Hooks
- Misc
- Special Hooks
Given the fact that peframe had already flagged debugger-detection behavior on this sample, and that I already knew it used timing-based sandbox-evasion, it was mandatory to enable these options.
With ScyllaHide active, I also had OllyDumpEx ready to go, so that once I caught the decrypted configuration in memory, I could dump the process and extract it cleanly rather than trying to read it byte-by-byte through the debugger's memory view.
After loading the 'Photoshop 2026.exe', I set a breakpoint on kernelbase.LoadLibraryExW and hit F9 (Run). Since Go resolves most of its Windows APIs calls dynamically rather than through a static import table, ws2_32.dll, and the networking functions I actually cared about, hadn't been loaded into memory yet. This breakpoint would fire every time any DLL got loaded and with that, I could watch the runtime load each library one by one, until ws2_32.dll finally showed up as an argument.
The breakpoint on LoadLibraryExW fired, catching ntdll.dll being loaded. RCX register held a pointer to the DLL name, and following it in the dump view showed the wide string clearly: L"ntdll.dll". This early in the process, before Go's own runtime had even started, Windows was still resolving its core system dependencies. I kept hitting F9, checking RCX each time, working my way through the loader until ws2_32.dll finally showed up.
This time, the run ended almost immediately, and the debugger log told a more interesting story than a simple crash:
Two things stood out. First, "Breakpoint deleted!" appeared without me touching anything, x64dbg reports this when the INT3 byte a software breakpoint plants gets overwritten by something other than the debugger itself. That's consistent with a self-integrity check: the malware periodically hashing or comparing its own code section in memory, detecting the planted breakpoint as tampering, and reacting to it.
Second, right before exiting, the process loaded 'powrprof.dll' and 'umpdc.dll', both related to Windows power management. That's not something you'd expect from a stealer unless it's checking for the presence of a battery or a specific power profile, a common anti-VM technique, since virtual machines typically report power states differently from physical hardware.
Switching to hardware breakpoints (bph) ruled out the self-integrity theory, hardware breakpoints never touch a byte of code, yet the process still died at the exact same spot with the exact same exit code every single time. This wasn't the malware reacting to a debugger. It was failing an environment check regardless.
Breakpoints on GetSystemPowerStatus and CallNtPowerInformation never fired. Since Go binaries are known to issue raw syscalls directly, bypassing ntdll.dll wrappers entirely, whatever power check runs here likely goes straight to the kernel, and straight past every hook ScyllaHide had planted.
ATTRIBUTION
By this point, the evidence had accumulated into a clear picture. The contract address 0x999941b74F6bbc921D5174A5b29911562cd2D7CF, the function selector 0xc2fb26a6, and the RPC endpoint ethereum-rpc.publicnode.com were the main fingerprints.
Cross-referencing these against public threat intelligence confirmed the attribution: this sample belongs to the Remus Stealer family, an infostealer first documented in early 2026, distributed primarily through fake software cracks and known for its use of EtherHiding as its primary C2 resolution mechanism.
The Etherscan event log for the contract 0x999941b74F6bbc921D5174A5b29911562cd2D7CF told the full operational history of this infrastructure, in chronological order:
191 days ago blablatst12345.net -> first test domain
191 days ago chalx.live:5902 -> operational (3 updates, testing rotation)
187 days ago chalx.live:5902 -> confirmed operational
132 days ago fightwa.biz:5902 -> most recent publicly documented C2191 days ago blablatst12345.net -> first test domain
191 days ago chalx.live:5902 -> operational (3 updates, testing rotation)
187 days ago chalx.live:5902 -> confirmed operational
132 days ago fightwa.biz:5902 -> most recent publicly documented C2Every one of these updates was written to the blockchain via the same method call, write(string), function selector 0xebaac771, emitting a DomainUpdated event each time. The operator updated the C2 URL four distinct times over roughly 60 days, each time paying a small gas fee, while every deployed Remus sample automatically pointed to whatever the contract currently held. No recompilation, no redeployment, no new binary to burn.
But wait. If the contract's entire update history ends at fightwa.biz:5902, where do darkfot.click, shhsift.click, and piarl.site fit in?
None of these domains appear anywhere in the contract's on-chain history. The most likely explanation is that the operator rotated infrastructure between April and August 2026 without updating the contract, using these domains as short-lived fallback C2s resolved through a separate mechanism entirely. They may have been hardcoded directly into this specific build, cycled through and discarded before the contract ever reflected them.
That also explains the 36-second interval between each DNS lookup observed during execution. The malware wasn't waiting for a response, it was burning through a pre-loaded list of fallback domains, one by one, before eventually falling back to the blockchain as the last resort (last DNS lookup on wireshark trace).
Here's some of the data I've collected while these domains were active:
- darkfot[.]click [145.223.23.25] [AS47583] [Hostinger]
- shhsift[.]click [159.65.136.5] [AS14061][DigitalOcean]
- piarl[.]site [N/A]
By the time I'm writing this report, all of these domains got taken down.
These three domains were, as far as public threat intelligence is concerned, new. They do not appear in any existing Remus report. That makes them the most operationally relevant IOCs from this analysis.
Conclusions
So I'm left with a question worth naming: what exactly is running here? Hell's Gate? Halo's Gate? Some custom syscall stub baked into the Go runtime? Without a confirmed SYSCALL pattern from static analysis or a kernel-level debugger like WinDbg with a live kernel connection, this stays an open question for now.
What I can say with confidence is this: the malware knows it's being watched, or at least knows it's not running on the hardware it expects. And it would rather quit cleanly than give anything away.
That said, walking away empty-handed from the debugger doesn't mean walking away empty-handed from the analysis. The network capture already told the full story: the domains, the timing, the Ethereum callback, the postdata. The debugger was an attempt to go one layer deeper and catch the decryption in memory. It didn't work. But the malware still ran, still reached out, and still left enough evidence behind to attribute it, document it, and report it.
Sometimes the malware wins the battle, but the investigation still wins the war.
REFERENCES
- Netskope Threat Labs — Blockchain Dead Drop Resolvers Explained, Vini Egerland, August 2026 https://www.netskope.com/blog/blockchain-dead-drop-resolvers-explained
- Palo Alto Networks Unit 42 — Remus Info Stealer Uses Blockchain-Anchored C2, July 2026 https://github.com/PaloAltoNetworks/Unit42-timely-threat-intel/blob/main/2026-07-30-Remus-Info-Stealer-Uses-Blockchain-Anchored-C2.txt
- Cyber Intelligence Insights — C2 in the Ether, Vasilis Orlof, April 2026 https://intelinsights.substack.com/p/c2-in-the-ether
- CyberSecurityNews — Remus Hides Its Command Server on Ethereum While Emptying Browser Vaults, August 2026 https://cybersecuritynews.com/remus-hides-its-command-server/
- Etherscan — Contract
0x999941b74F6bbc921D5174A5b29911562cd2D7CFhttps://etherscan.io/address/0x999941b74F6bbc921D5174A5b29911562cd2D7CF - MITRE ATT&CK Framework https://attack.mitre.org
- Cyber Intelligence Insights — C2 in the Ether, Vasilis Orlof, April 2026 https://intelinsights.substack.com/p/c2-in-the-ether
- CyberSecurityNews — Remus Hides Its Command Server on Ethereum While Emptying Browser Vaults, August 2026 https://cybersecuritynews.com/remus-hides-its-command-server/
- Etherscan — Contract
0x999941b74F6bbc921D5174A5b29911562cd2D7CFhttps://etherscan.io/address/0x999941b74F6bbc921D5174A5b29911562cd2D7CF - MITRE ATT&CK Framework https://attack.mitre.org