{
	"id": "2d76209a-6867-475f-9259-28024d4fff07",
	"created_at": "2026-04-06T00:09:50.315335Z",
	"updated_at": "2026-04-10T03:22:07.886466Z",
	"deleted_at": null,
	"sha1_hash": "201814a0037278b2ac75d079480975db14d5cfbb",
	"title": "CastleLoader Malware Analysis: Full Execution Breakdown",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 142047,
	"plain_text": "CastleLoader Malware Analysis: Full Execution Breakdown\r\nBy nevergiveupcpp\r\nArchived: 2026-04-05 18:26:03 UTC\r\nANY.RUN’s team conducted an extensive malware analysis of CastleLoader, the first link in the chain of attacks impacting\r\nvarious industries, including government agencies and critical infrastructures.\r\nIt’s a unique walkthrough of its entire execution path, from a packaged installer to C2 server connection, as well as an\r\noverview of a parser developed to extract initialized local variables and automatically decode indicators of compromise\r\n(IOCs) featured in them.\r\nKey Takeways \r\nCastleLoader is a stealthy malware loader used as the first stage in attacks against government entities and multiple\r\nindustries. \r\nIt relies on a multi-stage execution chain (Inno Setup → AutoIt → process hollowing) to evade detection. \r\nThe final malicious payload only manifests in memory after the controlled process has been altered, making\r\ntraditional static detection ineffective. \r\nCastleLoader delivers information stealers and RATs, enabling credential theft and persistent access. \r\nA full-cycle analysis allowed us to extract runtime configuration, C2 infrastructure, and high-confidence IOCs. \r\nCastleLoader as an Initial Access Threat \r\nCastleLoader is a malicious loader malware built to deliver and install other malicious components. It lays the groundwork\r\nfor the attack, becoming its starting point.\r\nThis loader has commonly occurred in cyber attacks since early 2025. It gained popularity due to its high infection rate and\r\nuniversal nature, making it a powerful yet evasive tool.\r\nIn several observed campaigns, CastleLoader is delivered through the ClickFix social-engineering technique, where victims\r\nare tricked into manually executing malicious commands via fake verification or update prompts. In these cases, ClickFix\r\nacts as the initial access vector, while CastleLoader serves as the second-stage loader that deploys follow-on payloads\r\ndirectly in memory, helping attackers evade traditional file-based detection.\r\nOne of CastleLoader’s malicious campaigns is known to impact a total of 469 devices. It became a significant threat to\r\norganizations, especially US-based government entities. Its broader scope includes industries like IT, logistics, travel, and\r\ncritical infrastructures across Europe.\r\nCastleLoader is dangerous as a link in the chain delivering information stealers and RATs, making credential theft and\r\npersistent network access a high risk. \r\nThe loader’s popularity has inspired ANY.RUN’s malware analysis team to break down its malicious sample in order\r\nto uncover what it’s made of, retrieve signatures, and retrieve malware configurations. \r\nDetect CastleLoader and More with Threat Intelligence Feeds \r\nhttps://any.run/cybersecurity-blog/castleloader-malware-analysis/\r\nPage 1 of 14\n\nHow live threat intelligence impacts the key performance metrics\r\nModern malware like CastleLoader is designed to evade traditional detection. To keep up with the pace of adversaries,\r\nsecurity teams need threat intelligence that reflects what attackers are using right now. \r\nANY.RUN’s Threat Intelligence Feeds provide real-time indicators extracted from live malware executions performed by\r\nthousands of SOC teams worldwide. With TI Feeds, they achieve: \r\nFaster threat detection: Identify active loaders, stealers, and RATs as soon as they appear in real-world\r\nattacks thanks to 99% unique data extracted from the latest sandbox analyses by 15K SOCs and 500K analysts. \r\nHigher confidence decisions: Indicators are backed by execution context, not guesswork or outdated reports. \r\nImproved SOC efficiency: Fewer false positives mean less alert fatigue and better use of analyst time. \r\nStronger risk management: Early visibility into emerging malware families helps prevent business disruption. \r\nBy combining real-time sandbox intelligence with immediate IOC delivery, ANY.RUN’s TI Feeds help organizations stay\r\nahead of fast-evolving threats like CastleLoader. \r\nInitial Analysis: Sandbox Telemetry \r\nThe analysis started with ANY.RUN’s Interactive Sandbox detonation.  \r\nView analysis \r\nThe launch of CastleLoader sample in ANY.RUN. Suspicious processes and network activities detected \r\nWhat instantly grabs our attention here is a system process chain, at the end of which a request to 94[.]159[.]113[.]32:80 was\r\nsent. To understand this activity better, we switched to the binary analysis. \r\nStatic analysis: Inspecting Inno Setup Installer  \r\nTo get a basic overview of the binary, let’s process it via DIE (Detect It Easy).  \r\nhttps://any.run/cybersecurity-blog/castleloader-malware-analysis/\r\nPage 2 of 14\n\nCastleLoader installer analyzed in Detect It Easy \r\nIt reveals that the binary consists of Object Pascal (Delphi) and Inno Setup Module (installer). \r\nThe next stage of the analysis requires the use of innoextract, a tool to unpack installers. We used a fork that allows you\r\nto unpack password-protected archives, which came in handy. \r\nFiles extracted from Inno Setup installer \r\nArchive extraction reveals several executables. At this point, it’s Autolt3.exe and the compiled script freely.a3x that grab\r\nour attention most. These are the files that directly participate in the calling chain. Other files, as it turned out later, aren’t\r\nrelated to the malware execution, and their role is unclear.\r\nNext, let’s use Autolt-Ripper to extract compiled Autolt scripts from A3X containers. As a result of this, we get a\r\nfile script.au3 containing 24,402 code lines. The majority of this code, which is responsible for the malicious chain, is\r\nunreadable: \r\n//A function’s minimal listing\r\nFunc FUNC_38( $XGOHK_KNZJTRNG ,$FRNQQSFKMV_ONCPFFG_IUESI ,$OYJVN )\r\n Local $VAR_2745 [5 ]= [( $FOCOFQYNAZZDTMNK [0 ][0 ]\u003c= $VAR_1884 ?$APITY_TTXPNVODYF_UOFBAYSHE :51205 ),51215 ,\r\n Local $NWBSM\r\n Local $JIQBD\r\n For $JIQBD =( $MON_GLZO__BPDFZTL [3 ]\u003e $MON_GLZO__BPDFZTL [9 ]?0 :$VAR_364 [0 ][0 ]) To( $G_HGLSAQTEAFZZZONM\r\n $NWBSM = $VAR_2745 [ $JIQBD ]\r\n $NWBSM -= $JIQBD\r\n $NWBSM += 14431\r\n $NWBSM = $IGFABA_UFUGKAMKV( $NWBSM ,$JIQBD )\r\n $NWBSM = $RM_I2U_3RPS4_I5Y0IIHAZ1_6( $NWBSM ,65535 )\r\nhttps://any.run/cybersecurity-blog/castleloader-malware-analysis/\r\nPage 3 of 14\n\n$VAR_2745 [ $JIQBD ]= $IDBABKRDVSBFUNLRSLIOXWAD( $NWBSM )\r\nNext\r\n $VAR_2745 = $WWXHKDX( $VAR_2745 ,\"\" )\r\n Return $VAR_2745\r\nEndFunc\r\nStill, we are able to learn about the loaded modules and WinAPI wrappers: \r\n//Some of the kernel32.dll module’s wrappers\r\nFunc _WINAPI_ASSIGNPROCESSTOJOBOBJECT ( $HJOB , $HPROCESS )\r\n Local $ACALL = DllCall ( \"kernel32.dll\" , \"bool\" , \"AssignProcessToJobObject\" , \"handle\" , $HJOB , \"handle\" , $HPROCESS\r\n If @error Then Return SetError ( @error , @extended , False )\r\n Return $ACALL [ 0 ]\r\nEndFunc\r\nFunc _WINAPI_ATTACHCONSOLE ( $IPID = + 4294967295 )\r\n Local $ACALL = DllCall ( \"kernel32.dll\" , \"bool\" , \"AttachConsole\" , \"dword\" , $IPID )\r\n If @error Then Return SetError ( @error , @extended , False )\r\n Return $ACALL [ 0 ]\r\nEndFunc\r\nFunc _WINAPI_ATTACHTHREADINPUT ( $IATTACH , $IATTACHTO , $BATTACH )\r\n Local $ACALL = DllCall ( \"user32.dll\" , \"bool\" , \"AttachThreadInput\" , \"dword\" , $IATTACH , \"dword\" , $IATTACHTO , \"bool\r\n If @error Then Return SetError ( @error , @extended , False )\r\n Return $ACALL [ 0 ]\r\nEndFunc\r\nFunc _WINAPI_CREATEEVENT ( $TATTRIBUTES = 0 , $BMANUALRESET = True , $BINITIALSTATE = True , $SNAME = \"\" )\r\n If $SNAME = \"\" Then $SNAME = Null\r\n Local $ACALL = DllCall ( \"kernel32.dll\" , \"handle\" , \"CreateEventW\" , \"struct*\" , $TATTRIBUTES , \"bool\" , $BMANUALRESET\r\n If @error Then Return SetError ( @error , @extended , 0 )\r\n Local $ILASTERROR = _WINAPI_GETLASTERROR ( )\r\n If $ILASTERROR Then Return SetExtended ( $ILASTERROR , 0 )\r\n Return $ACALL [ 0 ]\r\nEndFunc\r\nFunc _WINAPI_CREATEJOBOBJECT ( $SNAME = \"\" , $TSECURITY = 0 )\r\n If Not StringStripWS ( $SNAME , $STR_STRIPLEADING + $STR_STRIPTRAILING ) Then $SNAME = Null\r\n Local $ACALL = DllCall ( \"kernel32.dll\" , \"handle\" , \"CreateJobObjectW\" , \"struct*\" , $TSECURITY , \"wstr\" , $SNAME )\r\n If @error Then Return SetError ( @error , @extended , 0 )\r\nhttps://any.run/cybersecurity-blog/castleloader-malware-analysis/\r\nPage 4 of 14\n\nReturn $ACALL [ 0 ]\r\nEndFunc\r\nFunc _WINAPI_CREATEMUTEX ( $SMUTEX , $BINITIAL = True , $TSECURITY = 0 )\r\n Local $ACALL = DllCall ( \"kernel32.dll\" , \"handle\" , \"CreateMutexW\" , \"struct*\" , $TSECURITY , \"bool\" , $BINITIAL , \"wst\r\n If @error Then Return SetError ( @error , @extended , 0 )\r\n Return $ACALL [ 0 ]\r\nEndFunc\r\nSeveral WinAPI wrappers may potentially participate in attacks for further system infection,\r\nbecause it’s the Autolt scrip that prepares the environment and control handover. \r\nKey function calls \r\nThis combination of functions looks suspicious and hints at cross-process manipulations: \r\nkernel32.GetProcAddress—Dynamic function resolution\r\nkernel32.CreateFileW—Working with files\r\nkernel32.CreateProcessW—Creating processes\r\nkernel32.CreateMutextW—Creating mutexes\r\nkernel32.OpenProcess—Opening processdescriptors\r\nkernerl32.ReadProcessMemory—Reading the memory of other processes\r\nkernerl32.DuplicateTokenEx—Duplicating security tokens\r\nkernelbased.AdjustTokenPriviliges—Manipulatingthe privileges\r\nkernel32.WriteFile—Writing into files\r\nSince full-scale deobfuscation would take up too much time, let’s switch to dynamic analysis for now. \r\nDynamic Analysis: Tracing Execution \r\nLet’s launch Autolt3.exe in x32dbg with breakpoints at functions that we’ve listed above, with the compiled\r\nscript freely.a3x as a parameter. \r\nSoon after the initialization of Autolt3.exe, we see a kernel32.CreateProcessW call, where jsc.exe, the final link of our\r\nchain, is located. \r\nNote: this is a JScript.NET compilator, a part of an older .NET Framework. What’s unusual is that no extra data is\r\ntransmitted to lpCommanLine. \r\nA breakpoint at CreateProcessW function. A jsc.exe child process is created with CREATE_SUSPENDED\r\nflag \r\nhttps://any.run/cybersecurity-blog/castleloader-malware-analysis/\r\nPage 5 of 14\n\nAlso, there’s a CREATE_SUSPENDED flag in dwCreationFlags, which points to an uncommon use of jsc.exe. But how\r\ndoes it get the payload? \r\nThe next string of calls reveals this: \r\nkernel32.CreateProcessW creates the jsc.exe process flagged as CREATE_SUSPENDED. \r\nkernel32.GetThreadContext delivers registries — the context of the main flow. This is typical\r\nfor the preparation to process hollowing. \r\nkernel32.VirtualAllocEX allocates a 0x3B000-sized memory area in jsc.exe process with MEM_COMMIT |\r\n MEM_RESERVE flags and PAGE_EXECUTE_READWRITE protection. This allows you to place and launch\r\nany code. \r\nThe memory area allocation in the child process with permission to launch\r\n(PAGE_EXECUTE_READWRITE)  \r\nTo confirm this and extract the key module, let’s keep tracing the malware. The next critical call\r\nis kernel32.WriteProcessMemory. Among its arguments is a pointer to a buffer with loaded data, featuring familiar PE\r\nMagic and DOS Stub signatures. This clearly means that a PE file is injected into the jsc.exe process. \r\nAt this stage, we can safely dump a clean binary from the memory. \r\nA breakpoint at WriteProcessMemory. Malicious PE image is written into the allocated memory area  \r\nThe payload is revealed, but we continue unraveling the entire chain until the final call — kernel32.ResumeThreat. This\r\nwill help us make sure that the malware doesn’t do anything extra, like embedding another hidden process, before the\r\ncontrol handover.  \r\nThe next critical step is the call of kernel32.ReadProcessMemory. At this stage, the threat obtains a pointer to the PEB\r\n(Process Environment Block) structure, from which it extracts a PEB.ImageBaseAddress (base load address). This address\r\nis further rewritten to the injected PE module. That’s crucial for standard loading mechanisms of Windows, including\r\nearly ntdll.LdrInintializeThunk initialization, as this allows for the correct processing of import tables, relocating, and\r\nrestoring of the image’s data. \r\nhttps://any.run/cybersecurity-blog/castleloader-malware-analysis/\r\nPage 6 of 14\n\nA breakpoint at ReadProcessMemory. Extraction of PEB.ImageBaseAddress of the child process to replace\r\nit with the base address of the injected PE \r\nAfter this, kernel32.WriteProcessMemory is called, which completes the stage of replacing the base address in\r\nthe PEB structure. \r\nNext, kernel32.SetThreadContext is invoked, almost finalizing the process hollowing. At this stage, the malware writes a\r\npointer to the entry point of the injected module into the EAX register. \r\nAfter the call to kernel32.ResumeThread, control is handed over to ntdll.LdrInitializeThunk, which performs loader\r\ninitialization and prepares the process execution environment. \r\nOnce initialization is complete, ntdll.LdrInitializeThunk calls ntdll.NtContinue, restoring the execution context. \r\nAs a result, the execution continues from the address stored in the EIP register. This is the beginning of\r\nthe ntdll.RtlUserThreadStart procedure, which places the entry point from the EAX register onto the stack in accordance\r\nwith the __stdcall calling convention and then hands over control to ntdll.__RtlUserThreadStart. \r\nA breakpoint at SetThreadContext, writing an EntryPoint of the injected module into EAX registry before\r\nrenewing the flow \r\nNotably, this is not a common process hollowing. The regular method includes the extraction of the original\r\nmemory area via NtUnmapViewOfSection. But in CastleLoader’s case, the malware dismisses this step intentionally. \r\nTo monitoring tools like System Informed, the process doesn’t look off. It’s also not a part of an event chain known\r\nto EDR. \r\nThis decreases the probability of detection without disrupting the processing of all tables and\r\nstructures, ensuring normal functioning of the injected module. \r\nPreliminary Results \r\nInno Setup as a Delivery Container\r\nThe original Inno Setup installer turned out to be a container with a set of auxiliary files, among which the AutoIt3.exe +\r\nfreely.a3x combination played a key role. We were able to extract and partially decompile the AutoIt script; however, most\r\nof its logic was heavily obfuscated and consisted of numerous wrappers around the WinAPI. \r\nAutoIt Script and Process Hollowing via jsc.exe\r\nhttps://any.run/cybersecurity-blog/castleloader-malware-analysis/\r\nPage 7 of 14\n\nStatic analysis showed that the script prepares the environment and launches the next stage, while dynamic analysis\r\nconfirmed that after jsc.exe is started, one of the process hollowing techniques is executed: another executable module is\r\ninjected into the process’s address space. \r\nAs a result, we discovered a fully functional PE file — the main CastleLoader module —  inside the process and\r\nsuccessfully dumped it for further analysis. \r\nEvasion Through Multi-Stage Execution\r\nSuch a sophisticated multi-stage execution chain was not implemented merely to complicate analysis, but specifically as an\r\nattempt to conceal the execution of the main payload from detection mechanisms. Using Inno Setup as a container,\r\nan AutoIt script as an intermediate layer, and process hollowing over jsc.exe, allows CastleLoader to distribute across\r\nseveral components that appearbenign at first glance. \r\nPost-Execution Artifacts on Disk\r\nAfter the loader completes its execution, the files extracted by the Inno Setup installer remain on the disk. This may either\r\nbe a deliberate attempt to mimic the normal behavior of legitimate software, which often leaves installation artifacts behind,\r\nor simply an implementation flaw. Given the relative novelty of the malware family, it’s probably the latter. \r\nImpact on Detection Mechanisms\r\nStatic signatures, simple behavioral heuristics, and process monitoring systems become ineffective  \r\nThis execution model reduces the likelihood of detection, as each individual stage appears legitimate, and the final payload\r\nonly manifests in memory after the controlled process has been altered. As a result, static signatures, simple behavioral\r\nheuristics, and process monitoring systems become ineffective. A fully functional malicious module exists only at runtime,\r\nand only within an already modified process. y manifests in memory after the controlled process has been altered. As a\r\nresult, static signatures, simple behavioral heuristics, and process monitoring systems become ineffective. A fully functional\r\nmalicious module exists only at runtime, and only within an already modified process. \r\nGoing Back to Static Analysis \r\nAfter uploading the memory dump to Ghidra, let’s start the analysis of its execution context. Right after opening\r\nthe dump we see a kernel32.MessageBoxW call, which displays a fake error message: “System Error. The\r\nprogram can’t start because VCRUNTIME140.dll is missing from your computer. Try reinstalling the program to fix this\r\nproblem.” \r\nAfter that, the execution of malicious code continues. \r\nWinMain entry point in Ghidra decompilator. Early analysis of the malicious code’s structure \r\nDuring the analysis, we can see functions with unclear values. By studying their references, we see that they are actively\r\ncalled throughout the program’s execution. \r\nIn FUN_00e469f0, the first argument of the function is a pointer to the start of the PE module. At first, the value\r\nis dereferenced and checked for a DOS heading 0x5A4D (“MZ”). This is followed by NT heading’s validation and\r\ndecomposition of PE’s key structures. \r\nThe function manually gets access to the export table, allowing for a rewrite of the basic module address\r\n(IMAGE_DOC_HEADER*). Then each exported character goes through an embedded hash function, while the calculated\r\nhash is compared to the initial value.  \r\nhttps://any.run/cybersecurity-blog/castleloader-malware-analysis/\r\nPage 8 of 14\n\nGetProcAddressByHash function, dynamic resolution of API addresses by hash names \r\nSince we now know the origin of each digest and the way the function resolves the required APIs by hash, we can gather a\r\nset of potentially used network functions, run them through the hashing algorithm, and generate an enumeration (enum)\r\nfor Ghidra. \r\nUsing the script, we automatically replaced all hashes with their corresponding function names — the result can be seen in\r\nthe Equates Table. Each hash is now tied with a readable API name, along with the number of cross-references to it. \r\nThis also makes it easy to track all calls of these functions via the References section, where for each usage point there’s a\r\nreference to the corresponding API address. \r\nEquates table. Correlation of hashes with names of imported WinAPI functions \r\nAfter generating the enum and substituting API names in the Equates Table, we see that the binary\r\nuses WINHTTP.WinHttpOpen. Cross-references to the corresponding hash prove that. We annotated a function with this\r\ncall to make it easier to follow the logic. Then, by examining the cross-references to this function, we can move to its caller\r\n— the point where the HTTP session setup begins. \r\nInitSession function – calling for WinHttpOpen for the initialization of a HTTP session \r\nWhile examining the HTTP connection’s initialization stage, we identified a function that returns a pointer to the data\r\nstructure used as the initial configuration for the network logic. The format of this structure isn’t clear; but the fact\r\nthat it’s there suggests the presence of a dedicated procedure responsible for creating and populating the configuration\r\nstructure. \r\nWe annotated several references around the returned pointer and proceeded to analyze the function that forms\r\nthe configuration structure. This is done to restore its components and understand which parameters are used for network\r\nconnection. \r\nhttps://any.run/cybersecurity-blog/castleloader-malware-analysis/\r\nPage 9 of 14\n\nGetMalwareConfig calling and configuration handover to InitSession for the establishment of the connection \r\nSeveral nested functions lead us to a large-scale procedure, during which the configuration data is prepared. Its\r\nvalues aren’t static strings, but a mass of encrypted bytes packaged into DWORDs with two UTF-16LE characters and\r\nplaced right on the stack. This data is postprocessed with a simple bit-by-bit transformation into string buffers. \r\nA function for getting the configuration — XOR decoding of configuration strings with a cyclic key at the\r\nstack \r\nThe temporary buffers are then passed to UniStr::Copy and pasted into fixed global addresses. All of these addresses are\r\nlaid out sequentially in .data sections, effectively forming a single contiguous configuration block. \r\nAt the end, the function returns the address of the first element (0xE67830), allowing the entire data set to be used as an\r\narray or a structure with fixed offsets. \r\nAn example of a decryption algorithm \r\ninput[8] = 0x67;\r\ninput[9] = 0x4a;\r\ninput[10] = 0xda;\r\ninput[0xb] = 0xb6;\r\nstep = 0;\r\ninput[0xc] = 99;\r\ninput[0xd] = 0x7d;\r\ninput[0xe] = 0xa0;\r\ninput[0xf] = 0xe4;\r\ninput[0x10] = 0x31;\r\ninput[0x11] = 0x62;\r\ninput[0x12] = 0x87;\r\ninput[0x13] = 0xa7;\r\ninput[0x14] = 0x62;\r\ninput[0x15] = 0x49;\r\nhttps://any.run/cybersecurity-blog/castleloader-malware-analysis/\r\nPage 10 of 14\n\ninput[0x16] = 0x98;\r\ninput[0x17] = 0x98;\r\ninput[0x18] = 0x6c;\r\ninput[0x19] = 0x6d;\r\ninput[0x1a] = 0xbf;\r\ninput[0x1b] = 0xaa;\r\ninput[0x1c] = 0;\r\ndo {\r\noutput[step + 8] = (ushort)(byte)(\u0026key)[step \u0026 3] ^input[step + 8];\r\noutput[step + 9] = (ushort)(byte)(\u0026key)[step + 1 \u0026 3] ^input[step + 9];\r\noutput[step + 10] = (ushort)(byte)(\u0026key)[step + 2 \u0026 3] ^input[step + 10];\r\n step = step + 3;\r\n} while (step \u003c 0x15);\r\nUniStr::Copy(\u0026DAT_00e67848,(short*)(output + 8));\r\n//In this fragment,there’sa small static block of data (byte array)formed.\r\n//Then,bit-by-bit,it’sdecryptedby undergoing XOR operation with a cyclic one-table key.\r\n//Decrypted bytes are extended to UTF-16LE characters and written into an exit buffer, which is thenpasted intothe glob\r\n//viaUniStr::Copy.\r\n//Basically,thisis a simple custom decryption of strings using fixed bytes arrays and cyclic XORmasking byindex with\r\nBuilding a Custom Parser \r\nAfter manually decrypting several strings, we realized that the process could be automated. The extraction logic used\r\nby CastleLoader is known: it has a single UTF-16LE DWORD pattern, loop construct, and fixed addresses, from which\r\nthe XOR bytes are taken. That’s enough to identify the repeating code fragments and write a Python script that extracts all\r\nstrings from the dump in a single pass. \r\nParser’s results \r\nE32E6D: %s/settings/%s\r\nE33F4C:windows_version\r\nE3417F:machine_id\r\nE33D70:access_key\r\nE35E40: %s/tasks/complete/id/%lu\r\nE37732:http://94[.]159[.]113[.]32/service(C2)\r\nE377D2: gM7dczM61ejubNuJljRx (UserAgent)\r\nE378A8: N3sBJNQKOyBSqzOgQSQVf9 (Mutex)\r\nE3F4E9: Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0 Safari/537.36\r\n… and so on. \r\nThe analysis of the configuration function was the right call. We ended up with the entire strings array used\r\nby CastleLoader. As a result, we get the published script. \r\nhttps://any.run/cybersecurity-blog/castleloader-malware-analysis/\r\nPage 11 of 14\n\nMost importantly, the resulting strings feature the very C2 address which we saw in the sandbox analysis.\r\nNow it’s extracted not as a secondary effect of network activity, but as a part of malware configuration.\r\nThis decisively confirms its role and proves that retrieved IOCs are reliable for detection and analysis. \r\nFinal Observations \r\nSince we wanted to demonstrate the entire analysis process from start to finish, we deliberately followed\r\nthe extended analysis path, from coming up with hypotheses to testing and adjusting them. In practice, many of these stages\r\ncould have been skipped. \r\nANY.RUN provides sufficiently detailed telemetry to significantly shorten the analysis. \r\nANY.RUN provides sufficiently detailed telemetry to significantly shorten the analysis. For example, we didn’t have to\r\ninvestigate the Inno Setup module, since the sample did not remove the extracted files afterwards. \r\nThe final process could have been dumped immediately, too, to bypass the intermediate stages, as it was the only one\r\nthat actually interacted with the network and generated traffic. \r\nNevertheless, the full walkthrough proved valuable: it allowed us to reconstruct the entire execution chain, understand the\r\nloader’s internal logic, and verify that the extracted data really indicates CastleLoader’s presence. This approach gave us not\r\nonly the final set of IOCs, but also an understanding of the mechanisms behind them. \r\nAbout ANY.RUN \r\nANY.RUN is a leading provider of interactive malware analysis and threat intelligence solutions trusted by security teams\r\nworldwide. The platform combines real-time sandboxing with a comprehensive intelligence ecosystem, including Threat\r\nIntelligence Feeds, TI Lookup, and public malware submissions. \r\nMore than 500,000 security analysts and 15,000 organizations rely on ANY.RUN to accelerate investigations, validate TTPs,\r\ncollect fresh IOCs, and track emerging threats through live, behavior-driven analysis. \r\nBy giving defenders an interactive, second-by-second view of malware execution, ANY.RUN enables faster detection,\r\nbetter-informed decisions, and a stronger overall security posture. \r\nDiscover how ANY.RUN can enhance your SOC — start your 14-day trial today. \r\nIOCs \r\nAnalyzed Files \r\nName  MD5  SHA1 \r\n8b7c1657f4d5cf0cc82d68c1f1a385adf0de27d46fc544bba249698e6b427856.exe (Inno\r\nSetup Installer) \r\n9A0960C674378A049B8D9AD0E1C641C3  0580A364AB\r\nfreely.a3x (AutoIt Script)  AFBABA49796528C053938E0397F238FF  DD029CD47\r\npayload.exe (CastleLoader Core Module)  1E0F94E8EC83C1879CCD25FEC59098F1  9E11E8866F\r\nNetwork Indicators \r\nC2 Server \r\n94[.]159[.]113[.]32 \r\nHTTP Request \r\nhttp://94[.]159[.]113[.]32/service \r\nMutex \r\nN3sBJNQKOyBSqzOgQSQVf9 \r\nUser-Agents \r\ngM7dczM61ejubNuJljRx \r\nMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/133.0.0.0\r\nSafari/537.36 \r\nYARA Rules \r\nhttps://any.run/cybersecurity-blog/castleloader-malware-analysis/\r\nPage 12 of 14\n\nrule\r\nCastleLoader{\r\nmeta:\r\n author = \"ANY.RUN\"\r\n date = \"2025-12-02\"\r\n description = \"IdentifiesCastleLoadermalware samples\"\r\n threat = \"CastleLoader\"\r\n strings:\r\n $p1 ={ 44a0 2d39 }//CreateMutexW\r\n $p2 ={ 8206 d7 4e }//WinHttpOpen\r\n $p3 ={ 8103 08 6f }//WinHttpConnect\r\n $p4 ={ 187b d4 2e }//WinHttpOpenRequest\r\n $p5 ={ e4 f4 9633 }//WinHttpReceiveResponse\r\n $p6 ={ d8 da 5496 }//ShellExecuteW\r\n $p7 ={ 5f 9e 4316 }//GetUserNameW\r\n $p8 ={ b4 89 86 1b }//GetComputerNameW\r\ncondition:\r\nall of($p*)\r\n}\r\nMITRE ATT\u0026CK Techniques \r\nTactic  Technique  Description \r\nTA0002:\r\nExecution \r\nT1059.010: AutoHotKey \u0026 AutoIT  Execution via AutoIt script (freely.a3x) \r\nTA0005:\r\nDefense\r\nEvasion \r\nT1027.002: Software Packing  Multi-stage: Inno Setup → AutoIt → PE injection \r\n  T1055.012: Process Hollowing  Process hollowing into jsc.exe \r\n  T1106: Native API  API resolution via hash-based GetProcAddress \r\n \r\nT1140: Deobfuscate/Decode Files or\r\nInformation \r\nRuntime XOR-decoding of configuration strings (C2, User-Agent, Mutex); obfuscated AutoIt script \r\nTA0007:\r\nDiscovery \r\nT1082: System Information\r\nDiscovery \r\nCollects computer_name, windows_version, machine_id \r\nTA0011:\r\nCommand\r\nand Control \r\nT1071.001: Web Protocols  HTTP communication to 94[.]159[.]113[.]32:80/service \r\nnevergiveupcpp\r\nhttps://any.run/cybersecurity-blog/castleloader-malware-analysis/\r\nPage 13 of 14\n\nA reverse engineering and C/C++ development enthusiast with a focus on malware analysis, vulnerability research in\r\nbinaries and systems, and the development of low-level libraries. Actively participates in CTF competitions and develops\r\nproof-of-concepts to study and explore advanced techniques.\r\nA reverse engineering and C/C++ development enthusiast with a focus on malware analysis, vulnerability research in\r\nbinaries and systems, and the development of low-level libraries. Actively participates in CTF competitions and develops\r\nproof-of-concepts to study and explore advanced techniques.\r\nFollow nevergiveupcpp on:\r\nGithub\r\nX\r\nDiscord\r\nSource: https://any.run/cybersecurity-blog/castleloader-malware-analysis/\r\nhttps://any.run/cybersecurity-blog/castleloader-malware-analysis/\r\nPage 14 of 14",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://any.run/cybersecurity-blog/castleloader-malware-analysis/"
	],
	"report_names": [
		"castleloader-malware-analysis"
	],
	"threat_actors": [],
	"ts_created_at": 1775434190,
	"ts_updated_at": 1775791327,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/201814a0037278b2ac75d079480975db14d5cfbb.pdf",
		"text": "https://archive.orkl.eu/201814a0037278b2ac75d079480975db14d5cfbb.txt",
		"img": "https://archive.orkl.eu/201814a0037278b2ac75d079480975db14d5cfbb.jpg"
	}
}