CTF

SANS Holiday Hack 2018 - KringleCon Writeup

santa

I had a great time working through this year's Holiday Hack and would like to commend SANS and CounterHack for putting together an awesome set of challenges!

Below is my writeup on completing the various terminal challenges and main objectives in order. Feel free to also use the below TOC to skip around:

Terminal Challenges:
Terminal 1 - Essential Editor Skills
Terminal 2 - The Name Game
Terminal 3 - Lethal ForensicELFication
Terminal 4 - Stall Mucking Report
Terminal 5 - CURLing Master
Terminal 6 - Yule Log
Terminal 7 - Dev Ops Fail
Terminal 8 - Python Escape
Terminal 9 - Sleigh Bell Lottery

Full Objective/Terminal Challenges:
Objective 1 - Orientation Challenge
Objective 2 - Directory Browsing
Objective 3 - de Bruijn Sequence
Objective 4 - Data Repo Analysis
Objective 5 - AD Privilege Discovery
Objective 6 - Badge Manipulation
Objective 7 - HR Incident Response
Objective 8 - Network Traffic Forensics
Objective 9 - Ransomware Recovery
Objective 9.1 - Catch the Malware
Objective 9.2 - Identify the Domain
Objective 9.3 - Stop the Malware
Objective 9.4 - Alabaster's Password
Objective 10 - Who Is Behind It All?
Objective 10.1 - Piano Lock
Objective 10.2 - The Mastermind!

KringleCon Talks:
Talks

Final Narrative:
Narrative


This year the Holiday Hack is structured as a security conference at the North Pole called KringleCon. Your goals are to walk your character through the game and talk to elves for hints, watch talks, and complete terminal challenges and the main objectives.

The game portion of the challenge can be found here:
https://kringlecon.com/

frontgate

You can click on your character's necktie looking badge in order to see your progress, hints, talks, etc.

badge

Now, let's walk through the challenges and their solutions!


Objective 1 - Orientation Challenge:


q1-1

Terminal Challenge 1: Essential Editor Skills


bushy1

Bushy Evergreen wants your help with the first terminal challenge and you need to exit the VI editor to get back to the terminal shell.

t1q

You are provided a hint by Bushy for "Vi Editor Basics" at this URL:
https://kb.iu.edu/d/afcz

Terminal Solution

This first terminal starts off easy. Enter the quit command with :q! which completes the challenge.
t1a1
t1a2

Back to top

Objective 1 Solution:

Now, we need to answer all of the question at the KringleCon Holiday Hack History kiosk. After completing the terminal challenge, we were provided another hint:
https://holidayhackchallenge.com/past-challenges/

The kiosk asks us serveral questions:

q1a1
q1a2
q1a25

After answering the final question, the kiosk page displays the following answer:

q1a3

Now, we enter "Happy Trails" into the objectives page to complete objective 1!

q1fa-1

Back to top


Objective 2 Directory Browsing:


q2

Terminal Challenge 2: The Name Game


minty2

Minty Candycane needs help determing the first name of a worker named "Chan." This challenge provides a few options for an onboarding application:

t2

Minty provides a hint URL for PowerShell injection and sqlite dumping:
https://ss64.com/ps/call.html
https://www.digitalocean.com/community/questions/how-do-i-dump-an-sqlite-database

Terminal Solution

Enter "2" to "verify the system" which allows you to enter an IP address. After adding an IP, such as Google DNS, the application replies with the name of a database which is "onboard.db":

t2-6

Command injection can be performed by using an ampersand (or a semicolon) to execute a second command to open the database and provide a database shell.
8.8.8.8 & sqlite3 onboard.db

The tables command lists a single table name of "onboard.
.tables

Next, we need the column names which we can get from the schema.
.schema

We were told at the beginning that we need the first name of an entry with a last name of "Chan." The response from the below SQL query shows that the employee's name is Scott Chan:
select * from onboard where lname='Chan';

t2-2-2

Lastly, we can use command injection again (this time with a semicolon) to execute the runtoanswer application and enter the first name of "Scott" to complete this challenge:
8.8.8.8; ./runtoanswer

t2-3

Note: You could have also used the following two commands to complete the challenge as well by utilizing the dump command.
8.8.8.8 & sqlite3 onboard.db .dump > onboard.bak
8.8.8.8 & cat onboard.bak

Back to top

Objective 2 Solution:

We can now visit the CFP site at https://cfp.kringlecastle.com and click on "CFP" which leads us to https://cfp.kringlecastle.com/cfp/cfp.html.

o2new

Minty provides us the following hint:

2objhint

Since the challenge is named "Directory Browsing" we can simply remove "cfp.html" in order to browse to the /cfp directory:

t2-4
After selecting "rejected-talks.csv," we find that John McClane had submitted the rejected talk on "Data Loss for Rainbow Teams."

t2-5

Lastly, we enter "John McClane" into the objectives page to complete objective 2!

2ans

Back to top


Objective 3 de Bruijn Sequence:


q3

Terminal Challenge 3: Lethal ForensicELFication


tangle1

Tangle Coalbox needs help finding hidden information about an elf of whom a love poem was written--from use of the VI text editor:

t3-2

Tangle provides us the following hint url about VIM artifacts:
https://tm4n6.com/2017/11/15/forensic-relevance-of-vim-artifacts/

Terminal Solution

A good place to start is by running the history command which shows us a hidden directory of .secrets/her/ was created:
history

t3-1

The cat command can be used to view the file to notice the elf is referred to as "NEVERMORE."
cat poem.txt

t3-2

Now we need to find the command history for VIM which is stored in the viminfo file.
more .viminfo

Here we see that a string substitution was made for "NEVERMORE" with "Elinore."

t3-3

After entering "Elinore" into the answer application, this challenge is complete!

t3-4

Back to top

Objective 3 Solution:

We now need to get into the Speaker Unpreparedness Room which requires a door passcode.

speaker

Tangle Coalbox provided a hint in his chat that we can use an online de Brujin Sequence generator online where the length of the alphabet is 4 (4 door buttons) and the lenth of the PIN is 4 as well. Therefore, k=4 and n=4.

All of the Elves' chats past chats can be viewed by using the chat dropdown during gameplay to select the respective elf.

Another hint was provided with this link:
https://hackaday.com/2018/06/18/opening-a-ford-with-a-robot-and-the-de-bruijn-sequence/

I used this generator:
http://www.hakank.org/comb/debruijn.cgi

3obj

  • Triangle = 0
  • Square = 1
  • Circle = 2
  • Star = 3

Next, start entering the above sequence from left to right which wraps around and is circular. The correct door code was 0120 (or Triangle, Square, Circle, Triangle).

3obj2

Walking into the room, Morcel tells us the phrase needed to answer the objective question which is "Welcome unprepared speaker!"

3obj3

Lastly, we enter that phrase into the objectives page to complete objective 3!

3obj4
Back to top


Objective 4 Data Repo Analysis:


q4

Terminal Challenge 4: Stall Mucking Report


wanose1

In this challenge, Wunorse Openslae needs help in uploading report.txt to a samba share at //localhost/report-upload.

t4

Wunorse provided us a hint in chat that we may be able to find his password in memory as well as this link about passwords on the command line:
https://blog.rackspace.com/passwords-on-the-command-line-visible-to-ps

Terminal Solution

Listing processes shows the commands and arguments/flags used during execution.
ps -aux
a = Shows processes for all users
u = Displays the owner of the processes
x = Shows processes that are not attached to a terminal

ps1

The problem is that the full commands are not wrapped and we cannot see them. In order to see the full samba command, ps -aux can be piped to more which provides the report-upload user's password of directreindeerflatterystable.
ps -aux | more

ps2

The following command uses smbclient to grab the local file from the //localhost/report-upload path and set the user as report-upload.
smbclient //localhost/report-upload/ -U report-upload

The password of directreindeerflatterystable is now entered and the below command is used to put report.txt on the share and name it report.txt which completes the challenge.
put report.txt report.txt

t3new

Back to top

Objective 4 Solution:

For the objective, we need to find a hard coded credential in the github repository.

Wunorse provides a hint in chat to use Trufflehog with the entropy=True option for more in-depth repository searching and to watch Brian Hosteller's talk as well as view the tool's github page:
https://www.youtube.com/watch?v=myKrWVaq3Cw
https://github.com/dxa4481/truffleHog

We start by cloning the repo locally:
git clone https://git.kringlecastle.com/Upatree/santas_castle_automation.git

Then, Trufflehog is used to parse the local cloned repo for strings and secrets by enabling high signal regex and entropy checks:
trufflehog --regex --entropy=True santas_castle_automation

Browsing the results shows the password is "Yippee-ki-yay."

o42

We can now enter that password to complete this objective!

o43

Back to top


Objective 5 AD Privilege Discovery:


q5

Terminal Challenge 5: CURLing Master


holly1

Holly Evergreen needs help with sending a curl command to http://localhost:8080/ in order to get the candy striper stated again:

t5

Holly provides a hint with an introduction to HTTP/2--which enables multiplexing of full requests and responses and other new features to increasing browsing efficiency and speed:
https://developers.google.com/web/fundamentals/performance/http2/

Terminal Solution

Since the challenging is called "CURLing Master" we know that curl can be used. Curl is a tool which can be used to transfer data to or from a server using various supported protocols.

We can use the following command to use curl's http2-prior-knowledge option to use HTTP/2 without HTTP/1.1 upgrade and connect to the index.php page on localhost:8080:
curl --http2-prior-knowledge http://localhost:8080/index.php

t51

The above request responded that the candy striper could be turned on via a POST request to the index.php page with a parameter of "status=on" which is performed in the below command and completes this challenge:
curl -d "status=on" -X POST --http2-prior-knowledge http://localhost:8080/index.php

t52

Back to top

Objective 5 Solution:

For this objective, we need to load a SANS Slingshot Linux image and find the user with a reliable path from a Kerberoastable user to the Windows Domain Admins group. Further, RDP needs to be avoided as a control path as it depends on addition local privilege esclation flaws and we are looking for the simplest path to Domain Admin.

Holly provides a hint to use BloodHound and watch its demo by Raphael Mudge as well as view its github page:
https://www.youtube.com/watch?v=gOpsLiJFI1o&feature=youtu.be
https://github.com/BloodHoundAD/BloodHound

BloodHound is a Javascript web application which has a database fed by a PowerShell ingestor and uses graph theory to reveal hidden relationships and attack paths in an Active Directory environment.

The OVA file (which is a premade virual machine) for the image is downloaded from the link on the objectives page:
https://download.holidayhackchallenge.com/HHC2018-DomainHack_2018-12-19.ova

Now, the OVA file was imported into VMware Workstation and the VM was powered on. BloodHound was executed from the VM's Desktop and all needed data has been preloaded. The three horizontal bar menu button displays options for "Database Info," "Node Info," and "Queries." Clicking on "Queries" presents several predefined query options. Scrolling down a bit we see an option for "Shortest Paths to Domain Admins from Kerberoastable Users" and select it:

o51

Next, we select the Domain Admin group of "DOMAIN ADMINS@AD.KRINGLECASTLE.COM" which presents a map of several paths to Domain Admin (shown on the far right with a diamond icon).

blood1

The only path that doesn't require RDP to hit the Domain Admin is the below path from LDUDEJ00320@AD.KRINGLECASTLE.COM:

o52

Lastly, LDUDEJ00320@AD.KRINGLECASTLE.COM is entered as the answer to complete this objective!

o5ans

Back to top


Objective 6 Badge Manipulation:


q6

Terminal Challenge 6: Yule Log


pepper1

Pepper needs help in parsing an event log that shows evidence of password spraying in order to determine which user's account was successfully logged into by the attacker.

t6

Pepper provides a hint in the below URL which talks about MailSniper, a tool that performs password spraying:
https://securityweekly.com/2017/07/21/tsw11/

There is also a talk by Beau Bullock on password spraying:
https://www.youtube.com/watch?v=khwYjZYpzFw

A traditional brute force attack is not a good solution against Windows accounts as a lockout will usually be triggered quickly. Password spraying however is a reverse brute force attack that tries a single password for each username in a long list of usernames before cycling back to the top of the username list and trying the next password across all accounts and so on.

Terminal Solution

After running "ls" we notice there is an event log file named ho-ho-no.evtx and a python event log parser called evtx_dump.py. The below command uses python to use the parser against the event log file and outputs the results to a file named "output."
python evtx_dump.py ho-ho-no.evtx > output

t62

Windows event logs have Event IDs that represent if a logon attempt is successful or fails:

4624 - An account was successfully logged on
4625 - An account failed to log on

We can pipe the output to grep and use -B and -A to specify the number of lines before and after the match in order to start drilling down in the log.

The following command displays the IP address responsible for many failed logons:
cat output | grep -A40 4625 | grep IpAddress

log2

The next command displays the target username of any host that was sprayed by the attacker's IP of 172.31.254.101, resulting in a successful logon event ID of 4624:
cat output | grep -B 34 -A 10 172.31.254.101 | grep -B 1 -A 19 4624 | grep TargetUserName

log3

The username of minty.candycane is submitted to complete this challenge:

logsave1
logsave2

Back to top

Objective 6 Solution:

The objective involves bypassing a QR code badge reader to access a room.

Pepper provided the following hints for generating a barcode as well as for SQL injection:
https://www.the-qrcode-generator.com/
https://www.owasp.org/index.php/SQL_Injection_Bypassing_WAF#Auth_Bypass

The objectives page also provided a sample employee badge:
https://www.holidayhackchallenge.com/2018/challenges/alabaster_badge.jpg

badge2

Using a basic QR code scanning mobile app, the badge QR code is oRfjg5uGHmbduj2m which appears to be a user id.

Here is the Badge Scan-O-Matic 4000 in its glory:

badge1

The mouse can be used to insert a USB drive where a file from your computer can be selected. The alabaster_badge.jpg file was selected and the reader stated that only png image files were allowed.

Since the hint involves SQL Injection, getting an error to fire would be a good first step. The following query portion was saved into a new badge as a png file and inserted into the scanner.
'asdf or 1-- -' union

In order to capture the error, Burp Suite was running as an interception proxy and captured the response which states the database is MariaDB and shows the backend SQL query is:
SELECT first_name,last_name,enabled FROM employees WHERE authorized = 1 AND uid = '{}' LIMIT 1\".format(uid))\

burp

User input is saved between the brackets in the uid = '{}' of the query.

The following SQL query was embedded into a QR code and saved as openup.png:
asdf or 1-- -' union select 1,first_name,last_name from employees where 1=1-- -'

The union operator is used to join our new query to the initial query. The error message let us know that we will need three columns in the new query and we end this new query with a statement that that is always true.

badgeopen

The openup.png file was inserted into the reader and the badge reader read "USER ACCESS GRANTED - CONTROL NUMBER 19880715"

badgewinner

The answer of 19880715 was entered into the objective page to complete this challenge!

o6ans

Back to top


Objective 7 HR Incident Response:


q7

Terminal Challenge 7: Dev Ops Fail


sparkle1

Help Sparkle Redberry find her creds that were committed to git in a prior commit.

t7

Sparkle provided the following two URLs as hints:
https://gist.github.com/hofmannsven/6814451
https://en.internetwache.org/dont-publicly-expose-git-or-how-we-downloaded-your-websites-sourcecode-an-analysis-of-alexas-1m-28-07-2015/

Terminal Solution

Running ls shows that there is a directory named kcconfmgmt that we will change into.
ls
cd kcconfmgmt

Next, git -log displays all of the commits and respective notes. The note for commit 60a2ffea7520ee980a5fc60177ff4d0633f2516b reads:

"Per @tcoalbox admonishment, removed username/password from config.js, default settings in config.js.def need to be updated before use"
git log

git1

The next command will show that specific older version of the file where we now see the mongodb database password was hardcoded as twinkletwinkletwinkle:
git show 60a2ffea7520ee980a5fc60177ff4d0633f2516b

git2

The password is entered to complete the challenge!

t72

Back to top

Objective 7 Solution:

This objective involves gaining access to a word document from the Elf Resources website in order to determine which terrorist organization is secretly supported by the job applicant whose name begins with "K."

Sparkle provides a hint about CSV Injection as well as mentioning Brian Hostetler's CSV DDE Injection talk:
https://www.owasp.org/index.php/CSV_Injection
https://www.youtube.com/watch?v=Z3qpcKVv2Bg

The website is provided on the objectives page:
https://careers.kringlecastle.com/

elfsite

We are ultimately going to need to craft a csv file that has DDE injection that will copy the word document to a public area that we can then access.

First, an error was forced by attempting to view https://careers.kringlecastle.com/temp:

o7

The 404 error page let us know that publicly accessible files are served from C:\careerportal\resources\public.

To start, a fake submission was uploaded to see what type of output we would get back from the server:

elfsite2

The output states that data from uploaded files is added to C:\candidate_evaluation.docx:

elfsite3

Now, we know that we need to upload a CSV with DDE injection that will take the C:\candidate_evaluation.docx file and copy it to the C:\careerportal\resources\public directory.

Dynamic Data Exchange (DDE) allows contents from a spreadsheet or even Remote Code Execution (RCE) to be performed when Excel executes malicious code stored in a cell of a spreadsheet.

The following DDE code was stored in a spreadsheet named q7copy.csv:
=cmd|'/C copy C:\candidate_evaluation.docx C:\careerportal\resources\public'!A0

o71

The q7copy.csv sheet was now uploaded through the web form:

o72

After a few seconds, the candidate_evaluation.docx file can now be retrieved from https://careers.kringlecastle.com/public/candidate_evaluation.docx

o73

After opening the file, we see that the cyber terrorist organization is named Fancy Beaver.

o74

Fancy Beaver was entered into the objectives page to complete this challenge!

o7ans

Back to top


Objective 8 Network Traffic Forensics:


q8

Terminal Challenge 8: Python Escape


sugarplummary1-1

SugarPlum Mary needs help escaping from a restricted Python shell.

t8

SugarPlum provides a hint to watch Mark Baggett's talk on Escaping Python Shells.
https://www.youtube.com/watch?v=ZVx2Sxl3B9c

Terminal Solution

An initial attempt was made to import the subprocess module--which allows a user to spawn new processes--but unfortunately the import command was prohibited.
import subprocess

Luckily, string concatination can be used to bypass the import restrition by break import into two pieces which Python will put back together during execution.
sub = eval('__imp' + 'ort__("subprocess")')

Now, we can test this with the "id" command and see that it works.
sub.call("id")

Lastly, this command runs the application that completes the challenge!
sub.call("./i_escaped")

t81

Back to top

Objective 8 Solution:

This objective involves accessing and decrypted HTTP/2 network activity in order to access a particular document containing a song name via use of the Packalyzer website at https://packalyzer.kringlecastle.com

o8

SugarPlum provides a hint to watch Chris Elgee and Chris Davis' talk on HTTP/2
https://www.youtube.com/watch?v=PC6-mn9g9Cs

SugarPlum in the chat also states that HTML comments provide a hint that allows the server side code to be grabbed in order to find code relating to SSL keys. Additionally, she mentions that manipulating values in the URL may give back useful errors in order to compromise SSL on the website and steal logins.

Viewing the client side source code, we see an embedded javascript file referenced named custom.js:

o81

Another piece of client side source code has a comment that references a javascript file named app.js:

o82

We can use the prior two pieces of information to access app.js within the /pub directory which presents us with the server side source code:

pack1

An interesting bit of code from above is "dirname + process.env.DEV + process.env.SSLKEYLOGFILE which is a part of the key_log_path variable. Attempting to view the /DEV/ directory doesn't work:

pack3

Attempting to view the SSLKEYLOGFILE file provides an error message stating that the file is called packalyzer_clientrandom_ssl.log:

pack4-1

The combination of /DEV/packalyzer_clientrandom_ssl.log returns the actual SSL keylog file which can be used to decrypt pcaps of encrypted network traffic in tools like Wireshark. The packalyzer_clientrandom_ssl.log file was downloaded.

pack5

A fake account was created to enter the Packalyzer website. Once inside, the "SNIFF TRAFFIC" function was executed and the "Captures" tab was selected. From there, the pcap of the prior sniffing function was downloaded:

pack6

The pcap was opened in Wireshark and Edit / Preferences / Protocols / Down arrow to expand / SSL was browsed to. Now, the ssl keylog file was browsed to under and "OK" was selected.

o891

One of the logons was for Alabaster which was found by entering a filter of http2.data.data and scrolling through the packets and selecting "Uncompressed entity body" as the bottom of Wireshark:

o892

Out of the logons in the pcap, Alabaster's once logged in with alabaster/Packer-p@re-turntable192 showed a pcap under "Captures" of super_secret_packet_capture.pcap which was downloaded:

o893

The secret pcap was really called upload_sa4a5ae98007cb261119b208bf9369ef.pcap and was opened in Wireshark and one of the SMTP frames was selected, right clicked, and Follow TCP Stream was selected. The TCP Stream showed a base64 encoded email attachment which was copied to a file.

o894

The base64 file was converted to unix line endings and the following command was used to decode the base64 into a pdf:
base64 --decode attachment.txt > attachment.pdf

o895

The pdf was opened and included information on musical transposition and keys. A song of "Mary Had a Little Lamb" was mentioned at the end.

o896

o897

The song name was entered into the objectives page to complete this challenge!

o8ans

Back to top


Objective 9 Ransomware Recovery:


q9

9stuff

Terminal Challenge 9: Sleigh Bell Lottery


shiny1

Shinny Upatree needs help using a debugger in order to win the sleighbell lotto by performing some reverse engineering.

t91
t92

Shinny provides a hint about using gdb to call random functions.
https://pen-testing.sans.org/blog/2018/12/11/using-gdb-to-call-random-functions

Terminal Solution

First, we need to list the symbols in the binary and can use the nm command to do so. Symbols with a "T" in front of them are ones we can actually call and "winnerwinner" seems like a good one to pursue. Therefore, the below command uses nm and grep to display only the callable symbols:
nm ./sleighbell-lotto | grep T

t93

Next, we can run the GNU Project Debugger (GDB) with the -q flag to disable unneccessary output.
gdb -q ./sleighbell-lotto

Now, we can run the entire binary and see what happens. Unfortunately, we didn't win on the first time :(
run

Next, a breakpoint is set on main and the binary is run again.
break main
run

The binary is stopped at the breakpoint and the jump command is used to jump straight to the winnerwinner function.
jump winnerwinner

t94

The challenge is complete after the jump to winnerwinner is performed!

t95

Back to top


Objective 9.1 Catch the Malware:


q9-1

This objective involves building a snort rule that will alert only on bad ransomware traffic.

o91

Objective 9.1 Solution:

A hint was provided that malware authors change dynamic domain names and IP addresses frequently and that pattern searches are a better route to take.

o912

First, we can logon to http://snortsensor1.kringlecastle.com/ with creds of elf/onashelf and download a couple of the pcaps:

snort2

After opening a pcap in Wireshark, we notice that there are many DNS text records that contain the following string after the decimal point:
77616E6E61636F6F6B69652E6D696E2E707331

snort3

Next, we can write our snort rule. Christopher Davis created a great snort rule building tool at snorpy.com that is great in the event you are starting out or don't build snort rules everyday.

snort-4

Our rule is:
alert udp any any -> any any ( msg:"Ransomware oh noes"; content:"77616E6E61636F6F6B69652E6D696E2E707331"; sid:1000001; rev:001; )

Rule Breakdown:

The first part of the rule is the rule header:
alert Rule action, which in this case is to trigger an alert
udp Protocol
any any -> any any Source IP, Source Port, Destination IP, Destination Port

The section in parenthesis is the option portion of the rule and options are separated with semicolons:
msg:"Ransomware oh noes" Custom message to help remember what the rule is about
content:"77616E6E61636F6F6B69652E6D696E2E707331" String being searched for in the payload portion of the packet
sid:1000001 Snort rule ID (SID) which must be set to 1 million or higher for locally created rules
rev:001 The revision ID for the rule

Next, we add our rule to /etc/snort/rules/local.rules:

o914

Normally, we would have to restart snort for local rules to take affect but this system appears to do so on its own. After a few seconds we receive a completion message that our rule is correct.

o915

The completion message was entered into the objectives page to complete this challenge!

ans91

Back to top


Objective 9.2 Identify the Domain:


q9-2

The objectives page provides a link to a zip file that contains a Word document named CHOCOLATE_CHIP_COOKIE_RECIPE.docm. The .docm extension alerts us that macros are most likely embedded. We need to identify the domain name that the malware is communicating with.

From this point forward, all malware analysis should normally be performed in an isolated virtual machine with a dirty pipe network connection.

Objective 9.2 Solution:

Alabaster provides a hint that Word docm macros can be extracted using olevba in order to grab the ransomware source.
https://github.com/decalage2/oletools/wiki/olevba

The oletools module was installed using pip:
python2 -m pip install -U oletools

o922

Oleva was then run against the Word doc to detect any Visual Basic for Applications (VBA) macros.
python2 olevba-script.py CHOCOLATE_CHIP_COOKIE_RECIPE.docm

We can see a PowerShell script is embedded as Module1:

o923

The script in the macro was copied and executed in Powershell after removing the Invoke-Expression alias (iex) and piping the output of the script to a file named dropper1.ps1.

After executing dropper1.ps1, we see the domain the malware is communicating with is erohetfanu.com.

o924

The domain was entered into the objectives page to complete this challenge!

ans92

Back to top


Objective 9.3 Stop the Malware:


q9-3

For this challenge we need to identify a killswitch to stop the malware similar to WannaCry.

Alabaster provided us a hint about finding a non-minified version of the ransomware source code.

Objective 9.3 Solution:

Alabaster provides a hint that the malware may have a kill switch and to watch Chris Davis' talk on PowerShell malware (which as mentioned is in fact "crazy pants).
https://www.wired.com/2017/05/accidental-kill-switch-slowed-fridays-massive-ransomware-attack/
https://www.youtube.com/watch?v=wd12XRq2DNk

First, we need to remove iex and run the malware script that had been returned when we last ran our dropper1.ps1 script and save the response with a pipe to Outfile as source1.ps1. Source1.ps1 is now the full source code for the WannaCookie Ransomware.

Now, we can open the source1.ps1 file in PowerShell's Inegrated Scripting Environment (ISE) so that we can interact with the ransomware and set break points.
o925

Breakpoints can be set by selecting a line and hitting F9. Breakpoints were set on lines 36, 40, 46, 50, 55, and 63:

The malware is executed by clicking the green play button or hitting F5. You can then step into a line with F11 or step over a line with F10.

As variables are defined, you can type then into the terminal at the bottom of ISE. Here we see that the $cont variable returned several numbers:

o926

The above numbers are actually output in decimal. Using a decimal to hexidecimal converted we see that the domain of yipeekiyaa.aay is spelled out--ala John McClane's iconic line from the ultimate Christmas movie, Die Hard.

yipdec

However, if we keep stepping we will get to the ransomware's $a conversion function which we can see the output of by calling variable $outa:

o927

In the game, we can enter the yippeekiyaa.aaay domain into Ho Ho Ho Daddy and trigger the kill switch and stop the ransomware in its tracks:
https://hohohodaddy.kringlecastle.com/index.html

o928

Lastly, we enter the domain into the objectives page to complete this challenge!

ans93

Back to top


Objective 9.4 Alabaster's Password:


q9-4

Unfortunately, Alabaster let the ransomware run on his computer which encrypted his password vault database.

wanna

We can grab the encrypted file from the objectives page which is named alabaster_passwords.elfdb.wannacookie. We are also provided with the dump of the memory process of the ransomware which is named powershell.exe_181109_104716.dmp.

This objective involves aquiring asymmetric encryption keys from the WannaCookie author's DNS server in order to decrypt the encrypted symmetric key which is then used to decrypt the ransomed password vault database. Whew...brain buster here.

Objective 9.4 Solution:

Alabaster provides a hint that public / private key encryption may be involved and that strings can be pulled via PowerDump.
https://github.com/chrisjd20/power_dump

There are several hex strings in the ransomware source code and below are the ascii representations:
6B6579666F72626F746964 – keyforbotid
6B696C6C737769746368 – killswitch
7365727665722E637274 – server.crt
72616e736f6d697370616964 – randomispaid

At this point we can use functions from the source code to accomplish different goals with an editor such as Visual Studio Code. Our first task is to download the server.crt file by using the g_o_dns function (which most likely means get over DNS). The server.crt hex string is provided to the function and the output file is named server.crt.

o941

When opening server.crt in a text editor, it was missing the begin and end certificate header/footer which we can manually add. You can also use openssl to validate the the certifcate format is correct.

o942

Now, we can use the same g_o_dns function as before but use the hex representation for server.key (7365727665722E6B6579) to download the private key:

o943

o944

We know the public key is 256 bytes and hex is double that so now we can search the powershell.exe_181109_104716.dmp memory sample for a string that is 512 bytes with power_dump.py.

PowerShell is opened and we drop into a bash shell and then execute PowerDump and choose a few initial options:
bash
python2 power_dump.py
1 To load a dump file
ls To list the files
ld powershell.exe_181109_104716.dmp To load the specific dump file

Now that the dump is loaded, we need to process it to find strings, variables, script blocks, etc.
b To go back to the main menu
2 To process the memory dump
y To save the processing

o946

Next, we need to search the dump for stored PowerShell variables, filter for our 512 byte length, and dump the results.
4
len == 512
dump

o947

The dump results is stored as variable_values.txt and we can now see the encrypted symmetric key that was used to encrypt Alabaster's password database:

o948

Next, we take the ransomware source and modify it a bit to decrypt the password database. The top line is turned into a function and lines 36 and 37 are commented out so that the key is not removed after execution.

The p_k_e function is used to import the public and private keys which were saved as a pfx file named server.prx with a password of "alabaster." The private key required some padding which was added in line 47.

Next, we have a function to decrypt the encrypted symmetric key in order to decrypt the password database and output the decrypted file as alabaster_passwords.elfdb.wannacookie.

o949
o9410

The decrypted password database was opened in SQLite Browser and we see the vault password is ED#ED#EED#EF#G#G#G#ABA#BA#B

o9411

The vault password is entered into the objective page to complete this challenge!

ans94

Back to top


Objective 10 Who Is Behind It All?:


q10

Lastly, we need to figure who the mastermind is behind the KringleCon plan.

Objective 10.1 Piano Lock Solution:


There is one last room we need to get into but it is locked with a Piano Lock:

piano

Entering the vault password doesn't unlock the door and we are told that the tune is correct but the key isn't right.

o101

The earlier pdf we extracted from the Packalyzer pcap was about musical keys and transpositions. Also, Alabaster gave us a hint that the tune should be in the key of D and not E.

Therefore the notes were transposed down a whole step to the key of D which unlocked Santa's vault.

o103

(I knew my music undergrad would help me in security one day...)

IMG_5131

The "You have unlocked Santa's vault!" phrase was entered into the objectives page to complete this challenge!

o105
o106
o107

Back to top

Objective 10.2 The Mastermind!:


In Santa's Vault we find out that Santa was the mastermind behind the KringleCon plan. The purpose of the plan was to find skilled security professionals to help Santa defend the North Pole against attack for years to come!

o104-1

The final answer to Santa was entered into the objectives page to complete the final challenge!

o108

Back to top


KringleCon Talks:


talks

Keynote:
Dave Kennedy
The Five Ways the Cyber Grinch Stole Christmas

HH Challenge Director:
Ed Skoudis [CHC]
KringleCon: Start Here


Talks:
Brian Hostetler [CHC]
CSV DDE Injection: Pwn Web Apps Like a Ninja
Track 2

Chris Davis [CHC]
Analyzing PowerShell Malware
Track 4

Mark Baggett
Escaping Python Shells
Track 7

Beau Bullock
Everything You've Wanted to Know About Password
Spraying But Were Afraid to Ask

Track 6

Mick Douglas
PowerShell for Pen Testing
Track 6

Micah Hoffman
Breach Data and You
Track 5

Heather Mahalik
Smartphone Forensics: Why Building a Toolbox Matters
Track 5

Jason Nickola
Crash Course in Web App Pen Testing with Burp Suite
Track 5

Larry Pesce
Software-Defined Radio: The New Awesome
Track 1

Derek Rook
Pivoting: SSH
Track 1

John Strand
Evil Clouds
Track 1

Chris Elgee and Chris Davis [CHC]
HTTP/2: Because 1 Is the Loneliest Number
Track 2

Brian Hostetler [CHC]
Buried Secrets: Digging Deep Through Cloud
Repositories

Track 4

Jay Beale
Quick Intro to Attacking a Kubernetes Cluster
Track 6

Jack Daniel
The Secret to Building Community
Track 1

Jon Gorenflo
Intro to Hashcat
Track 6

Katie Knowles
Sneaking Secrets from SMB Shares
Track 4

Tim Medin
Hacking Dumberly Not Harderer
Track 7

Deviant Ollam
Key Decoding
Track 5

Mike Poor
PCAP for Fun and Profit
Track 4

Mike Saunders
Web App 101: Getting the Lay of the Land
Track 7

John Strand
Malware Zoo
Track 7

Rachel Tobac
How I Would Hack You: Social Engineering Step-by-Step
Track 2

Back to top


Final Narrative:


As you walk through the gates, a familiar red-suited holiday figure warmly welcomes all of his special visitors to KringleCon.

Suddenly, all elves in the castle start looking very nervous. You can overhear some of them talking with worry in their voices.

The toy soldiers, who were always gruff, now seem especially determined as they lock all the exterior entrances to the building and barricade all the doors. No one can get out! And the toy soldiers' grunts take on an increasingly sinister tone.

The toy soldiers act even more aggressively. They are searching for something -- something very special inside of Santa’s castle -- and they will stop at NOTHING until they find it. Hans seems to be directing their activities.

In the main lobby on the bottom floor of Santa's castle, Hans calls everyone around to deliver a speech. Make sure you visit Hans to hear his speech.

The toy soldiers continue behaving very rudely, grunting orders to the guests and to each other in vaguely Germanic phrases. Suddenly, one of the toy soldiers appears wearing a grey sweatshirt that has written on it in red pen, "NOW I HAVE A ZERO-DAY. HO-HO-HO."

A rumor spreads among the elves that Alabaster has lost his badge. Several elves say, "What do you think someone could do with that?"

Hans has started monologuing again. Please visit him in Santa's lobby for a status update.

Great work! You have blocked access to Santa's treasure... for now. Please visit Hans in Santa's Secret Room for an update.

And then suddenly, Hans slips and falls into a snowbank. His nefarious plan thwarted, he's now just cold and wet.

But Santa still has more questions for you to solve!

Congrats! You have solved the hardest challenge! Please visit Santa and Hans inside Santa's Secret Room for an update on your amazing accomplishment!

Back to top


Author image

About Shawn Davis