RingZer0 CTF Malware Analysis: Capture 2

Welcome back. I recently found the RingZer0 CTF website while looking for some malware analysis/RE challenges. CTF-style malware analysis challenges can be harder to find online; I’d definitely like to see a Vulnhub for compromised machines, where the challenge is to recreate the infection timeline, but for now I’ll settle.

Capture 2 seems like an interesting challenge because the given file is a memory image. I’ll run it over to my RemSift machine (Remnux and SIFT installed on Ubuntu) and hopefully expand my memory forensics knowledge.

I ran volatility’s imageinfo plugin on the image to identify the OS and version with a search of the KDBG structures.

It appears to match the profile for Windows XP Service Pack 2. This is good because if I have to pull malware from this image and analyze it, which is likely, I’m much more likely to understand Windows libraries.

Question 1: What is the CVE of the exploited vulnerability?

Well, that’s a tough question to begin with. CVEs are very specific identifiers for exploitable vulnerabilities, and there are thousands of them. If I’m lucky, I can look in the command history for the memory image using volatility’s plugin cmdscan, and maybe the attacker will have used a metasploit module with a CVE I can look up.

Except I forgot cmdscan only works for Windows 7 and above. Let’s try the consoles plugin instead.

The consoles plugin in action.

Well unfortunately, the plugin didn’t give me a command history as it might on a Windows 7 machine. We have a process ID and we could probably get some strings out of memory, but I feel like this might be a dead end. Maybe we can work backwards from more evidence to get the CVE, so I’ll move on.

Question 2: Process Name and PID of the Exploited Process

Okay, I might know how to do this. A process that has been exploited by malware should show signs of compromise, including the loading of malicious libraries or remapping of memory addresses. One of the easiest ways to use a process to call malicious code is writing malware to a place where it can be executed in memory. The first way to look for evidence of this in memory is looking at the process maps for containers that have the permissions Read, Write, and Execute set. This information can be found in a process’s VAD, or Virtual Address Descriptor.

Many processes may have memory containers with RWX set, so searching through all the VADs in memory could be tedious. Fortunately, there is a Volatility plugin that searches for VADs with RWX set on memory containers; it’s called malfind.

A process with the VAD protection RWX; in this case, malicious.

As you can see, malfind is extremely helpful. It displays the process name, process ID number and the address in question, in case we want to dump the memory at this location for further analysis.

Fortunately, it also displays the beginning of the data at the location in hexidecimal and ASCII, and you can see the ‘MZ’ translated from the hexidecimal value 4d 5a. MZ is the file header for a Windows executable, which means the data at this location could be a malicious executable injected into svchost.exe. Plus, svchost is a commonly used process for hijacking and injection because there are usually several legitimate instances running on a given machine. I submitted this as the answer, and jackpot! Let’s move on:

Question 3: Connect back IP and port?

This question is likely asking about the network activity of the compromised machine connecting back to the attacker. More than likely, a backdoor of some kind was used; perhaps a reverse shell. Let’s run the memory image through the gauntlet of volatility’s network plugins, starting with connections and connscan:

connections didn’t display any results, but connscan pulled through. This is likely because the connections listed by connscan were terminated by the time the memory image was acquired.

As you can see, there were several remote network processes occurring on different ports. However, only one of them matches the Process ID of the compromised process svchost.exe, which is 1092. The infected machine is connecting back to 10.0.75.16 (looks like a computer on the same internal subnet) through port 21. Port 21 is commonly used by FTP, the File Transfer Protocol, and is another indication this may be our reverse shell to the attacker.

And we were correct. Moving on…

Question 4: What is the Victim’s User Password?

The first thing that comes to mind when thinking about extracting passwords from memory is a post-exploitation tool called Mimikatz. Used offensively, it exploits the lsass.exe process with malicious code and reads passwords from memory structures. It was recently adapted into a Volatility plugin for use on offline memory dumps, which will be helpful to us here. Let’s run it.

Running the mimikatz plugin on the memory image.

No dice on that. Well, maybe it’s am issue with my RemSift installation. I pointed the mimikatz plugin at the whole memory image, but there’s another approach where you dump the memory of the lsass process and point mimikatz at it instead. Unfortunately, I tried this and found that volatility doesn’t have support for minidumps (the format of the process memory dump). This means I’ll need to take it to a native installation of Mimikatz, on Windows.

Using Mimikatz against the minidump on my FLARE (Windows 7) VM.

No luck there either. Maybe we can try a different approach to recovering the passwords, although I can’t imagine why Mimikatz would be failing. Let’s look for password hashes in the registry hives.

I’ll use the volatility plugin hivelist to find the memory addresses of the SYSTEM and SAM hives, which hold the hashes to the passwords we want. After that, there’s a plugin called hashdump that parses the hashes. Let’s try that strategy:

Using Volatility’s hashdump, passing in the offsets of the SYSTEM and SAM hives.

Okay, good signs: we see the user and hash for ‘victim’, the account we need. Let’s see if the hash is crackable.

I used hashkiller.com, an automated hash decrypting website. Some of you may use CrackStation, but I’m glad I tried another site, as it didn’t work for me.

And it worked! The decrypted password was correct.

Well, I think that’s enough for now; I’ll be attempting more challenges like these in the next CTF-related blog post. Thanks for reading!