Description

<scenario>
A fictional organisation has been affected by a ransomware attack. It has been successful in setting up an emergency channel for communication and has access to parts of its infrastructure.

Can you find all the flags?
</scenario>

Solution

In the attached PCAP file, we find an IRC conversation where we get some clues about the flags. The first flag, CTF[AES128] can be found as the PASS in the IRC connection.

CAP LS 302
PASS CTF[AES128]
NICK D3f3nd3r
USER user1 0 * :realname

IRC conversation:

<D3f3nd3r>: hello
<An4lys3r>: aaaah, at last, it's working!
<D3f3nd3r>: well done setting up the emergency environment so fast!
<An4lys3r>: Thanks. I'm glad we did a test run a couple of months ago
<D3f3nd3r>: Yes, I agree
<An4lys3r>: So what do we know so far, why is our production environment not accessible
<D3f3nd3r>: Well, I'm in the data center now and the consoles I managed to look at is showing a ransom note.....
<An4lys3r>: so it's that bad
<D3f3nd3r>: yup
<An4lys3r>: Have you found any clue to what group and ransom strain is used, if we are lucky enough there is a free decryptor available
<D3f3nd3r>: I would not bet on it, but I'll transfer the ransom note to you shortly.

PRIVMSG An4lys3r :.DCC SEND RANSOM_NOTE.gz 199 0 95285 221.
PRIVMSG #emergency :SHA-256 checksum for /home/user/emergency_net/DCC/RANSOM_NOTE.gz (remote): 7113f236b43d1672d881c6993a8a582691ed4beb4c7d49befbceb1fddfb14909
:An4lys3r!~user1@10.0.0.10 PRIVMSG D3f3nd3r :.DCC SEND RANSOM_NOTE.gz 167772170 40899 95285 221.

<An4lys3r>: Thanks, I'll have a look.
<D3f3nd3r>: I managed to access our FPC system and it looks like it is untouched. I will try carving out pcaps from days / weeks before the encryption started from different segments.
<An4lys3r>: good, put them on the ftp, I'll have a look at that later.
<D3f3nd3r>: by the way, Christine came by and handed me a disk image from one of the clients, see if they left any clues on disk. I'll upload it to the ftp shortly.
<An4lys3r>: We totally need external help, restoring and investigating this incident will be a massive task. You don't happen to have the contact info to Allsafe, I think our rep is called Elliot?
<D3f3nd3r>: Agree, I already called them in. He is here now sharing some interesting stuff.
<D3f3nd3r>: They picked up some info on a closed forum regarding our situation, someone posted a WORDLIST scraped from our public website. And they where ranting about recording network traffic from a windows workstation called CTF-PC01. I'll upload the file to the ftp.
<D3f3nd3r>: He also handed over a strange looking string CTF[E65D46AD10F92508F500944B53168930], does it make sense to you?
<An4lys3r>: not really, but why don't you ask john?
<D3f3nd3r>: Alright, I'll see what I can do with it.
<D3f3nd3r>: To keep in mind, he also mention they have intel about a suspicious IP address involved in C2 and exfiltration activities lately, the IP is 195.200.72.82

What we can get from the conversation is:

  • Ransom note (DCC)
  • Disk image (FTP)
  • Wordlist/Windows PC CTF-PC01 (FTP)
  • Strange looking string: CTF[E65D46AD10F92508F500944B53168930] (ask john)
  • C2 and exfiltration activities lately, the IP is 195.200.72.82

Strange looking string

If we take the string E65D46AD10F92508F500944B53168930 from the flag and use this as input to John the Ripper we see that it’s an LM hash that we can crack very fast.

Using default input encoding: UTF-8
Using default target encoding: CP850
Loaded 2 password hashes with no different salts (LM [DES 256/256 AVX2])
Warning: poor OpenMP scalability for this hash type, consider --fork=16
Will run 16 OpenMP threads
Proceeding with single, rules:Single
Press 'q' or Ctrl-C to abort, 'h' for help, almost any other key for status
Almost done: Processing the remaining buffered candidate passwords, if any.
Proceeding with wordlist:password.lst
Enabling duplicate candidate password suppressor
L                (?:2)
RICKROL          (?:1)
2g 0:00:00:00 DONE 2/3 (2024-10-01 10:33) 11.76g/s 2891Kp/s 2891Kc/s 3469KC/s KASTNER..ELPOLLI
Warning: passwords printed above might be partial
Use the "--show --format=LM" options to display all of the cracked passwords reliably
Session completed.

Flag 2: CTF[RICKROLL]

Transmitted files

If we check the FTP streams in the capture, we can find four files that are transferred to an FTP server.

  • corp_net1.pcap
  • corp_net2.pcap
  • disk1.img.gz
  • WORDLIST.txt

RANSOM_NOTE.gz can be found in the stream directly following the DCC connection.

Ransom Note

After unpacking RANSOM_NOTE.gz, we get an ASCII file containing a bunch of garbled text like the following:

CCCCCCCCCCCTCCCCCFCCCCC[CCCCCOCCCCCRCCCCTCCCCCTTCCCCTFCCCCT[CCCCTOCCCCTRCCCCFCCCCCFTCCCCFFCCCCF[CCCCFOCCCCFRCCCC[CCCCC[TCCCC[FCCCC[[CCCC[OCCCC[RCCCCOCCCCCOTCCCCOFCCCCO[CCCCOOCCCCORCCCCRCCCCCRTCCCCRFCCCCR[CCCCROCCCCRRCCCTCCCCCTCTCCCTCFCCCTC[CCCTCOCCCTCRCCCTTCCCCTTTCCCTTFCCCTT[CCCTTOCCCTTRCCCTFCCCCTFTCCCTFFCCCTF[CCCTFOCCCTFRCCCT[CCCCT[TCCCT[FCCCT[[CCCT[OCCCT[RCCCTOCCCCTOTCCCTOFCCCTO[CCCTOOCCCTORCCCTRCCCCTRTCCCTRFCCCTR[CCCTROCCCTRRCCCFCCCCCFCTCCCFCFCCCFC[CCCFCOCCCFCRCCCFTCCCCFTTCCCFTFCCCFT[CCCFTOCCCFTRCCCFFCCCCFFTCCCFFFCCCFF[CCCFFOCCCFFRCCCF[CCCCF[TCCCF[FCCCF[[CCCF[OCCCF[RCCCFOCCCCFOTCCCFOFCCCFO[CCCFOOCCCFORCCCFRCCCCFRTCCCFRFCCCFR[CCCFROCCCFRRCCC[CCCCC[CTCCC[CFCCC[C[CCC[COCCC[CRCCC[TCCCC[TTCCC[TFCCC[T[CCC[TOCCC[TRCCC[FCCCC[FTCCC[FFCCC[F[CCC[FOCCC[FRCCC[[CCCC[[TCCC[[FCCC[[[CCC[[OCCC[[RCCC[OCCCC[OTCCC[OFCCC[O[CCC[OOCCC[ORCCC[RCCCC[RTCCC[RFCCC[R[CCC[ROCCC[RRCCCOCCCCCOCTCCCOCFCCCOC[CCCOCOCCCOCRCCCOTCCCCOTTCCCOTFCCCOT[CCCOTOCCCOTRCCCOFCCCCOFTCCCOFFCCCOF[CCCOFOCCCOFRCCCO[CCCCO[TCCCO[FCCCO[[CCCO[OCCCO[RCCCOOCCCCOOTCCCOOFCCCOO[CCCOOOCCCOORCCCORCCCCORTCCCORFCCCOR...<SNIP>

If we use the regex CTF\[[A-Z]*\] to search the file, we get one match which is the flag.

Flagga 3: CTF[OR]

corp_net1.pcap

In the PCAP we find out that three files have been transmitted over FTP.

  • puzzle.exe
  • Recycle-Bin.zip
  • archive

We can also find some DNS queries that look like some data exfiltration activity.

puzzle.exe

Checking the strings in the executable, we see that it is a PyInstaller executable. To extract the contents, we can use pyinstxtractor.

python3 pyinstxtractor.py Puzzle.exe

[+] Processing Puzzle.exe
[+] Pyinstaller version: 2.1+
[+] Python version: 3.12
[+] Length of package: 18773937 bytes
[+] Found 214 files in CArchive
[+] Beginning extraction...please standby
[+] Possible entry point: pyiboot01_bootstrap.pyc
[+] Possible entry point: pyi_rth_inspect.pyc
[+] Possible entry point: pyi_rth_pkgres.pyc
[+] Possible entry point: pyi_rth_setuptools.pyc
[+] Possible entry point: pyi_rth_multiprocessing.pyc
[+] Possible entry point: pyi_rth_pkgutil.pyc
[+] Possible entry point: puzzle_new.pyc
[!] Warning: This script is running in a different Python version than the one used to build the executable.
[!] Please run this script in Python 3.12 to prevent extraction errors during unmarshalling
[!] Skipping pyz extraction
[+] Successfully extracted pyinstaller archive: Puzzle.exe

You can now use a python decompiler on the pyc files within the extracted directory

Now we’re able to decompile puzzle_new.pyc with a Python decompiler like pycdc.

pycdc puzzle_new.pyc > puzzle_new.py

Analyzing the source code, we can see that it’s a puzzle game written using PyGame. Inside the code, there’s also a Base64 string containing an image.

To extract the image we can use PyGame’s functions for saving images. We can rewrite the last part of the game to do the following:

image = uri_to_pygame_image(uri)
pygame.image.save(image, "test.png")

If we start the game with this change the image will be saved as test.png.

Analyzing the image we can find the flag right next to the head.

Flag 4: CTF[HAPPY BIRTHDAY]

Recycle-Bin.zip

Unpacking the zip file we get the contents of someone’s Windows Recycle Bin. In the Recycle Bin, we can find a bunch of different files like .txt, .jpg, .zip, and .pdf.

Checking the dates of the files we can find a couple of files that were created in 1984.

Checking the original file name of the file we get the following.

T)���BC:\Users\aleksej.pazjitnov\Downloads\INKEMW2QIVHFIT2NJFHE6U25.txt

Base32 decoding the file name returns the next flag.

Flag 5: CTF[PENTOMINOS]

archive

This file is gzip compressed, unpacking the file returns another gzip compressed file.

If we run mv archive archive.gz && gunzip archive.gz && file archive until we get the output archive: POSIX tar archive (GNU) we end up with a tar archive. Unpacking the tar archive returns yet another gzip compressed file, so we have to repeat the previous steps until we end up with an ASCII file that contains the flag.

Flag 6: CTF[IRRITATING]

Exfil

Start by dumping all the exfiltrated data. The following script can be used to dump all the data.

#!/usr/bin/env python3

from scapy.all import *
import sys

if len(sys.argv) != 2:
    print("Usage: python3 extract.py <pcap_file>")
    sys.exit(1)

pcap_file = sys.argv[1]

packets = rdpcap(pcap_file)

data = ""
i = 0
for packet in packets:
    if (
        packet.haslayer(DNS)
        and packet.haslayer(IP)
        and packet[IP].src == "195.200.72.82"
        and packet[IP].dst == "192.168.137.28"
    ):
        data += packet[DNS].qd.qname.decode("utf-8")
        i += 1

data = data.replace(".", "")
print(data)

print(f"Extracted {i} packets")

Running the script returns a Base32 encoded string containing a PNG file. Unfortunately, the file is corrupt, but we can still view the image with GIMP.

Flag 7: CTF[TOPPALUA]

corp_pcap2.pcap

In the traffic, we can find some NTLM authentications. For example, the following WebDAV connection:

PROPFIND /share HTTP/1.1
Connection: Keep-Alive
User-Agent: Microsoft-WebDAV-MiniRedir/10.0.19045
Depth: 0
translate: f
Content-Length: 0
Host: dcc01

HTTP/1.1 401 Unauthorized
Content-Type: text/html
Server: Microsoft-IIS/10.0
Date: Thu, 29 Aug 2024 17:20:52 GMT
WWW-Authenticate: Negotiate
WWW-Authenticate: NTLM
Content-Length: 1264

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<title>401 - Unauthorized: Access is denied due to invalid credentials.</title>
<style type="text/css">
<!--
body{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;}
fieldset{padding:0 15px 10px 15px;} 
h1{font-size:2.4em;margin:0;color:#FFF;}
h2{font-size:1.7em;margin:0;color:#CC0000;} 
h3{font-size:1.2em;margin:10px 0 0 0;color:#000000;} 
#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS", Verdana, sans-serif;color:#FFF;
background-color:#555555;}
#content{margin:0 0 0 2%;position:relative;}
.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}
-->
</style>
</head>
<body>
<div id="header"><h1>Server Error</h1></div>
<div id="content">
 <div class="content-container"><fieldset>
  <h2>401 - Unauthorized: Access is denied due to invalid credentials.</h2>
  <h3>You do not have permission to view this directory or page using the credentials that you supplied.</h3>
 </fieldset></div>
</div>
</body>
</html>
PROPFIND /share HTTP/1.1
Connection: Keep-Alive
User-Agent: Microsoft-WebDAV-MiniRedir/10.0.19045
Depth: 0
translate: f
Content-Length: 0
Host: dcc01
Authorization: Negotiate TlRMTVNTUAABAAAAl4II4gAAAAAAAAAAAAAAAAAAAAAKAGFKAAAADw==

HTTP/1.1 401 Unauthorized
Server: Microsoft-IIS/10.0
Date: Thu, 29 Aug 2024 17:20:52 GMT
Content-Type: text/html
WWW-Authenticate: Negotiate TlRMTVNTUAACAAAACAAIADgAAAAFAomi/ia/MJVbZNcAAAAAAAAAAJoAmgBAAAAACgB8TwAAAA9NAFUARABKAAIACABNAFUARABKAAEAHgBXAEkATgAtADUARgBWADcATQBOAFUAQgBBADAASwAEABQATQBVAEQASgAuAEwATwBDAEEATAADADQAVwBJAE4ALQA1AEYAVgA3AE0ATgBVAEIAQQAwAEsALgBNAFUARABKAC4ATABPAEMAQQBMAAUAFABNAFUARABKAC4ATABPAEMAQQBMAAAAAAA=
Content-Length: 335

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN""http://www.w3.org/TR/html4/strict.dtd">
<HTML><HEAD><TITLE>Not Authorized</TITLE>
<META HTTP-EQUIV="Content-Type" Content="text/html; charset=us-ascii"></HEAD>
<BODY><h2>Not Authorized</h2>
<hr><p>HTTP Error 401. The requested resource requires user authentication.</p>
</BODY></HTML>
PROPFIND /share HTTP/1.1
Connection: Keep-Alive
User-Agent: Microsoft-WebDAV-MiniRedir/10.0.19045
Depth: 0
translate: f
Content-Length: 0
Host: dcc01
Authorization: Negotiate TlRMTVNTUAADAAAAGAAYAHQAAAA2ATYBjAAAAAYABgBYAAAABgAGAF4AAAAQABAAZAAAAAAAAADCAQAAFQKIogoAYUoAAAAPhk7z6xG3/SLGAjTu7rXUnkwAQQBCAEMAVABGAEMAVABGAC0AUABDADAAMQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACkBqFXDQOR01g1S7Id99EuAQEAAAAAAAAVi+zgNvraATbAAVP3q3iLAAAAAAIACABNAFUARABKAAEAHgBXAEkATgAtADUARgBWADcATQBOAFUAQgBBADAASwAEABQATQBVAEQASgAuAEwATwBDAEEATAADADQAVwBJAE4ALQA1AEYAVgA3AE0ATgBVAEIAQQAwAEsALgBNAFUARABKAC4ATABPAEMAQQBMAAUAFABNAFUARABKAC4ATABPAEMAQQBMAAgAMAAwAAAAAAAAAAAAAAAAIAAA/W9iNXriUxTguPY6sX5dGCFHnmjsIufucIJ+rbLzkyAKABAAAAAAAAAAAAAAAAAAAAAAAAkAIABIAFQAVABQAC8AZABjAGMAMAAxAC4AbABvAGMAYQBsAAAAAAAAAAAA

HTTP/1.1 200 OK
Server: Microsoft-IIS/10.0
Date: Thu, 29 Aug 2024 17:20:52 GMT
Content-Type: text/html
WWW-Authenticate: NTLM
Content-Length: 0

To extract the NTLM hashes, we can use NTLMRawUnHide by running the command python3 NTLMRawUnHide.py -i corp_net2.pcap -o ntlmhashes.

Now we can use the extracted hashes with John the Ripper paired with the wordlist that was sent by FTP.

john ntlmhashes -wordlist=./wordlist

Using default input encoding: UTF-8
Loaded 13 password hashes with 13 different salts (netntlmv2, NTLMv2 C/R [MD4 HMAC-MD5 32/64])
Will run 16 OpenMP threads
Press 'q' or Ctrl-C to abort, 'h' for help, almost any other key for status
[RHODE_ISLAND_Z] (CTF)
[RHODE_ISLAND_Z] (CTF)
[RHODE_ISLAND_Z] (CTF)
[RHODE_ISLAND_Z] (CTF)
[RHODE_ISLAND_Z] (CTF)
[RHODE_ISLAND_Z] (CTF)
[RHODE_ISLAND_Z] (CTF)
[RHODE_ISLAND_Z] (CTF)
[RHODE_ISLAND_Z] (CTF)
[RHODE_ISLAND_Z] (CTF)
[RHODE_ISLAND_Z] (CTF)
[RHODE_ISLAND_Z] (CTF)
[RHODE_ISLAND_Z] (CTF)
13g 0:00:00:00 DONE (2024-10-01 13:48) 1300g/s 20000p/s 260000c/s 260000C/s [123456]..[SEPTEMBER]
Use the "--show --format=netntlmv2" options to display all of the cracked passwords reliably
Session completed.

Flag 8: CTF[RHODE_ISLAND_Z]

disk.img.gz

Running string on the unpacked disk image reveals a bash script and a SslKeyLogFile.

#!/bin/bash
password=$(SSLKEYLOGFILE=sslkeylogfile curl --insecure https://whatyoulookingat.com/1.txt)
openssl enc -aes-128-cbc -pass pass:$password -in secret -out secret.encrypted
shred secret
rm secret
rm sslkeylogfile
rm $0
SERVER_HANDSHAKE_TRAFFIC_SECRET cb68ed4293ea43b5ae0f949b7d36f9e801cdea8025cb8ce61b2226a1ba502118 c9275180cf4e5bcdd6835e02459d453d47420201b92ed20ed507e278d2c9616778fa573479bd8ec3b1fad7e74dcf27f7
EXPORTER_SECRET cb68ed4293ea43b5ae0f949b7d36f9e801cdea8025cb8ce61b2226a1ba502118 1c375d3b154029a9c7d9ff5b4f7f07b75ba9751570c454423cc6d21c53a27e504d3e193d3e087a6e1feb7c31383e637d
SERVER_TRAFFIC_SECRET_0 cb68ed4293ea43b5ae0f949b7d36f9e801cdea8025cb8ce61b2226a1ba502118 ba5519d408d2cc9c285781eec7c2951bfbf069609b57b18906754624e0628820ed1888d0f22b770325c872b5f1f5bee3
CLIENT_HANDSHAKE_TRAFFIC_SECRET cb68ed4293ea43b5ae0f949b7d36f9e801cdea8025cb8ce61b2226a1ba502118 c85ae912b5caf1eb39452864e582c083a39f4ad89f27608aff7bb3287edb85b002111af149480f28e0c60e543075dd7b
CLIENT_TRAFFIC_SECRET_0 cb68ed4293ea43b5ae0f949b7d36f9e801cdea8025cb8ce61b2226a1ba502118 3a6be8bc746c002fe02a76da433307d5787bf230b9d0c2ee9ab776a17459fd2f037e8bee0a1b26b759e1ba02879ae920

Here we see that a file has been encrypted using the password found in the file 1.txt on whatyoulookingat.com.

If we use the key log file with corp_net1.pcap we can find the download of the file 1.txt and get the contents, pheiph0Xeiz8OhNa.

Mounting the disk image, we get the file secret.encrypted. We can decrypt this file using the password in 1.txt, which returns the final flag.

Flag 9: CTF[OPPORTUNISTICALLY]