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.

Written on March 22, 2022