Holiday Hack 2020: Open HID Lock
Objective
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:
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:
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 comment 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:
The HID-locked door is in the Workshop, with the panel just to the left of it:
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:
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
Story
On opening the door, I’m in a dark empty room with a set of glowing eyes at the bottom:
On walking into the eyes, I’m suddenly the Santa character standing on the other side of the portrait in the main hall:
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: