SANS Holiday Hack Challange 2022: Writeup
This is my write-up for the SANS Holiday Hack Challenge 2022.
Main Objectives
The first part of the objective is an introduction where you are told about how your badge work, how the terminal works and a tutorial on setting up your wallet. It also establishes the backstory and sends you down in the underground tunnels. After this is completed there are five main objective chapters, each containing a few challenges.
Recover the Tolkien Ring
The first chapter is to recover the Tolkien Ring. This chapter revolves around DFIR.
Wireshark Practice
The first challenge is a terminal where you get a PCAP and need to answer a few questions about the traffic.
To answer the first question, we look at the traffic, see that there is a lot of HTTP traffic and then go to File
-> Export objects
-> HTTP
to export them. We can then find the answer to the second question by looking at the list of files to export and sort by size to find app.php
. To find the answer to the third question we look at that same entry in the objects list and see that it starts at packet 687
. By looking at this packet in the list we can answer the fourth question. Note that this packet is the first packet of the response so the IP address of the web server is the source address of this packet: 192.185.57.242
. Looking at the contents of this app.php
file we find a line at the end of the javascript block referencing Ref_Sept24-2020.zip
. For the sixth question we can filter the packets for tls
and look at the “Server Hello” packets for certificates. There are not that many entries so we can quickly go through them manually and find, apart from the legitimate Microsoft certificates, two other countries: SS
and IL
which translate into the answer Israel, South Sudan
. Finally, the answer to the last question is obviously: yes
the host is infected.
In summary these are the questions and answers to complete the terminal:
- Can you help me? yes
- There are objects in the PCAP file that can be exported by Wireshark and/or Tshark. What type of objects can be exported from this PCAP? http
- What is the file name of the largest file we can export? app.php
- What packet number starts that app.php file? 687
- What is the IP of the Apache server? 192.185.57.242
- What file is saved to the infected host? Ref_Sept24-2020.zip
- Attackers used bad TLS certificates in this traffic. Which countries were they registered to? Submit the names of the countries in alphabetical order separated by a commas (Ex: Norway, South Korea). Israel, South Sudan
- Is the host infected (Yes/No)? yes
Windows Event Logs
In this challenge we get a Windows event log with some suspicious entries. We can start by converting the logfile into a human-readable format. This can be done with python-evtx:
The rest of the analysis is done mostly by using grep on this XML file. We note that there are a lot of events related to powershell activity. One of the tags present is <Data Name="ScriptBlockText">
containing the executed script. We can perform some initial triage by grepping for ScriptBlockText
and browsing through the various commands. Doing this we find a lot of suspicious activity on 2022-12-24
. Looking at the strange commands in that day we see that they read a file called Recipe
. Looking at the commands and searching for Get-Content
and recipe
we find multiple commands of interest for the third question. The one that follows the exact description of the question is: $foo = Get-Content .\Recipe| % {$_ -replace 'honey', 'fish oil'}
. To answer the next question we can search for the variable $foo
and find commands that match the description. By doing this we find: $foo | Add-Content -Path 'Recipe'
. If we search for that command in the log we find a similar command having been run multiple times against Recipe.txt
which answers question 5. By searching for commands such as del
and rm
in the log we find execution like del .\Recipe.txt
so files have indeed been deleted and the answer to question 6 is “yes”. However, looking at the deletion commands we do not find anything relating to Recipe
. Additionally, looking for Recipe
we see no deletion looking command so the answer to question 7 is “no”. By looking at the full entry corresponding to the deletion command we can find event id 4104. We can also conclude from the replacement command that the secret ingredient is “honey” and that it has been compromised. Therefore we have the information to answer the final three questions and solve the terminal.
In summary these are the questions and answers to complete the terminal:
- Are you ready to begin? yes
- What month/day/year did the attack take place? For example, 09/05/2021. 12/24/2022
- An attacker got a secret from a file. What was the original file’s name? Recipe
-
The contents of the previous file were retrieved, changed, and stored to a variable by the attacker. This was done multiple times. Submit the last full PowerShell line that performed only these actions. *$foo = Get-Content .\Recipe % {$_ -replace ‘honey’, ‘fish oil’}* -
After storing the altered file contents into the variable, the attacker used the variable to run a separate command that wrote the modified data to a file. This was done multiple times. Submit the last full PowerShell line that performed only this action. *$foo Add-Content -Path ‘Recipe’* - The attacker ran the previous command against a file multiple times. What is the name of this file? Recipe.txt
- Were any files deleted? (Yes/No) yes
- Was the original file (from question 2) deleted? (Yes/No) no
- What is the Event ID of the log that shows the actual command line used to delete the file? 4104
- Is the secret ingredient compromised (Yes/No)? yes
- What is the secret ingredient? honey
Suricata Regatta
In this challenge we are tasked with writing a number of Suricata rules to capture some packets. To understand the various fields we have available for the different protocols we can reference the Suricata documentation on rules. The first rule should capture DNS lookups for the domain “adv.epostoday.uk”. The important parts of this rule is to check for udp on port 53 and then use the “dns.query” flag with content set to “adv.epostoday.uk”. The second rule should capture http traffic between the host “192.185.57.242” and the internal network. The important parts here are using “<>” to capture packets in both directions and using the “$HOME_NET” variable to capture the whole home net. For the third rule we want to find TLS certificates for the host “CN=heardbellith.Icanwepeh.nagoya”. The important parts of this rule are using the “tls” protocol and then the “tls.cert_sibject” flag with content “CN=heardbellith.Icanwepeh.nagoya”. Finally the last rule requires us to find the javscript snippet “let byteCharacters = atob”. The important parts here are that we look for http traffic and then use the “http.response_body” flag to get the full body whether it is compressed or not and then combine it with content “let byteCharacters = atob”.
In summary, here are the four rules we need to write:
With this done we have recovered the Tolkien Ring!
Recover the Elfen Ring
The second chapter is to recover the Elfen Ring. This chapter revolves around DevOps topics.
Clone with a Difference
We are given the URI to a git repo which is supposed to be public: git@haugfactory.com:asnowball/aws_scripts.git
. To be able to clone this we modify the URI into a https URL instead as is common with most popular git hosts: https://haugfactory.com/asnowball/aws_scripts.git
. This way we can clone the repo and find the last word in the README.md
file: maintainers
.
Prison Escape
In this terminal we are tasked with escaping a Docker container. I followed an excellent guide from the Snyk team to find out that the container is running in “privileged” mode and then to escape it. In short, the final commands I used were:
Jolly CI/CD
In this challenge we are inside a network of multiple hosts and have been given the address of a git repo. First we have to wait a bit for the infrastructure to come up and then clone the repo. We can do this by running:
Once we have the repo, we can take a look at the commit log by running git log
. There we find a commit with the message “whoops”. If we check out the commit before that one, we find a private SSH key which we copy to another directory and set the appropriate permissions on.
We can then create an SSH config with that key and check out the repo but this time with credentials:
We can then add two steps to the CI/CD configuration to exfiltrate the deploy key by copying it to the webroot and making it world-readable. We can then push this new config, wait for a bit for it to be executed, download that key and connect to the webserver to get the flag.
By doing this we recover the Elfen ring!
Recover the Web Ring
The third chapter is to recover the Web Ring. This chapter, unsurprisingly, revolves around web topics.
Naughty IP
For the first four objectives we need to analyse a PCAP file to investigate some web-based attacks. First we need to find a naughty IP address. We can do this in Wireshark by going to the “conversations” window and sorting on number of packets to find the IP address “18.222.86.32” and by filtering on it we see that they have been doing some brute force login attacks.
Credential Mining
We can investigate this brute force more closely by filtering on “ip.addr==18.222.86.32 && http.request.method == POST” to find all HTTP POST requests from this IP and finding the first username tried: “alice”.
404 FTW
After the brute force login we need to find the first successful request. We can do this by filtering on the suspicious IP address and looking for HTTP responses with status code 200 among all packets after packet 21457: “ip.addr==18.222.86.32 && http.response.code == 200 && frame.number > 21457”. We can then find the first successful response and go to the corresponding request to see that the URL was “http://www.toteslegit.us/proc”.
IMDS, XXE, and Other Abbreviations
Finally we can find the XXE attack by looking at HTTP requests originating from the web server ip address “10.12.42.16” with this filter: “ip.src == 10.12.42.16 && http.request”. This reveals the URL that was fetched: “http://169.254.169.254/latest/meta-data/identity-credentials/ec2/security-credentials/ec2-instance”.
Open Boria Mine Door
The next challenge requires us to input some input to make the “circuits” connect from left to right.
- For the first one, check the source to find the string
@&@&&W&&W&&&&
which is a valid input. - For the second one, we can inject a HTML div tag which covers the whole input box:
- For the third one, we can inject some javascript to create a div like in the second one:
Glamtariel’s Fountain
For the last challenge we are supposed to navigate a strange web application. The intention of this challenge is to teach some ways you can interact with a web application, especially how XXE attacks work but unfortunately I don’t think it was well designed at all. The steps to complete it is essentially:
First we interrogate both the fountain and Galadriel normally with all items until you get to the third batch. Then we change the JSON request into an XML request by changing the Content-Type header to “application/xml” and changing the body as shown below:
JSON body
XML body
Now we add an XXE attack to the request and guess the path to the ringlist.
After that, we use the new URL you find to look at the hidden images and make new requests.
Finally, we change which field you inject the entity into.
This recovers the Web ring!
Recover the Cloud Ring
The fourth chapter is to recover the Cloud ring. This chapter, again unsurprisingly, revolves around cloud topics.
AWS CLI Intro
In the first challenge we are tasked with configuring the AWS CLI tool. We can do this by running aws configure
and inputting the data provided. Afterwards we can use aws sts get-caller-identity
to see who we are authenticated as.
This gives us back the following information and finishes the challenge:
Trufflehog Search
In this challenge we use Trufflehog to find secrets in a git repo:
This gives us, among other things, the following result:
Found unverified result 🐷🔑❓
Detector Type: AWS
Decoder Type: PLAIN
Raw result: AKIAAIDAYRANYAHGQOHD
Commit: 106d33e1ffd53eea753c1365eafc6588398279b5
File: put_policy.py
Email: asnowball alabaster@northpolechristmastown.local
Repository: https://haugfactory.com/asnowball/aws_scripts.git
Timestamp: 2022-09-07 07:53:12 -0700 -0700
Line: 6
So the answer to the challenge is: put_policy.py
Exploitation via AWS CLI
Finally, in this challenge we combine the two previous challenges to recover a key, authenticate against it and then use various commands to traverse the various policies associated with our account to finally find that we have access to an S3 bucket and a Lambda function.
First we get the credentials like in the previous challenge:
Then we configure the AWS CLI like in the first challenge:
Finally we investigate various resources in the AWS API as prompted by the challenge:
This nets us the Cloud ring!
Recover the Burning Ring of Fire
The final chapter revolves around blockchains and smart contracts.
Buy a Hat
To solve the first challenge, we go to a KTM, approve a transfer of 10 KC to address 0x8bd9a48b6208c63Be1f33F0e263623cB2a354e75 by inputting that information together with our wallet key. We then we go to the hat machine and input our wallet id and the id of the hat to get the hat.
Blockchain Divination
To solve this challenge, we note the block id of the transaction in the previous challenge and then go to the blockchain explorer and enter this id. In this block we can see that the coins were transferred from address 0x8bd9a48b6208c63Be1f33F0e263623cB2a354e75 to address 0xc27A2D3DE339Ce353c0eFBa32e948a88F1C86554 which is were the smart contract is located.
Exploit a Smart Contract
To solve the final challenge, we grab the list of existing owners from the gallery page, we then fetch the tool written by QwertyPetabyte and modify the allowlist in the code to include our address as well as the current owners’ addresses.
We then calculate a new proof and Merkle root using this list. We can now go to the web app and submit the validation since the Merkle root is not provided by the server but instead sent from the client side as part of the request. We can therefore replace the root and input our generated proof and root to submit a valid claim of a token.
By doing this we recover the Burning Ring of Fire.
Conclusion
Thanks to SANS for hosting another great edition of the Holiday Hack challenge. These challenges are very nice, especially for beginners as they cover a broad range of topics and there’s almost always something to take away, even for an experienced person. I strongly recommend you to check out the next one if you get the opportunity to.