Objective

image-20210110070324037

Terminal - Speaker UNprep

Door

Challenge

Bushy Evergreen is standing outside the Speaker Unpreparedness room, where the door is currently locked:

Ohai! Bushy Evergreen, just trying to get this door open.

It’s running some Rust code written by Alabaster Snowball.

I’m pretty sure the password I need for ./door is right in the executable itself.

Isn’t there a way to view the human-readable strings in a binary file?

Going into the terminal presents the challenge for the door, along with the two follow on challenges:

Help us get into the Speaker Unpreparedness Room!

The door is controlled by ./door, but it needs a password! If you can figure
out the password, it'll open the door right up!

Oh, and if you have extra time, maybe you can turn on the lights with ./lights
activate the vending machines with ./vending-machines? Those are a little
trickier, they have configuration files, but it'd help us a lot!

(You can do one now and come back to do the others later if you want)

We copied edit-able versions of everything into the ./lab/ folder, in case you
want to try EDITING or REMOVING the configuration files to see how the binaries
react.

Note: These don't require low-level reverse engineering, so you can put away IDA
and Ghidra (unless you WANT to use them!)
elf@9452ddb1b63d ~ $ 

Solution

Running ./door prompts for a password:

elf@9452ddb1b63d ~ $ ./door 
You look at the screen. It wants a password. You roll your eyes - the 
password is probably stored right in the binary. There's gotta be a
tool for this...
What do you enter? >

On entering the wrong password, it checks for a few seconds, and then reports failure:

What do you enter? > password
Checking......
Beep boop invalid password

Bushy hints that the password for ./door is in the executable itself. Running strings against the binary will dump out all the instances of n bytes in a row that are valid ASCII, where the default n is 4, unless it’s set with the -n or --bytes flags. I set n to 12, and piped the results into less to scroll through them. This line jumped out:

elf@9452ddb1b63d ~ $ strings door | grep -i pass    
/home/elf/doorYou look at the screen. It wants a password. You roll your eyes - the password is probably stored right in the binary. There's gotta be a Be sure to finish the challenge in prod: And don't forget, the password is "Op3nTheD00r" 
Beep boop invalid password

Entering that password opens the door:

elf@9452ddb1b63d ~ $ ./door 
You look at the screen. It wants a password. You roll your eyes - the 
password is probably stored right in the binary. There's gotta be a
tool for this...
What do you enter? > Op3nTheD00r
Checking......
Door opened!

Lights

Challenge

Now I can enter the Speaker Unpreparedness room, but it’s dark (the lights are off) and the vending machine is out of order:

image-20210110072032359

After some information about the HID challenge (covered in that section), Bushy mentions the second challenge:

Hey, you want to help me figure out the light switch too? Those come in handy sometimes.

The password we need is in the lights.conf file, but it seems to be encrypted.

There’s another instance of the program and configuration in ~/lab/ you can play around with.

What if we set the user name to an encrypted value?

Solution

Back in the terminal, the lights binary offers a similar prompt for a password:

elf@3c10d11086c7 ~ $ ./lights 
The speaker unpreparedness room sure is dark, you're thinking (assuming
you've opened the door; otherwise, you wonder how dark it actually is)

You wonder how to turn the lights on? If only you had some kind of hin---

 >>> CONFIGURATION FILE LOADED, SELECT FIELDS DECRYPTED: /home/elf/lights.conf
 
---t to help figure out the password... I guess you'll just have to make do!

The terminal just blinks: Welcome back, elf-technician

What do you enter? >

A wrong password has the same result as with door:

What do you enter? > password
Checking......
Beep boop invalid password

The lab directory has copies of the binarys and conf files that are editable. The lights.conf file has an encrypted password and a username:

elf@3c10d11086c7 ~/lab $ cat lights.conf 
password: E$ed633d885dcb9b2f3f0118361de4d57752712c27c5316a95d9e5e5b124
name: elf-technician

Bushy suggested putting the encrypted password into the name field. This didn’t make a ton of sense to me. I’ve certainly run into scenarios where it makes sense to pass encrypted stuff into a field that you know gets encrypted again. It’s not clear to me why the name field would be decrypted. But, it’s worth a try:

elf@3c10d11086c7 ~/lab $ cat lights.conf 
password: E$ed633d885dcb9b2f3f0118361de4d57752712c27c5316a95d9e5e5b124
name: E$ed633d885dcb9b2f3f0118361de4d57752712c27c5316a95d9e5e5b124

Now running lights, where it used to say the name, it now says “Computer-TurnLightsOn”:

elf@3c10d11086c7 ~/lab $ ./lights 
The speaker unpreparedness room sure is dark, you're thinking (assuming
you've opened the door; otherwise, you wonder how dark it actually is)

You wonder how to turn the lights on? If only you had some kind of hin---

 >>> CONFIGURATION FILE LOADED, SELECT FIELDS DECRYPTED: /home/elf/lab/lights.conf

---t to help figure out the password... I guess you'll just have to make do!

The terminal just blinks: Welcome back, Computer-TurnLightsOn

What do you enter? >

Trying that as the password works:

What do you enter? > Computer-TurnLightsOn
Checking......
That would have turned on the lights!
If you've figured out the real password, be sure you run /home/elf/lights

My best guess is that for each entry in the config, it tried to decrypt it, and if it fails, it uses the unencrypted input. I tested this by putting a string that would fail decryption into the password field:

elf@3c10d11086c7 ~/lab $ cat lights.conf 
password: abcd
name: 0xdf

Now the password “abcd” works:

elf@3c10d11086c7 ~/lab $ ./lights 
The speaker unpreparedness room sure is dark, you're thinking (assuming
you've opened the door; otherwise, you wonder how dark it actually is)

You wonder how to turn the lights on? If only you had some kind of hin---

 >>> CONFIGURATION FILE LOADED, SELECT FIELDS DECRYPTED: /home/elf/lab/lights.conf
 
---t to help figure out the password... I guess you'll just have to make do!

The terminal just blinks: Welcome back, 0xdf

What do you enter? > abcd
Checking......
That would have turned on the lights!
If you've figured out the real password, be sure you run /home/elf/lights

Vending Machine

Challenge

Wow - that worked? I mean, it worked! Hooray for opportunistic decryption, I guess!

So hey, if you want, there’s one more challenge.

You see, there’s a vending machine in there that the speakers like to use sometimes.

Play around with ./vending_machines in the lab folder.

You know what might be worth trying? Delete or rename the config file and run it.

Then you could set the password yourself to AAAAAAAA or BBBBBBBB.

If the encryption is simple code book or rotation ciphers, you’ll be able to roll back the original password.

Solution

Just like the previous two, vending-machines requests a password:

elf@758ab2ae848b ~ $ ./vending-machines 
The elves are hungry!

If the door's still closed or the lights are still off, you know because
you can hear them complaining about the turned-off vending machines!
You can probably make some friends if you can get them back on...

Loading configuration from: /home/elf/vending-machines.json

I wonder what would happen if it couldn't find its config file? Maybe that's
something you could figure out in the lab...

Welcome, elf-maintenance! It looks like you want to turn the vending machines back on?
Please enter the vending-machine-back-on code >

Same result on invalid password:

Please enter the vending-machine-back-on code > password
Checking......
Beep boop invalid password

In the lab folder, I can get rid of the config file and re-run:

elf@758ab2ae848b ~/lab $ mv vending-machines.json vending-machines.json.bk
elf@758ab2ae848b ~/lab $ ./vending-machines 
The elves are hungry!

If the door's still closed or the lights are still off, you know because
you can hear them complaining about the turned-off vending machines!
You can probably make some friends if you can get them back on...

Loading configuration from: /home/elf/lab/vending-machines.json

I wonder what would happen if it couldn't find its config file? Maybe that's
something you could figure out in the lab...

ALERT! ALERT! Configuration file is missing! New Configuration File Creator Activated!

Please enter the name >

On entering it, it ask for a password, and then goes back into the normal move asking for the password. The new password I just set works:

Please enter the name > 0xdf
Please enter the password > 0xdf

Welcome, 0xdf! It looks like you want to turn the vending machines back on?
Please enter the vending-machine-back-on code > 0xdf
Checking......
That would have enabled the vending machines!

If you have the real password, be sure to run /home/elf/vending-machines

The config file is back:

elf@758ab2ae848b ~/lab $ cat vending-machines.json
{
  "name": "0xdf",
  "password": "3DLU"
}

Already it’s worth noting that the encrypted password is the same length as the password input. I can already deduce this is encrypted and not hashed based on that (and confirm with another run with another password of a different length). I also ran some tests to see if the username impacted the encrypted password - it did not.

Next I started with a long password, 32 As. The result was:

{
  "name": "0xdf",
  "password": "XiGRehmwXiGRehmwXiGRehmwXiGRehmw"
}

What’s interesting there is that the pattern seems to repeat every eight characters. With 32 Bs, the encrypted password was DqTpKv7fDqTpKv7fDqTpKv7fDqTpKv7f. The pattern is different, but it repeats every eight bytes.

Another test, the password !@#$%^&*(),.<>?, showed that symbol characters seem unchanged in this encryption:

{
  "name": "0xdf",
  "password": "!@#$%^&*(),.<>?"
}

Does the encrypted value of a byte change based on the values of the other bytes? A password of BAB encrypted to DiT. That is neat, because the first and third characters match the first and third characters from the long string of Bs, and the second character matches the second character from the long string of As.

To decrypt, I created a config with this password having each character (lower and upper) and digit eight times:

aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffgggggggghhhhhhhhiiiiiiiijjjjjjjjkkkkkkkkllllllllmmmmmmmmnnnnnnnnooooooooppppppppqqqqqqqqrrrrrrrrssssssssttttttttuuuuuuuuvvvvvvvvwwwwwwwwxxxxxxxxyyyyyyyyzzzzzzzzAAAAAAAABBBBBBBBCCCCCCCCDDDDDDDDEEEEEEEEFFFFFFFFGGGGGGGGHHHHHHHHIIIIIIIIJJJJJJJJKKKKKKKKLLLLLLLLMMMMMMMMNNNNNNNNOOOOOOOOPPPPPPPPQQQQQQQQRRRRRRRRSSSSSSSSTTTTTTTTUUUUUUUUVVVVVVVVWWWWWWWWXXXXXXXXYYYYYYYYZZZZZZZZ00000000111111112222222233333333444444445555555566666666777777778888888899999999

The encrypted result is:

9VbtacpgGUVBfWhPe9ee6EERORLdlwWbwcZQAYue8wIUrf5xkyYSPafTnnUgokAhM0sw4eOCa8okTqy1o63i07r9fm6W7siFqMvusRQJbhE62XDBRjf2h24c1zM5H8XLYfX8vxPy5NAyqmsuA5PnWSbDcZRCdgTNCujcw9NmuGWzmnRAT7OlJK2X7D7acF1EiL5JQAMUUarKCTZaXiGRehmwDqTpKv7fLbn3UP9Wyv09iu8Qhxkr3zCnHYNNLCeOSFJGRBvYPBubpHYVzka18jGrEA24nILqF14D1GnMQKdxFbK363iZBrdjZE8IMJ3ZxlQsZ4Uisdwjup68mSyVX10sI2SHIMBo4gC7VyoGNp9Tg0akvHBEkVH5t4cXy3VpBslfGtSz0PHMxOl0rQKqjDq2KtqoNicv3ehm9ZFH2rDO5LkIpWFLz5zSWJ1YbNtlgophDlgKdTzAYdIdjOx0OoJ6JItvtUjtVXmFSQw4lCgPE6x7

I’ll drop into a Python terminal to play with this. If I jump eight characters at a time, it gives the different encrypted outputs in position 0:

>>> enc[0::8]
'9GeOw8knMaofqbR1Y5AcCuT7iUXDLyhHSPzEFQ6ZxsmI4NvtB0rK32pWgdjJVl'

9 is encrypted a in position 0, G is encryted b in position 0, e is encrypted c in position 0, etc.

For position 1, it’s:

>>> enc[1::8]
'VU9Rcwyn086mMhjzfN5ZuG7DLaiqbvxYFBkA1K3EldS2gpH4sPQterWJoTOIXC'

encs is eight strings, each 62 characters long, representing the output of encrypting each character, with eight different results for the eight different positions:

>>> encs = [enc[i::8] for i in range(8)]
>>> len(encs)
8
>>> [len(e) for e in encs]
[62, 62, 62, 62, 62, 62, 62, 62]

I’ll look at the encrypted string 3DLU generated earlier. I know the input order was:

>>> string.ascii_letters + string.digits
'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'

For that 3 in position 0, it comes at index 52, which is a 0:

>>> encs[0].index('3')
52
>>> (string.ascii_letters + string.digits)[encs[0].index('3')]
'0'

For position 1 value D, it translates to x:

>>> (string.ascii_letters + string.digits)[encs[1].index('D')]
'x'

The rest of the encrypted string decrypts as well:

>>> (string.ascii_letters + string.digits)[encs[2].index('L')]
'd'
>>> (string.ascii_letters + string.digits)[encs[3].index('U')]
'f'

Now turing to the actual conf file:

{
  "name": "elf-maintenance",
  "password": "LVEdQPpBwr"
}

I can do this in a one-liner with list comprehension:

>>> ''.join([(string.ascii_letters + string.digits)[encs[i%8].index(c)] for i, c in enumerate(passwd)])
'CandyCane1'

It might be easier to read in a for loop:

>>> res = ''
>>> for i, c in enumerate(passwd):
...     idx = encs[i%8].index(c)
...     res += (string.ascii_letters + string.digits)[idx]
... 
>>> res
'CandyCane1'

Entering this solves the challenge and enables the vending machine:

elf@72df84d05883 ~ $ ./vending-machines 
The elves are hungry!

If the door's still closed or the lights are still off, you know because
you can hear them complaining about the turned-off vending machines!
You can probably make some friends if you can get them back on...

Loading configuration from: /home/elf/vending-machines.json

I wonder what would happen if it couldn't find its config file? Maybe that's
something you could figure out in the lab...

Welcome, elf-maintenance! It looks like you want to turn the vending machines back on?
Please enter the vending-machine-back-on code > CandyCane1
Checking......

Vending machines enabled!!

The vending machine, Release the Snacken, will now talk to me, and provides the portals for the Santavator:

We’re outta glazed donuts.

We’re outta jelly donuts.

We’re outta Bavarian cream-filled donuts.

We’re outta cinnamon rolls.

We’re outta apple fritters.

We’re outta bear… wait a minute…

WE’RE OUTTA BEAR CLAWS.

All I’ve got are these Portal Candies. Enjoy!

Can I interest you in a box of weasles, by chance?

Hints

After each of the three challenges in the terminal, Bushy gives some hints about the HID locks and the Proxmark3. After the door:

Oh, this might be a good time to mention another lock in the castle.

Santa asked me to ask you to evaluate the security of our new HID lock.

If ever you find yourself in possession of a Proxmark3, click it in your badge to interact with it.

It’s a slick device that can read others’ badges!

Then after turning on the lights:

Oh, did I mention that the Proxmark can simulate badges? Cool, huh?

There are lots of references online to help.

In fact, there’s a talk going on right now!

And after the vending machines:

Your lookup table worked - great job! That’s one way to defeat a polyalphabetic cipher!

Good luck navigating the rest of the castle.

And that Proxmark thing? Some people scan other people’s badges and try those codes at locked doors.

Other people scan one or two and just try to vary room numbers.

Do whatever works best for you!

There’s more information in the hints section of the badge:

  • You can use a Proxmark to capture the facility code and ID value of HID ProxCard badge by running lf hid read when you are close enough to someone with a badge.
  • Larry Pesce knows a thing or two about HID attacks. He’s the author of a course on wireless hacking!
  • The Proxmark is a multi-function RFID device, capable of capturing and replaying RFID events.
  • There’s a short list of essential Proxmark commands also available.
  • You can also use a Proxmark to impersonate a badge to unlock a door, if the badge you impersonate has access. lf hid sim -r 2006......

Terminal - 33.6kbps

Challenge

The objective also suggested talking to Fitzy Shortstack in the kitchen, but all he’ll talk about is his modem:

“Put it in the cloud,” they said…

“It’ll be great,” they said…

All the lights on the Christmas trees throughout the castle are controlled through a remote server.

We can shuffle the colors of the lights by connecting via dial-up, but our only modem is broken!

Fortunately, I speak dial-up. However, I can’t quite remember the handshake sequence.

Maybe you can help me out? The phone number is 756-8347; you can use this blue phone.

Solution

Clicking on the phone, it loads up on the screen:

image-20210110103448935

Clicking on the handset lifts it and makes a dial tone. Clicking on each of the sounds on the paper will make a noise like part of a modem sound. On dialing the number from Fitzy, it sounds like it connects, and then it waits. If I wait too long or if i enter the wrong sound, it hangs up immediately.

To solve this, I’ll dial the number, then click on baa DEE brrr, aaah, WEWEWwrwrrwrr, beDURRdunditty, SCHHRRHHRTHRTR. The connection completes, as does this challenge.

Hints

On solving, Fitzy is grateful, and adds a commnet about Shinny Upatree:

탢ݵרOُ񆨶$Ԩ؉楌Բ ahem! We did it! Thank you!!

Anytime you feel like changing the color scheme up, just pick up the phone!

You know, Santa really seems to trust Shinny Upatree…

Open HID Lock

Find Lock and Proxmark3

To open the HID lock, I’m going to clone the badges of elves around the castle and try to reply them at the locked door. First I need a Proxmark3. I’ll find it in the wrapping room on floor 1.5. It happens to trigger the same tamper script I used to find parts for the Santavator:

image-20210110105135049

The HID-locked door is in the Workshop, with the panel just to the left of it:

image-20210110105300780

Collect badges

Armed with the Proxmark3, I can walk around the castle and standing next to each elf I encounter, and opening the Proxmark3 from the items menu in the badge:

image-20210110105437550 image-20210110105648254

The command to read a badge is lf hid read. Not all elves have badges, but, for example, next to Noel Neotie in the Wrapping room:

[magicdust] pm3 --> lf hid read
#db# TAG ID: 2006e22ee1 (6000) - Format Len: 26 bit - FC: 113 - Card: 6000

The following elves have badges that can be read by the Proxmark3:

Elf Location hid
Angel Candysalt Splunk Room (1) #db# TAG ID: 2006e22f31 (6040) - Format Len: 26 bit - FC: 113 - Card: 6040
Holly Evergreen Kitchen (1) #db# TAG ID: 2006e22f10 (6024) - Format Len: 26 bit - FC: 113 - Card: 6024
Noel Noetie Wrapping Room (1.5) #db# TAG ID: 2006e22ee1 (6000) - Format Len: 26 bit - FC: 113 - Card: 6000
Sparkle Redberry Lobby (1) #db# TAG ID: 2006e22f0d (6022) - Format Len: 26 bit - FC: 113 - Card: 6022
Bow Ninecandle Talks (2) #db# TAG ID: 2006e22f0e (6023) - Format Len: 26 bit - FC: 113 - Card: 6023
Shinny Upatree Outside #db# TAG ID: 2006e22f13 (6025) - Format Len: 26 bit - FC: 113 - Card: 6025

Open Door

The hints from Fitzy was that Shinny was really trusted, and that is the badge that opens the door:

[magicdust] pm3 --> lf hid sim -r 2006e22f13 
[=] Simulating HID tag using raw 2006e22f10
[=] Stopping simulation after 10 seconds.
[=] Done
image-20210110110004497

Story

On opening the door, I’m in a dark empty room with a set of glowing eyes at the bottom:

image-20210110110210290

On walking into the eyes, I’m suddenly the Santa character standing on the other side of the portrait in the main hall:

image-20210110110303558

Now I have access to all the challenges that were previously only available to Santa and staff…

On cool thing about Santa’s badge - It has a Teleport menu:

image-20210110110642506