Skip to content

The Captain's Comms⚓︎

Difficulty:
Direct link: The Captain's Comms terminal

Objective⚓︎

Request

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.

Chimney Scissorsticks

Chimney Scissorsticks @ Brass Bouy Port

Ahoy there, I'm Chimney Scissorsticks!
You may have noticed some mischief-makers planning to stir up trouble ashore.
They've made many radio broadcasts which the captain has been monitoring with his new software defined radio (SDR).
The new SDR uses some fancy JWT technology to control access.
The captain has a knack for shortening words, some sorta abbreviation trick.
Not familiar with JWT values? No worries; just think of it as a clue-solving game.
I've seen that the Captain likes to carry his journal with him wherever he goes.
If only I could find the planned "go-date", "go-time", and radio frequency they plan to use.
Remember, the captain's abbreviations are your guiding light through this mystery!
Once we find a JWT value, these villains won't stand a chance.
The closer we are, the sooner we'll be thwarting their pesky plans!
We need to recreate an administrative JWT value to successfully transmit a message.
Good luck, matey! I've no doubts about your cleverness in cracking this conundrum!

Hints⚓︎

Comms Abbreviations

From: Chimney Scissorsticks
Terminal: The Captain's Comms

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

Comms Web Interception Proxies

From: Chimney Scissorsticks
Terminal: The Captain's Comms

Web Interception proxies like Burp and Zap make web sites fun!

Comms Journal

From: Chimney Scissorsticks
Terminal: The Captain's Comms

I've seen the Captain with his Journal visiting Pixel Island!
Captain's Journal

Comms JWT Intro

From: Chimney Scissorsticks
Terminal: The Captain's Comms

A great introduction to JSON Web Tokens is available from Auth0.

Comms Private Key

From: Chimney Scissorsticks
Terminal: The Captain's Comms

Find a private key, update an existing JWT!

Solution⚓︎

Ok let's solve The Captain's Comms...
Crazy

Jump into the terminal and start putting pieces of the puzzle together. This is Captain's battlestation:

Set-up

First, the background. We have the newly installed 'Just Watch This' Software Defined Radio system and are looking for the miscreants 'go-time' date and time for the attack so we could send a misleading transmission for 4 hours prior, and this will make sure islands' authorities are locked & loaded for response.
There are different ROLEs that are required for AUTHORIZATION to different items in Captain's Comms.

Background

Let's look at the Owner's Card - from this we can gather that we should look for rMonitor.tok file containing the radioMonitor token which is somewhere in the default /jwtDefault directory. The proper use of this AUTHORIZATION token will allow viewing signals but not decode them. To decode, we would need radioDecoder role token. Sounds like radioMonitor is the initial role we should focus on obtaining. Cool, onto finding more about getting to this file.

Owner's Card

Quickly check our current role. Copy the justWatchThisRole cookie value for https://captainscomms.com site (using Dev Tools) and decode the value using JWT.io. Good to know - our current role is radioUser. Also, keep in mind that the message is signed by RS256 (asymmetric algorithm) so you can't simply modify its contents, you would need the key to re-sign the payload.

Current Role

Ok now let's refer to the Owner's Manual Volume 1. This confirms that we are on the lowest permissions role (radioUser) as well as we need to look for radioMonitor mentioned on the Owner's Card.

Just Watch This Owner's Manual Volume 1

Let's try to get the radioMonitor role token based on all this information. From the Owner's Card, location should be https://captainscomms.com/jwtDefault/rMonitor.tok. On first access to this location, error "Invalid authorization token provided" occurs. Ok, let's observe normal traffic using Burp while interacting with Captain's Comms. The request shows that we are actually authenticating with the token via Authorization header on each request. The rest of Captain's Comms requests likely require this header and that's why there was an error. This is a typical request to the website:

Observe

Re-send the request for https://captainscomms.com/jwtDefault/rMonitor.tok with our current Authorization header and value:

radioMonitor Token

The token is returned and it can be confirmed. We can now access the radioMonitor required for Captain's SDR.

radioMonitor Token Decoded

You can either use Burp to intercept the request to the SDR and replace Authorization header or simply copy-paste the new token value into justWatchThis cookie value. The second way is more convenient.

radioMonitor Cookie

SDR is now accessible but not not very useful without the radioDecoder role.

SDR Accessible

Need radioDecoder

Let's target obtaining radioDecoder token now. This token is not far away and after some tinkering, it can be found the same way as radioMonitor, by simply accessing https://captainscomms.com/jwtDefault/rDecoder.tok with the radioMonitor token in the Authorization header. Got it and confirmed:

radioDecoder Token

Again, copy-paste the token into justWatchThis cookie and access the SDR - all 3 transmissions can now be decoded!
Transmission 1 tells you that Captain's private key is in a folder called TH3CAPSPR1V4T3F0LD3R. 🤦‍♂️

Transmission 1

Transmission 2 gives us some kind of encoded message - we can investigate this further later.

Transmission 2

Transmission 3 provides the frequency 10426 Hz.

Transmission 3

OK now we need to focus on obtaining the final JWT Radio Administrator privileges needed for the Captain's Transmitter because it's inaccessible with current privileges.

Transmitter Access

Reading through Captain's To-Do List, he seems to have used their less-than-convincing ChatNPT to store JWT private and public keys. We also have that journal from Chimney Scissorsticks (Comms Journal hint). Captain's Journal mentions another role GeeseIslandsSuperChiefCommunicationsOfficer which is likely the final JWT Radio Administrator role we need.

Captain's To-Do List

Now let's review Captain's ChatNPT Initial To-Do List since it was crossed off from Captain's To-Do List. This is interesting because we know exactly where this "same directory" is, so looking for capsPubKey.key file in keys folder should be no problem.

Captain's ChatNPT Initial To-Do List

Make the request to https://captainscomms.com/jwtDefault/keys/capsPubKey.key with radioMonitor or radioDecoder token and Captain's public key is retrieved.

capsPubKey.key

Fix up the formatting a bit (no empty spaces) and capsPubKey.key is good to go:

capsPubKey.key

Going back to Owner's Manual Volume II - it stresses the need to protect KEYs in FOLDERs. This feels like another hint, we need to go after finding Captain's private key, especially now that we know the folder name. Just Watch This Owner's Manual Volume 2

At this point we should be able to find Captain's private key. We know all his keys are in keys folder and specifically he mentioned that we would never be able to find the private key folder but we did find it to be TH3CAPSPR1V4T3F0LD3R via Transmission 1. Based on Chimney Scissorsticks' hint that went something like "I hear the Captain likes to abbreviate words in his filenames", combine this with confirmed known public key name, we can make an educated guess that private key is called something like capsPrivKey.key. Let's make the Burp request (again using our radioDecoder token) to https://captainscomms.com/jwtDefault/keys/TH3CAPSPR1V4T3F0LD3R/capsPrivKey.key.

Captain's Private Key Request

Private key secured! Just a bit of formatting to remove empty spaces, and capsPrivKey.key is ready to be used.

Captain's Private Key

Now we need to create a JWT token that would give us GeeseIslandsSuperChiefCommunicationsOfficer role and sign it using Captain's private key. Let's start with radioDecoder token, Base64 decode it, modify the value and sign the JWT. All this can be easily done on JWT.io - modify the role, paste public and private keys, and confirm signature is verified since both keys are present.

Admin Token Creation

Again, change the justWatchThis cookie to the new admin value (JWT token from JWT.io) and access Captain's Transmitter.

Captain's Transmitter

We know the frequency from Transmission 3 and now just need to decode message in Transmission 2 for date and time. Let's refer to Just Watch This Appendix A - it points to the Lincolnshire Poacher Number Station.

Just Watch This Appendix A - Decoder Index

Based on Lincolnshire Poacher Number Station format, we can strip metadata and determine that actual message is "12249 12249 16009 16009 12249 12249 16009 16009". Now we need to decode it - we can use DCODE to try to find the most fitting cipher. After trying out a few different ciphers, I found that to decipher it, DCODE's Octal converter can be used:

Decode Octal

Now the final step is to send the misleading transmission. Since decoded date and time is 12/24 16:00, we need to send it for 4 hours earlier, so 12:00.

Modified Message

Answer

Frequency: 10426 HZ Go-Date: 1224 Go-Time: 1200 Modified Message

Response⚓︎

Chimney Scissorsticks @ Brass Bouy Port

Brilliant work! You've outsmarted those scoundrels with finesse!

Got Em!!!