SANS Holiday Hack 2019 Write-Up
7) HR Incident Response
According to the document C:\candidate_evaluation.docx
, the organization “Fancy Beaver” is secretly supported by the job applicant named “Krampus”.
This document was not publicly accessible by default, but the careers site did have a publicly accessible directory at C:\careerportal\resources\public\
. This directory could be discovered by forcing a 404
error from the web server by navigating to an invalid path in a standard web browser. The 404
error would inadvertently display the publicly accessible path.
Knowing this information, and the location of the original document, we can determine that we need to move the document to the publicly accessible location for us to exfiltrate. Fortunately, the site allows for the user to upload a “CSV with your work history” to the site, and states that elves will “review” the work history and determine your qualification to a position.
Essentially, we can infer that the CSV will be opened by a user at some point. Knowing this, we can craft a malicious CSV that will run shell commands by invoking the excel formula =cmd
. We can infer that Microsoft Office products are being used by the extension .docx
earlier revealed to us.
After crafting a simply copy payload using the =cmd
formula, saving the payload to a CSV, and uploading it to the web server, after a few seconds (simulating the time necessary for a user to open the file), we can navigate to the /public/
web directory and download the .docx
we need.
8) Network Traffic Forensics
The name of the song described in the document sent from Holly Evergreen to Alabaster Snowball is Mary Had a Little Lamb
.
The first packet capture given to us is distributed by the packalyzer web application (after an account is created). This packet capture displays primarily HTTP/2 traffic, all encrypted. In order to decrypt the traffic, we need a list of SSL keys used in the transactions at the time of the traffic capture.
Through an HTML source code comment, we are directed to a publicly accessible directory on the web server that houses a javascript source code file - app.js
. This houses the main logic and functionality of the web application. After reviewing the source code, we can determine that we need a log file that keeps track of all SSL keys used with each packet capture.
We do not know the name of the log file, but after reviewing the source code, we figure out we can enumerate the name of the file by forcing an ENOENT
error (since this reveals too much information). After forcing the error by navigating to https://packalyzer.kringlecastle.com/sslkeylogfile/, we get the following:
Error: ENOENT: no such file or directory, open '/opt/http2packalyzer_clientrandom_ssl.log/'
Thus, we can infer that the name of the log is packalyzer_clientrandom_ssl.log
. And, according to the source code, the log should be stored in /dev/
. Thus, we can navigate to that directory and download that file. This file contains all SSL keys used in each HTTP/2 connection within the last few minutes, so a new packet capture should be downloaded around the same time this log is.
Once we obtain the log, we can import it into wireshark
and decrypt the HTTP/2 traffic. After filtering all HTTP/2 traffic and inspecting the packets, we can see packets with payloads containing login information to the site. Several users are included, but only one is an administrator to the site - Alabaster Snowball
. Once we log into the packalyzer site with his credentials, we can see that he has access to a special packet capture, super_secret_packet_capture.pcap
. This packet capture displays SMTP traffic, and after following the TCP stream, we can view the b64-encoded attachment in the email:
After decoding the b64 and outputting the data into a file, we notice that this is a .pdf
containing the instructions to using the piano.
9) Ransomware Recovery
9.1) Catch the Malware
This task involves using snort
to create a rule that alerts upon detection of the malware known as Wannacookie
.
After analyzing the packet capture given to us, we can determine that the malware communicates over DNS (udp port 53). We could create a simple rule to alert on that alone, but that would alert on benign traffic as well. As such, we need to fine tune our heuristics slightly.
If we inspect the payloads of the packets created by the malware (DNS lookups to long, arbitrary domains), we can notice a byte sequence that is common across all malware packets. For instance, the sequential bytes 36 63 36
. If we create a snort
rule to alert on UDP traffic over port 53, and only if the packet contains the common bytes, our alert will successfully be tuned:
alert udp any any -> any 53 ( msg:"Malware alert"; content:"|36|63|36|"; sid:1002; )
9.2) Identify the Domain
This task involves determining the domain that the malware communicates over. Eventually, we determine that the domain is erohetfanu.com
.
We are given a .docx
with an embedded macro that was believed to be the initial infection vector. Using olevba
, we can dump the macros from the document and obtain the dropper PowerShell code.
In the dropper code, we notice the malicious domain erohetfanu.com
.
9.3) Stop the Malware
This task involves finding a killswitch in the malware in order to stop further infection. Eventually, we determine that the domain we need to register as the killswitch is yippeekiyaa.aaay
.
This is determined by inspecting the malware source code, and using breakpoints within PowerShell ISE
. Upon inspecting this line of code in the main wanc()
function:
We can determine that this is the logic behind the killswitch. However, the exact name of the killswitch domain is obfuscated by several layers of encoding. We can view the ASCII version by using the debugger to step through each function call, and viewing the variable at the time that the H2A (hex_to_ascii
) function is called:
9.4) Recover Alabaster’s Password
This task involves decrypting a file provided to us by Alabaster, along with a memory dump taken at the time of infection. Eventually, we determine that the password Alabaster needed was ED#ED#EED#EF#G#F#G#ABA#BA#B
.
After inspection of the malware source code, we can determine that the files were encrypted using a symmetric AES key. An AES key exists in the memory dump, however, the key is encrypted by a public/private key pair. We will need to obtain the public/private key before we can use the AES key.
Upon inspection of the g_o_dns
function, we determine that the malware is not storing the keys on the client, but communicating the keys via obfuscated DNS traffic. We just need to determine the appropriate request to the DNS server in order to obtain the keys. g_o_dns
accepts an argument, $f
, that adds to the subdomain string of erohetfanu.com
. In the source code, the public key is obtained from the DNS server from the following line of source code:
The argument 7365727665722E637274
is actually a hex-encoded string, and upon conversion to ASCII, equals server.crt
. That filename often denotes a public key in an X509 key pair. After stepping through the traffic with the PowerShell ISE
debugger, we can obtain each part of the DNS traffic and combine it all into a long base64
string, which will equal the server.crt
. However, this base64
string does not include the necessary starting keywords to denote the presence of a certificate, so we must add the first line manually:
Next, we must obtain the corresponding private key. Since the argument passed to g_o_dns
was simply a hex-encoded value of the string server.crt
, we should be able to obtain the private key by passing a hex-encoded version of the string server.key
. After doing so, and obtaining the key in a similar fashion as server.crt
, we are able to obtain server.key
.
However, the keys must be combined into a .pfx
package for PowerShell to work with them. openssl
can do this using the command:
openssl pkcs12 -export -out out.pfx -inkey server.key -in server.crt
The following PowerShell code can be written to import the .pfx
into PowerShell and decrypt the AES key using the public/private key pair stored in the .pfx
:
The $message
variable stores the 512-bit encrypted value of the AES key. The .pfx
is imported and represented as $PFX
, and the key is decrypted using the private key stored in $PFX
.
H2B
(hex-to-bytes) and B2H
(bytes-to-hex) functions provided by the malware author are used here in order to format correctly for the functions that are expecting data in certain formats. The decrypted key, represented as hex, can be hashed with the function sh1
and compared to the key in memory to validate that the decryption worked successfully. In this case, it did match.
Now that we have the decrypted AES symmetric key, we can write more code to decrypt our .elfdb
file using the malware author-provided functions:
This code, similar to what was provided in the source code, loops through the user profile looking for .wannacookie
files (encrypted files), stores them in an array, converts the AES key from hex to raw bytes, then calls the decryption function, telling it to decrypt all .wannacookie
files in the \forensic_artifacts\
directory with the AES key. This code will run for a moment, and then the elfdb
decrypts to plaintext.
Upon attempting to open the .elfdb
file, we notice that it is a SQLite
database. We can use SQLlite viewer
or any other software to view the contents. Within the database, we can view the password for the vault, ED#ED#EED#EF#G#F#G#ABA#BA#B
.
10) Who is Behind It All?
Santa
is the mastermind behind the whole KringleCon plan. Santa hired Hans and dressed some elves up as the toy soldiers in order to find a person capable of solving all these challenges and defending the North Pole from actual malicious entities.
Once we obtain Alabaster’s password from 9.4
, we immediately notice that these are keys that can be played on the piano lock. Upon playing them, however, we receive an error stating that the key is wrong. This is confirmed by the verbage in the document sent by Alabaster in the packalyzer
challenge, wherein he states that elves hear notes on a different spectrum than humans.
In a hint provided by Alabaster, he states that the song should be in the key of D
, not E
. With this information, we can transpose the notes in the password down a full step to unlock the door, and find Santa, Hans, and the toy soldiers with their true identities revealed.