PacketWatch's Team Sixty43 profiles how a ClickFix attack leverages the finger protocol to deliver its first payload (CastleLoader). See the TTPs and IOCs.
Recently, Team Sixty43 investigated an EDR alert that turned out to be ClickFix. While ClickFix attacks have been a common technique leveraged by threat actors for some time now, there is a wide range of methods that ClickFix is applied. In this particular case, the finger protocol was leveraged to download the first payload stage. This method has been in use since at least late last year, but in recent weeks, this method has been used to deliver CastleLoader, which is used to download additional payloads such as infostealers, remote access trojans, and even ransomware. As we triaged this EDR alert, the threat actor infrastructure hosting each payload stage was still active, and we were able to retrieve each stage for further analysis.
Many of the details listed in this article may look familiar, as Anna Pham at Huntress wrote an excellent blog about the detailed inner workings of this malware. This article will look at it from a "rapid triage" perspective, as well as provide additional IOCs from this campaign. In this specific case, as we stepped through the different phases of this loader, we leveraged ChatGPT to assist with quickly analyzing, decoding, and decrypting various parts of the payloads. This process allowed us to unpack and understand the behavior of the loader and extract relevant IOCs without ever having to actually detonate the malware or spend precious hours doing manual static analysis. It also served as a benchmark to test modern AI model capabilities with this sort of work (spoiler: It did very well!) The entire process outlined below took just over an hour with the help of AI tools.
We hope this article will be especially helpful to smaller security teams with limited resources and provide tips and ideas for how to leverage basic AI tools to assist with malware triage.
Instead of using any sort of agentic AI to just auto-magically rip apart and analyze the malware, we used a more manual, step-by-step approach, which enabled a deeper understanding of the malware behavior while also using AI to assist with the more technical and complex tasks. AI should be a tool to assist and enhance an analyst, not replace them.
As you will see from the analysis below, CastleLoader is an incredibly complex piece of malware, with several stages, encryption, obfuscation, and in-memory execution. Modern threat actors are going to great lengths to make their malware difficult to detect.
Before diving into the malware analysis, let’s review what the finger protocol is and why it should be blocked and disabled in every network environment.
The finger protocol was officially introduced in RFC 1288 in December 1991. Per the RFC, finger “is a simple protocol which provides an interface to a remote user information program (RUIP).” In practice, one would send a command such as finger user1@example.com. This would return basic information about the user, such as their login name, home directory, login time, and more. The command can also be run without specifying a user, which will return information for all logged in users. The protocol does not use any authentication, and the data is not encrypted. Due to the insecure nature of the protocol, it is now disabled by default on many modern operating systems.
However, the executable for finger is still present, and the commands can still be invoked manually. This is why administrators need to take extra steps to ensure this protocol is not abused. The simplest way to prevent this abuse is to block TCP/79 at the firewall. Additionally, Group Policy or Application Control policies can be applied to block finger.exe from running.
Initial Payload
When viewing the EDR alert, it captured the following command that was executed on the host:
This command uses the finger protocol to call finger.uslinked[.]org and execute a series of commands that are retrieved from this call. The returned commands are as follows:
These obfuscated commands achieve the following:
The de-obfuscated Python script is as follows:
Second Payload
The script above shows a call to a second URL to download the next stage payload. This second stage is a large blob of Base64 encoded text, with special characters (in this case, Cyrillic) substituted in for further obfuscation. The simple replacement functions can be seen at the end of the script:
We wanted to test ChatGPT's ability and accuracy regarding basic de-obfuscation. By copy/pasting the encoded blob and asking it to decode it, we get the following:
This Python script has yet another embedded Base64-encoded blob, with an additional Base64-encoded XOR key. The encoded blob contains encrypted shellcode. The Python script uses Windows APIs to allocate executable memory, copies the shellcode into memory, and then executes it.
ChatGPT was quickly able to tell us the following about the shellcode:
Third Payload
By emulating the program logic, we can use curl to download the next stage from the new sedaliarealty[.]net URL. This results in the download of a new file.
curl -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/143.0.0.0 Safari/537.36" \
hxxps://sedaliarealty[.]net/ebd417db-979c-51f8-aedf-88a2bf8aa6c3/v6
At this phase, based on some of the commands seen in the shellcode above, we were hoping that this file would simply be an MSI file. This was not the case. Running the 'file' command on this new binary returned "data":
Figure 07: ‘file’ type of the newly downloaded binary: stage3_payload.bin
Viewing the first several bytes of the file confirms that this is not a known filetype:
The next thought was that this payload is still encoded or encrypted. At this point, we directed ChatGPT to circle back to the shellcode stored in the previous Python phase for more clues. After a second pass, it quickly identified what appears to be an RC4-style routine that uses the first 64 bytes of the payload as the decryption key. It then generated the Python code below to emulate the decryption routine in the shellcode and output the results as a new file:
This theory turned out to be correct, as the Python script executed with no errors and produced a new file. Running 'file' on this new decrypted file shows that the decryption worked, and we now have a DOS executable:
The next step is to see if there is anything else embedded in this file. To do this, we grep for 'MZ' to look for executables:
Figure 11: grepping for ‘MZ’ bytes in the payload
Wow! We got 7 hits. What about any MSI markers?
This returned 0 results, so no MSI. The 7 MZ hits mean there are potentially embedded files. First, we tried some automated tools to try to extract further payloads:
Both of these options were not able to carve anything out. The next step was to take a closer look at how the file behaves. We ran 'objdump' on the file to try and uncover clues:
Figure 16: First half of object dump output
For many analysts, assembly and shellcode present steep technical hurdles with analysis. This is another opportunity to test ChatGPT's ability to assist us. We screenshotted the object dump and pasted it in the chat, and it immediately identified a pattern (highlighted in red). The jmp -> call -> pop pattern is common with shellcode and is used to obtain the current memory address without relying on fixed pointers. In this case, EDI now points to the embedded payload data. It expanded upon its analysis even further:
This block of assembly also reveals yet another decryption scheme. There are 2 key parts to this:
10: mov %ecx,%eax
12: mov $0x8,%ebx
17: xor %edx,%edx
19: div %ebx
This code computes ecx % 8, which means the algorithm cycles every 8 bytes.
1b: lea 0x4(%edi,%edx,1),%ebx
1f: mov (%ebx),%al
21: lea 0xc(%edi,%ecx,1),%ebx
25: xor %al,(%ebx)
This assembly effectively translates to payload[i] ^= key[i % 8], which is an XOR decoder!
Lastly, the code:
2a: lea 0xc(%edi), %eax
2d: mov (%eax), %ecx
2f: lea 0x10(%edi,%ecx,1), %eax
33: lea 0x10(%edi), %edx
36: push %eax
37: call *%edx
locates the decrypted payload, resolves a function pointer, and then calls it. Altogether, this shellcode decrypts another (hopefully final) stage and then executes it (from memory).
Decrypting the Third Payload
We were then able to rapidly prototype the following Python code, which emulates this assembly logic and runs the "8-byte XOR" decryption routine and then writes the results to yet another new file.
Running this code shows the following results (it worked!):
Figure 20: Python XOR decryptor output
Phase Four
As you can see from the above screenshot, after all of that work, we are back to a 'data' file type, which means we still have a bit more to do. We ran objdump on this new file to see what we are dealing with:
Figure 21: ‘objdump’ output of ‘next_stage.bin’ file
Again, we tossed a screenshot of the dump into ChatGPT to assist with the assembly analysis. Starting at offset 0x4, we see a more normal function prologue:
push ebp
mov esp, ebp
sub $0xc, esp
Looks like we are getting close! To better align the memory offsets (shaving off the first 4 bytes), we run the following command to rewrite the file:
tail -c +5 next_stage.bin > next_stage_code.bin
At this point of the process, ChatGPT's theory is that this is an in-memory PE loader, due to the presence of memset, memcpy, string-length helpers, and API-hash resolution. It was interesting to see the reasoning model formulate a theory as to what the malware is based on the data it had observed so far.
We can now check for PE indicators to see if there is, in fact, an embedded PE that can be carved. The following Python code was used to run this check:
Running this code provided the following output:
We can see at memory offset 0xe00 the exact PE signature we were looking for: PE\x00\x00.
Carving The Final Payload
To carve this out, we run the following dd command:
dd if=next_stage_code.bin of=carved_payload_from_0xe00.bin bs=1 skip=$((0xe00)) status=progress
Figure 24: ‘dd’ command and output
Looks like that worked! Let's check the file type:
Finally! After several rounds of de-obfuscation and decryption, we have a viable payload. Checking the file against VirusTotal, we confirm our suspicion, this is indeed CastleLoader:
It is worth noting that although the binary itself gets detected by many AV vendors, the way this loader is designed (it executes the payload in memory), the PE file never touches disk and has a much higher chance of not being detected. Additional defense-in-depth, such as detection on C2 traffic or other network IOCs can help detect this malware.
With this specific variant, we discovered one additional network IOC by detonating this in our lab: crewllovekorps[.]com:
This is the domain the final payload reaches out to after it is executed. Our friends at Validin already had this domain classified as malicious and associated it with CastleLoader.
What a journey! We were able to learn so many things from this event. First, and most important, ClickFix continues to be a huge problem, and threat actors continue to find ways to implement it in creative ways. This particular campaign relies on the use of the finger protocol, which gives defenders an advantage. Finger is almost never used for legitimate purposes in modern networks, so in most cases, it can be blocked/disabled without any risk to the environment. By taking this single step, organizations can protect themselves from further infection from this ClickFix campaign.
We learned that modern AI models such as ChatGPT (5.5) are now incredibly powerful tools when it comes to malware triage and analysis. What used to take hours or even days can now be accomplished in minutes. In the right scenario, these AI tools can be leveraged by security analysts to not only boost productivity, but be used as a learning tool. While AI may not get everything right, it is now in a place where it can be used for more complex tasks such as malware analysis.
Lastly, CastleLoader is an incredibly interesting piece of malware that goes to great lengths to avoid detection. AI tools are now commonly used by threat actors as well, enabling them to rapidly create more advanced malware. Single security controls such as EDR are not silver bullets (not that they ever were). A robust, defense-in-depth security strategy is required to have a chance at protecting your organization. Using advanced network monitoring tools such as PacketWatch will give organizations the ability to detect malicious behavior over the wire when endpoint tools fail.
John Garner
This profile is provided FREE to the cybersecurity community.
Visit our Cyber Threat Profile Blog for additional profiles.
Visit our Cyber Threat Intelligence Blog for intelligence reports.
Subscribe to be notified of future intelligence profiles and reports: