HHC 2022 - Tolkien Ring Walkthrough

The walkthrough for the Tolkien Ring, the first of 5 rings in the 2022 Holiday Hack Challenge

HHC 2022 - Tolkien Ring Walkthrough

Navigation Shortcut

Go to the Tolkien Ring, its down in KringleCon tunnel, just past the Hall of Talks.

Note: The locations of the challenges aren't meant to be a secret (though the location of some of the treasure boxes are!). Once you are in the KringleCon tunnel, you continue to progress down to each specific room tied to a ring (i.e. Tolkien Ring, Elfen Ring, etc.)
Note: As you visit a new location, your "Destinations" will populate in the status bar, and can be used as a shortcut to transport to location. From the task bar, click on the purple Marker Icon (1) from the task bar, which will load the Destinations shortcut.  From there you can click on any of the locations you've previously visited (2) to use Santa's Christmas magic to teleport to the location. A location will be denoted with hyphens (i.e. -) until you visit the location.

1.1 Wireshark Challenge

  • Download the suspicious.pcap file
  • Click on the Raspberry Pi next to Sparkle Redberry to launch the terminal.  The upper pane will be used to answer questions, while the lower pane can be used to run commands via tools such as tshark
  • Don't forget to type hint in the upper pane if you need a nudge!

1. There are objects in the PCAP files that can be exported by Wireshark and/or Tshark. What type of objects can be exported from this PCAP?


Open the pcap in Wireshark, navigate to the Conversations, by navigating to Statistics (1) --> Conversations (2)

Analyze the conversations, and specifically on the TCP tab, it specifies traffic going over HTTP (port 80) and HTTPS (Port 443)



2. What is the file name of the largest file we can export?


  1. Click on File
  2. Navigate to Export Objects
  3. Select HTTP...

Which will load the following 3 files:

This also gives us the answer to the next question...


Based on the hint/syntax from this link

tshark -Q -r $pcap_file --export-objects $protocol,$dest_dir

Can use the command (needs the files directory to exist):

tshark -Q -r suspicious.pcap --export-objects 'http','files'

Note that two different app.php files are downloaded, but Linux automatically renames one to app(1).php.



3. What is the packet number that starts app.php?

See the Wireshark Section from Question 2


Packet # 687

4. What is the IP of the Apache Server?


Inspect packet 687 to see the Source and Destination IPs, as well as the Source/Destination Ports. It's safe to assume the Apache Server would be running on port 80, so therefore the correct IP is

Additionally, you could follow the TCP Stream (right click on packet 687 --> Follow --> TCP Stream), and note that the HTTP Server responding to the requests (click the drop down of Entire Conversation, and click on each of the options). The server responses will be the usual HTTP/1.1 200 OK headers.


5. What file is saved to the infected host?

Inspecting the second app.php file shows your answer:

└─$ tail  app\(1\).php                                                                                                                                   1 ⚙
    // now that we have the byte array, construct the blob from it
    let blob1 = new Blob([byteArray], {type: 'application/octet-stream'});

    saveAs(blob1, 'Ref_Sept24-2020.zip');



The saveAs function saves the blob as Ref_Sept24-2020.zip



6. Attackers used bad TLS certificates in this traffic. What countries were they registered to? Submit the names of the countries in alphabetical order separated by a commas (Ex: Norway, South Korea).

tshark -r suspicious.pcap -Y 'ssl.handshake.type == 11' -T fields -e x509sat.CountryName | sort | uniq | sed -z 's/,/\n/g' | sort | uniq | sed -z 's/\n/,/g'

The command looks for ssl.handshake types where the server responds with the certificate.  We are then trying to extract the x509sat.CountryName field from those responses.  The sort, uniq, are intended to remove duplicates, while sed separates responses that have multiple country codes per line onto a new line.  After which there is another sort and uniq to remove duplicates, and sed takes each of the country codes and puts them.

Looking those values up, using a site such as ssl.com you find the answer: Ireland, Israel, South Sudan, United States


Walking the dog a bit more to explain how you might extract some of those values (outside of the useful sources listed below), you could open up the file in wireshark. From there:

  1. Add a ssl.handshake.type == 11 filter to only look at the server sending it's certificate
  2. Select a packet, and drill down into it's certificate
  3. Highlight/select the countryName,
  4. Click on the value in the hex output
  5. Which shows the CountryName value in the footer of wireshark.

You in theory could go each packet and collect these names, but that's very cumbersome, and not befitting of a Linux master like yourself, which is why the recommended path is the tshark/sort/uniq/sed combo listed above.


Ireland, Israel, South Sudan, United States

Useful sources:

To find the ssl.handshake.type == 11 value: https://subscription.packtpub.com/book/networking-and-servers/9781785887819/4/ch04lvl1sec27/the-ssl-tls-handshake
To find the x509sat.CountryName code to use as a filter: https://www.wireshark.org/docs/dfref/x/x509sat.html

7 . Is the host Infected (Yes/No)?


Yes, otherwise why would Santa be having problems?!?!

1.2 Find the Next Objective

This is the second objective in the Tolkien Ring, which directly tells you what needs to be done.  Go back to Dusty Giftwrap and interact with them (i.e. click on them) a few times to find the next objective... Windows Event Logs!

1.3 Windows Event Log


This is another objective that is a low barrier of entry.  The challenge is located in the Tolkien Ring Hall, just next to Dusty Giftwrap.  The console doesn't look like a Raspberry pi, but instead a rectangular computer screen with a black and white CLI.  Once the CLI is opened, be sure to use the hint functionality within the upper pane if you are lost.

1.  What month/day/year did the attack take place? For example, 09/05/2021

This one requires opening and looking at the log file before generating the command.  A quick review shows a format of lines that start with Verbose MM/DD/YYYY. Use that to filter the results, sort through all of them, and get a unique count (uniq -c) of each entry.  The last sort is used to order the final results with the most occurrences of the date at the very bottom.

grep 'Verbose' powershell.evtx.log | cut -d ' ' -f 1 | sort | uniq -c | sort



2. An Attacker got a secret from a file. What was the original file's name?

It mentions a file - and a common parameter in PowerShell to denote a file is -Path. We add a space before the -Path value in our grep to avoid any *-Path PowerShell commands:

elf@d03f3a9179dc:~$ tac powershell.evtx.log | grep '$foo'
$foo = Get-Content .\Recipe| % {$_ -replace 'honey', 'fish oil'} $foo | Add-Content -Path 'recipe_updated.txt'
$foo = Get-Content .\Recipe| % {$_-replace 'honey','fish oil'} $foo | Add-Content -Path 'recipe_updated.txt'
$foo = Get-Content .\Recipe| % {$_-replace 'honey','fish oil'}
$foo | Add-Content -Path 'recipe_updated.txt'
$foo | Add-Content -Path 'Recipe.txt'
$foo = Get-Content .\Recipe| % {$_-replace 'honey','fish oil'}
$foo | Add-Content -Path 'Recipe.txt'
$foo = Get-Content .\Recipe| % {$_ -replace 'honey', 'fish oil'}
$foo | Add-Content -Path 'Recipe.txt'
$foo | Add-Content -Path 'Recipe'

We use tac instead of cat to print out the results in reverse order -PowerShell logs prepend new logs to the file, so tac allows us to view the results chronologically when reading from top to bottom, to read through the results more easily.  The results gives some insight into what might've been occurring, looks like someone was trying to update the Recipe file...

Answer: Recipe

3. The contents of the previous file were retrieved, changed, and stored to a variable by the attacker. Submit the full PowerShell line that performed only these actions.

You'll find the answer to this question in the output of our question above. To break down the question:

The contents of the previous file (Recipe) were retrieved (Get-Content),

Powershell prints files with the Get-Content command.


Typically you can look for a For-Each, but an alias for that command is  % {}. The command is looping through each word of the output, and changing the word honey to fish oil (-replace 'honey','fish oil').

stored to a variable by the attacker

Powershell variables are prefixed with a $, of which $foo was in the output.

The output has two lines that are similar.  We want the first entry, with the space between the honey and fish oil ('honey', 'fish oil').


$foo = Get-Content .\Recipe| % {$_ -replace 'honey', 'fish oil'} $foo | Add-Content -Path 'recipe_updated.txt'

4. After storing the altered file contents into the variable, the attacker used it to run a separate command that wrote the modified data to a file. Submit the full PowerShell line that performed only this action.


$foo | Add-Content -Path 'Recipe.txt'

5. What was the name of the file that was edited:



6. Were any files deleted (Yes/No)

The file was deleted by being rewritten.



7. Was the original file deleted (Yes/No)

The original file was rewritten.



8 . What is the event ID of the log that shows the actual command line used to delete the file?

Add a flag to display 1 line before, switch back to cat so the most recent command deleting the file appears first. The Event ID is listed after the phrase Microsoft-Windows-PowerShell.

elf@d01279575070:~$ cat powershell.evtx.log | grep '\$foo' -B 1
Verbose 12/24/2022 3:05:07 AM   Microsoft-Windows-PowerShell    4104    Execute a Remote Command       "Creating Scriptblock text (1 of 1):
$foo | Add-Content -Path 'Recipe'
<-- Truncated for brevity -->



9. Is the secret ingredient compromised (Yes/No)?

The secret ingredient was switched from honey to fish oil.



10. What is the secret ingredient?



1.4 Find the Next Objective


Talk to Fitzy Shortstack for the next objective.


Continue to move "deeper" - aka more to the right - into the Tolkien Ring Hall, chat with Grinchum along the way (optional), and find Fitzy Shortstack next to the Raspberry Pi on the ice near the ice monster. Chat with them to find the next objective...

1.5 Suricata Regatta

Find the Raspberry Pi in the Tolkien hall and click on it to launch the web console.  Read the instructions.


Use your investigative analysis skills and the suspicious.pcap file to help develop Suricata rules for the elves!

There's a short list of rules started in suricata.rules in your home directory.

First off, the STINC (Santa's Team of Intelligent Naughty Catchers) has a lead for us.
They have some Dridex indicators of compromise to check out.
First, please create a Suricata rule to catch DNS lookups for adv.epostoday.uk.
Whenever there's a match, the alert message (msg) should read Known bad DNS lookup, possible Dridex infection.
Add your rule to suricata.rules

Once you think you have it right, run ./rule_checker to see how you've done!
As you get rules correct, rule_checker will ask for more to be added.

If you want to start fresh, you can exit the terminal and start again or cp suricata.rules.backup suricata.rules

Good luck, and thanks for helping save the North Pole!

elf@de38ec98aa33:~$ ls -al

Create Suricata Rule #1: Catching DNS Lookups


First, please create a Suricata rule to catch DNS lookups for adv.epostoday.uk.
Whenever there's a match, the alert message (msg) should read Known bad DNS lookup, possible Dridex infection.
Add your rule to suricata.rules

General syntax, found here:

alert dns any any -> any any (msg:"Test dns.query option"; dns.query; content:"google"; nocase; sid:1;)

Customized as requested:

alert dns any any -> any any (msg:"Known bad DNS lookup, possible Dridex infection"; dns.query; content:"adv.epostoday.uk"; nocase; sid:133700;)

Paste the rule into the suricata.rules file, and run the rule_checker:

elf@de38ec98aa33:~$ echo 'alert dns any any -> any any (msg:"Known bad DNS lookup, possible Dridex infection"; dns.query; content:"adv.epostoday.uk"; nocase; sid:133700;)' >> suricata.rules
elf@de38ec98aa33:~$ ./rule_checker 
8/12/2022 -- 22:42:38 - <Notice> - This is Suricata version 6.0.8 RELEASE running in USER mode
8/12/2022 -- 22:42:38 - <Notice> - all 9 packet processing threads, 4 management threads initialized, engine started.
8/12/2022 -- 22:42:38 - <Notice> - Signal Received.  Stopping engine.
8/12/2022 -- 22:42:38 - <Notice> - Pcap-file module read 1 files, 5172 packets, 3941260 bytes
First rule looks good!

< -- Truncated -->  
Note: Be sure to read the whole output to see the First rule looks good! before panicing if you only read the last sentence of Please Try Again!. That error message is referring to the second rule... which we'll try now!

Rule #2: Infected IP Address Communicates over HTTP


STINC thanks you for your work with that DNS record! In this PCAP, it points to
Develop a Suricata rule that alerts whenever the infected IP address communicates with internal systems over HTTP.
When there's a match, the message (msg) should read Investigate suspicious connections, possible Dridex infection


alert http 80 <> any any (msg:"Investigate suspicious connections, possible Dridex infection"; sid:133701; rev:1;)

Repeat the same steps to echo the rule to append the suricata.rules file, and run the ./rule_checker.

Rule #3: Bad Certificates


We heard that some naughty actors are using TLS certificates with a specific CN.
Develop a Suricata rule to match and alert on an SSL certificate for heardbellith.Icanwepeh.nagoya.
When your rule matches, the message (msg) should read Investigate bad certificates, possible Dridex infection


alert tls any any <> any any (msg:"Investigate bad certificates, possible Dridex infection";tls.cert_subject; content:"CN=heardbellith.Icanwepeh.nagoya"; sid:133702; rev:1;)

Rule #4: GZip Compressed Javascript atob


OK, one more to rule them all and in the darkness find them.
Let's watch for one line from the JavaScript: let byteCharacters = atob
Oh, and that string might be GZip compressed - I hope that's OK!
Just in case they try this again, please alert on that HTTP data with message Suspicious JavaScript function, possible Dridex infection


alert http any any <> any any (msg:"Suspicious JavaScript function, possible Dridex infection";file_data; content:"let byteCharacters = atob"; sid:133703; rev:1;)

GLORRYYYYY - Tolkien Ring Achieved!

Once complete, you will have successfully received the first of 5 rings!

More Walkthroughs

Below are the other walkthroughs for the 2022 Holiday Hack Challenge: