{
	"id": "d9874e39-e5e9-4361-9365-971017eb5af7",
	"created_at": "2026-04-06T00:15:43.186938Z",
	"updated_at": "2026-04-10T03:37:08.95287Z",
	"deleted_at": null,
	"sha1_hash": "cd006acc6cbd745ba01ad333cbfb070c61a4ecf3",
	"title": "PXA Stealers Evolution to PureRAT: Part 6 - Finally, the Final Stage PureRAT (Stage 9)",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 2698684,
	"plain_text": "PXA Stealers Evolution to PureRAT: Part 6 - Finally, the Final\r\nStage PureRAT (Stage 9)\r\nBy Darkrym\r\nPublished: 2025-09-03 · Archived: 2026-04-05 15:33:27 UTC\r\nIntroduction #\r\nAfter eight stages of obfuscation, loaders, stealers, droppers, and more obfuscation, we’ve arrived at the final\r\npayload. And this one doesn’t disappoint. Stage 9 is where all the scaffolding comes together: an obfuscated\r\n.NET Reactor–protected DLL that unpacks its configuration, establishes a secure channel to its command-and-control (C2) servers, and transforms into a fully fledged remote access trojan (RAT).\r\nIt leverages reflection to hide execution, TLS with pinned certificates for encrypted comms, and Protocol Buffers\r\nto structure its configs and tasking messages. More importantly, it fingerprints the host in detail from antivirus\r\nproducts and OS version, to idle time and crypto wallets before slipping into a modular task loop designed to pull\r\ndown whatever plugins the operator needs.\r\nIf that sounds familiar, it the architecture and feature set line up neatly with PureRAT, a commercial malware\r\nfamily from the PureCoder ecosystem. While marketed as a general-purpose backdoor, in practice PureRAT acts\r\nas a flexible payload letting attackers bolt on other modules as needed.\r\nCatching up where we left off, we’re now dealing with Stage 9 a .NET Reactor–protected DLL, loaded entirely\r\nin-memory by the previous stage’s loader. Unlike traditional DLLs with exported entry points, this one hides\r\nbehind reflection-based invocation, with execution routed through an obfuscated method call.\r\nMhgljosy.Formatting.TransferableFormatter.SelectFormatter()\r\nFIle Name: Mhgljosy.dll SHA265: e0e724c40dd350c67f9840d29fdb54282f1b24471c5d6abb1dca3584d8bac0aa\r\nDetection: No hits on VirusTotal — appears to be previously unknown.\r\nhttps://www.darkrym.com/posts/python_malware_part6/\r\nPage 1 of 22\n\nTraditional static analysis wasn’t viable here .NET Reactor makes life painful, filling binaries with junk logic,\r\ncontrol-flow flattening, and encrypted strings. Dynamic analysis was the obvious path forward: let the loader drop\r\nthe DLL into memory, attach dnSpy to the live process, and throw some breakpoints at key points inside the DLL.\r\nBut I’m still a sucker for static, so before switching gears I gave automated deobfuscators a shot. I cycled through\r\na handful of them with limited results, until a colleague (shoutout to @RussianPanda9xx) suggested trying\r\nNETReactorSlayer:\r\nhttps://github.com/SychicBoy/NETReactorSlayer\r\nAnd it worked.\r\nThe tool stripped away enough layers of obfuscation to leave us with something far more legible. With the clutter\r\nreduced, we can use dnSpy to poke around again.\r\nhttps://www.darkrym.com/posts/python_malware_part6/\r\nPage 2 of 22\n\nNETReactorSlayer is straightforward to use: open the GUI, select your binary, and run it. It prints a log of what it\r\nis doing:\r\n [INFO] 7844 Proxied calls fixed.\r\n [INFO] 1078 Strings decrypted.\r\n [INFO] 587 Calls to obfuscator types removed.\r\n [INFO] Renaming obfuscated symbols...\r\nThe key part here are symbol renaming, string decryption, and removing control-flow redirection. Together they\r\nturn a spaghetti mess into something you can actually read, navigate and debug.\r\nBack to dnSpy #\r\nJumping back to Mhgljosy.Formatting.TransferableFormatter.SelectFormatter() in dnSpy, we can see what it\r\nlooks like now. Still doesn’t make a tonne of sense, right? Well, it’s not a magic bullet you don’t get the answer on\r\na silver platter. But trust me, this is soooooooo much better than what we had before. And once you start clicking\r\naround, the surrounding code begins to open up and make a lot more sense.\r\nAppDomain.CurrentDomain.UnhandledException += transferableFormatter.PostFormatter;\r\nhttps://www.darkrym.com/posts/python_malware_part6/\r\nPage 3 of 22\n\nSubscriberSpec.ReceiveAttachedSubscriber();\r\nThis simply tell the assembly to run PostFormatter whenever it encounters and error, then it runs\r\nSubscriberSpec.ReceiveAttachedSubscriber(); . That makes ReceiveAttachedSubscriber our next pivot,\r\nwhile the exception handler is worth keeping in mind it could be abused to trigger PostFormatter deliberately.\r\nIn ReceiveAttachedSubscriber we immediately hit a base64 blob alongside the target method. Before diving\r\ninto the method itself, lets quickly decode that blob as it might give us some quick wins.\r\nThe decoded output shows a GZip header. Easy enough we just add a GZip decompress stage into the recipe and\r\nrun it again.\r\nhttps://www.darkrym.com/posts/python_malware_part6/\r\nPage 4 of 22\n\nIt’s looking better, but still not quite there. To see what we’re missing, we check how the assembly itself handles\r\nit, right after the blob is decoded, it’s handed off to FormatConcreteFormatter() .\r\nThat Serializer.Deserialize\u003cT\u003e() call comes from protobuf-net, a well-known .NET implementation of\r\nGoogle’s Protocol Buffers. So the attacker isn’t just cramming raw bytes into a struct they’re using a proper\r\nprotobuf schema under the hood. Now lets add protobuf decoding to the recipe.\r\nhttps://www.darkrym.com/posts/python_malware_part6/\r\nPage 5 of 22\n\nThe config gives us an IP address, what look like port numbers, another base64 blob in the middle, and a few\r\nstrings tacked on at the end. Decoding that blob next, we get:\r\nFrom the bytes 30 82 04 ea we can recognise ASN.1 DER (Distinguished Encoding Rules) encoding, most\r\ncommonly used in X.509 certificates, PKCS#7/PKCS#12 bundles, or private key blobs.\r\nSure enough, looking back at the .NET assembly we see that just beneath the blob it’s instantiating an X.509\r\ncertificate. For the uninitiated, this is a standardised format defining the structure of a public key certificate.\r\nThat already starts to shape our understanding of what ReceiveAttachedSubscriber is really doing.\r\nInside the C2 Function #\r\nJumping back into the method and scrolling down, it becomes clear that its primary job is to set up a connection.\r\nhttps://www.darkrym.com/posts/python_malware_part6/\r\nPage 6 of 22\n\nI’m going to explain the full function up front, since it helps frame the rest of the analysis and we’ll dive into\r\ndetails as needed. The routine establishes a persistent TCP socket wrapped in an SslStream with custom\r\ncertificate validation, tunnelling all traffic over TLS. It operates in a reconnect loop: after a short delay it\r\ndisposes of any stale connection, spins up a new socket, and retries against one of its configured servers. Once\r\nconnected, it sends an initial “hello,” starts a randomised 20–40 second keepalive timer, and enters a read loop that\r\ncontinuously processes new messages\\commands. Each incoming message is dispatched to a new thread, allowing\r\ntasks to run in parallel.\r\nBut were does the server details actually come from? The remote IP and port aren’t visible in plaintext. We already\r\nspotted an IP address earlier, so the next step is to trace its usage. Right-clicking on subscriberSharer (the field\r\nholding that base64 blob) and selecting Analyse shows us:\r\nThis view shows us everything that touches our base64 blob. In blue is a little spoiler for what’s coming, I’ll let\r\nyou guess what PureHVNC might be for now.\r\nMore importantly, in red we can see that the blob is used by the MergeSubscriber method, which is called from\r\nthe ReceiveAttachedSubscriber routine we’re currently dissecting. So the next logical step is to dive into\r\nMergeSubscriber .\r\nhttps://www.darkrym.com/posts/python_malware_part6/\r\nPage 7 of 22\n\nIt’s a straightforward but very telling loop:\r\n1. Iterate over endpoints from subscriberSharer.ReflectChooser (Our config from earlier).\r\nHostnames are resolved via DNS to all A records.\r\nRaw IPs skip DNS and are used directly.\r\n2. Iterate over ports from subscriberSharer.AddChooser .\r\nFor each host/port pair, it attempts a connection with\r\nSubscriberSpec.m_BasicProfile.Connect(...) .\r\n3. Success short-circuit – The first successful connection returns true , handing control back to\r\nReceiveAttachedSubscriber to set up the TLS stream.\r\nThis is textbook C2 pivoting behaviour. Rather than relying on a single hard-coded server, the malware cycles\r\nthrough multiple domains and ports until one responds, making takedown harder.\r\n\"1\": \"157.66.26.209\",\r\n\"2\": [\r\n56001,\r\n56002,\r\n56003\r\nAlthough, in our sample only a single address is present, but the framework clearly supports a broader, more\r\nresilient infrastructure.\r\nPulling the IP address up in Shodan shows it belongs to a Windows server in Vietnam. If you think back to Stage\r\n5, we were already tracing links that pointed toward a Vietnamese actor using the handle “Lone None.” This fits\r\nneatly with that earlier lead and strengthens the attribution thread.\r\nhttps://www.darkrym.com/posts/python_malware_part6/\r\nPage 8 of 22\n\nSo once the connection is established — what happens next? #\r\nIn the middle of the function there’s a big cluster of methods, this is where the real action kicks off. Let’s step\r\nthrough them and see what they’re doing.\r\nThe first call we hit is RequestSetSubscriber()\r\nThis method queries Windows Management Instrumentation (WMI) under root\\SecurityCenter2 for the\r\nclass AntiVirusProduct . It loops through the results and pulls the displayName values (e.g., Windows\r\nhttps://www.darkrym.com/posts/python_malware_part6/\r\nPage 9 of 22\n\nDefender, Kaspersky, etc.). If nothing is found, it falls back to \"N/A\" .\r\nIn short, it fingerprints the host’s security software and reports it back, giving the operator immediate awareness of\r\nwhat protections are in place.\r\nThe next call is PlaySubscriber() :\r\nThis routine gathers a set of hardware identifiers ( Win32_Processor.ProcessorId ,\r\nWin32_DiskDrive.SerialNumber , Win32_PhysicalMemory.SerialNumber ), then appends environment data such\r\nas the Windows domain name and the output of ParseSubscriber() . That helper method pulls\r\nEnvironment.UserName and, if available, Environment.UserDomainName , formatting it like user[DOMAIN] .\r\nThe full string is then fed into FormatterCompressor.FormatRandomExplorer(...) , which is simply a MD5 hash\r\nfunction. The result is cached in uppercase for consistency.\r\nIn short: PlaySubscriber() generates a stable, pseudo-unique fingerprint for the victim host by combining\r\nhardware serials with user/domain info, letting the C2 reliably distinguish between different machines.\r\nThen comes ListenConvertibleSubscriber()\r\nThis method checks whether the host has a camera/webcam. It queries WMI ( Win32_PnPEntity ) for devices\r\nwhere PNPClass is Image or Camera , grabs their Caption names, and returns true if any are found.\r\nIn short: it tells the C2 if webcam capture is an option on the compromised machine.\r\nhttps://www.darkrym.com/posts/python_malware_part6/\r\nPage 10 of 22\n\nUp Next: ParseSubscriber()\r\nThis method works as a user identity probe feeding into the host fingerprint we saw earlier. On its first run it\r\ninitialises m_FactoryProgramCategory , then sets the value to the current Environment.UserName . If a domain\r\nname is available it appends Environment.UserDomainName , formatting the result as username[DOMAIN] , but\r\nonly if it passes a null or empty check via SendConcreteCalc() .\r\nIn Short: ParseSubscriber() collects the logged-in username (and optionally the domain), giving the operator\r\ncontext about who is on the host.\r\nThen we meet ListenCombinedSubscriber() :\r\nhttps://www.darkrym.com/posts/python_malware_part6/\r\nPage 11 of 22\n\nThis method pulls the WindowsIdentity of the running process, wraps it in a WindowsPrincipal , and checks it\r\nagainst a list of built-in Windows roles in descending order of importance: Administrator , User , Guest ,\r\nSystemOperator , AccountOperator , BackupOperator , PowerUser , PrintOperator , and Replicator . If it\r\nfinds a match, it returns the role name as a string; if none match or an error occurs, it falls back to \"Unknown\" .\r\nIn short: it reports what kind of Windows account the malware is running under, letting the C2 operator know\r\nwhether they have admin privileges.\r\nIt then sends a hard-coded version string, \"4.1.9\" .\r\nSummary: the malware identifies itself to the C2 with a fixed version number, likely used by the operator to track\r\nbuilds or maintain compatibility.\r\nNext is ListenAutomatedSubscriber()\r\nhttps://www.darkrym.com/posts/python_malware_part6/\r\nPage 12 of 22\n\nThis method queries WMI ( Win32_OperatingSystem ) for the Caption field, which usually returns strings such\r\nas “Microsoft Windows 10 Pro” or “Windows Server 2019 Datacenter.” It then normalises the name by checking\r\nfor substrings: 7 , 8 , 8.1 , 10 , and 11 are mapped to their corresponding Windows desktop releases, while\r\n2012 , 2016 , 2019 , and 2022 are mapped to Windows Server editions. Finally, it appends the system\r\narchitecture ( 32Bit or 64Bit ) using Environment.Is64BitOperatingSystem .\r\nSummary: ListenAutomatedSubscriber() fingerprints the victim’s OS and formats it into a clean label such as\r\n“Windows 10 64Bit”, which is later reported back to the C2.\r\nIt gets intresting with, RemoveSelector()\r\nThis method builds a profile of installed wallets and messaging apps by searching registry keys, file system\r\npaths, and browser extension IDs. It starts with a dictionary of known Chrome/Chromium extension IDs for\r\ncryptocurrency wallets, then checks common browser profile paths to see if any are present. It also scans for\r\nhttps://www.darkrym.com/posts/python_malware_part6/\r\nPage 13 of 22\n\nlocal storage folders and registry keys tied to desktop wallets, and even looks for non-wallet apps that are\r\nfrequent credential targets such as Foxmail and Telegram Desktop.\r\nImportantly, this function doesn’t actually perform the theft itself it only enumerates what’s installed.\r\nSummary: This fingerprints the system for crypto wallets and select comms apps, returning a list like\r\n“MetaMask, Exodus, Ledger Live, Telegram”. This helps the attacker quickly identify and prioritise high-value\r\nvictims.\r\nNext, FillSelector()\r\nThis method works as an idle-time probe. It calls the Windows GetLastInputInfo API to grab the timestamp of\r\nthe last keyboard or mouse event, subtracts that from the current system tick count, and formats the result into a\r\nhuman-readable Xd Yh Zm Ws string. If the call fails, it just returns \"-1\" .\r\nSummary: FillSelector() reports how long the machine has been idle, letting the C2 operator gauge whether\r\nthe victim is actively using the system and time actions like data theft or screen capture for when the user is away.\r\nFinally, ListenSegmentedSubscriber()\r\nThis one is straightforward it simply reports the malware’s own executable path, giving the C2 operator visibility\r\ninto exactly where on disk the binary is running.\r\nTo make the picture clearer, I renamed the methods based on what we’ve uncovered:\r\nhttps://www.darkrym.com/posts/python_malware_part6/\r\nPage 14 of 22\n\nOne detail worth noting is .RestartChooser , which resolves to the value APPDATA pulled straight from the\r\nconfig decoded earlier.\r\nRecap: What ReceiveAttachedSubscriber() Does #\r\nAt its core, ReceiveAttachedSubscriber() is the main client loop that establishes, maintains, and manages\r\ncommunication with the C2. It starts by unpacking configuration data and setting up its environment before\r\nmoving into a persistent connect–retry cycle.\r\nConfiguration Load – The routine unpacks the embedded protobuf blob, applies execution gates, and\r\nspins up optional helper threads if flags are set.\r\nConnection Loop – After a short delay it disposes of any old sockets and repeatedly attempts to connect to\r\nthe configured C2 hosts and ports. Each attempt begins with a probe, then upgrades to TLS with certificate\r\npinning against the embedded X.509 certificate.\r\nOnce a connection succeeds, the malware performs a detailed handshake, sending back a structured metadata\r\nobject ( ExternalFormatter ) that fingerprints the victim machine:\r\nInstalled antivirus products\r\nA stable host ID (hardware + user/domain info, MD5’d)\r\nWebcam presence\r\nUsername and domain\r\nAccount privileges (Admin/User/etc.)\r\nOS version and architecture\r\nCrypto wallet and comms app reconnaissance\r\nSystem idle time\r\nThe implant’s executable path\r\nCampaign/config tag ( RestartChooser , e.g. “APPDATA”)\r\nThe active C2 IP and port\r\nFrom there, the client keeps the session alive with a randomised 20–40 second keepalive timer while listening\r\nfor tasks.\r\nhttps://www.darkrym.com/posts/python_malware_part6/\r\nPage 15 of 22\n\nTasking Loop – It continuously receives length-prefixed protobuf messages from the C2. Each message\r\nis deserialized and executed on a separate worker thread.\r\nResilience – Any error or disconnect triggers a full cleanup and restarts the loop, ensuring persistence.\r\nTasking Loop #\r\nWe’ve spent most of our time unpacking the handshake and connection setup, but we haven’t dug into the task\r\nloop yet. That’s where the real functionality lives once the session is established, this loop is responsible for\r\npulling commands from the C2 and dispatching them for execution. Let’s focus on that in the next portion.\r\nThe task loop is fairly straightforward once unpacked:\r\n1. (Red) Read the first 4 bytes to determine the payload length.\r\n2. (Blue) Read that many bytes into a buffer — this is the actual payload.\r\n3. (Green) Deserialize the buffer with the protobuf routine we saw earlier:\r\nPassiveFormatter.FormatConcreteFormatter(...) .\r\n4. (Green) Spawn a new thread and call DecideFlexibleController() on the message to execute the task.\r\nIt’s pretty clear this is a command-and-control loop, structured, threaded, and designed to process arbitrary\r\ninstructions from the operator.\r\nhttps://www.darkrym.com/posts/python_malware_part6/\r\nPage 16 of 22\n\nYou might remember the earlier references to PureHVNC. Jumping into the assembly explorer, we can see\r\nseveral namespaces tied to PureHVNC components, strong evidence that this sample is tied to Pure Hidden VNC.\r\nWhile PureHVNC is now considered legacy, many of its modules live on in PureCoder’s newer malware\r\nfamilies, each designed to serve a specific purpose:\r\nPureCrypter – a crypter used to inject malware into legitimate processes, evade detection, and frustrate\r\nanalysis with anti-VM and anti-debug checks.\r\nPureMiner – a silent cryptojacker that hijacks the victim’s CPU and GPU resources to mine\r\ncryptocurrency for the attacker without consent.\r\nPureLogs Stealer – an information stealer that exfiltrates browser data, saved credentials, and session\r\ntokens, often delivering them directly to the attacker’s Telegram.\r\nBlueLoader – a loader that deploys additional payloads on infected systems, giving attackers an easy\r\nway to stage and update malware campaigns.\r\nPureRAT – a modular backdoor that establishes an encrypted C2 channel, and allows operators to\r\nload additional modules\r\nThis sample appears to be PureRAT, a backdoor designed to let attackers load in different malicious modules.\r\nThe developer openly advertised this tool as a custom-coded .NET remote administration tool, with a lightweight,\r\nTLS/SSL-encrypted client and multilingual GUI, offering extensive surveillance and control features such as\r\nhidden desktop access (HVNC/HRDP), webcam and microphone spying, real-time and offline keylogging, remote\r\nCMD, and application monitoring (e.g., browsers, Outlook, Telegram, Steam). It includes management tools like\r\nfile, process, registry, network, and startup managers, plus capabilities for DDoS attacks, reverse proxying, .NET\r\ncode injection, streaming bot management, and execution of files in memory or disk. Though it notably “excludes\r\npassword/cookie recovery” (Stealer Functionality) as that is sold separately.\r\nhttps://www.darkrym.com/posts/python_malware_part6/\r\nPage 17 of 22\n\nAs we have discovered in our analysis, once installed, it establishes an SSL-encrypted C2 channel and begins\r\nexfiltrating host details.\r\nAfter initial reconnaissance, it enters a task loop where the operator can push new modules on demand,\r\ndynamically expanding the malware’s capabilities for surveillance, and remote control.\r\nUnfortunately, my analysis ends here, as I was unable to obtain any samples of the threat actors’ plugins.\r\nClosing Thoughts: From Fake PDFs to PureRAT #\r\nAcross nine stages, this campaign evolved from humble beginnings into a fully weaponised, modular ecosystem.\r\nEach stage peeled back another layer of the attacker’s tradecraft, and together they paint a clear picture of a\r\ndetermined and technically adept adversary.\r\nStage 1–2 (Part 1) – The operation began with a phishing lure disguised as a copyright notice. Through\r\nDLL sideloading, BYOB (WinRAR), and LOLBIN abuse ( certutil ), the actor achieved stealthy initial\r\nexecution. These stages showed early reliance on trusted binaries and simple obfuscation to quietly\r\nestablish a foothold.\r\nStage 3–4 (Part 2) – Obfuscated Python scripts evolved into Base85-encoded bytecode and marshalled\r\npayloads, executed entirely in memory. These stages revealed the actor’s custom cryptographic loaders,\r\nmulti-layered obfuscation, and heavy use of dynamic execution to frustrate static analysis.\r\nStage 5 (Part 3) – The first weaponised payload appeared: a Python-based infostealer. It targeted\r\nChrome/Firefox data, enumerated AV via WMI, and exfiltrated archives to Telegram channels tied to the\r\nhttps://www.darkrym.com/posts/python_malware_part6/\r\nPage 18 of 22\n\nhandle @LoneNone. This stage cemented attribution links to PXA Stealer while hinting at a Vietnamese\r\noperator.\r\nStage 6–7 (Part 4) – A turning point. The actor pivoted from Python to compiled Windows executables.\r\nUsing hybrid cryptography (RC4 + Base64), process hollowing ( RegAsm.exe ), and in-memory shellcode\r\ninjection, they delivered a packed .NET loader (Stage 7). This loader featured AMSI patching, ETW\r\nunhooking, and modular reflection-based loading, showing some serious runtime evasion.\r\nStage 8 (Part 5) – The complexity escalated with AES-encrypted payloads, GZip compression, and .NET\r\nreflection loaders. Payloads were hidden in memory-only byte arrays, decrypted at runtime, and executed\r\nwithout exports or disk artifacts. Dynamic memory dumping revealed Mhgljosy.dll, protected with .NET\r\nReactor, confirming the use of commercial protections to frustrate analysts.\r\nStage 9 (Part 6) – At last, the final payload emerged: PureRAT. With TLS C2 communications, protobuf-based configs, fingerprinting of AV, OS, users, crypto wallets, and privilege levels, it transformed into a\r\nflexible RAT with modular plugin support. Links to the PureCoder ecosystem (PureRAT, PureHVNC,\r\nPureCrypter, PureLogs, BlueLoader, etc.) demonstrate that the campaign was not a one-off but part of a\r\nbroader, evolving threat actor going from their own payloads to off-the-shelf RAT’s.\r\nThe Actors Behind the Curtain #\r\nThe recurring Telegram infrastructure, metadata linking to @LoneNone, and C2 servers traced to Vietnam\r\nstrongly suggest a Vietnamese threat actor. Their progression from amateurish obfuscation to abusing\r\nprofessional-grade tools like .NET Reactor shows not just persistence, but also access to commercial malware\r\ntooling hallmarks of a serious and maturing operator.\r\nMalware Families \u0026 Ecosystem #\r\nCustom Python Loaders (Stage 2–4) – staged bytecode, cryptographic loaders\r\nPXA Stealer (Stage 5) – early infostealer variant\r\n.NET Loaders (Stage 6–8) – modular reflection-based loaders.\r\nPureRAT (Stage 9) – final payload, a full-featured backdoor tied to the PureCoder ecosystem\r\nConclusion #\r\nWhat began as a fake PDF quickly escalated into a multi-language, multi-stage, and multi-family operation that\r\nchained together Python, .NET, and commercial RAT tooling. The campaign demonstrates a clear trajectory:\r\nStealthy entry → Layered loaders → Credential theft → Runtime evasion → Full-featured RAT.\r\nFrom opportunistic phishing to a professional PureRAT deployment, this campaign reflects not only the creativity\r\nof its operator, but also the shifting threat landscape, where commodity malware families, custom loaders, and C2\r\necosystems converge into a single, resilient attack chain.\r\nhttps://www.darkrym.com/posts/python_malware_part6/\r\nPage 19 of 22\n\nAnnex A: Software and Artefacts Enumerated by RemoveSelector() #\r\nA) Browser-based wallets and auth extensions (by Chrome/Chromium extension ID)\r\n- ibnejdfjmmkpcnlpebklmnkoeoihofec → TronLink\r\n- nkbihfbeogaeaoehlefnkodbefgpgknn → MetaMask\r\n- fhbohimaelbohpjbbldcngcnapndodjp → Binance Chain Wallet\r\n- ffnbelfdoeiohenkjibnmadjiehjhajb → Yoroi\r\n- cjelfplplebdjjenllpjcblmjkfcffne → Jaxx Liberty\r\n- fihkakfobkmkjojpchpfgcmhfjnmnfpi → BitApp Wallet\r\n- kncchdigobghenbbaddojjnnaogfppfj → iWallet\r\n- aiifbnbfobpmeekipheeijimdpnlpgpp → Terra Station\r\n- ijmpgkjfkbfhoebgogflfebnmejmfbml → BitClip\r\n- blnieiiffboillknjnepogjhkgnoapac → EQUAL Wallet\r\n- amkmjjmmflddogmhpjloimipbofnfjih → Wombat\r\n- jbdaocneiiinmjbjlgalhcelgbejmnid → Nifty Wallet\r\n- afbcbjpbpfadlkmhmclhkeeodmamcflc → Math Wallet\r\n- hpglfhgfnhbgpjdenjgmdgoeiappafln → Guarda\r\n- aeachknmefphepccionboohckonoeemg → Coin98 Wallet\r\n- imloifkgjagghnncjkhggdhalmcnfklk → Trezor Password Manager\r\n- oeljdldpnmdbchonielidgobddffflal → EOS Authenticator\r\n- gaedmjdfmmahhbjefcbgaolhhanlaolb → Authy\r\n- ilgcnhelpchnceeipipijaljkblbcobl → GAuth Authenticator\r\n- bhghoamapcdpbohphigoooaddinpkbai → Authenticator\r\n- mnfifefkajgofkcjkemidiaecocnkjeh → TezBox\r\n- dkdedlpgdmmkkfjabffeganieamfklkm → Cyano Wallet\r\n- aholpfdialjgjfhomihkjbmgjidlcdno → Exodus Web3\r\n- jiidiaalihmmhddjgbnbgdfflelocpak → BitKeep\r\n- hnfanknocfeofbddgcijnmhnfnkdnaad → Coinbase Wallet\r\n- egjidjbpglichdcondbcbdnbeeppgdph → Trust Wallet\r\n- hmeobnfnfcmdkdcmlblgagmfpfboieaf → XDEFI Wallet\r\n- bfnaelmomeimhlpmgjnjophhpkkoljpa → Phantom\r\n- fcckkdbjnoikooededlapcalpionmalo → MOBOX WALLET\r\n- bocpokimicclpaiekenaeelehdjllofo → XDCPay\r\n- flpiciilemghbmfalicajoolhkkenfel → ICONex\r\n- hfljlochmlccoobkbcgpmkpjagogcgpk → Solana Wallet\r\n- cmndjbecilbocjfkibfbifhngkdmjgog → Swash\r\n- cjmkndjhnagcfbpiemnkdpomccnjblmj → Finnie\r\n- dmkamcknogkgcdfhhbddcghachkejeap → Keplr\r\n- kpfopkelmapcoipemfendmdcghnegimn → Liquality Wallet\r\n- hgmoaheomcjnaheggkfafnjilfcefbmo → Rabet\r\n- fnjhmkhhmkbjkkabndcnnogagogbneec → Ronin Wallet\r\n- klnaejjgbibmhlephnhpmaofohgkpgkd → ZilPay\r\n- ejbalbakoplchlghecdalmeeeajnimhm → MetaMask (alt ID)\r\n- ghocjofkdpicneaokfekohclmkfmepbp → Exodus Web3 (alt ID)\r\nhttps://www.darkrym.com/posts/python_malware_part6/\r\nPage 20 of 22\n\n- heaomjafhiehddpnmncmhhpjaloainkn → Trust Wallet (alt ID)\r\n- hkkpjehhcnhgefhbdcgfkeegglpjchdc → Braavos Smart Wallet\r\n- akoiaibnepcedcplijmiamnaigbepmcb → Yoroi (alt ID)\r\n- djclckkglechooblngghdinmeemkbgci → MetaMask (alt ID)\r\n- acdamagkdfmpkclpoglgnbddngblgibo → Guarda Wallet\r\n- okejhknhopdbemmfefjglkdfdhpfmflg → BitKeep (alt ID)\r\n- mijjdbgpgbflkaooedaemnlciddmamai → Waves Keeper\r\nB) Browser profile roots checked (where it searches for those extensions)\r\n- Chromium\\User Data\\ → Chromium\r\n- Google\\Chrome\\User Data\\ and Google(x86)\\Chrome\\User Data\\ → Chrome\r\n- BraveSoftware\\Brave-Browser\\User Data\\ → Brave\r\n- Microsoft\\Edge\\User Data\\ → Edge\r\n- Tencent\\QQBrowser\\User Data\\ → QQBrowser\r\n- MapleStudio\\ChromePlus\\User Data\\ → ChromePlus\r\n- Iridium\\User Data\\ → Iridium\r\n- 7Star\\7Star\\User Data\\ → 7Star\r\n- CentBrowser\\User Data\\ → CentBrowser\r\n- Chedot\\User Data\\ → Chedot\r\n- Vivaldi\\User Data\\ → Vivaldi\r\n- Kometa\\User Data\\ → Kometa\r\n- Elements Browser\\User Data\\ → Elements\r\n- Epic Privacy Browser\\User Data\\ → Epic Privacy\r\n- uCozMedia\\Uran\\User Data\\ and Uran\\User Data\\ → Uran\r\n- Fenrir Inc\\Sleipnir5\\setting\\modules\\ChromiumViewer\\ → Sleipnir5\r\n- CatalinaGroup\\Citrio\\User Data\\ → Citrio\r\n- Coowon\\Coowon\\User Data\\ → Coowon\r\n- liebao\\User Data\\ → liebao\r\n- QIP Surf\\User Data\\ → QIP Surf\r\n- Orbitum\\User Data\\ → Orbitum\r\n- Comodo\\Dragon\\User Data\\ → Dragon\r\n- Amigo\\User\\User Data\\ → Amigo\r\n- Torch\\User Data\\ → Torch\r\n- Comodo\\User Data\\ → Comodo\r\n- 360Browser\\Browser\\User Data\\ → 360Browser\r\n- Maxthon3\\User Data\\ → Maxthon\r\n- K-Melon\\User Data\\ → K-Melon\r\n- Sputnik\\Sputnik\\User Data\\ → Sputnik\r\n- Nichrome\\User Data\\ → Nichrome\r\n- CocCoc\\Browser\\User Data\\ → CocCoc\r\n- Chromodo\\User Data\\ → Chromodo\r\n- Mail.Ru\\Atom\\User Data\\ → Atom\r\nC) Desktop wallets and related apps (filesystem checks under %APPDATA%)\r\n- atomic\\Local Storage\\leveldb → Atomic Wallet\r\nhttps://www.darkrym.com/posts/python_malware_part6/\r\nPage 21 of 22\n\n- Electrum\\wallets → Electrum\r\n- Ethereum\\keystore → Ethereum (keystore)\r\n- Exodus\\exodus.wallet → Exodus\r\n- com.liberty.jaxx\\IndexedDB → Jaxx\r\n- Zcash\\ → Zcash\r\n- Telegram Desktop\\Telegram.exe → Telegram Desktop\r\n- Root of system drive contains a directory named “Foxmail” → Foxmail\r\nD) Desktop wallets (registry → path lookup)\r\n- HKCU\\Software\\Bitcoin\\Bitcoin-Qt → read `strDataDir`, then check ...\\wallets exists → Bitcoin-Qt\r\n- HKCU\\Software\\Dash\\Dash-Qt → read `strDataDir`, then check the directory exists → Dash-Qt\r\n- HKCU\\Software\\Litecoin\\Litecoin-Qt → read `strDataDir`, then check the directory exists → Litecoin-Qt\r\nE) Program Files (x64) check\r\n- %ProgramFiles%\\Ledger Live\\Ledger Live.exe → Ledger Live\r\nReply by Email\r\nSource: https://www.darkrym.com/posts/python_malware_part6/\r\nhttps://www.darkrym.com/posts/python_malware_part6/\r\nPage 22 of 22",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://www.darkrym.com/posts/python_malware_part6/"
	],
	"report_names": [
		"python_malware_part6"
	],
	"threat_actors": [
		{
			"id": "0661a292-80f3-420b-9951-a50e03c831c0",
			"created_at": "2023-01-06T13:46:38.928796Z",
			"updated_at": "2026-04-10T02:00:03.148052Z",
			"deleted_at": null,
			"main_name": "IRIDIUM",
			"aliases": [],
			"source_name": "MISPGALAXY:IRIDIUM",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "9f101d9c-05ea-48b9-b6f1-168cd6d06d12",
			"created_at": "2023-01-06T13:46:39.396409Z",
			"updated_at": "2026-04-10T02:00:03.312816Z",
			"deleted_at": null,
			"main_name": "Earth Lusca",
			"aliases": [
				"CHROMIUM",
				"ControlX",
				"TAG-22",
				"BRONZE UNIVERSITY",
				"AQUATIC PANDA",
				"RedHotel",
				"Charcoal Typhoon",
				"Red Scylla",
				"Red Dev 10",
				"BountyGlad"
			],
			"source_name": "MISPGALAXY:Earth Lusca",
			"tools": [
				"RouterGod",
				"SprySOCKS",
				"ShadowPad",
				"POISONPLUG",
				"Barlaiy",
				"Spyder",
				"FunnySwitch"
			],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "f8dddd06-da24-4184-9e24-4c22bdd1cbbf",
			"created_at": "2023-01-06T13:46:38.626906Z",
			"updated_at": "2026-04-10T02:00:03.043681Z",
			"deleted_at": null,
			"main_name": "Tick",
			"aliases": [
				"G0060",
				"Stalker Taurus",
				"PLA Unit 61419",
				"Swirl Typhoon",
				"Nian",
				"BRONZE BUTLER",
				"REDBALDKNIGHT",
				"STALKER PANDA"
			],
			"source_name": "MISPGALAXY:Tick",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "8941e146-3e7f-4b4e-9b66-c2da052ee6df",
			"created_at": "2023-01-06T13:46:38.402513Z",
			"updated_at": "2026-04-10T02:00:02.959797Z",
			"deleted_at": null,
			"main_name": "Sandworm",
			"aliases": [
				"IRIDIUM",
				"Blue Echidna",
				"VOODOO BEAR",
				"FROZENBARENTS",
				"UAC-0113",
				"Seashell Blizzard",
				"UAC-0082",
				"APT44",
				"Quedagh",
				"TEMP.Noble",
				"IRON VIKING",
				"G0034",
				"ELECTRUM",
				"TeleBots"
			],
			"source_name": "MISPGALAXY:Sandworm",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "7bd810cb-d674-4763-86eb-2cc182d24ea0",
			"created_at": "2022-10-25T16:07:24.1537Z",
			"updated_at": "2026-04-10T02:00:04.883793Z",
			"deleted_at": null,
			"main_name": "Sandworm Team",
			"aliases": [
				"APT 44",
				"ATK 14",
				"BE2",
				"Blue Echidna",
				"CTG-7263",
				"FROZENBARENTS",
				"G0034",
				"Grey Tornado",
				"IRIDIUM",
				"Iron Viking",
				"Quedagh",
				"Razing Ursa",
				"Sandworm",
				"Sandworm Team",
				"Seashell Blizzard",
				"TEMP.Noble",
				"UAC-0082",
				"UAC-0113",
				"UAC-0125",
				"UAC-0133",
				"Voodoo Bear"
			],
			"source_name": "ETDA:Sandworm Team",
			"tools": [
				"AWFULSHRED",
				"ArguePatch",
				"BIASBOAT",
				"Black Energy",
				"BlackEnergy",
				"CaddyWiper",
				"Colibri Loader",
				"Cyclops Blink",
				"CyclopsBlink",
				"DCRat",
				"DarkCrystal RAT",
				"Fobushell",
				"GOSSIPFLOW",
				"Gcat",
				"IcyWell",
				"Industroyer2",
				"JaguarBlade",
				"JuicyPotato",
				"Kapeka",
				"KillDisk.NCX",
				"LOADGRIP",
				"LOLBAS",
				"LOLBins",
				"Living off the Land",
				"ORCSHRED",
				"P.A.S.",
				"PassKillDisk",
				"Pitvotnacci",
				"PsList",
				"QUEUESEED",
				"RansomBoggs",
				"RottenPotato",
				"SOLOSHRED",
				"SwiftSlicer",
				"VPNFilter",
				"Warzone",
				"Warzone RAT",
				"Weevly"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "75455540-2f6e-467c-9225-8fe670e50c47",
			"created_at": "2022-10-25T16:07:23.740266Z",
			"updated_at": "2026-04-10T02:00:04.732992Z",
			"deleted_at": null,
			"main_name": "Iridium",
			"aliases": [],
			"source_name": "ETDA:Iridium",
			"tools": [
				"CHINACHOPPER",
				"China Chopper",
				"LazyCat",
				"Powerkatz",
				"SinoChopper",
				"reGeorg"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "3a0be4ff-9074-4efd-98e4-47c6a62b14ad",
			"created_at": "2022-10-25T16:07:23.590051Z",
			"updated_at": "2026-04-10T02:00:04.679488Z",
			"deleted_at": null,
			"main_name": "Energetic Bear",
			"aliases": [
				"ATK 6",
				"Blue Kraken",
				"Crouching Yeti",
				"Dragonfly",
				"Electrum",
				"Energetic Bear",
				"G0035",
				"Ghost Blizzard",
				"Group 24",
				"ITG15",
				"Iron Liberty",
				"Koala Team",
				"TG-4192"
			],
			"source_name": "ETDA:Energetic Bear",
			"tools": [
				"Backdoor.Oldrea",
				"CRASHOVERRIDE",
				"Commix",
				"CrackMapExec",
				"CrashOverride",
				"Dirsearch",
				"Dorshel",
				"Fertger",
				"Fuerboos",
				"Goodor",
				"Havex",
				"Havex RAT",
				"Hello EK",
				"Heriplor",
				"Impacket",
				"Industroyer",
				"Karagany",
				"Karagny",
				"LightsOut 2.0",
				"LightsOut EK",
				"Listrix",
				"Oldrea",
				"PEACEPIPE",
				"PHPMailer",
				"PsExec",
				"SMBTrap",
				"Subbrute",
				"Sublist3r",
				"Sysmain",
				"Trojan.Karagany",
				"WSO",
				"Webshell by Orb",
				"Win32/Industroyer",
				"Wpscan",
				"nmap",
				"sqlmap",
				"xFrost"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "54e55585-1025-49d2-9de8-90fc7a631f45",
			"created_at": "2025-08-07T02:03:24.563488Z",
			"updated_at": "2026-04-10T02:00:03.715427Z",
			"deleted_at": null,
			"main_name": "BRONZE BUTLER",
			"aliases": [
				"CTG-2006 ",
				"Daserf",
				"Stalker Panda ",
				"Swirl Typhoon ",
				"Tick "
			],
			"source_name": "Secureworks:BRONZE BUTLER",
			"tools": [
				"ABK",
				"BBK",
				"Casper",
				"DGet",
				"Daserf",
				"Datper",
				"Ghostdown",
				"Gofarer",
				"MSGet",
				"Mimikatz",
				"Netboy",
				"RarStar",
				"Screen Capture Tool",
				"ShadowPad",
				"ShadowPy",
				"T-SMB",
				"down_new",
				"gsecdump"
			],
			"source_id": "Secureworks",
			"reports": null
		},
		{
			"id": "a66438a8-ebf6-4397-9ad5-ed07f93330aa",
			"created_at": "2022-10-25T16:47:55.919702Z",
			"updated_at": "2026-04-10T02:00:03.618194Z",
			"deleted_at": null,
			"main_name": "IRON VIKING",
			"aliases": [
				"APT44 ",
				"ATK14 ",
				"BlackEnergy Group",
				"Blue Echidna ",
				"CTG-7263 ",
				"ELECTRUM ",
				"FROZENBARENTS ",
				"Hades/OlympicDestroyer ",
				"IRIDIUM ",
				"Qudedagh ",
				"Sandworm Team ",
				"Seashell Blizzard ",
				"TEMP.Noble ",
				"Telebots ",
				"Voodoo Bear "
			],
			"source_name": "Secureworks:IRON VIKING",
			"tools": [
				"BadRabbit",
				"BlackEnergy",
				"GCat",
				"NotPetya",
				"PSCrypt",
				"TeleBot",
				"TeleDoor",
				"xData"
			],
			"source_id": "Secureworks",
			"reports": null
		},
		{
			"id": "18a7b52d-a1cd-43a3-8982-7324e3e676b7",
			"created_at": "2025-08-07T02:03:24.688416Z",
			"updated_at": "2026-04-10T02:00:03.734754Z",
			"deleted_at": null,
			"main_name": "BRONZE UNIVERSITY",
			"aliases": [
				"Aquatic Panda",
				"Aquatic Panda ",
				"CHROMIUM",
				"CHROMIUM ",
				"Charcoal Typhoon",
				"Charcoal Typhoon ",
				"Earth Lusca",
				"Earth Lusca ",
				"FISHMONGER ",
				"Red Dev 10",
				"Red Dev 10 ",
				"Red Scylla",
				"Red Scylla ",
				"RedHotel",
				"RedHotel ",
				"Tag-22",
				"Tag-22 "
			],
			"source_name": "Secureworks:BRONZE UNIVERSITY",
			"tools": [
				"Cobalt Strike",
				"Fishmaster",
				"FunnySwitch",
				"Spyder",
				"njRAT"
			],
			"source_id": "Secureworks",
			"reports": null
		},
		{
			"id": "d4e7cd9a-2290-4f89-a645-85b9a46d004b",
			"created_at": "2022-10-25T16:07:23.419513Z",
			"updated_at": "2026-04-10T02:00:04.591062Z",
			"deleted_at": null,
			"main_name": "Bronze Butler",
			"aliases": [
				"Bronze Butler",
				"CTG-2006",
				"G0060",
				"Operation ENDTRADE",
				"RedBaldNight",
				"Stalker Panda",
				"Stalker Taurus",
				"Swirl Typhoon",
				"TEMP.Tick",
				"Tick"
			],
			"source_name": "ETDA:Bronze Butler",
			"tools": [
				"8.t Dropper",
				"8.t RTF exploit builder",
				"8t_dropper",
				"9002 RAT",
				"AngryRebel",
				"Blogspot",
				"Daserf",
				"Datper",
				"Elirks",
				"Farfli",
				"Gh0st RAT",
				"Ghost RAT",
				"HOMEUNIX",
				"HidraQ",
				"HomamDownloader",
				"Homux",
				"Hydraq",
				"Lilith",
				"Lilith RAT",
				"McRAT",
				"MdmBot",
				"Mimikatz",
				"Minzen",
				"Moudour",
				"Muirim",
				"Mydoor",
				"Nioupale",
				"PCRat",
				"POISONPLUG.SHADOW",
				"Roarur",
				"RoyalRoad",
				"ShadowPad Winnti",
				"ShadowWali",
				"ShadowWalker",
				"SymonLoader",
				"WCE",
				"Wali",
				"Windows Credential Editor",
				"Windows Credentials Editor",
				"XShellGhost",
				"XXMM",
				"gsecdump",
				"rarstar"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "6abcc917-035c-4e9b-a53f-eaee636749c3",
			"created_at": "2022-10-25T16:07:23.565337Z",
			"updated_at": "2026-04-10T02:00:04.668393Z",
			"deleted_at": null,
			"main_name": "Earth Lusca",
			"aliases": [
				"Bronze University",
				"Charcoal Typhoon",
				"Chromium",
				"G1006",
				"Red Dev 10",
				"Red Scylla"
			],
			"source_name": "ETDA:Earth Lusca",
			"tools": [
				"Agentemis",
				"AntSword",
				"BIOPASS",
				"BIOPASS RAT",
				"BadPotato",
				"Behinder",
				"BleDoor",
				"Cobalt Strike",
				"CobaltStrike",
				"Doraemon",
				"FRP",
				"Fast Reverse Proxy",
				"FunnySwitch",
				"HUC Port Banner Scanner",
				"KTLVdoor",
				"Mimikatz",
				"NBTscan",
				"POISONPLUG.SHADOW",
				"PipeMon",
				"RbDoor",
				"RibDoor",
				"RouterGod",
				"SAMRID",
				"ShadowPad Winnti",
				"SprySOCKS",
				"WinRAR",
				"Winnti",
				"XShellGhost",
				"cobeacon",
				"fscan",
				"lcx",
				"nbtscan"
			],
			"source_id": "ETDA",
			"reports": null
		},
		{
			"id": "d53593c3-2819-4af3-bf16-0c39edc64920",
			"created_at": "2022-10-27T08:27:13.212301Z",
			"updated_at": "2026-04-10T02:00:05.272802Z",
			"deleted_at": null,
			"main_name": "Earth Lusca",
			"aliases": [
				"Earth Lusca",
				"TAG-22",
				"Charcoal Typhoon",
				"CHROMIUM",
				"ControlX"
			],
			"source_name": "MITRE:Earth Lusca",
			"tools": [
				"Mimikatz",
				"PowerSploit",
				"Tasklist",
				"certutil",
				"Cobalt Strike",
				"Winnti for Linux",
				"Nltest",
				"NBTscan",
				"ShadowPad"
			],
			"source_id": "MITRE",
			"reports": null
		},
		{
			"id": "b3e954e8-8bbb-46f3-84de-d6f12dc7e1a6",
			"created_at": "2022-10-25T15:50:23.339976Z",
			"updated_at": "2026-04-10T02:00:05.27483Z",
			"deleted_at": null,
			"main_name": "Sandworm Team",
			"aliases": [
				"Sandworm Team",
				"ELECTRUM",
				"Telebots",
				"IRON VIKING",
				"BlackEnergy (Group)",
				"Quedagh",
				"Voodoo Bear",
				"IRIDIUM",
				"Seashell Blizzard",
				"FROZENBARENTS",
				"APT44"
			],
			"source_name": "MITRE:Sandworm Team",
			"tools": [
				"Bad Rabbit",
				"Mimikatz",
				"Exaramel for Linux",
				"Exaramel for Windows",
				"GreyEnergy",
				"PsExec",
				"Prestige",
				"P.A.S. Webshell",
				"AcidPour",
				"VPNFilter",
				"Neo-reGeorg",
				"Cyclops Blink",
				"SDelete",
				"Kapeka",
				"AcidRain",
				"Industroyer",
				"Industroyer2",
				"BlackEnergy",
				"Cobalt Strike",
				"NotPetya",
				"KillDisk",
				"PoshC2",
				"Impacket",
				"Invoke-PSImage",
				"Olympic Destroyer"
			],
			"source_id": "MITRE",
			"reports": null
		}
	],
	"ts_created_at": 1775434543,
	"ts_updated_at": 1775792228,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/cd006acc6cbd745ba01ad333cbfb070c61a4ecf3.pdf",
		"text": "https://archive.orkl.eu/cd006acc6cbd745ba01ad333cbfb070c61a4ecf3.txt",
		"img": "https://archive.orkl.eu/cd006acc6cbd745ba01ad333cbfb070c61a4ecf3.jpg"
	}
}