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:

image-20231221143958833

Location Layout

My boat docks at the north-east corner:

image-20231221144906124Click for full size image

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:

image-20240103163611787

Bow Ninecandle has lost the combination to the padlock on the bathroom:

img

I’m asked for help:

Bow Ninecandle

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:

image-20231221145737192

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:

image-20231221154705704

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:

image-20231221151734155

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

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:

image-20240103163714255

Chimney Scissorsticks waits next to a table labeled The Captain’s Comms:

img
Chimney Scissorsticks

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:

image-20231222131815063

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:

captains_desk

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:

image-20231222143651055

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, named capsPubKey.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:

image-20231222150124560

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:

image-20231222150452464

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:

image-20231222150636813

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”:

image-20231222150853660

I’ll update the cookie in my browser. Now I can access the SDR.

image-20231222152126911

The peaks are clickable, but clicking them just throws an error:

image-20231222152151966

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.

image-20231222153507163

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:

image-20231222152935836

I’ll note that folder name down, THECAPSPR1V4T3F0LD3R.

The second one provides a Lincolnshire Poacher message:

image-20231222154838654

The third one is a Radio Fax, which slow shows an image of the Geese Islands with a frequency in it:

image-20231222154313188

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:

image-20231222164953382

If I update my cookie to this new token, now I can load the transmitter:

image-20231222165950875

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):

image-20231222170431341

When I click “Transmit”, it solves the challenge:

image-20231222170509444

Epilogue

Chimney is pleased:

Chimney Scissorsticks

Chimney Scissorsticks

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