Redline Stealer

Redline Stealer

in

Intro

For this hunt, I will be sharing my analysis notes and thought processes on how I approached the Redline Stealer malware, what I learned from reverse engineering it and how it given me an idea of what I can build upon the things that I currently know. Here is some background on this malware family from Malpedia:

RedLine Stealer is a malware available on underground forums for sale apparently as standalone ($100/$150 depending on the version) or also on a subscription basis ($100/month). This malware harvests information from browsers such as saved credentials, autocomplete data, and credit card information. A system inventory is also taken when running on a target machine, to include details such as the username, location data, hardware configuration, and information regarding installed security software. More recent versions of RedLine added the ability to steal cryptocurrency. FTP and IM clients are also apparently targeted by this family, and this malware has the ability to upload and download files, execute commands, and periodically send back information about the infected computer.”

Malpedia

Recently, many content creators had been targeted by this particular malware campaign, abusing powerful and catastrophic yet publicly available tools (ahem, YouTube’s Copyright Claims system) to conduct cunning yet startlingly convincing attacks. I wanted to gain an understanding of the mechanics behind these attacks better through slightly lower level tools (as well as a great amount of improvising!) and techniques that can be used to handle crimeware.

To start with the hunt, here were the tools I used:

  • Detect It Easy
  • CAPA 4
  • dnSpy
  • Process Hacker
  • x64dbg
  • PE Sieve

Analysis

Overlay Bytes

To evade sandboxes and antimalware, the original file contained an overlay, which caused it to be too big to analyse inside automated environments (reference).

The sample totals to 700MB, which can evade set file size limits within sandboxes and antimalware solutions

Within Detect It Easy, the PE is shown to have its normal sections, as well as the bytes that prevent it from being analysed.

Rows of bytes consisting of 0x30 (0 in ASCII) lay dormant within the executable

The below script can be used to strip the overlay bytes from the executable to bring it back close to its original size.

import pefile
import sys
import os

data = []
filename = sys.argv[1]

print(f"[*] Original file size: {os.path.getsize(filename)}")
print("[*] Stripping overlay from file, standby...")

pe = pefile.PE(filename)
overlay = pe.get_overlay_data_start_offset()

strip_filename = filename + ".strip" 

with open(filename, "rb") as fp:
    data = fp.read(overlay)
    with open(strip_filename, "wb") as fp:
        fp.write(data)


print(f"[*] Stripped file size: {os.path.getsize(strip_filename)}")
print(f"[*] New file is called {strip_filename}")
print("[+] Done!")

Alternatively, de4dot is capable of guessing the type of obfuscator used by the malware authors and removing the overlay, which I went with.

de4dot identified a possible obfuscator used and cleaned the overlay bytes as well as light obfuscation

Initial Triage

Searching through VirusTotal, there were no community comments at the time of investigation despite the sample having been uploaded there for a while. It was only known to be malicious by several AV engines.

Vendor results from VirusTotal

Intezer however, was a different story. When running the sample inside its sandbox, it reported the following TTPs:

TTPs as well as their techniques, severity ratings and further details were identified in Intezer

As expected, all platforms also reported that the implant steals credentials. At this point, it was time to investigate within dnSpy.

Anti-Debugging (dnSpy)

After loading the sample into dnSpy, I found that its classes and objects had very deceptive names (surprise, surprise in crimeware). After attempting to run it, the sample halted its execution due to the presence of the debugger.

An anti-debugging technique was used to slow down dynamic analysis

This Redline sample detected dnSpy through dynamically imported functions, and to deal with this, I patched the IL assembly instruction for the line of if (ImageInvoker.DisableReference()) - the new logic of the expression was that if the sample detects the debugger, it runs. Reverse engineering psychology, right?

The original logic of the expression within the IL instructions was bfalse.s, before it got reversed to btrue.s through patching

After saving the module, the implant worked perfectly.

Hunting for the payload

After scouting through the executable, I found an abnormally long series of bytes which even dnSpy couldn’t process them all.

Noticing an array of bytes present within the C#

…10000+ lines later

It was like staring down an elephant inside the room! I set a breakpoint at the caller so I can extract it from memory. It was 509KB in total.

Chucking a Pokéball at the payload in memory

After decompressing the gzip data with CyberChef, the payload was found to be indeed a .NET-based PE. However, it was heavily obfuscated. de4dot was unable to detect which obfuscator was used on it as well.

.NET assembly found in memory, containing obfuscated namespaces, classes and methods

Exploring Process Hollowing

Definitely not a generated meme

I wanted to explore process hollowing as it happened at code level, but given that the code of the payload was heavily obfuscated, viewing the unmanaged calls through dnSpy proven difficult.

Some of my wild guesses were:

  • .NET and PowerShell abuse System.Reflection.Assembly.Load - the process hollowing may have been happening through the invoked .NET assembly, so it may bave been best to set a breakpoint at this function and extract .NET assemblies from there. The ImageDictionary class was likely responsible for this.

I noticed that the sample killed its own process prior to starting InstallUtil. I set a breakpoint at various functions I believed the malware used (including Process.WaitForExit), and after a bit (hours, actually) of stepping through the code inside the debugger and observing the call stack, here was an example of what I seen:

Call stack of the functions called before Process.WaitForExit

Quite the mess! Trying to analyse the obfuscated .NET assembly in dnSpy was a difficult task, so in the end I opted for continuing the dynamic analysis through x64dbg as the executable will eventually remove its own obfuscation once it is fully loaded in memory.

I’m aware that process hollowing uses the following APIs, which I set breakpoints for (as well as their counterparts) inside x64dbg, the ones in bold being prioritised due to them containing arguments related to what was seen in the TTPs: )

  • CreateProcess
  • ZwUnmapViewOfSection
  • VirtualAllocEx
  • WriteProcessMemory
  • SetThreadContext
  • ResumeThread

This is a classic pattern of process hollowing to make room for the malicious process, launching a legitimate Windows executable and using it as a sacrifical lamb to hide from security tools that lack the capability to detect and prevent malicious usage of these APIs. In the below sections. I was able to catch a few calls to a number of calls on some breakpoints.

CreateProcessW

After a lot of trial and error, the first breakpoint that caught my eye was a call to CreateProcessW.

First call made to CreateProcessW

One of its arguments within the stack aimed to execute 64-bit PowerShell, along with a Base64-encoded command that causes the console to sleep for 10 seconds. Unimportant, but still one of the TTPs and a way to identify similar behaviour.

As seen in the stack

The full command line can be as seen in Process Hacker:

CreateProcessA

As expected, the malware eventually made a call to CreateProcessA that requested the Windows API to start a suspended process with the image of InstallUtil. ZwUnmapViewOfSection and VirtualAllocEx calls targeting InstallUtil followed not long after, removing all executable instructions of the original PE image and allocating space for the payload to be injected.

First breakpoint at CreateProcessA

Command line presented to the function

Below shows the strings of the original executable in memory before the injection and the parent-child relationship between the processes:

Normal strings expected within the executable

The sample presented itself as the parent process for InstallUtil - this can be helpful when hunting for IOCs through SIEMs

WriteProcessMemory

Finally, it was the Windows API call we had all been waiting for - WriteProcessMemory! Being able to catch a payload as it is being written to a target (whether it’s a file, process or network destination) is a crucial part of the analysis; in this case I am simply retrieving the evidence that a write operation is taking place. Below, the API in question as well as the PE header of the payload was spotted in x64dbg.

WriteProcessMemory as well as the parameters passed to it on the stack

Seeing the PE header in the stack gave the impression something cool was probably happening and worth watching! I allowed the program to run the function until it had returned a couple of times and completed its transfer of data.

Spotting a partial chunk of the PE within the dump

Process Hacker also displayed corresponding results about the injection taking place within the new process.

Query strings, file paths and more slightly obfuscated data relating to credential stores present in memory

The next calls to SetThreadContext and ResumeThread would then set the entry point to the new code section and take the process out of suspended state, hence proving the proxy execution of a trusted developer utility.

In other targeted campaigns, I would imagine malware authors would go through a lot more effort to hide strings in memory, especially from tools such as EDRs. Several of them were found in plaintext relating to software file paths, password databases and query strings which indicates successful code injection has taken place, and the final Redline payload is now running and attempting to steal personal information.

Seeing those strings, it was about time to dump the payload from memory.

Dumping the injected PE

Aggressively tossing out the malware from memory

Given the process hollowing technique was used to inject the payload into InstallUtil, I used PE Sieve to extract the malware. PE Sieve is a powerful tool for detecting processes that were targeted in a potential code injection attack, dumping replaced or injected PEs, shellcode, hooks and other in-memory patches from memory and saving them into a file readily available for analysis.

PE Sieve detected 1 occurrence of malicious code and dumped it into a new file

Of course, resulting threat intelligence tells that this executable is related to the Redline Stealer campaign due to code reuse.

The payload as seen in VirusTotal, it was also recognised by the signatures within Florian Roth’s tool

Threat intelligence as shown in Intezer

WSAConnect

The payload itself was a portable executable, which could still be run alone. It was responsible for connecting to the command and control server as well as extracting and marshalling credentials and banking information to send back. Different command and control servers use a variety of protocols such as HTTP/S, DNS and IRC (ah, good old days!). Occasionally, threat actors write their own custom C2 protocols which do not adhere to the transmission rules of a well known service associated with their assigned port, and in turn can increase analysis time if it is not already known within threat intelligence, and circumvent firewall rules within organisations. In this case, the Redline sample attempted to connect back to 65[.]21[.]74[.]139 on port 20775, and for that it required the Win32 APIs.

MSDN described WSAConnect as one of the functions responsible for creating a network connection to IPv4 and IPv6 hosts. What I was most interested in was name - this parameter contained the address pointing to the variable that held the string of the C2 address within this malware.

The target here was to identify the name parameter, which is a socketaddr struct that contained the IP address of the C2 server

After following the stack and sequentially the DWORD for the pointer within the name parameter, the IP address of the command and control server was located within the memory dump.

The sequence of bytes containing the address pointing to the parameter in question

The IP address of the C2 as seen in the dump

IOCs

Original SHA256: b4781474596c183da5b10c22ce2260c802ef4f553ed347f4813ad30cab0d56e2

Stripped SHA256: 62B06D71CD6403A1E2DB56E498A5A8B14B6908F5DDFEC9FA4D5F49F6F4A70678

65[.]21[.]74[.]139

Process Creation: - "C:\\Windows\\System32\\WindowsPowerShell\v1.0\\powershell.exe" -enc UwB0AGEAcgB0AC0AUwBsAGUAZQBwACAALQBTAGUAYwBvAG4AZABzACAAMQAwAA==

Process Creation - C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\InstallUtil.exe

Injected payload SHA256: 16263ec84e6175336debb2da5fda9560236b1ce00bf2eec1e2bb5714a9ce3430

References

https://malpedia.caad.fkie.fraunhofer.de/details/win.redline_stealer https://tria.ge/220705-zwf3dsdaaq https://www.virustotal.com/gui/file/62b06d71cd6403a1e2db56e498a5a8b14b6908f5ddfec9fa4d5f49f6f4a70678 https://analyze.intezer.com/analyses/6146f62d-9f78-4e38-b944-b62daa82ade7/ https://www.virustotal.com/gui/file/16263ec84e6175336debb2da5fda9560236b1ce00bf2eec1e2bb5714a9ce3430 https://analyze.intezer.com/analyses/a3ba1334-11b9-4534-934d-f17f6c501c69

VMProtected Variant

While nearly finishing the unpacked variant, I decided to have a brief look at the one John Hammond mentioned in his Twitter status too. As I am still learning the ropes of unpacking malware in different circumstances, I want to re-visit this on a future occasion!

Initial Triage

Pretty much the same principles applied to getting rid of the overlay. It went down from 471MB to a mere 600KB.

Original SHA256: f8df7a34f17242157f9095b4aa05740c7ea9769bacd766cb1b0eac817a52455b

Stripped SHA256: 514eef525b97f3e00ff6f4bc60955c0fe0a5ff74d5996b448e80e6eef699c5ed

Detect It Easy indicates the sample was packed with VMProtect 3.2-3.5 through its import hashes

CAPA 4 particularly didn’t enjoy being fed this sample (who would with any malware really?), probably most likely due to VMProtect 3

Assumptions for Future Analysis

Because there is a lot of threat intelligence and analysis on Redline, many of its behaviours had been already documented and there would be a great number of assumptions to make when re-exploring this variant:

  • Reading files and registry keys - due to its nature of accessing password databases and files, ReadFile and RegOpenKey will be most likely used)
  • Internet Connections - it tries to connect back to C2 servers, and the connections can be emulated. Some Windows API functions for this include WSAConnect and WSASocketW.

These functionalities would be enough to consider setting breakpoints at and exploring when I unpack this variant.

Another assumption to make is that some or many of its functions would need to be devirtualised due to it being packed by VMProtect, and if I wanted to make the executable runnable again I would need to fix the original entry point and the import address table. In the real world, there would be a high chance I would use automated tools such as UnpacMe to extract the payload, but it would be great to have some practise unpacking manually as well.

Threat Intelligence

https://tria.ge/220829-ray23sbdh9 https://www.virustotal.com/gui/file/514eef525b97f3e00ff6f4bc60955c0fe0a5ff74d5996b448e80e6eef699c5ed https://analyze.intezer.com/analyses/cd7437cf-35f9-4804-93bf-186362abd9b1 https://www.joesandbox.com/analysis/695059/0/html

Ending Thoughts

Investigating this sample had unearthed some skills that laid dormant in my arsenal for a very long time, and it allowed me to experiment with things that worked and did not work. I had a lot of fun working on this, going some of the extra miles with what I currently know in this hunt may not have been practical in the real world (malware reports are more focused on exposing immediate effects of malware rather than verbose steps on how to expose them) but they can come in handy on future occasions. There were a few things that I learned:

  • Overlays within malware - to be honest, I was surprised when I saw that this technique worked to bypass protections, but it works. Because of this flaw combined with an innocent Microsoft Office icon and convincing document title, unsuspecting victims who had been sent similar malware with no intervention from their antimalware solutions would have been impacted by this campaign
  • Evading anti-debugging - patching the logic of this sample was exceptionally easy, especially since the malware authors did not put that much effort into preventing further analysis on it. However, that was not to say that I was unable to explore with a bit of trial and error on amending the IL instructions and source code!
  • Understanding when to switch tools or techniques - dnSpy was definitely a good choice for static analysis on the executable before it performed code injection attacks, but made terribly for dynamic analysis especially since native APIs were outside of its scope. With x64dbg, it was possible to monitor the calls made to these APIs and see the attack happening in real time, and I would be able to save time rather than attempting to deobfuscate and understand the malware behaviour by myself!

Hopefully this post was easy and comprehensive for other beginners who are also keen on getting into malware analysis. I’m looking forward to taking on more challenges!

Thank you for reading, if you want to talk about this post or have any questions feel free to reach out to me on any of my social media handles.

Shoutouts

This exercise was made possible thanks to HuskyHacks, check his social media out!

Also check out billycontra, this awesome individual proofread my endeavors and provided some helpful advice before it went live!