Holiday Hack 2023: Brass Bouy Port
Geography
Getting To
Based on the comments from the elves at Rainraster Cliffs, I’ll head to Steampunk Island, where I find Brass Bouy Port on the eastern side on the tip of the nose:
Location Layout
My boat docks at the north-east corner:
The Goose of Pixel Island is offers a “cluck cluck” (odd for a Goose).
Faster Lock
Challenge
The Faster Lock Combination challenge is in the badge:
Bow Ninecandle has lost the combination to the padlock on the bathroom:
I’m asked for help:
Bow Ninecandle
Hey there! I’m Bow Ninecandle, and I’ve got a bit of a… ‘pressing’ situation.
You see, I need to get into the lavatory, but here’s the twist: it’s secured with a combination padlock.
Talk about bad timing, right? I could really use your help to figure this out before things get… well, urgent.
I’m sure there are some clever tricks and tips floating around the web that can help us crack this code without too much of a flush… I mean fuss.
Remember, we’re aiming for quick and easy solutions here - nothing too complex.
Once we’ve gathered a few possible combinations, let’s team up and try them out.
I’m crossing my legs - I mean fingers - hoping we can unlock this door soon.
After all, everyone knows that the key to holiday happiness is an accessible lavatory!
Let’s dive into this challenge and hopefully, we won’t have to ‘hold it’ for too long! Ready to help me out?
Clicking on the lock opens up interaction with the lock:
Solution
Collect numbers
I’ll follow the steps in the reference video. The numbers for the lock change on each page refresh, but I’ll note the ones I found while solving.
First, I need the “sticky number”. I’ll apply light tension and rotate around and around noting where it gets slowed down / slightly stuck. The combination changes each time the page is loaded, but for this example, I’ll identify 30.
Next I’ll find the two guess numbers. These are between 0 and 11, and with full tension, I’ll start at 0 turning looking for places where it gets stuck between two half numbers. In my care, it gets stuck between 4.5 and 5.5, so I’ll note 5. And then again it gets stuck between 9.5 and 10.5, so I’ll note 10.
The Math
The first number is the sticky number plus five, so it’s 35.
To find the third number, I’ll divide the first number by 4 to get 8 reminder 3. I’ll make a chart from my guess numbers:
5 15 25 35
10 20 30 0
I’ll divide each of these by four and check the remainder:
1 3 1 3
2 0 2 0
I only need the ones that match the remainder above, so that’s 15 and 35. I can go to each of these and put on full tension and see which one is looser. It’s 15, so that’s likely the third number.
For the second number, I’ll start two rows again, this time with the first number being the remainder above plus 2 and plus 6, and then adding 8 four times:
5 13 21 29 37
9 17 25 33 1
I can eliminate 13 and 17 as they are too close to the third number, 15.
Try Them
With eight possibilities left, I’ll try then, and when I try 35-1-15, it opens:
Hack Solution
Leak Numbers
In the JavaScript for the iFrame, this section jumps out as most interesting:
if (moved) {
lock_dial.angle += degree_change
if (stage == 0) {
if (cursors.right.isDown) {
if (current_mark == lock_numbers.first_number) {
first_set = true
} else {
first_set = false
}
} else {
if (cursors.left.isDown && first_set) {
stage = 1
} else {
statusBox.clear().fillStyle(0xFF0000, 1).fillRect(530, 660, 20, 20); // Red color for locked status
stage = -1
}
}
}
if (stage == 1) {
if (cursors.left.isDown) {
degrees_traversed += degree_change
if (Math.abs(degrees_traversed) >= 720) {
statusBox.clear().fillStyle(0xFF0000, 1).fillRect(530, 660, 20, 20); // Red color for locked status
stage = -1
} else if (Math.abs(degrees_traversed) >= 360) {
first_passed = true
}
if (first_passed) {
if (current_mark == lock_numbers.second_number) {
second_set = true
} else {
second_set = false
}
}
} else {
if (cursors.right.isDown && second_set) {
stage = 2
degrees_traversed = 0
} else {
statusBox.clear().fillStyle(0xFF0000, 1).fillRect(530, 660, 20, 20); // Red color for locked status
stage = -1
}
}
} else if (stage == 2 || stage == 3) {
degrees_traversed += degree_change
if (Math.abs(degrees_traversed) <= 360) {
if (cursors.right.isDown) {
if (current_mark == lock_numbers.third_number) {
stage = 3
} else {
stage = 2
}
} else {
statusBox.clear().fillStyle(0xFF0000, 1).fillRect(530, 660, 20, 20); // Red color for locked status
stage = -1
}
} else {
statusBox.clear().fillStyle(0xFF0000, 1).fillRect(530, 660, 20, 20); // Red color for locked status
stage = -1
}
This is what handles the turns to the three spots. It’s referencing lock_numbers
throughout. I’ll enter that into the console:
One way to solve is just use first_number
, second_number
, and third_number
to open it.
Skip First Two Numbers
But I can do better. As I move to the first number and then start moving back, it sets the stage
variable from 0 to 1. If I go more than a full rotation and then to the second number, stage
increments to 2. Then when I turn after the second number, it sets stage
to 3.
I’ll set stage = 3
in the console, and go directly to the third number and the lock opens!
Invoke Open
That solution still involves turning the lock to the correct third number and pulling down. There’s also this function in the code:
function moveLockIntoUnlockedPosition() {
isTweenActive = true;
game.scene.scenes[0].tweens.add({
targets: [lock_dial, lock_body],
y: '+=75',
duration: 500, // can adjust the duration as needed
ease: 'Power2',
onComplete: function () {
game.scene.scenes[0].tweens.add({
targets: lockContainer,
y: '-=215',
x: '+=105',
angle: '-=90', // Rotate 90 degrees to the left
duration: 500,
ease: 'Power2',
onComplete: function () {
game.scene.scenes[0].tweens.add({
targets: lockContainer,
y: '+=800',
x: '-=200',
duration: 1000,
ease: 'Linear',
onComplete: function () {
latch_back.setVisible(false)
latch_front.setVisible(false)
latch_open_back.setVisible(true)
latch_open.setVisible(true)
game.scene.scenes[0].tweens.add({
targets: latch_open,
scaleX: -1,
x: '+=45',
duration: 500,
ease: 'Linear',
yoyo: false,
onComplete: function () {
checkit()
}
})
}
})
}
});
}
});
}
It’s called moveLockIntoUnlockedPosition
. That seems like exactly what I want to do. I’ll just enter that into the console (with trailing ()
to call it), and hit enter, and the lock opens!
Epilogue
Bow is pleased:
Bow Ninecandle
Oh, thank heavens! You’re a lifesaver! With your knack for cracking codes, we’ve just turned a potential ‘loo catastrophe’ into a holiday triumph!
The Captain’s Comms
Challenge
The badge gives the background for the Captain’s Comms as well as the user group to get access to:
Chimney Scissorsticks waits next to a table labeled The Captain’s Comms:
Chimney Scissorsticks
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!”
Challenge
Background
The challenge starts with a “Background” message:
Major takeaways:
- Different items in the communications area can be interacted with by clicking on them.
- Some items require authorization with a specific role.
- I need to use the Captain’s transmitter to send a misleading message with the correct date, frequency, and modified time (4 hours early).
Comms Area
At the start, there are several areas that highlight as clickable:
The clickable items bring up either reading pages or an interface to that equipment. The speaker turns on or off radio static. At this time, the other equipment requires some role. For example, the SDR:
The roles required are:
- SDR - radioMonitor
- Transmitter - JWT Radio Administrator
Reading Summary
The books and papers present additional information:
- Roles are set using bearer tokens. [JWT Owners Manual Vol 1]
- Running requires lowest role, “radioUser”. [JWT Owners Manual Vol 1]
- To listen to transmissions, need “radioMonitor”. [JWT Owners Manual Vol 1]
- To decode messages, need “radioDecoder”. [JWT Owners Manual Vol 1]
- To use the TRANSMITTER, need “specific JWT system administrator ROLE”. [JWT Owners Manual Vol 1]
- It provides references to jwt.io, confirming that these tokens are JWTs. [JWT Owners Manual Vol 1]
- The administrator role is uniquely created when the software is installed. [JWT Owners Manual Vol 2]
- Keys are used to sign the JWTs, and they are created during install. It recommends putting them in folders with limited access. [JWT Owners Manual Vol 2]
- There are different types of transmissions that JWT can receive. Comes with different decoders (CW = Morse Code, RadioFax = Weather Fax or WeFax). [JWT Appendix A]
- There are also “numbers stations” that transmit coded messages. [JWT Appendix A]
- An example of a numbers station is the Lincolnshire Poacher which used the format “Music-{5-digits}-{6 chimes}-{5-digit number groups}-{6 chimes}-Music” and gives this reference. [JWT Appendix A]
- With the SDR window optn, clicking on a signal peak while having the “radioDecoder” role will hear and decode the signal. [JWT Appendix A]
- The
rMonitor.tok
file was created in the/jwtDefault
directory during installation. It contains a token for the “radioMonitor” role. [JWT Owners Card] - The Captain is asked ChatNPT about storing JWT keys, and it provided a list that is not yet worked through. [Captain’s To-Do List]
- There’s a reference to the Captain’s private journal and his leaving it on Pixel Island, hinting there’s a clue about a role in there. [Captain’s To-Do List]
- The private key for JWT is in a folder that is not named. [ChatNPT Output]
- The public key is in a
keys
folder in the same directory as the “roleMonitor” token, namedcapsPubKey.key
. [ChatNPT Output] - File permissions for the key may be restricted. [ChatNPT Output]
Get radioMonitor Role
Tokens
Just visiting the site, my browser stores two cookies:
Both have a Java Web Token (JWT) like format, though the CaptainsCooke
doesn’t seem to decode like a typical JWT. I’ll focus on the justWatchThisRole
. JWT.io shows it uses public key crypto (matching the reading above) and has several fields:
The role
is the most important part. “radioUser” let’s met get basic access to the system, and nothing more.
rMonitor.tok
The references mentioned a /jwtDefault
folder with a rMonitor.tok
file. If I try to go directly to the site, it returns an authorization error:
The references mentioned sending the role token as an Authorization
header using the “Bearer” method, which is to put in a header of the form Authorization: Bearer {token}
. It works:
oxdf@hacky$ curl https://captainscomms.com/jwtDefault/rMonitor.tok -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJISEMgMjAyMyBDYXB0YWluJ3MgQ29tbXMiLCJpYXQiOjE2OTk0ODU3OTUuMzQwMzMyNywiZXhwIjoxODA5OTM3Mzk1LjM0MDMzMjcsImF1ZCI6IkhvbGlkYXkgSGFjayAyMDIzIiwicm9sZSI6InJhZGlvVXNlciJ9.BGxJLMZw-FHI9NRl1xt_f25EEnFcAYYu173iqf-6dgoa_X3V7SAe8scBbARyusKq2kEbL2VJ3T6e7rAVxy5Eflr2XFMM5M-Wk6Hqq1lPvkYPfL5aaJaOar3YFZNhe_0xXQ__k__oSKN1yjxZJ1WvbGuJ0noHMm_qhSXomv4_9fuqBUg1t1PmYlRFN3fNIXh3K6JEi5CvNmDWwYUqhStwQ29SM5zaeLHJzmQ1Ey0T1GG-CsQo9XnjIgXtf9x6dAC00LYXe1AMly4xJM9DfcZY_KjfP-viyI7WYL0IJ_UOtIMMN0u-XO8Q_F3VO0NyRIhZPfmALOM2Liyqn6qYTjLnkg"
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJISEMgMjAyMyBDYXB0YWluJ3MgQ29tbXMiLCJpYXQiOjE2OTk0ODU3OTUuMzQwMzMyNywiZXhwIjoxODA5OTM3Mzk1LjM0MDMzMjcsImF1ZCI6IkhvbGlkYXkgSGFjayAyMDIzIiwicm9sZSI6InJhZGlvTW9uaXRvciJ9.f_z24CMLim2JDKf8KP_PsJmMg3l_V9OzEwK1E_IBE9rrIGRVBZjqGpvTqAQQSesJD82LhK2h8dCcvUcF7awiAPpgZpcfM5jdkXR7DAKzaHAV0OwTRS6x_Uuo6tqGMu4XZVjGzTvba-eMGTHXyfekvtZr8uLLhvNxoarCrDLiwZ_cKLViRojGuRIhGAQCpumw6NTyLuUYovy_iymNfe7pqsXQNL_iyoUwWxfWcfwch7eGmf2mBrdEiTB6LZJ1ar0FONfrLGX19TV25Qy8auNWQIn6jczWM9WcZbuOIfOvlvKhyVWbPdAK3zB7OOm-DbWm1aFNYKr6JIRDLobPfiqhKg
The returned token looks very similar, but the role is now “radioMonitor”:
I’ll update the cookie in my browser. Now I can access the SDR.
The peaks are clickable, but clicking them just throws an error:
Public Key
There is also a note suggesting that the public key is in /jwtDefault/keys/capsPubKey.key
. I am able to grab that as well:
oxdf@hacky$ curl https://captainscomms.com/jwtDefault/keys/capsPubKey.key -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJISEMgMjAyMyBDYXB0YWluJ3MgQ29tbXMiLCJpYXQiOjE2OTk0ODU3OTUuMzQwMzMyNywiZXhwIjoxODA5OTM3Mzk1LjM0MDMzMjcsImF1ZCI6IkhvbGlkYXkgSGFjayAyMDIzIiwicm9sZSI6InJhZGlvVXNlciJ9.BGxJLMZw-FHI9NRl1xt_f25EEnFcAYYu173iqf-6dgoa_X3V7SAe8scBbARyusKq2kEbL2VJ3T6e7rAVxy5Eflr2XFMM5M-Wk6Hqq1lPvkYPfL5aaJaOar3YFZNhe_0xXQ__k__oSKN1yjxZJ1WvbGuJ0noHMm_qhSXomv4_9fuqBUg1t1PmYlRFN3fNIXh3K6JEi5CvNmDWwYUqhStwQ29SM5zaeLHJzmQ1Ey0T1GG-CsQo9XnjIgXtf9x6dAC00LYXe1AMly4xJM9DfcZY_KjfP-viyI7WYL0IJ_UOtIMMN0u-XO8Q_F3VO0NyRIhZPfmALOM2Liyqn6qYTjLnkg"
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsJZuLJVB4EftUOQN1Auw
VzJyr1Ma4xFo6EsEzrkprnQcdgwz2iMM76IEiH8FlgKZG1U0RU4N3suI24NJsb5w
J327IYXAuOLBLzIN65nQhJ9wBPR7Wd4Eoo2wJP2m2HKwkW5Yadj6T2YgwZLmod3q
n6JlhN03DOk1biNuLDyWao+MPmg2RcxDR2PRnfBartzw0HPB1yC2Sp33eDGkpIXa
cx/lGVHFVxE1ptXP+asOAzK1wEezyDjyUxZcMMmV0VibzeXbxsXYvV3knScr2WYO
qZ5ssa4Rah9sWnm0CKG638/lVD9kwbvcO2lMlUeTp7vwOTXEGyadpB0WsuIKuPH6
uQIDAQAB
-----END PUBLIC KEY-----
I’ll save that to a file for future use.
Get radioDecoder Role
It’s a reasonable assumption that if JWT stores the token for the “radioMonitor” role in /jwtDefault/rMonitor.tok
, that it might store a token for the “radioDecoder” role in /jetDefault/rDecoder.tok
. If I request that with the original token, it returns an invalid token error:
oxdf@hacky$ curl https://captainscomms.com/jwtDefault/rDecoder.tok -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJISEMgMjAyMyBDYXB0YWluJ3MgQ29tbXMiLCJpYXQiOjE2OTk0ODU3OTUuMzQwMzMyNywiZXhwIjoxODA5OTM3Mzk1LjM0MDMzMjcsImF1ZCI6IkhvbGlkYXkgSGFjayAyMDIzIiwicm9sZSI6InJhZGlvVXNlciJ9.BGxJLMZw-FHI9NRl1xt_f25EEnFcAYYu173iqf-6dgoa_X3V7SAe8scBbARyusKq2kEbL2VJ3T6e7rAVxy5Eflr2XFMM5M-Wk6Hqq1lPvkYPfL5aaJaOar3YFZNhe_0xXQ__k__oSKN1yjxZJ1WvbGuJ0noHMm_qhSXomv4_9fuqBUg1t1PmYlRFN3fNIXh3K6JEi5CvNmDWwYUqhStwQ29SM5zaeLHJzmQ1Ey0T1GG-CsQo9XnjIgXtf9x6dAC00LYXe1AMly4xJM9DfcZY_KjfP-viyI7WYL0IJ_UOtIMMN0u-XO8Q_F3VO0NyRIhZPfmALOM2Liyqn6qYTjLnkg"
Invalid authorization token provided.
This is different from what I get if I request a random file name that doesn’t exist. That’s a good sign I’m on the right track.
I’ll try with the new token for “radioMonitor”. It works:
oxdf@hacky$ curl https://captainscomms.com/jwtDefault/rDecoder.tok -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJISEMgMjAyMyBDYXB0YWluJ3MgQ29tbXMiLCJpYXQiOjE2OTk0ODU3OTUuMzQwMzMyNywiZXhwIjoxODA5OTM3Mzk1LjM0MDMzMjcsImF1ZCI6IkhvbGlkYXkgSGFjayAyMDIzIiwicm9sZSI6InJhZGlvTW9uaXRvciJ9.f_z24CMLim2JDKf8KP_PsJmMg3l_V9OzEwK1E_IBE9rrIGRVBZjqGpvTqAQQSesJD82LhK2h8dCcvUcF7awiAPpgZpcfM5jdkXR7DAKzaHAV0OwTRS6x_Uuo6tqGMu4XZVjGzTvba-eMGTHXyfekvtZr8uLLhvNxoarCrDLiwZ_cKLViRojGuRIhGAQCpumw6NTyLuUYovy_iymNfe7pqsXQNL_iyoUwWxfWcfwch7eGmf2mBrdEiTB6LZJ1ar0FONfrLGX19TV25Qy8auNWQIn6jczWM9WcZbuOIfOvlvKhyVWbPdAK3zB7OOm-DbWm1aFNYKr6JIRDLobPfiqhKg"
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJISEMgMjAyMyBDYXB0YWluJ3MgQ29tbXMiLCJpYXQiOjE2OTk0ODU3OTUuMzQwMzMyNywiZXhwIjoxODA5OTM3Mzk1LjM0MDMzMjcsImF1ZCI6IkhvbGlkYXkgSGFjayAyMDIzIiwicm9sZSI6InJhZGlvRGVjb2RlciJ9.cnNu6EjIDBrq8PbMlQNF7GzTqtOOLO0Q2zAKBRuza9bHMZGFx0pOmeCy2Ltv7NUPv1yT9NZ-WapQ1-GNcw011Ssbxz0yQO3Mh2Tt3rS65dmb5cmYIZc0pol-imtclWh5s1OTGUtqSjbeeZ2QAMUFx3Ad93gR20pKpjmoeG_Iec4JHLTJVEksogowOouGyDxNAagIICSpe61F3MY1qTibOLSbq3UVfiIJS4XvGJwqbYfLdbhc-FvHWBUbHhAzIgTIyx6kfONOH9JBo2RRQKvN-0K37aJRTqbq99mS4P9PEVs0-YIIufUxJGIW0TdMNuVO3or6bIeVH6CjexIl14w6fg
Get Admin Access
Decode Messages
There are X clickable peaks in the SDR. Each of them gives a different kind of decoded message.
The one marked 1 is a morse code (CW) message, coming through as a series of beeps that the JWT decoder kindly (albeit slowly) writes to the screen:
I’ll note that folder name down, THECAPSPR1V4T3F0LD3R
.
The second one provides a Lincolnshire Poacher message:
The third one is a Radio Fax, which slow shows an image of the Geese Islands with a frequency in it:
I’ll note 10426 Hz.
Get Private Key
I’ll use the info from the message above to get the private key. Some guessing at folder paths finds it at /jwtDefault/keys/TH3CAPSPR1V4T3F0LD3R/capsPrivKey.key
, and using the “roleDecoder” token returns the key:
oxdf@hacky$ curl https://captainscomms.com/jwtDefault/keys/TH3CAPSPR1V4T3F0LD3R/capsPrivKey.key -H "Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJISEMgMjAyMyBDYXB0YWluJ3MgQ29tbXMiLCJpYXQiOjE2OTk0ODU3OTUuMzQwMzMyNywiZXhwIjoxODA5OTM3Mzk1LjM0MDMzMjcsImF1ZCI6IkhvbGlkYXkgSGFjayAyMDIzIiwicm9sZSI6InJhZGlvRGVjb2RlciJ9.cnNu6EjIDBrq8PbMlQNF7GzTqtOOLO0Q2zAKBRuza9bHMZGFx0pOmeCy2Ltv7NUPv1yT9NZ-WapQ1-GNcw011Ssbxz0yQO3Mh2Tt3rS65dmb5cmYIZc0pol-imtclWh5s1OTGUtqSjbeeZ2QAMUFx3Ad93gR20pKpjmoeG_Iec4JHLTJVEksogowOouGyDxNAagIICSpe61F3MY1qTibOLSbq3UVfiIJS4XvGJwqbYfLdbhc-FvHWBUbHhAzIgTIyx6kfONOH9JBo2RRQKvN-0K37aJRTqbq99mS4P9PEVs0-YIIufUxJGIW0TdMNuVO3or6bIeVH6CjexIl14w6fg"
-----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-----
I’ll save that to a file.
Generate JWT
I now I have all I need to sign JWTs for this application, which means I can give myself any role I want. I’ll look back at the Captain’s Journal from Rainraster Cliffs and see the Captain talking about his new role as “GeeseIslandSuperChiefCommunicationsOfficer” (it’s also mentioned in the badge objective). I’ll set role to that.
I can do this in JWT.io, but it’s a bit tricky. It’s important to put the keys in first, and then edit values:
If I update my cookie to this new token, now I can load the transmitter:
Transmit Message
Decode Lincolnshire Poacher
Actually messages from Lincolnshire Poacher were not cracked, and are suspected of using a one-time pad, which would be uncrackable without the pad.
This message is simpler. It repeats the same two numbers:
12249 12249 16009 16009 12249 12249 16009 16009
They both end with 9, and removing it gives something that fits the pattern I’m looking for, a date and time - 12/24 at 1600.
Send Message
I’ll enter the frequency from the RadioFax (10426), the date from the Lincolnshire Poarcher, and the time four hours early (as instructed):
When I click “Transmit”, it solves the challenge:
Epilogue
Chimney is pleased:
Chimney Scissorsticks
Brilliant work! You’ve outsmarted those scoundrels with finesse!