HomeMalware Analysis
Brute Ratel C4 Badger Used to Load Latrodectus
HomeMalware Analysis
Brute Ratel C4 Badger Used to Load Latrodectus

Editor’s note: The current article is authored by Mohamed Talaat, a cybersecurity researcher and malware analyst. You can find Mohamed on X and LinkedIn.

Brute Ratel C4 (BRC4) is a customized, commercial command and control (C2) framework that was first introduced in December 2020. Its primary use is for conducting adversarial attack simulation, red-team engagements, and penetration tests.

What sets BRC4 payloads apart from other C2 frameworks like Cobalt Strike or Metasploit is their ability to effectively bypass and avoid endpoint detection and response (EDR) solutions. This is due to the extensive research conducted by the developer on these software solutions.

As you read our investigation and analysis of the BRC4 badger that was spotted loading Latrodectus loader into memory after a successful connection to the BRC4 C2 servers, the effectiveness of BRC4 will become clear.

What’s Latrodectus?  

Latrodectus is a recently discovered malware loader that is suspected to be a potential successor to the IcedID malware. Security researchers believe that Latrodectus was developed by the same threat actor group responsible for IcedID, due to similarities in development and behavior. Like other malware loaders, Latrodectus is used to deploy additional, more sophisticated malware onto compromised systems.

Latrodectus was one of the malware targeted in Operation Endgame, a law enforcement operation aimed at disrupting cybercriminal activities. However, it seems that the developers behind Latrodectus were able to quickly recover from the temporary disruption caused by the operation and rebuild their infrastructure.

Latrodectus has been observed to be delivered as part of a multi-stage attack that typically starts with a phishing email containing a malicious Java script or PDF file used to trick victims into installing a malicious MSI file. This MSI file contains an older version of the BRC4 badger, which is the focus of our analysis.

Initial triage  

While looking for new malware to investigate, we found an interesting sample submitted to ANY.RUN‘s Public Submissions database. 

The sample in question

It was an MSI file, which matched the description above of how the malware is delivered as part of a multi-stage attack that involves a malicious MSI.

About MSI files

MSI files are a container file format that utilize the COM structure technology, allowing them to store necessary files for minimal user action. This makes them similar to self-extracting ZIP files, as they can unfold and start executing in a pre-defined order.

Additionally, the installation procedure for MSI files allows execution with elevated privileges (NT AUTHORITY\SYSTEM), which means that unprivileged users can execute their malware as SYSTEM. This makes MSI files an attractive deployment method for threat actors.

ANY.RUN’s process tree displaying the connections between processes

Upon execution of the malicious file, the Windows command line utility “msiexec” was spawned to execute the MSI file. The “msiexec” process then ran the following command:

“C:\Windows\System32\rundll32.exe”C:\Users\admin\AppData\Roaming\upfilles.dll, stow

This command loaded the BRC4 badger DLL (upfilles.dll) and executed the export function “stow”, which initiated the infection chain. This behavior is visible in the process tree above.

Upon seeing the process execution flow and the command used to load the BRC4 badger DLL, we decided to investigate the MSI file further.

Analyze malware and phishing threats in ANY.RUN sandbox 

Sign up for free

Static analysis and reverse engineering  

We began our analysis using Orca, a Microsoft database editing tool for examining and editing MSI files. Upon opening the MSI file in Orca, we navigated to the CustomActions table in the main database stream.

There we found a LaunchFile action which started an embedded executable, viewer.exe. This executable then launched rundll32.exe, taking the name of the aforementioned DLL and the exported function as arguments.

LaunchFile action in orca

Because we can treat MSI files as self-extracting ZIP files, we can unzip them using any basic extractor tool. Upon doing this, we found only a few files of interest, those were the ones mentioned in the CustomActions table, which is where the MSI file developer can specify custom actions to take place during the execution process of the MSI file such as executing an export from a DLL of interest.

As we mentioned, MSI files can be treated as self-extracting ZIP files and can be unzipped using any basic extractor tool.

When we unzipped the MSI file, we found only a few files of interest. These files were mentioned in the CustomActions table, which is where the developer of the MSI file can specify custom actions to take place during the execution process of the MSI file, such as executing an export from a DLL of interest.

The file which contains the dll

After unzipping the MSI file, we did not find the upfilles.dll file. Yet, after further investigation, we discovered that the DLL was hidden inside the disk1.cab file.

Analysis showed the presence of the dll inside disk1.cab

We then unzipped disk1.cab and extracted the upfilles.dll loader. 

The contents of the cab file

upfilles.dll – initial loader  

After taking a closer look at the export, we quickly noticed that the string kernel32.dll was constructed using a technique called stack string builds, which is a common method for obfuscating strings.

Analysis of kernel32.dll

The function used the obfuscated string kernel32.dll to obtain the base address of the DLL in memory. To do this, the function first attempted to locate the Process Environment Block (PEB) and parse it to get a pointer to the list of loaded modules. It then compared the length of the target DLL to the lengths of the names of the modules loaded into the process memory, until it found a match.

Comparison of the target_dll to the one of the cur_module_name

Having obtained the base address of kernel32.dll, a standard technique was employed to get the addresses of the functions necessary to load up the next stage of Brute Ratel in memory. 

  • Get a pointer to the PEB_LDR_DATA through the PEB
  • Locate the export directory of kernel32.dll
  • Walk the ENT (Export Names Table), hash function names, and compare the hashes until a match is found 
The address of the function with a matching hash is returned

Functions resolved by hash:

  • GetProcAddress  
  • VirtualAlloc  
  • LoadLibraryA  
Functions resolved by hash

The loader then proceeded to decrypt the next stage using an XOR operation with a dynamically generated key. The next stage employed numerous EDR evasion techniques, which we will analyze in detail later. 

Decryption of the next stage

The encrypted next stage of the badger was stored in the last section of the initial DLL (upfilles.dll), the section name was “hVr” 

Encrypted BRC4 badger

Having decrypted the payload, a PAGE_EXECUTE_READWRITE memory was allocated to write the decrypted payload into, and then jump to it.

Decrypted BRC4 badger

Get a 14-day free trial of ANY.RUN sandbox 

Request now

Memory-only Brute Ratel Implant  

The version of Brute Ratel that was loaded into memory during this attack was an older one, which likely contains many weaknesses that have since been fixed in later versions of BRC4.

The technique used by the implant to keep the process alive involves jumping back and forth between different threads using the Sleep API. The Sleep API suspends the execution of the current thread for a specified amount of time, allowing other threads that were created to perform their tasks to take control.

 

The thread sleeps for one minute giving control to other threads

The BRC4 badger executes entirely in memory and never writes any files to disk in order to avoid leaving system-level artifacts. Its execution process begins by loading another embedded DLL into memory, which then writes x64 shellcode. This shellcode is responsible for decrypting and writing the final payload to memory.

CreateRemoteThread function

X64 BRC4 shellcode  

The x64 shellcode used in the BRC4 badger employs control-flow obfuscation techniques to calculate the address of the subsequent block of code.

The call used to put the address of the next inst onto the stack

The shellcode used a unique method to locate the address of NTDLL. It first obtained a pointer to the PEB and then found the PEB_LDR_DATA structure, which was set to the NTDLL!PEB_LDR_DATA during process initialization. The PEB_LDR_DATA structure was located somewhere in the middle of the NTDLL. It then walked through the NTDLL until it reached the very start of the DLL, at which point it returned.

Walking ntdll

The shellcode used a standard anti-debugging technique called NTGlobalFlag to detect the presence of a debugger before decrypting and loading the final payload into memory.

 

Checking for flags set by a debugger

Instead of calling the function address directly, which could be detected by an already installed EDR hook, the shellcode retrieved the System Service Number (SSN) of the resolved function. It did this by walking the syscall stub and then returning the SSN to be used later to invoke the corresponding function.

Malware’s use of SSN

This technique employed by BRC4 was also heavily used in the final payload to resolve and invoke the needed functions.  

The process of dynamically retrieving syscall numbers or SSNs (which are just unique identifiers to functions exported by the kernel) is the outcome of an earlier research that solved the problem of having the syscall numbers change across different Windows versions and was named “Hell’s Gate”. This technique requires a clean version of NTDLL. 

A breakdown of the technique is as follows:

  • Walk the given function’s syscall stub, until it finds the function’s SSN
Execution of the technique
  • Having obtained the function’s SSN, there’s no point going through the whole syscall stub, instead we get a pointer to the last couple of instructions of the stub
Pointer to syscall
  • Jump to a custom function which will invoke the syscall
Jump to a custom function

Having resolved the necessary functions to map the final payload to memory. The final payload is XOR decrypted using a dynamically generated key.

Payload decryption

BRC4 Final Payload  

The final payload was designed to be highly EDR evasive. It implements many EDR evasion techniques meant to circumvent different components of different EDR vendors, the most notable of which is the “Hell’s Gate” technique using direct syscalls. 

There are other evasion techniques which we’ll break down, but it’s worth noting that aside from being evasive its core functionality is to gather system information, upload it to its C2 servers over HTTPS, then get further commands for what to do next. 

Unregister DLL load callbacks 

Some EDR products may register their function callbacks at the kernel level to receive telemetry from DLL load or unload events.

To bypass this, a technique is used where an empty callback function is registered, which is added to the end of the chain of registered callback functions. The list of callbacks is stored in a circular doubly-linked list, where the last element points to the first one in the chain.

By finding the pointer to the start of the chain, the technique can walk the list and unlink all of the registered callbacks, effectively suppressing the EDR’s attempt to receive DLL load and unload telemetry if it has already registered its own callback functions at the kernel level.

Last node’s Flink points to the first callback entry which is the head of the list of callback functions

Proxying DLL Loads to Hide from ETWTI Stack Tracing 

This technique is used to evade EDRs that rely on stack tracing telemetry for detection. The author disclosed a detailed description of this technique on their blog.

Some EDRs may trace and analyze function stack frames stored on the stack to find suspicious patterns and detect malicious activity. To avoid detection, this technique creates a clean stack for DLL loading by running the LoadLibraryExA function in a separate thread, hence its own clean stack frame.

Details of the technique

Evading ETW event logging (patchless evasion) 

This is a new technique for evading Event Tracing for Windows (ETW). Typically, ETW patching involves overwriting the first few bytes of the “ETWEventWrite” function so that it returns prematurely, avoiding ETW telemetry.

However, in this case, the author used a patchless evasion method. They set hardware breakpoints at two common functions called by ETW to log process events, “NtTraceEvent” and “NtTraceControl.” Then, they registered their own VEH to catch EXCEPTION_SINGLE_STEP exceptions, which occur when a hardware breakpoint is hit.

When the breakpoint is hit and the handler catches, execution is redirected to a dummy function that does nothing but return zero. This prevents the actual function logic from executing, and as a result, the event is not logged. 

ETW evasion

C2 Communication  

The malware first resolves all the necessary APIs and then performs system discovery to gather information about the infected system.

This information is stored in a JSON construct and then encrypted using an RC4 encryption algorithm with the key LDTPTF78OUCCVQ0I.

The encrypted data is then uploaded to one of the hardcoded command and control (C2) domains.

The gathered information includes the current PID, thread ID, computer name, Windows version, and other system details.

Before encryption 

{“cds”:{“auth”:”6J1D1M4P9A57JGC2″},”mtdt”:{“h_name”:”DESKTOP-8VTQJ38″,”wver”:”x64/10.0″,”ip”:”0.0.0.0,0.0.0.0″,”arch”:”x64″,”bld”:”1337″,”p_name”:”QwA6AFwAVwBpA 

G4AZABvAHcAcwBcAFMAeQBzAHQAZQBtADMAMgBcAHIAdQBuAGQAbABsADMAMgAuAGUAeABlAA==”,”uid”:”*dtm”,”pid”:”4248″,”tid”:”1248″}} 

The ANY.RUN sandbox providess the C2 domains that the malware communicates with to send the collected system information over HTTPS.

C2 domains detected by ANY.RUN

It appears that we’re not receiving any response from the C2 domains because the domains are currently down. 

 It also checks for a response from the C2 before it begins listening for further commands to execute. 

Indicators of Compromise

Hashes

b4a482a7e96cfdef632a7af286120156 MSI
ccb6d3cb020f56758622911ddd2f1fcb upfilles.dll
83bca228a6a8f5e6d7c95d2a08494d32 in-memory DLL (decrypted DLL embedded in upfilles.dll)

BRC4 Domains  

boriz400[.]com

anikvan[.]com 

ridiculous-breakpoint-gw.aws-use1.cloud-ara.tyk[.]io 

uncertain-kitten-gw.aws-euc1.cloud-ara.tyk[.]io 

Mohamed Talaat
+ posts

Mohamed Talaat is a Computer Engineer with a Bachelor in Computer Engineering from Suez Canal University (Ismailia, Egypt). Despite not having a strong cybersecurity background, he took it upon himself to establish a career in cybersecurity. Нe found himself a better fit in Blue Teaming and malware analysis. Engaging in malware analysis and the development of TTPs, he also writes detection rules as part of his daily routine.

Mohamed on LinkedIn.

mohamed-talaat
Mohamed Talaat
Mohamed Talaat is a Computer Engineer with a Bachelor in Computer Engineering from Suez Canal University (Ismailia, Egypt). Despite not having a strong cybersecurity background, he took it upon himself to establish a career in cybersecurity. Нe found himself a better fit in Blue Teaming and malware analysis. Engaging in malware analysis and the development of TTPs, he also writes detection rules as part of his daily routine.

Mohamed on LinkedIn.

What do you think about this post?

5 answers

  • Awful
  • Average
  • Great

No votes so far! Be the first to rate this post.

0 comments