OtterCTF 2018 – Network Challenges – Otter Leak Write-up

OtterCTF dates from December 2018 and includes reverse engineering, steganography, network traffic, and more traditional forensics challenges. This write-up covers the network forensics portion. I have previously written-up the memory forensics section, and the Birdman’s Data and Look At Me network challenges. The whole CTF is available to play as of the publication of this post.

I managed to complete three of the four challenges in the network traffic section of the CTF. This post is a write-up of the Otter Leak challenge.

We start off by downloading the PCAP. The MD5 and SHA1 hashes are:

MD5: d0ab559c54fffe713fd13e9b0f7174df
SHA1: 35a934a665497c111ad572299840f002476cff81

Opening the PCAP file with Wireshark, we can check the Protocol Hierarchy to get a quick summary of the kind of traffic we are working with.

We can see some SSH traffic, but more interesting at the moment is the SMBv2 traffic which is often used to transfer files. We could use a tool like Network Miner to extract any file objects from the PCAP, but Wireshark gives us the means to do this as well.

Checking the Export SMB Objects window, we can see a large number of files with names suggesting they are images, but with a file size of only 1 byte. Let’s export them all to a new directory and see what we have.

We can use the cat command to print the content of all our 1-byte files to the terminal…

cat export/%5cotter-under-water.jpg.638x0_q80_crop-smart*

…giving us the following output:

LS0gLS0tLS0gLi0uIC4uLi4uIC4gLS0tIC0gLS0uLi4gLi4uLS0gLi0uIC4uIC0uIC0uLi4gLS4uLi4gLi4uLi0=

Our output has the = padding suggesting we might be dealing with base64 encoding. Let’s see what CyberChef makes of this.

Running the From Base64 operation gives us something that looks like Morse Code.

-- ----- .-. ..... . --- - --... ...-- .-. .. -. -... -.... ....-

We could try to decipher this by hand, or we can use CyberChef’s From Morse Code operation to do it for us.

And just like, out pops our plaintext leaked data and our flag.

CTF{M0R5EOT73RINB64}

 

OtterCTF 2018 – Network Challenges – Look At Me Write-up

OtterCTF dates from December 2018 and includes reverse engineering, steganography, network traffic, and more traditional forensics challenges. This write-up covers the network forensics portion. I have previously written-up the memory forensics section, and the Birdman’s Data network challenge. The whole CTF is available to play as of the publication of this post.

I managed to complete three of the four challenges in the network traffic section of the CTF. This post is a write-up of the Look At Me challenge.

We start by downloading the challenge PCAP and calculating hashes for reference.

MD5: d7dbb2394596594b438ab3110ace3408
SHA1: fc16f0636a7f141b8b17e0e7a38b776dd5c21c82

Opening up the PCAP in Wireshark, the first thing is that we are not working with TCP/IP traffic; instead this appears to be USB data from a Wacom CTL-471 drawing tablet. After some Google searching I found a write-up of a 2017 BITSCTF challenge featuring USB traffic from a Wacom CTL-460 tablet, which was a huge help in solving this challenge.

With the help of The Blog Post I realised that the packets containing the Leftover Capture Data we need could be filtered within Wireshark based on the Frame Length

((usb.transfer_type == 0x01) && (frame.len == 37))

Then extract to a separate PCAP with tshark for further processing.

tshark -r look_at_me.pcap -w filtered.pcap -Y '((usb.transfer_type == 0x01) && (frame.len == 37))'

The data we need is a representation of the X/Y coordinates of the pen on the drawing tablet, and the Z value representing the pressure of the pen. Using the packet in the screenshot above as an example:

02:f0:82:0a:ba:05:00:08:00

02:f0 - Header
82:0a - X
ba:05 - Y
00:08 - Z (Pressure)
00    - Padding?

This data is contained within the usb.capdata field; we can use tshark again to extract this to a text file and discard the rest of the PCAP.

tshark -r filtered.pcap -T fields -e usb.capdata -Y usb.capdata > usb.capdata.txt

The next thing to do was to use awk (shamelessly lifted from The Blog Post) to convert these raw hex values to little-endian X/Y and Z coordinates.

awk -F: '{x=$3$4;y=$5$6}{z=$7}$1=="02"{print x,y,z}' usb.capdata.txt > usb.capdata.txt.xyz

After installing the pwntools Python library and running a small Python script “inspired” by The Blog Post, we have the coordinates in a format suitable to be plotted as an image using Gnuplot.

#!/usr/bin/python
from pwn import *

for line in open('usb.capdata.txt.xyz').readlines():
  coord = line.strip().split(' ')
  x = int(coord[0],16)
  y = int(coord[1],16)
  z = int(coord[2],16)

  if z > 0:
    print u16(struct.pack(">H",x)),u16(struct.pack(">H",y))

We feed our newly converted coordinates into Gnuplot

And out pops an image!

After exporting to a PNG file, we can flip it for easier reading.

convert -flip flag.png flag-flipped.png

There we go! Submit the flag and claim the points, thanks in large part to The Blog Post.

CTF{0TR_U58}

Next up in my OtterCTF series, Otter Leak.

13Cubed Mini Memory CTF Write-up

At the beginning of March 2020 Richard Davis published a small memory forensics CTF challenge to his 13Cubed Youtube channel, with four questions and the generous prize of a Nintendo Switch Lite for a randomly selected entrant with all four correct flags. Well, I didn’t win, but I did have a lot of fun digging into the memory image. And as Richard has published his official solution I thought I’d show my working as well.

We start off as usual by downloading the memory dump and calculating some hashes.

MD5: f3cc405eaf4e63cb9c4b4986c86a7016
SHA1: 7d2b7802b87da03c5e96f159d0bc7ba29896a07c

Before we can dig any deeper into the image we need to tell Volatility which profile to use by running the imageinfo plugin.

vol.py -f memdump.mem imageinfo

We are offered a few possibilities but Win10x64_17134 seems sensible enough for now. On with the challenge!

Flag 1

Find the running rogue (malicious) process. The flag is the MD5 hash of its PID.

There are a few different plugins which will show us information about processes; my favourite is pstree as it makes spotting parent/child relationships much easier.

vol.py -f memdump.mem --profile=Win10x64_17134 pstree

We have a lot of running processes! Things get more interesting after scrolling down a bit further.

There are a number of processes named svchost.exe running under explorer.exe – this should never happen with a legitimate svchost.exe process! Let’s dig a bit deeper with pstree, using grep to show the column headers, and filter out the svchost.exe processes with a Parent Process ID of 4824 (explorer.exe)

vol.py -f memdump.mem --profile=Win10x64_17134 pstree | grep -E "^Name|svchost" | grep -E "^Name|4824"

The question specified a running process; 8560 looks a likely candidate given it is the only one that has any threads attached, but let’s use the psscan plugin to confirm.

vol.py -f memdump.mem --profile=Win10x64_17134 psscan | grep -E "^Offset|svchost" | grep -E "^Offset|4824"

As the screenshot above shows, all the candidate process have an exit time except for 8560, suggesting it is our running rogue process. Calculate the MD5 hash of the PID and we have our first flag.

echo -n 8560 | md5sum
bc05ca60f2f0d67d0525f41d1d8f8717

Flag 2

Find the running rogue (malicious) process and dump its memory to disk. You’ll find the 32 character flag within that process’s memory.

We start by dumping the memory of our rogue process to disk, and extracting the human-readable strings.

vol.py -f memdump.mem --profile=Win10x64_17134 memdump -p 8560 -D .
strings memdump.mem > 8560.dmp.strings

Easy so far. Unfortunately our output file contains almost 24 million lines (23,912,252 to be exact). We know the flag is 32 characters long, so let’s run strings again and specify that only lines with 32 characters or more should be extracted, then run those through sort and uniq to remove any duplicates.

strings -n 32 8560.dmp.strings | sort | uniq > 8560.dmp.strings.32

That’s a big reduction but still leaves 491,446 lines to search through. Sadly, with no idea what the flag looked like, I wasn’t able to find a more elegant way of filtering it out so resorted to paging through the file using less until I found something interesting.

"contents": "da391kdasdaadsssssss t.h.e. fl.ag.is. M2ExOTY5N2YyOTA5NWJjMjg5YTk2ZTQ1MDQ2Nzk2ODA=",

The last part of the string is longer than 32 characters, and looks like base64; let’s decode it and find the second flag.

echo -n M2ExOTY5N2YyOTA5NWJjMjg5YTk2ZTQ1MDQ2Nzk2ODA= | base64 -d
3a19697f29095bc289a96e4504679680

Flag 3

What is the MAC address of this machine’s default gateway? The flag is the MD5 hash of that MAC address in uppercase with dashes (-) as delimiters. Example: 01-00-A4-FB-AF-C2.

This question incorporates a bit of Windows host-based forensics knowledge. Details of the host’s network connections are held in the SOFTWARE registry hive, under the following key:

Microsoft\Windows NT\CurrentVersion\NetworkList\Signatures\Unmanaged

We can use Volatility to query the registry hives in memory using the printkey plugin; by default printkey will search through all available registry hives in the memory image, but we can be a bit more precise and use the hivelist plugin to find the address of the SOFTWARE hive rather than brute-forcing it.

vol.py -f memdump.mem --profile=Win10x64_17134 hivelist

The hivelist plugin completes and tells us the virtual address of the SOFTWARE hive is 0xffffd38985eb3000. Now to use printkey to query the registry itself. The network data sits under a randomly generated sub-key; we will need to determine that before getting the data we are after.

vol.py -f memdump.mem --profile=Win10x64_17134 printkey -o "0xffffd38985eb3000" -K "Microsoft\Windows NT\CurrentVersion\NetworkList\Signatures\Unmanaged"

Luckily there is only one sub-key, making the task easier.

010103000F0000F0080000000F0000F0E3E937A4D0CD0A314266D2986CB7DED5D8B43B828FEEDCEFFD6DE7141DC1D15D

Running printkey again with our newly discovered path gives us our network data.

vol.py -f memdump.mem --profile=Win10x64_17134 printkey -o "0xffffd38985eb3000" -K "Microsoft\Windows NT\CurrentVersion\NetworkList\Signatures\Unmanaged\010103000F0000F0080000000F0000F0E3E937A4D0CD0A314266D2986CB7DED5D8B43B828FEEDCEFFD6DE7141DC1D15D"

The MAC address of the default gateway is at the bottom of the output under DefaultGatewayMac. The question asks for the answer as the MD5 hash of the upper-case MAC address, with dashes as delimiters. Sounds like a task for CyberChef!

There we go. Flag three:

6496d43b622a2ad241b4d08699320f4e

Flag 4

Find the full path of the browser cache created when an analyst visited www.13cubed.com. The path will begin with “Users\.” Convert the path to uppercase. The flag is the MD5 hash of that string.

This one was relatively straightforward. We need to find a filepath created when www.13cubed.com was visited in a web browser. The question tells us that the path begins with “Users\” and we can assume that it contains the string “13cubed” as well. I first tried the filescan plugin to check for relevant file objects in memory, but this did not give me any meaningful results.

I tried again using the mftparser plugin which, perhaps obviously, parses the Master File Table combined with grep to filter on the string “13cubed

vol.py -f memdump.mem --profile=Win10x64_17134 mftparser | grep -i "13cubed"

This gives two results, one HTML file and one PNG image. As we are looking for a web browser artefact I went with the path of the HTML file:

Users\CTF\AppData\Local\Packages\MICROS~1.MIC\AC\#!001\MICROS~1\Cache\AHF2COV9\13cubed[1].htm

We need to convert this to upper-case and calculate the MD5 hash to get the flag; back to CyberChef.

Final flag – done.

b5bdd048030cd26ab2d0e7f7e351224d

I didn’t win the Nintendo Switch but had a huge amount of fun working through the challenge, especially working on registry analysis via the memory image. I would encourage anyone reading this who wants to improve their forensics and incident response skills to subscribe to the 13Cubed Youtube channel, and I hope that Richard finds the time to put more challenges together in the future!

Security Blue Team VIP CTF #1 – “Switching Teams” Write-up

The first CTF created by Security Blue Team was initially for subscribers only, but was made available to the public for a short time at the end of February 2020. While it covered network traffic analysis, password cracking, steganography, forensics, and some general knowledge challenges I didn’t have as much time as I would have liked to spend, so concentrated on the aspects that were most interesting to me personally.

This write-up covers the second of three password cracking challenges – Switching Teams. You can find the rest of my write-ups for Security Blue Team VIP CTF #1 here.

This time we have a password-protected ZIP archive name Admin.zip, and a dictionary file named SuperSecret.txt. We start by extracting the password hash from the archive using the zip2john utility.

zip2john Admin.zip

This archive contains a mix of plaintext and password-protected files. To make sure we get the correct password, we can specify which file we are interested in with the -o flag. The archive contains a file called John/Flag1.txt which sounds like something we are interested in.

With the following command we can extract the correct password hash to a file.

zip2john -o John/Flag1.txt Admin.zip > flag1.hash
cat flag1.hash

So now we have a file containing our hash, and a file containing our wordlist. We could use a brute-force attack as suggested in the question, but let’s use what we are given first. Let’s feed both files to John.

john --wordlist=SuperSecret.txt flag1.hash

Almost immediately John returns our password – a1b2c3d4 – but we’re not done yet. Our flag is inside the password-protected archive, so let’s extract it (supplying our cracked password when prompted) and take a look.

unzip Admin.zip
cat John/Flag1.txt

There we go. Now we have our flag.

SBTVIP{Secure_contain_pr0t3ct}

The final password cracking challenge – Jumbled – involved setting a mask and was more suited to a different password-cracking tool, hashcat. I was unable to get hashcat to run correctly on my SIFT virtual machine, and so as I had limited time for this CTF, I decided to skip it and move on to other challenges instead.

Security Blue Team VIP CTF #1 – “Weekpass” Write-up

The first CTF created by Security Blue Team was initially for subscribers only, but was made available to the public for a short time at the end of February 2020. While it covered network traffic analysis, password cracking, steganography, forensics, and some general knowledge challenges I didn’t have as much time as I would have liked to spend, so concentrated on the aspects that were most interesting to me personally.

This write-up covers the first of three password cracking challenges – Weekpass. You can find the rest of my write-ups for Security Blue Team VIP CTF #1 here.

We are provided with two files – passwd and shadow – which contain the user account details and password hash. For this challenge we will combine the two files, and use John The Ripper to crack the hash.

To combine the files we use a utility bundled with John called unshadow

unshadow passwd shadow > weekpass.hash
cat weekpass.hash

Now that we have our hash in a format that John can use, we need to find a wordlist or dictionary; the list of approximately 14.3 million plaintext passwords from the 2009 RockYou breach is still a good starting point a decade onwards. The list is included with Kali linux or can be downloaded from the internet. As I am using the SANS SIFT virtual machine, I downloaded the list and passed it to John via the following command.

john --wordlist=rockyou.txt weekpass.hash

After a couple of minutes work (a downside of cracking passwords on virtual machines) John has found a match – welcome01 – and we have our flag.

hilltopCTF{welcome01}

Next up in the password cracking category, Switching Teams.

Security Blue Team VIP CTF #1 – “Twin” Write-up

The first CTF created by Security Blue Team was initially for subscribers only, but was made available to the public for a short time at the end of February 2020. While it covered network traffic analysis, password cracking, steganography, forensics, and some general knowledge challenges I didn’t have as much time as I would have liked to spend, so concentrated on the aspects that were most interesting to me personally.

Of the five “general knowledge” questions, four were multiple choice. This write-up covers the one general knowledge challenge which required a bit of command-line work – Twin. You can find the rest of my write-ups for Security Blue Team VIP CTF #1 here.

After downloading and extracting the archive we are indeed presented with 4400 files, totalling 88000 lines.

ls | wc -l
cat * | wc -l

Still, we can find the duplicate line by chaining together a few Linux command-line tools: cat, sort, and uniq. First we cat all 4400 files out, and sort all 88000 files into alphabetical order. Then use uniq with the -c flag to count the occurrences of each line. This should be 1 in every case except for our flag. Next use sort again, this time with the -n and -r flags so that we sort in numerical order, which is then reversed so that our duplicate line appears at the top of the list. Optionally, use head to restrict the output to the first 10 lines.

cat * | sort | uniq -c | sort -nr | head

2 VXZ5eWdiY1BHU3tnajFhNV9wNGFfYTNpM2VfbzNfZjNjNGU0NzNxfQ==

Given the == at the end of the line, the output looks like base64. Let’s feed it to CyberChef and see what we can do.

UvyygbcPGS{gj1a5_p4a_a3i3e_o3_f3c4e473q}

The From Base64 operation gave us human-readable text, but we still don’t have our flag in the correct format. It looks like a substitution cipher, so let’s try the Rot13 function.

That’s much better. We have our flag!

HilltopCTF{tw1n5_c4n_n3v3r_b3_s3p4r473d}

Security Blue Team VIP CTF #1 – Sneaky Transmission Write-up

The first CTF created by Security Blue Team was initially for subscribers only, but was made available to the public for a short time at the end of February 2020. While it covered network traffic analysis, password cracking, steganography, forensics, and some general knowledge challenges I didn’t have as much time as I would have liked to spend, so concentrated on the aspects that were most interesting to me personally.

This write-up covers the network analysis challenge – Sneaky Transmission. You can find the rest of my write-ups for Security Blue Team VIP CTF #1 here.

After downloading the PCAP file we can open it in Wireshark to see what we are working with. While the question refers to a DoS attack, and to the possibility of a photo, all we see in the PCAP is ICMP traffic.

Nothing here is obviously an image, but the TTL values of the IMCP requests look a bit strange. Using the following Display Filter we can examine them more easily.

icmp.type == 8

The TTL value changes with each packet, which might be an indication of a covert channel; one byte per packet perhaps? We can easily extract the TTL values using tshark and redirect them to a file.

tshark -r sneaky_transmission.pcapng -Y "icmp.type == 8" -Tfields -e ip.ttl

The data will be much easier to work with if we output it to a file.

tshark -r sneaky_transmission.pcapng -Y "icmp.type == 8" -Tfields -e ip.ttl > ttl.txt

We now have a file containing what we think might be individual bytes, one-per-line, which we need to turn into something more intelligible. One of my favourite tools for playing with data like this is CyberChef, so let’s load our ttl.txt file as input and see what we can make from it.

First, let’s convert From Decimal back to the raw bytes.

That looks a lot like the “magic bytes” at the start of a JPEG file! CyberChef can render that as an image.

And there we are. We have our sneaky transmission, just as the question hinted at.

HilltopCTF{sn34k_p1c}

OtterCTF 2018 – Network Challenges – Birdman’s Data Write-up

OtterCTF dates from December 2018 and includes reverse engineering, steganography, network traffic, and more traditional forensics challenges. I have written-up the memory forensics section in a previous post. The whole CTF is available to play online as of March 2020.

This series of write-ups will cover the three challenges I was able to complete out of the four available in the network analysis section of the CTF, starting with a write-up of the Birdman’s Data challenge.

We start by downloading the PCAP containing the challenge data, and calculating some hashes.

MD5: 67157597613fc288fe8dbce910707a2f
SHA1: ae7d7060bab931c6241e18aacbeb03a61a744c10

When examining a PCAP I like to start by checking the Conversations and Protocol Hierarchy to get an idea of what kind of traffic we are dealing with.

We can see some HTTP traffic in the Protocol Hierarchy so let’s look into that.

This looks like plaintext HTTP traffic to an online text encryption service. We can follow the HTTP stream to get some more details of what is being sent and received, including the parameters used by the encryption service.

As we examine the HTTP stream further we find two parameters named key

{"key":"XfCtxvD1yFZbxQ/+ULhAcA=="}
{"key":"sEhrZxQpnNnINixu3KQ1Tg=="}

And a third parameter named ciphertext.

{"cipherText":"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"}

Assuming that the first key parameter is the Key, and the second is the IV, we can use the online service to decrypt the ciphertext.

It worked! Out pops the plaintext message. But we’re not done yet, we still need to extract the flag.

The layout of the text is a little bit odd; looking at the first characters of the first four lines seems to spell CTF{… With a bit of command-line work we can clean this up.

cat plaintext.txt | cut -c 1 | tr -d '\n'

There we go! Now we can submit our flag and claim the points.

CTF{EmiNeM_FOR_LifE_gEez}

Next up in my OtterCTF series, Look At Me.

Defcon 2019 DFIR CTF – Memory Forensics Write-up

In an effort to improve my forensics skills I have been working through publicly available forensics CTFs when I have some free time.

The 2019 Unofficial Defcon DFIR CTF was created by the Champlain College Digital Forensics Association and made public by David Cowen on his Hacking Exposed Computer Forensics blog. The CTF covers Windows and Linux “dead” forensics, a “live” triage VM, memory forensics, and a cryptography challenge. This write-up focuses on the memory forensics questions.

Links to the CTF files and registration/scoreboard can be found on this HECF blog post.

The following MD5 hash was provided for the Triage-Memory.mem file:

MD5: c0c80a06ad336a6e20d42c895a0e067f

Let’s get started!

flag 1 – get your volatility on

We begin with a straightforward one; calculate the SHA1 hash of the memory image.

sha1sum Triage-Memory.mem

flag<c95e8cc8c946f95a109ea8e47a6800de10a27abd>

flag 2 – pr0file

Again, reasonably simple. We need to work out which profile to use with Volatility to conduct our analysis. The imageinfo plugin will suggest a number of suitable candidates.

vol.py -f Triage-Memory.mem imageinfo

The output lists a few possibilities, but Win7SP1x64 is a sensible choice for now.

flag<Win7SP1x64>

flag 3 – hey, write this down

There are a few Volatility modules we can use to list running process IDs. My personal preference is pstree just because it makes the parent/child relationship more obvious, which can help to spot anything unusual.

vol.py -f Triage-Memory.mem --profile=Win7SP1x64 pstree

We are looking specifically for notepad.exe so we can cut out a lot of the unrelated output using grep

vol.py -f Triage-Memory.mem --profile=Win7SP1x64 pstree | grep -i "notepad.exe"

Using grep to filter the output we can easily see that the PID is 3032.

flag<3032>

flag 4 – wscript can haz children

We already have the answer to this from the pstree output in Flag 3, but using grep as a filter will make it easier to spot. The -A 2 option tells grep to display the matching line and the 2 lines that follow it.

vol.py -f Triage-Memory.mem --profile=Win7SP1x64 pstree | grep -A 2 -i "wscript.exe"

The output shows that wscript.exe has one child process, UWkpjFjDzM.exe, which itself has a child process called cmd.exe; a good indication that something is wrong there.

flag<UWkpjFjDzM.exe>

flag 5 – tcpip settings

The question asks for the IP address of the machine when the memory dump was taken. The netscan plugin will show details of network artefacts captured in the memory dump.

vol.py -f Triage-Memory.mem --profile=Win7SP1x64 netscan

The question asks for the IP address of the machine at the time of the memory dump. We can see processes listening on addresses 0.0.0.0 and 127.0.0.1, which are unlikely to be our flag, and 10.0.0.101 which is a much more likely. Another interesting observation is that our process from Flag 4 is connecting to another machine on port 4444 – the default port for many Metasploit payloads. Keep that in mind for later.

flag<10.0.0.101>

flag 6 – intel

Based on our work to find Flag 4 and Flag 5, we can answer this quite easily. Let’s examine the netscan output more closely.

vol.py -f Triage-Memory.mem --profile=Win7SP1x64 netscan | grep "UWkpjFjDzM.exe"

We can see our “infected” process UWkpjFjDzM.exe connecting to 10.0.0.106 on port 4444.

flag<10.0.0.106>

flag 7 – i <3 windows dependencies

As the name suggests, the dlllist plugin will list the DLLs loaded by each process. This is a lot of output, so to find the answer I used grep with increasing values for the -B option to show the associated process. Not very subtle but it worked!

vol.py -f Triage-Memory.mem --profile=Win7SP1x64 dlllist | grep -B 33 "VCRUNTIME140.dll"

There we are! Initially I submitted OfficeClickToRun.exe as the flag, but when that was rejected I tried the short name (OfficeClickToR) next to the Process ID near the top of the output.

flag<OfficeClickToR>

flag 8 – mal-ware-are-you

Ok, we have already identified our potential malware from Flags 4, 5, and 6. So take its PID (3496) and dump the executable using the procdump plugin, then calculate the MD5 of the extracted binary.

vol.py -f Triage-Memory.mem --profile=Win7SP1x64 procdump -p 3496 -D .
md5sum executable.3496.exe

flag<690ea20bc3bdfb328e23005d9a80c290>

flag 9 – lm-get bobs hash

Another relatively simple one. The hashdump plugin will, predictably, dump the password hashes from memory.

vol.py -f Triage-Memory.mem --profile=Win7SP1x64 hashdump

We need to supply the LM hash, which is the first portion of the hash after Bob’s user ID (1000)…

flag<aad3b435b51404eeaad3b435b51404ee>

flag 10 – vad the impaler

Information on VAD nodes can be extracted using the vadinfo plugin. It outputs a lot of data, so for ease of reading I’ve used grep to focus on the lines we are interested in.

vol.py -f Triage-Memory.mem --profile=Win7SP1x64 vadinfo | grep -A 2 "0xfffffa800577ba10"

We can see the VAD node at offset 0xfffffa800577ba10 has the PAGE_READONLY protection. That’s our flag.

flag<PAGE_READONLY>

11 – more vads?!

This is essentially the same question as Flag 10, just with a bit of extra grep. Instead of filtering on the starting offset, we filter on both start and end.

vol.py -f Triage-Memory.mem --profile=Win7SP1x64 vadinfo | grep -A 2 "Start 0x00000000033c0000 End 0x00000000033dffff"

This time the protection is PAGE_NOACCESS.

flag<PAGE_NOACCESS>

flag 12 – vacation bible school

We are looking for a VBS script now. There are a few ways we could do this but the easiest is simply to check the command-line used to start the wscript.exe process that we observed in the pstree output for Flag 4. We know the wscript.exe PID is 5116, so we can pass that to the cmdline plugin to reduce the reading we have to do.

vol.py -f Triage-Memory.mem --profile=Win7SP1x64 cmdline -p 5116

We can see that wscript.exe was called with a script called vhjReUDEuumrX.vbs from the %TEMP% directory. Strip the extension and we have our flag.

flag<vhjReUDEuumrX>

flag 13 – thx microsoft

The Application Compatibility Cache (or shimcache) contains details of program execution and can be parsed using the shimcache plugin. We are looking for an application executed at a specified date and time, so we can use grep to filter the output.

vol.py -f Triage-Memory.mem --profile=Win7SP1x64 shimcache | grep "2019-03-07 23:06:58"

This time we need to include the file extension.

flag<Skype.exe>

flag 14 – lightbulb moment

Extracting the text from a running notepad.exe process is relatively straightforward but does require a couple of steps. First we need to dump the process memory using the memdump plugin; we found the PID for notepad.exe in Flag 3 (3032). The next step is to use the strings utility to extract all of the human-readable little-endian strings and write them to a file.

vol.py -f Triage-Memory.mem --profile=Win7SP1x64 memdump -p 3032 -D .
strings -e l 3032.dmp > 3032.dmp.strings

Once we have our strings output we can use grep to search for our flag. The word “flag” seems a reasonable place to start.

grep "flag" 3032.dmp.strings

There we go!

flag<REDBULL_IS_LIFE>

flag 15 – 8675309

Details about file records are held in the Master File Table (MFT) and can be extracted from the memory dump using the mftparser plugin. We are specifically looking for the Short Name of the file at record 59045; once again, grep will help us here.

vol.py -f Triage-Memory.mem --profile=Win7SP1x64 mftparser | grep -A 20 "59045"

Reading through the output we can see the 8.3 short file name EMPLOY~1.XLS.

flag<EMPLOY~1.XLS>

flag 16 – whats-a-metasploit?

We can be pretty sure that UWkpjFjDzM.exe (PID: 3496) is our Meterpreter process, given what we found out answering Flag 4, 5, and 6, but let’s make sure. First we dump the process executable using the procdump module, then calculate its SHA1 hash so we can search public sandboxes like VirusTotal.

vol.py -f Triage-Memory.mem --profile=Win7SP1x64 procdump -p 3496 -D .
sha1sum executable.3496.exe

Searching VirusTotal for the SHA1 hash (ab120a232492dcfe8ff49e13f5720f63f0545dc2) gives us a report clearly showing that the sample is malicious.

We submit the process ID (3496) and we have completed the memory analysis section!

flag<3496>

This is a really well put together set of challenges, and when I have more time I will probably return to take on the Windows and Linux challenges as well.

Memlabs Memory Forensics Challenges – Lab 1 Write-up

In an effort to improve my forensics skills I have been working through publicly available forensics CTFs when I have some free time.

Memlabs is a set of six CTF-style memory forensics challenges released in January 2020 by @_abhiramkumar and Team bi0s. This write-up covers the first memory image which has three flags to uncover.

Unlike most CTFs I have encountered, Memlabs does not actually ask any questions or give hints regarding the flags, only that the flags have the following format:

flag{stage1_is_n0w_d0n3}

No hashes were provided to check against but I calculated the following:

MD5: b9fec1a443907d870cb32b048bda9380
SHA1: 02a58ccf572e6b369934268842551722c4411a60

Let’s go!

Flag 1

First let’s determine what kind of memory image we are working with. As usual for memory forensics, I’m going to work with Volatility.

vol.py -f MemoryDump_Lab1.raw imageinfo

The first suggestion is Win7SP1x64; this seems like a sensible starting point.

We have no clues as to what we are supposed to be looking for. Let’s check the running processes using the pstree module and see if anything stands out.

vol.py -f MemoryDump_Lab1.raw --profile Win7SP1x64 pstree

The only processes that stand out are WinRAR.exe (PID: 1512), cmd.exe (PID: 1984), and mspaint.exe (PID: 2424). DumpIt.exe is likely the tool used to capture the memory dump so I am ignoring it for now. We can use the cmdline and consoles modules to show the command that launched these processes, and any console output associated with them.

vol.py -f MemoryDump_Lab1.raw --profile Win7SP1x64 cmdline -p 1512,1984,2424
vol.py -f MemoryDump_Lab1.raw --profile Win7SP1x64 consoles

The output from cmdline tells us that WinRAR.exe was launched with a file called Important.exe which seems, well, important but the consoles plugin shows a command St4Ge$1 being run and the following output:

ZmxhZ3t0aDFzXzFzX3RoM18xc3Rfc3Q0ZzMhIX0=

Decoding this from base64 gives us our first flag:

echo "ZmxhZ3t0aDFzXzFzX3RoM18xc3Rfc3Q0ZzMhIX0=" | base64 -d

flag{th1s_1s_th3_1st_st4g3!!}

Flag 2

I actually found Flag 3 before Flag 2 as I spotted the reference to Important.rar in the cmdline output, but for ease of reading I’ll keep this order. As I had examined the cmd.exe and WinRAR.exe processes already I guessed that Flag 2 was hidden in the mspaint.exe process, so began by dumping the process memory.

vol.py -f MemoryDump_Lab1.raw --profile Win7SP1x64 memdump -p 2424 -D .

After some Googling I found a blogpost detailing how to extract RAW images from memory dumps. I renamed the dump from 2424.dmp to 2424.data and opened it up with the GIMP image editing suite, setting the Image Type to RGB Alpha, and fiddling with the Offset, Width, and Height values through trial and error until I got something that looked intelligible.

That’s definitely text but not very easy to read. I’m better with Volatility than with GIMP so I took a screenshot of the image preview and flipped it vertically, revealing the flag.

flag{G00d_BoY_good_girL}

Flag 3

The output from the cmdline module showed that WinRAR.exe had been launched with a file called Important.rar. Lets extract that from the memory image and take a look.

vol.py -f MemoryDump_Lab1.raw --profile Win7SP1x64 filescan | grep -i "important.rar"
vol.py -f MemoryDump_Lab1.raw --profile Win7SP1x64 dumpfiles -Q 0x000000003fa3ebc0 -D .
file file.None.0xfffffa8001034450.dat

I renamed the file to Important.rar and tried extracting the contents.

unrar x Important.rar

Unfortunately we need a password. Fortunately the password hint tells us where to find it. We can use the hashdump module to dump the NTLM hashes.

vol.py -f MemoryDump_Lab1.raw --profile Win7SP1x64 hashdump

We only need the second part of the hash, but we do need to convert it to upper-case first. Rather than doing it manually I used CyberChef to do it for me.

Now we have the password we can extract the archive and view its contents – a PNG image containing our flag.

 

flag{w3ll_3rd_stage_was_easy}

Despite completing the first challenge I found the lack of direction or motivation incredibly frustrating. The whole point of forensic investigation is to follow a trail, building on what has been found already to come to a specified conclusion. Real investigations have a purpose. Why was this memory dump captured in the first place? Why are you asking me to take the time to do some analysis? I did learn a new technique in finding Flag 2, but for now I am skipping the rest of Memlabs to work on something more representative of real-world DFIR.