There were 11 Defense challenges with four having two or more sub-challenges, for a total of 20 flags to find with 1720 points possible.
Last updated
Time to start sleuthing! I'm definitely better at defense than offense, and was able to complete these within a few days without any hints. I kind of wish I knew what the hints said though.
D1 - Secure Your Perimeter
Prerequisites: Complete the tutorial.
The first Defense challenge was testing your understanding of Common Vulnerabilities and Exposures better known as CVEs. They told you to submit the CVE of the highest priority vulnerability to remediate from the list. The flag was in the CVE ID format.
Given:
by Digital Defense
PDF of a network diagram
json file containing the vulnerability scanner's results (over 700 lines, probably over 80 different results, screenshot below)
D1 - Secure Your Perimeter [hint]
First things first. What are CVEs anyway? Why are they important? What kind of information do they contain?
In this case, I'm not supplying you with the actual json file, so you just got the screenshot which has less information to go over. I made sure to include the answer in it, so you should have had pretty easy time to find the flag.
D1 - Secure Your Perimeter [solution]
As long as you understand CVEs, this one wasn't particularly difficult. Download and open the json file in a text editor. The diagram isn’t really important.
Look at the “severity_name”; most of them are "Info" or "Low", there are also some "Mediums", but look at the "Critical" ones. There are only five; 3 browser vulns, 1 python vuln and finally a Windows critical one. Between browsers, python, and Windows... which is more important? Copy the Windows critical one and submit it as the flag:
CVE-2024-29994
D1 - Secure Your Perimeter [Points Breakdown and Number of Solves]
Total Points Possible: 300
Hint 1 costs 30 points.
Hint 2 costs 60 points.
Hint 3 costs 180 points and was basically a walkthrough. If you took it, you were only able to gain 30 points from this challenge.
646 people solved this one.
D2 - Look for Insider Threats
Prerequisites: Complete the tutorial.
One standard way to look for insider threats is to try to find sensitive data in places it shouldn't be.
For this one, you are required to use Regex to find Tax Identification Numbers (TINs) that have been encrypted by a script that they give you. You are also given a script file to run the Regex against. If you enter the successful Regex into the downloaded script, it'll give you the flag.
Below is the description of the script and the actual script that encrypts the TINs.
The "encryption" method, which they've taken to calling Visionàry Algorithm Protecting IDs, involves modifying each digit using its corresponding value in the passphrase: LUCKYLION
They give an example run of a regex script against the python script:
python snort.py 'regex(_|\s+)goes_?here$'
D2 - Look for Insider Threats [hint]
First, download the snort.py file and ensure the hash matches by opening the terminal on whatever Linux host you’re using, navigating to the folder the file is in and running the following command:
sha256sum snort.py
If using Windows, use PowerShell, navigate to the folder the file is in and run
Get-FileHash snort.py
If the hashes match, you’ve got the right file!
At this point, in order to figure this out, you need to understand three things:
What the script that encrypts the TINs is actually doing
ASCII Tables and how they relate to characters
Regex
(this isn't really necessary, but it's what stymied me for a while: you do not need the word regex in the command)
Once you understand these 3 (or 4) things, you should be good to grab the flag!
D2 - Look for Insider Threats [solution]
First of all, what is the script doing? It's basically performing a ROT13-like cypher, only rotating the key letters by the value of the number in the TIN in the same position. Using the first "L" in the key as an example; "L" in ASCII decimal is 76, so if the TIN starts with 0, the letter will still be L because 76+0=76. But if the TIN starts with 1, it becomes 76+1=77, which is "M". And so on. But you must understand the ASCII table because, otherwise, what are you going to do with Y?
Now that we know what the script is doing... How to form the Regex? If you run a non-functioning command you get the following back:
python snort.py ‘[’ malformed regex: [reason]
You can’t make it the Regex too broad: an expression with all the capital letters will match anything with 9 letters, you'd definitely get legitimate words like adventure and residence and get the “ill-fitting message”.
python snort.py ‘[A-Z]{9}’ valid regex, but ill-fitting
BUT look at the encrypting program: the phrase LUCKYLION is merely shifted by 0-9 places. So, the first letter can ONLY be the letters L-U, the second can only be U-^, and so on.
found unauthorized user handling TINs: RegexRanger
So the flag was:
RegexRanger
Side note: I struggled with this for some time before I realized that the "regex" in the command was not necessary. All of my tries included it. Apparently, leaving in the regex word gives the wrong answer, but removing gives the correct answer. lol
D3 - Investigate a Suspicious Email
Prerequisites: Complete the tutorial.
Someone forwarded you a suspicious email. See if you can find evidence of phishing.
D3 - Investigate a Suspicious Email [solution]
You can scan the QR Code with your phone, or, if you dislike QR Codes for this reason, you can also right on the QR code and select “Search image with Google”. Google Lens will search the image and come up with: QR code: Text
synt{rirel_pgs_arrqf_ebg13}
Which is not the flag... But then you can enter this into CyberChef or another similar encryption/decryption program and use ROT13 to get the flag:
flag{every_ctf_needs_rot13}
D4 - Write IOC detection
Prerequisites: Complete D3.
After determining information about a credential harvesting site, write a Suricata rule to alert on outgoing HTTP traffic to the phishing domain. The flag is the missing information.
You are given a partially complete Suricata rule to start with:
alert http $CORP_NET any -> $EXTERNAL_NET any (msg:"Detected traffic to wood-chewers.trees"; http.host; _____________; sid:1000001; rev:1;)
D4 - Write IOC detection [solution]
The easiest way to complete this was just to review both the Suricata doc as well as look carefully at the incomplete rule above. Reviewing both indicates that the missing part is in the options and has to do with "http.host". You also notice that the sid is just a reference number for the alert, so really has nothing to do with the missing part. Unsurprisingly, there is as section under "Rule Options" and "http.host". One of the examples shows a very simple rule that only contains two parts: "http.host" and "content:"URL"". That makes the missing part of the rule:
content:”wood-chewers.trees”
D5.1 - Identify compromised user
Prerequisites: Complete D4.
Alright! You've got a Suricata rule set up to alert you on any traffic going there. Now you need to review the logs you've collected for any potential compromised users!
You are given another json file that is the output from the Suricata rule. From this, you need to identify how many users you'll need to review.
Given:
suricata_alert.json (screenshot below)
D5.1 - Identify compromised user [solution]
You're not able to do this because you don't have the file, but I just counted the number of unique source IPs. In this case, there were no duplicates so it’s just the number of total source IPs seen, which you can get if you search for "src_ip". Most text editors will display the count of instances found.
8
D5.2 - Identify compromised user
Prerequisites: Complete D5.1.
Continue reviewing the same json file to determine how we can actually tell if a user may have sent credentials to the phishing site. The flag is the field name and value that you can use to determine this. Here's another screenshot of another section of that file to help.
D5.2 - Identify compromised user [solution]
This one had a file to download that shared the filename as challenge D5.1. Sometimes they are different files though!
For this one, I just reviewed the file for anything that looked like information had been sent. The only thing I could find was this, which turned out to be the flag:
“http_method”: “POST”
D5.3 - Identify compromised user
Prerequisites: Complete D5.2.
After determining how we can tell if information has been sent or not, use this to determine the IP address responsible for that traffic. The IP is the flag.
D5.3 - Identify compromised user [solution]
You found the method to determine if information was sent to the phishing site. Now you just have to find the source IP for that field.
10.15.38.78
The only extra thing here was that there was a dest_ip also listed which may have confused some. If you weren't sure which one was the answer (although you had unlimited tries for this one and accuracy wasn't important), you could have thought about the directionality of the actions (it is outgoing to the phishing website, so it would be the source) or saw that all the dest_ips were the same, while all the src_ips were different. Either way, we got this flag!
D5.4 - Identify compromised user
Prerequisites: Complete D5.3.
This time, we're given network logs in a CSV file. We're also given that the IP address belongs to host WDIGCVY2S with user bob_wctf24. The flag is the bash query command that will quickly let you identify data associated with the IP found in the previous sub-challenge.
Given:
networklogs.csv
D5.4 - Identify compromised user [solution]
It's a very small file, but that doesn't help you in this case, since you need to run a bash query. If you've used Linux before, you had a leg up on this one. I remembered "grep" was the search function for Linux, so I just needed a refresher on the syntax, but after that I just had to run it!
grep 10.15.38.78 networklogs.csv
For future reference, the syntax is: grep <search pattern> <location>
D6 - PCAP Analysis
Prerequisites: Complete D5.4.
As you have probably guessed, this time we're given a PCAP to determine which tool was downloaded on the host and where it came from. The flag is the full request URI that the tool was downloaded from.
Given:
pcap.zip (which contains anydesk_hostonly.pcapng)
D6 - PCAP Analysis [solution]
If you don't know what you're looking for, or how to search, you’ll probably need to dig around for this as there are 196 packets. However, when you first open the file, it's actually right there. But we'll act as though it wasn't. There are a couple of different ways to search in Wireshark, the first being filtering (there are examples if you click on the small down arrow at the right of the filter bar) such as "ip.addr==192.0.2.1" or using search options like protocols (TCP, HTTP), which will show you only the things that match your filter. The second way is by searching. That option is somewhat hidden, but definitely there! If you click the magnifying glass above the filter bar, you'll get some more text fields that drop down. If you just want anything that matches "Get" for example, you'll want to mark it as a "string", enter "Get" and hit enter.
It’s a "Get" request and when you find it, look in the bottom left window for “Full Request URI” under "Hypertext Transfer Protocol" and submit that.
http://anydesk.com:8000/AnyDesk.exe
D7.1 - Review Connection Logs (Host A)
Prerequisites: Complete D6.
Now we know the user, host, and tool that was used to infiltrate our network! The next step is to determine what was done with AnyDesk. However, where do we even start? This time we're not given any files - the flag is the full path (beginning with C:) to the directory where AnyDesk's logs are stored.
D7.1 - Review Connection Logs (Host A) [solution]
You just need to know where to find the of logs AnyDesk. Google “anydesk logs” and there is a question under People also ask, “Where can I find AnyDesk logs?”
C:\Users\bob_wctf24\Appdata\Roaming\Anydesk
For this, we mostly used Open-Source Intelligence (OSINT), but we also had to use previous knowledge - the username was identified in D5.4.
D7.2 - Review Connection Logs (Host A)
Prerequisites: Complete D7.1.
Now that we have AnyDesk's logs, can we identify the fields in the logs that identify our attacker? The flag this time is the attacker's IP and exact timestamp of when the connection was opened in the following format: YYYY-MM-DD 00:00:00.000,IP.IP.IP.IP
Given:
ad_svc.trace (screenshot below)
D7.2 - Review Connection Logs (Host A) [solution]
There aren’t a ton of logs here, and really only 2 IPs, so mostly the problem is figuring out which time it was. All time dates/times are the same except for the milliseconds. It’s the time where it initially says “New ANY connection”.
2024-04-18 06:42:31.190,203.0.161.68
Thankfully, this challenge allowed for unlimited attempts since I chose wrong the times twice... :-|
D8 - YARA Analysis
Prerequisites: Complete D7.2.
This was one Defense challenge that gave most people trouble, including me! A json file is given to you that contains Strelka's analysis of the malicious file. You're asked to create a YARA rule that will detect the same file.
You are given:
curl -H "Content-Type: text/plain" <URL> -X POST -d 'rule test {condition: true}'
strelka.json (screenshots below)
D8 - YARA Analysis [hint]
Basically, understand how YARA rules are formatted and made first. Then review the strelk file for anything unique that could be used to identify the file. It’s a lot of trial and error. Being methodical helped on this one. You have to read the output you get, which looked like this:
{“target_file”:true,”total_matches”:”2/100”}
You want the first condition to be true (as in this example, but it could also read false) and the second condition to be 1/100.
Another website that might help:
virustotal.github.io/yara-x/docs/
D8 - YARA Analysis [solution]
First, I tried strings as I was just learning about YARA. I tried searching for the string “anydesk”, which gave me True and 100/100. Then I tried “.exe” and that gave me 2/100 BUT the first condition was False. So, no help there.
Then I read about the hash module, which got me nowhere. All were False and 0/100.
Then I read about the PE module, which turned out to be the right path. It took a lot of trying different variations, but I got to PE rules to give me True and 2/100. Then I added strings "anydesk" and determined the real file will likely have a lot of these strings and YARA can count the number of matches. Fiddling with the number of these got me the flag in the end!
This is what my final rule turned out to be:
curl -H “Content-Type: text/plain" https://target-flask.chals.io/api/v1/yara-scan -X POST -d ‘import “pe” rule test {strings $a = “anydesk” nocase condition: #a>6 and pe.size_of_image == 24416256 and pe.checksum == 5359632}’
Which gave me the flag:
y3t_an0th3r_r3curs1v3_acr0nym
Unfortunately, I forgot to grab a screenshot before I moved on. Oh well.
D9.1 - Review Connection Logs (Host B)
Prerequisites: Complete D8.
Like before, we're given more logs to analyze. This time though, we obtained them from a host that we detected the activity by using the YARA rule we created in the previous challenge. We're asked to use the logs to determine three things and submit all three as the flag: 1) Upload or Download to/from our internal host? 2) Directory Name on the remote machine? 3) Port Number on the internal machine that accepted the connection?
Given:
ad.trace
user.conf
ad_svc.trace (different file than D7.2)
D9.1 - Review Connection Logs (Host B) [solution]
Reviewing ad.trace, you can find whether it was an upload or download. Reviewing user.conf, you can find the name of the folder, and using the last file, ad_svc.trace, you can find the port.
From ad.trace, one of the descriptions says “Download started”. Thinking about the directionality of this log and the wording of the question, determines that this is an upload to our internal host. The host downloaded it, so therefore the threat actor uploaded it to the internal host.
From user.conf, one of the lines says “local browser” and a file path, and the other says “remote browser” and a file path. Simply use the last folder in the remote path.
From ad_svc.trace, the port appears at the end of the IP address for the remote user
upload,fun_files,57836
I originally tried download and got it wrong. Whoops, wasn't paying enough attention. lol
D9.2 - Review Connection Logs (Host B)
Prerequisites: Complete D9.1.
Same scenario as D9.1, but this time the flag is the path (beginning with C:) of the directory that the threat actor dropped a file into on our host using the logs.
Given:
ad.trace (same file as D9.1)
user.conf (slightly different file than D9.1)
ad_svc.trace (same file as D9.1)
D9.2 - Review Connection Logs (Host B) [solution]
There’s realistically only one choice for this (the others being the remote host file path and the AnyDesk location), so I just entered that.
C:\Users\wctf24\AppData\Local\Temp
Side note: I belatedly realized that the user is different because this is Host B. This is important for the next part.
D10.1 - Strelka Analysis
Prerequisites: Complete D9.2.
We've identified another suspicious file on this host, so now we need to determine if it's malicious. This can be done using the automated Strelka sandbox. We have to submit the right command to Strelka in order to find the flag, which is the SHA256 hash of the file.
Given:
Path to Suspicious File: C:\Users\wctf24\AppData\Local\Temp\img_001.scr
This one was confusing since I wasn't sure if we are looking at Host A or B at this point. But assuming the TA did the same to both, we can use either I guess.
Anyway, I used the hostname from D5.4, D7.1, and D8 (WDIGCVY2S) and the path from this description and kept getting “bad request”. So I escaped the backslashes for the path and got a bunch of text!
To save the output for the later sub-challenges, just put:
command >> outputfilename
D10.2 - Strelka Analysis
Prerequisites: Complete D10.1.
Continuing the analysis from D10.1, what is the epoch timestamp of the Portable Executable (PE) file?
D10.2 - Strelka Analysis [solution]
For this one, I just used the file I created above and searched for “time”. There were only 2 entries that even had times, and only one of them had something that looked like an epoch timestamp: 1722121366… which was wrong. I compared that number to the time I got in the terminal and they were different… meaning that is not the PE timestamp. So, I just took the second time (compile_time) and converted it using an online converter (search for "convert time to epoch") and came up with the epoch timestamp:
1714829820
D10.3 - Strelka Analysis
Prerequisites: Complete D10.2.
Continuing the analysis from the previous sub-challenge, what is the PE checksum in hex?
D10.3 - Strelka Analysis [solution]
Same as before; just used the previous file created. Found the checksum which is “463362” and tried to use CyberChef to change it To Hex. But that didn’t work, so I tried another online tool to convert and this time verified it by using the above example. Not sure what CyberChef was doing, but whatever. It is an example of how things don't always work the way you think they will, so it helps to try a variety of tools when you're stuck.
71202
D10.4 - Strelka Analysis
Prerequisites: Complete D10.3.
Continuing the analysis from the previous sub-challenge, what is the name of the malware?
D10.4 - Strelka Analysis [solution]
Again, just used the file from before.
After reviewing the file again, at the beginning it had a category of “yara” and two keys: “darkgate” and “mz_file”. Reasoning that Strelka is identifying the file using these, I tried it and it worked! Also, darkgate showed up a ton in that file.
darkgate
D10.5 - Strelka Analysis
Prerequisites: Complete D10.4.
Continuing the analysis from the previous sub-challenge, what is the C2 identified in the DarkGate config?
D10.5 - Strelka Analysis [solution]
Realistically, under “darkgate”: {“config”{, there is only one thing in that list that could make sense as a C2, which is what I entered and it worked!
fresh-eats.trees
Side Note: A "C2" means "Command and Control" and in Cybersecurity, it refers to how threat actors communicate with compromised devices. Usually it refers to IPs and/or domains, which is why I reasoned it had to be that domain.
D11 - Trace the handoff
Prerequisites: Complete D10.5.
Based on all of the prior investigation and analysis, the threat actor has access to our environment. Based on threat intelligence, we know that threat actors often sell access to quickly and easily monetize their efforts. Now search for who bought the access. Their Tox ID is the flag
D11 - Trace the handoff [solution]
This one was tough because you had to use their data search engine, which isn’t the easiest to use… The left hand menu is just what columns you wanted to see on the search page (which took me a while because I assumed it was for searching). There was also an area you could choose to search for “posts” or “btc-transactions”. Of course, there were no actual posts to see, just the “document” aka table/json data.
So, I ended up searching posts for “Topic” and “Title”. The “Topic” was “Illegitimate Access Advertisements”. I looked around for a bit, “Lucky Lion” got me nowhere, whereas I saw titles and descriptions for “medical database” and “government access” etc, so I searched for “casino”. And thankfully there was only one hit!
Date: May 10, Author: DeliciousHardwood, Title: “Feeling Lucky? We’d be Lion if we said we weren’t”, forum.name: “zer0daze”.
Then I used the cypto_wallet and searched the btc-transactions for that and found one hit as well on May 12. This one, the crypto_wallet was listed as “outputs.account” so I looked at “inputs.account”. It listed 6 different ones, so I searched posts for them and came up with… nothing. So I searched in transactions again and the third came up with something on Feb 11, but this time came up as the outputs.account. So I searched the 5 input accounts for posts and the third came up with a post on Feb 9. This post gave me the Tox ID I needed!