If you want to play the challenge yourself, you can find it here:

https://2024.holidayhackchallenge.com/

Story line

Let’s start off by talking to the elf:

Greetings! I’m the genius behind the North Pole Elf Stack SIEM. And oh boy, we’ve got a situation on our hands.

Our system was attacked—Wombley’s faction unleashed their FrostBit ransomware, and it’s caused a digital disaster.

The logs are a mess, and Wombley’s laptop—the only backup of the Naughty-Nice List—was smashed to pieces.

Now, it’s all up to you to help me trace the attack vectors and events. We need to figure out how this went down before it’s too late.

You’ll be using a containerized ELK stack or Linux CLI tools. Sounds like a fun little puzzle, doesn’t it?

Your job is to analyze these logs… think of it as tracking snow tracks but in a digital blizzard.

If you can find the attack path, maybe we can salvage what’s left and get Santa’s approval.

Santa’s furious at the faction fighting, and he’s disappointed. We have to make things right.

So, let’s show these attackers that the North Pole’s defenses are no joke!

Hints

I’m part of the ElfSOC that protects the interests here at the North Pole. We built the Elf Stack SIEM, but not everybody uses it. Some of our senior analysts choose to use their command line skills, while others choose to deploy their own solution. Any way is possible to hunt through our logs!
If you are using your command line skills to solve the challenge, you might need to review the configuration files from the containerized Elf Stack SIEM.
One of our seasoned ElfSOC analysts told me about a great resource to have handy when hunting through event log data. I have it around here somewhere, or maybe it was online. Hmm.
Our Elf Stack SIEM has some minor issues when parsing log data that we still need to figure out. Our ElfSOC SIEM engineers drank many cups of hot chocolate figuring out the right parsing logic. The engineers wanted to ensure that our junior analysts had a solid platform to hunt through log data.
I was on my way to grab a cup of hot chocolate the other day when I overheard the reindeer talking about playing games. The reindeer mentioned trying to invite Wombley and Alabaster to their games. This may or may not be great news. All I know is, the reindeer better create formal invitations to send to both Wombley and Alabaster.
Some elves have tried to make tweaks to the Elf Stack log parsing logic, but only a seasoned SIEM engineer or analyst may find that task useful.

Recon

Upon clicking on the challenge, an iframe pops up with some instructions and a menu.

Quick Start Instructions
Quick Start Instructions
Menu
Menu

In the menu we find four buttons, “Easy Mode”, “Hard Mode”, “Help” and “Download”. The Help page will show us some information about how to set up the SIEM.

Elf Stack Help

Description

  • Help the ElfSOC analysts and test your technical and security skills while you investigate a malicious attack. You will parse a set of log files to identify the malicious attack vector and various events within an attack chain.
  • The log parsing skills emphasized by this challenge can be done with the provided containerized Elf Stack SIEM, through traditional Linux CLI tools, or however you want. There are two challenge modes (EASY and HARD) which determines the difficulty of questions presented to you.
  • Note: You do not have to use the containerized SIEM to solve any of the questions, but it might make things a bit easier!
  • You can download the containerized Elf Stack SIEM configuration and log files by selecting the “Download” button.

Challenge Modes

Easy Mode
  • This mode teaches basic log parsing with a common SIEM utility like the ELK stack. You are provided a Docker Compose configuration that allows you to fully setup an ELK stack within a containerized environment.
  • Select this mode if you are new to security, or you want to continue on with the story. This mode is meant to help you learn while doing.
Hard Mode
  • This mode expects you have some knowledge on parsing log files. The attack path is more complex and you will need to research how to identify the steps within the attack chain.
  • Select this mode if you want to challenge your security skills.

Optional: Elf Stack SIEM

Containerized ELK Stack
  • The containerized SIEM is provided to assist in solving the challenge. The SIEM is fully functional and configured to ingest the provided log files.
  • Note: This was built and tested on an Ubuntu 22.04 Linux virtual machine.
Containerized ELK Stack: Prerequisites
  • Minimum system specs to run the containerized SIEM. The specs below minimize the loss of logs during ingestion. Adjusting the specs down may cause longer delays in log ingestion, loss of logs during ingestion, or slow performance:
    • RAM: Minimum 16GB
    • CPU Cores: Minimum 4
    • Hard drive space: Minimum 30GB / Recommended 40GB
    • A network interface with internet connectivity
  • Follow the instructions on Docker Installation Guide to install Docker on your respective platform.
  • After installation of Docker, download the Elf Stack files from the download page.
  • Unzip/Extract the containerized files into a single directory.
Containerized ELK Stack: Setup
  • NOTE: Setup time depends on internet connectivity and system resources.

  • Browse to the directory containing the container SIEM files and setup the environment. Time to complete ~2-10 minutes:

    docker compose up setup
    
  • Run the ELF Stack SIEM to automatically ingest the logs. Time to complete ~20-30 minutes:

    docker compose up
    
  • The terminal output will display:

    • When logs ingestion is complete.
    • The login URL and credentials.
  • After the login URL and credentials are displayed, the Elf Stack SIEM is ready for use.

  • NOTE: After your Elf Stack SIEM is setup, ensure you set the timeframe to look at events in 2024.

Containerized ELK Stack: Teardown
  • Use the following command to shut down the Elf Stack SIEM:

    docker compose down --volumes
    
  • NOTE: The command requires the –volumes syntax to clear the volume data which may skew your results if you set the stack up again later.

Upon clicking the download button, we’ll get links to three files:

The files starting with “log_chunk_” are zipped log files, and the “elf-stack-siem-with-logs.zip” file contains the Elf Stack SIEM setup, which is optional.

Set up environment

There are multiple ways to go around solving this challenge, we can use the provided Elf Stack SIEM, but we can also use plain bash commands or Python. I chose to go with the latter, but my RAM didn’t like it 😄.

In oder to read the logs with Python, we’ll first have to transform the logs into a more usable format. What the current format looks like can be found in the provided SIEM’s config, namely in the logstash.conf file. There, we find that grok is used, along with the format string.

<%{NONNEGINT:syslog_pri}>%{NONNEGINT:version}%{SPACE}(?:-|%{TIMESTAMP_ISO8601:syslog_timestamp})%{SPACE}(?:-|%{IPORHOST:hostname})%{SPACE}(?:%{SYSLOG5424PRINTASCII:event_source}|-)%{SPACE}(?:-|%{SYSLOG5424PRINTASCII:event_source_id})%{SPACE}(?:-|%{SYSLOG5424PRINTASCII:msgid})%{SPACE}(?:-|(?<structured_data>(\[.*?[^\\]\])+))(?:%{SPACE}%{GREEDYDATA:message_json}|)

There is not support for grok in the standard library, we there is a package out there called py3grok, which allows us to parse the log lines into dictionaries. We can use this in a script to transform both log files into a single big json file.

from py3grok import GrokEnvironment
import json


# Parse log files to JSON
grok_env = GrokEnvironment()
pattern = "<%{NONNEGINT:syslog_pri}>%{NONNEGINT:version}%{SPACE}(?:-|%{TIMESTAMP_ISO8601:syslog_timestamp})%{SPACE}(?:-|%{IPORHOST:hostname})%{SPACE}(?:%{SYSLOG5424PRINTASCII:event_source}|-)%{SPACE}(?:-|%{SYSLOG5424PRINTASCII:event_source_id})%{SPACE}(?:-|%{SYSLOG5424PRINTASCII:msgid})%{SPACE}(?:-|(?<structured_data>(\\[.*?[^\\\\]\\])+))(?:%{SPACE}%{GREEDYDATA:message_json}|)"
grok = grok_env.create(pattern)

with open("logs.json", "w") as out_file:
    out_file.write("[\n")

    for log_filename in ["log_chunk_1.log", "log_chunk_2.log"]:
        with open(log_filename, "r") as f:
            for line in f:
                text = line.strip()
                log = grok.match(text)
                for key, value in json.loads(log["message_json"]).items():
                    log[f"message.{key}"] = value
                del log["message_json"]  # We don't need it anymore, so save some RAM by deleting it
                out_file.write(json.dumps(log))
                out_file.write(",\n")

    out_file.seek(out_file.tell()-2)
    out_file.write("\n]\n")

This will take some time to run, but once finished we find a 4.5 GB large logs.json file.

Now that we have it in a more common format, we can look into loading the file. Because loading it will take a long time (due to the file size), we prefer it to be kept in memory while we make changes to the script. A Jupyter Notebook is the perfect solution for this. It’s like an interactive shell, everything will stay in memory in between changes.

We can use the official Jupyter Notebook setup, but I prefer to use Visual Studio Code (VSCode). It’s easier in use, and requires less setup. In VSCode, we can just create a file ending in .ipynb, and it’ll automatically load it as a notebook.

We can then use the pandas library to load and query the data.

import pandas as pd
df = pd.read_json("logs.json")
df
syslog_priversionsyslog_timestamphostnameevent_sourceevent_source_idmsgidstructured_datamessage.timestampmessage.hostnamemessage.AdditionalInformation_RequestedUPNmessage.UserInformation_UPNmessage.CertificateInformation_CertificateTemplatemessage.AdditionalInformation_CallerComputermessage.CertificateTemplateInformation_CertificateTemplateNamemessage.ModifierInformation_UserNamemessage.ModifierInformation_Computermessage.Details_ModificationTypemessage.Details_NewSecuritySettingsmessage.CallerComputer
013412024-09-15T00:10:01-04:00kringleSSleigHAuthLogNaNNaNNaN2024-09-15T03:10:01.304953-04:00kringleSSleigHNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
113412024-09-15T00:10:01-04:00kringleSSleigHAuthLogNaNNaNNaN2024-09-15T03:10:01.314490-04:00kringleSSleigHNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
213412024-09-15T00:10:01-04:00SleighRider.northpole.localWindowsEventNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
313412024-09-15T00:10:02-04:00SleighRider.northpole.localWindowsEventNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
413412024-09-15T00:10:03-04:00dc01.northpole.localWindowsEventNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
234314113412024-09-16T11:14:12-04:00dc01.northpole.localWindowsEventNaNNaNNaNNaNNaNadministrator@northpole.localNaNNaNNaNNaNNaNNaNNaNNaNNaN
234314213412024-09-16T11:15:12-04:00dc01.northpole.localWindowsEventNaNNaNNaNNaNNaNNaNnutcrakr@northpole.localElfUsers172.24.25.153NaNNaNNaNNaNNaNNaN
234314313412024-09-16T11:15:12-04:00dc01.northpole.localWindowsEventNaNNaNNaNNaNNaNNaNNaNNaNNaNElfUsersnutcrakr10.12.25.24Permissions Update[Details not specified in log]172.24.25.153
234314413412024-09-16T11:33:12-04:00SleighRider.northpole.localWindowsEventNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
234314513412024-09-16T11:33:12-04:00SleighRider.northpole.localWindowsEventNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN

The loading might take a while, for me it took 4m 28.8s and used in excess of 100 GB of RAM/swap.

Silver

With the setup ready, we can start with the challenge. Let’s click Easy Mode and start with the first task.

Question 1

How many unique values are there for the event_source field in all logs?

Starting off easy, we can use panda’s nunique function on the “event_source” field.

df["event_source"].nunique()
5

Answer: 5

Question 2

Which event_source has the fewest number of events related to it?

For question 2, the value_counts function can be used.

df["event_source"].value_counts()
event_sourcecount
WindowsEvent2299324
NetflowPmacct34679
GreenCoat7476
SnowGlowMailPxy1398
AuthLog269

Answer: AuthLog

Question 3

Using the event_source from the previous question as a filter, what is the field name that contains the name of the system the log event originated from?

Next up is finding the column. We can filter on the event source, and then use .T.dropna(how="all").T to strip off all columns that only contain empty values. This way we remove the columns used by other event sources.

df[df["event_source"] == "AuthLog"].T.dropna(how="all").T
syslog_priversionsyslog_timestamphostnameevent_sourcemessage.timestampmessage.hostnamemessage.servicemessage.message
013412024-09-15T00:10:01-04:00kringleSSleigHAuthLog2024-09-15T03:10:01.304953-04:00kringleSSleigHCRON[4863]:pam_unix(cron:session): session opened for use…
113412024-09-15T00:10:01-04:00kringleSSleigHAuthLog2024-09-15T03:10:01.314490-04:00kringleSSleigHCRON[4863]:pam_unix(cron:session): session closed for use…
15713412024-09-15T00:17:01-04:00kringleSSleigHAuthLog2024-09-15T03:17:01.331687-04:00kringleSSleigHCRON[4872]:pam_unix(cron:session): session opened for use…
15813412024-09-15T00:17:01-04:00kringleSSleigHAuthLog2024-09-15T03:17:01.341866-04:00kringleSSleigHCRON[4872]:pam_unix(cron:session): session closed for use…
145713412024-09-15T01:17:01-04:00kringleSSleigHAuthLog2024-09-15T04:17:01.457972-04:00kringleSSleigHCRON[4923]:pam_unix(cron:session): session opened for use…
232813113412024-09-16T11:58:01-04:00kringleSSleigHAuthLog2024-09-16T14:58:01.331792-04:00kringleSSleigHCRON[6769]:pam_unix(cron:session): session closed for use…
234184913412024-09-16T11:59:01-04:00kringleSSleigHAuthLog2024-09-16T14:59:01.339409-04:00kringleSSleigHCRON[6777]:pam_unix(cron:session): session opened for use…
234185013412024-09-16T11:59:01-04:00kringleSSleigHAuthLog2024-09-16T14:59:01.345015-04:00kringleSSleigHCRON[6777]:pam_unix(cron:session): session closed for use…
234188513412024-09-16T12:00:01-04:00kringleSSleigHAuthLog2024-09-16T15:00:01.348709-04:00kringleSSleigHCRON[6780]:pam_unix(cron:session): session opened for use…
234188613412024-09-16T12:00:01-04:00kringleSSleigHAuthLog2024-09-16T15:00:01.353084-04:00kringleSSleigHCRON[6780]:pam_unix(cron:session): session closed for use…

Answer: hostname

Question 4

Which event_source has the second highest number of events related to it?

We can reuse the result from question 2 here.

df["event_source"].value_counts()
event_sourcecount
WindowsEvent2299324
NetflowPmacct34679
GreenCoat7476
SnowGlowMailPxy1398
AuthLog269

Answer: NetflowPmacct

Question 5

Using the event_source from the previous question as a filter, what is the name of the field that defines the destination port of the Netflow logs?

Reusing what we did for question 3, we can run the following query.

df[df["event_source"] == "NetflowPmacct"].T.dropna(how="all").T
syslog_priversionsyslog_timestamphostnameevent_sourcemessage.event_typemessage.ip_srcmessage.ip_dstmessage.port_srcmessage.port_dstmessage.ip_protomessage.timestamp_startmessage.timestamp_endmessage.packetsmessage.bytesmessage.src_hostmessage.dst_host
71816613412024-09-15T10:37:43-04:00kringleconnectNetflowPmacctpurge172.24.25.93172.24.25.2529994.0808.0tcp2024-09-15T10:37:43-04:000000-00-00T00:00:00-00:001.040.0SnowSentry.northpole.local
71816713412024-09-15T10:37:43-04:00kringleconnectNetflowPmacctpurge172.24.25.25172.24.25.93808.029996.0tcp2024-09-15T10:37:43-04:000000-00-00T00:00:00-00:001.071.0SnowSentry.northpole.local
71816813412024-09-15T10:37:43-04:00kringleconnectNetflowPmacctpurge172.24.25.25172.24.25.93808.029998.0tcp2024-09-15T10:37:43-04:000000-00-00T00:00:00-00:001.04731.0SnowSentry.northpole.local
71816913412024-09-15T10:37:43-04:00kringleconnectNetflowPmacctpurge172.24.25.93172.24.25.2529998.0808.0tcp2024-09-15T10:37:43-04:000000-00-00T00:00:00-00:001.040.0SnowSentry.northpole.local
71817013412024-09-15T10:37:43-04:00kringleconnectNetflowPmacctpurge172.24.25.93172.24.25.2529998.0808.0tcp2024-09-15T10:37:43-04:000000-00-00T00:00:00-00:001.0104.0SnowSentry.northpole.local
77566113412024-09-15T10:38:43-04:00kringleconnectNetflowPmacctpurge34.98.72.95172.24.25.25443.052275.0tcp2024-09-15T10:38:43-04:000000-00-00T00:00:00-00:001.040.0
77566213412024-09-15T10:38:43-04:00kringleconnectNetflowPmacctpurge172.24.25.25146.75.81.4452218.0443.0tcp2024-09-15T10:38:43-04:000000-00-00T00:00:00-00:001.041.0
77566313412024-09-15T10:38:43-04:00kringleconnectNetflowPmacctpurge172.24.25.25172.24.25.93808.030109.0tcp2024-09-15T10:38:43-04:000000-00-00T00:00:00-00:001.041.0SnowSentry.northpole.local
77566413412024-09-15T10:38:43-04:00kringleconnectNetflowPmacctpurge172.24.25.93172.24.25.2530109.0808.0tcp2024-09-15T10:38:43-04:000000-00-00T00:00:00-00:001.052.0SnowSentry.northpole.local
77566513412024-09-15T10:38:43-04:00kringleconnectNetflowPmacctpurge172.24.25.20146.75.81.4452218.0443.0tcp2024-09-15T10:38:43-04:000000-00-00T00:00:00-00:001.041.0

We’ll find the remote port in the message.port_dst column.

Answer: port_dst

Question 6

Which event_source is related to email traffic?

We can list the distinct event sources using the unique function.

df["event_source"].unique()
array(['AuthLog', 'WindowsEvent', 'GreenCoat', 'SnowGlowMailPxy',
       'NetflowPmacct'], dtype=object)

Answer: SnowGlowMailPxy

Question 7

Looking at the event source from the last question, what is the name of the field that contains the actual email text?

Once again we can reuse a previous query from question 3 and 5.

df[df["event_source"] == "SnowGlowMailPxy"].T.dropna(how="all").T
syslog_priversionsyslog_timestamphostnameevent_sourcemessage.Frommessage.Tomessage.Subjectmessage.Message-IDmessage.Return-Pathmessage.Bodymessage.Received_Timemessage.ReceivedIP1message.ReceivedIP2
48667613412024-09-15T08:26:14-04:00SecureElfGwySnowGlowMailPxyelf_user00@northpole.localasnowball04@northpole.localWelcome to the North Pole!<532A9346-9F5F-4C29-BD40-CA171DD0E7DE@SecureEl…elf_user00@northpole.localDear asnowball04,\n\nI wanted to inform you th…2024-09-15 08:26:14-04:00172.24.25.25172.24.25.20
48684313412024-09-15T08:26:17-04:00SecureElfGwySnowGlowMailPxyGingerGem@merry.elveself_user10@northpole.localRequest for Competitor Analysis Report<99712D58-D39D-4186-B1E0-BA34B37D3A83@SecureEl…GingerGem@merry.elvesDear elf_user10,\n\nHope this email finds you …2024-09-15 08:26:17-04:00172.24.25.25172.24.25.20
48694613412024-09-15T08:26:19-04:00SecureElfGwySnowGlowMailPxyasnowball_05@northpole.localwcub303@northpole.localTravel Arrangements - Urgent<5A40805A-532B-4AD0-B05B-25091BBEB757@SecureEl…asnowball_05@northpole.localDear wcub303,\n\nI hope this message finds you…2024-09-15 08:26:19-04:00172.24.25.25172.24.25.20
51691513412024-09-15T08:37:41-04:00SecureElfGwySnowGlowMailPxyelf_user02@northpole.localwcub101@northpole.localMeeting Schedules Update<96D21546-EC3F-4BFE-9358-C7CE74705F83@SecureEl…elf_user02@northpole.localDear wcub101,\n\nI hope this email finds you i…2024-09-15 08:37:41-04:00172.24.25.25172.24.25.20
51715013412024-09-15T08:37:45-04:00SecureElfGwySnowGlowMailPxyelf_user07@northpole.localelf_user07@northpole.localEmployee Surveys - Your Valuable Feedback Matt…<F486377B-82EC-47AC-A096-F0D7CDD239D4@SecureEl…elf_user07@northpole.localDear elf_user07,\n\nI hope this email finds yo…2024-09-15 08:37:45-04:00172.24.25.25172.24.25.20
234192713412024-09-16T12:01:09-04:00SecureElfGwySnowGlowMailPxywcub808@northpole.localwcub303@northpole.localNo Subject<12D146C1-B183-465D-B128-573B0B7A0BAF@SecureEl…wcub808@northpole.localwcub808,\n\nI hope this email finds you ready …2024-09-16 12:01:09-04:00172.24.25.25172.24.25.20
234193213412024-09-16T12:01:14-04:00SecureElfGwySnowGlowMailPxyHollyHelper@stocking.chimneyasnowball_05@northpole.localHealth and Safety Updates: Ensuring a Secure W…<EC9C4C52-2381-4EDA-A7C8-193DCA7C7AE9@SecureEl…NorthPolePostmaster@northpole.exchangeDear asnowball_05,\n\nI hope this email finds …2024-09-16 12:01:14-04:00172.24.25.25172.24.25.20
234193313412024-09-16T12:01:19-04:00SecureElfGwySnowGlowMailPxyTinselTwinkle@stocking.chimneyelf_user06@northpole.localEmployee Surveys - Your Valuable Insights Matter!<F7297E75-ED87-441E-AD5E-E069531907E0@SecureEl…NorthPolePostmaster@northpole.exchangeDear elf_user06,\n\nI hope this email finds yo…2024-09-16 12:01:19-04:00172.24.25.25172.24.25.20
234193613412024-09-16T12:01:24-04:00SecureElfGwySnowGlowMailPxyelf_user02@northpole.localelf_user08@northpole.localUrgent: System Outage Updates<75324EA6-777B-4341-BABB-0A0577906233@SecureEl…elf_user02@northpole.localDear elf_user08,\n\nI hope this email finds yo…2024-09-16 12:01:24-04:00172.24.25.25172.24.25.20
234193913412024-09-16T12:01:28-04:00SecureElfGwySnowGlowMailPxyelf_user05@northpole.localelf_user03@northpole.localPerformance Reviews<9EE973CD-029D-4F86-B3B3-D1A9DCCC74BC@SecureEl…elf_user05@northpole.localDear elf_user03,\n\nI hope this email finds yo…2024-09-16 12:01:28-04:00172.24.25.25172.24.25.20

We’ll then see the email contents in message.Body.

Answer: Body

Question 8

Using the ‘GreenCoat’ event_source, what is the only value in the hostname field?

For this one we can combine the filter with the unique function.

df[df["event_source"] == "GreenCoat"]["hostname"].unique()
array(['SecureElfGwy'], dtype=object)

Answer: SecureElfGwy

Question 9

Using the ‘GreenCoat’ event_source, what is the name of the field that contains the site visited by a client in the network?

You know how this works by now.

df[df["event_source"] == "GreenCoat"].T.dropna(how="all").T
syslog_priversionsyslog_timestamphostnameevent_sourcemessage.timestampmessage.ipmessage.user_identifiermessage.methodmessage.urlmessage.http_protocolmessage.status_codemessage.response_sizemessage.protocolmessage.additional_infomessage.host
8487713412024-09-15T05:57:55-04:00SecureElfGwyGreenCoat2024-09-15T05:57:55-04:00172.24.25.93elf_user03CONNECTdisc601.prod.do.dsp.mp.microsoft.com:443HTTP/1.1200.00.0HTTPSoutgoing via 172.24.25.25SnowSentry
8494213412024-09-15T05:57:56-04:00SecureElfGwyGreenCoat2024-09-15T05:57:56-04:00172.24.25.93elf_user03CONNECTkv601.prod.do.dsp.mp.microsoft.com:443HTTP/1.1200.00.0HTTPSoutgoing via 172.24.25.25SnowSentry
8622213412024-09-15T05:58:26-04:00SecureElfGwyGreenCoat2024-09-15T05:58:26-04:00172.24.25.93elf_user03CONNECTdisc601.prod.do.dsp.mp.microsoft.com:443HTTP/1.1200.00.0HTTPSoutgoing via 172.24.25.25SnowSentry
8748513412024-09-15T05:58:52-04:00SecureElfGwyGreenCoat2024-09-15T05:58:52-04:00172.24.25.93elf_user03CONNECTdisc601.prod.do.dsp.mp.microsoft.com:443HTTP/1.1200.00.0HTTPSoutgoing via 172.24.25.25SnowSentry
8782513412024-09-15T05:58:58-04:00SecureElfGwyGreenCoat2024-09-15T05:58:58-04:00172.24.25.93elf_user03CONNECTdisc601.prod.do.dsp.mp.microsoft.com:443HTTP/1.1200.00.0HTTPSoutgoing via 172.24.25.25SnowSentry
190172713412024-09-16T11:36:26-04:00SecureElfGwyGreenCoat2024-09-16T11:36:26-04:00172.24.25.93elf_user03CONNECTaax.amazon-adsystem.com:443HTTP/1.1200.00.0HTTPSoutgoing via 172.24.25.25SnowSentry
190172813412024-09-16T11:36:26-04:00SecureElfGwyGreenCoat2024-09-16T11:36:26-04:00172.24.25.93elf_user03CONNECThbopenbid.pubmatic.com:443HTTP/1.1200.00.0HTTPSoutgoing via 172.24.25.25SnowSentry
190172913412024-09-16T11:36:26-04:00SecureElfGwyGreenCoat2024-09-16T11:36:26-04:00172.24.25.93elf_user03CONNECTbidder.criteo.com:443HTTP/1.1200.00.0HTTPSoutgoing via 172.24.25.25SnowSentry
190173013412024-09-16T11:36:26-04:00SecureElfGwyGreenCoat2024-09-16T11:36:26-04:00172.24.25.93elf_user03CONNECTfastlane.rubiconproject.com:443HTTP/1.1200.00.0HTTPSoutgoing via 172.24.25.25SnowSentry
190173113412024-09-16T11:36:26-04:00SecureElfGwyGreenCoat2024-09-16T11:36:26-04:00172.24.25.91elf_user01CONNECTx.bidswitch.net:443HTTP/1.1200.00.0HTTPSoutgoing via 172.24.25.25VirtualStation

We then find the sites in the message.url column.

Answer: url

Question 10

Using the ‘GreenCoat’ event_source, which unique URL and port (URL:port) did clients in the TinselStream network visit most?

This one should also be pretty clear from the previous ones.

df[df["event_source"] == "GreenCoat"]["message.url"].value_counts()
message.urlcount
pagead2.googlesyndication.com:443150
ib.adnxs.com:443105
securepubads.g.doubleclick.net:44398
cdn.cookielaw.org:44382
cm.g.doubleclick.net:44380
eq97f.publishers.tremorhub.com:4431
featuregates.org:4431
batch.cootlogix.com:4431
delivery-cdn-cf.adswizz.com:4431
adswizz-match.dotomi.com:4431

Answer: pagead2.googlesyndication.com:443

Question 11

Using the ‘WindowsEvent’ event_source, how many unique Channels is the SIEM receiving Windows event logs from?

To count the amount of unique values, we can use nunique again.

df[df["event_source"] == "WindowsEvent"]["message.Channel"].nunique()
5

Answer: 5

Question 12

What is the name of the event.Channel (or Channel) with the second highest number of events?

One last value count for good pratice.

df[df["event_source"] == "WindowsEvent"]["message.Channel"].value_counts()
message.Channelcount
Security2268402
Microsoft-Windows-Sysmon/Operational17713
Microsoft-Windows-PowerShell/Operational11751
System191
Windows PowerShell50

Answer: Microsoft-Windows-Sysmon/Operational

Question 13

Our environment is using Sysmon to track many different events on Windows systems. What is the Sysmon Event ID related to loading of a driver?

For this one we’ll have to look online. A good place is Microsoft’s documentation, were find that Event ID 6 is used for the driver loaded events.

Answer: 6

Question 14

What is the Windows event ID that is recorded when a new service is installed on a system?

Microsoft’s documentation will help us once again here. Although the documentation can be hard to find, it often does exist.

Answer: 4697

Question 15

Using the WindowsEvent event_source as your initial filter, how many user accounts were created?

Before we can query the logs, we need to know how to look for account creation events. We can once again look at Microsoft’s documentation, and find that Event ID 4720 is used for that.

len(
    df[
        (df["event_source"] == "WindowsEvent")
        & (df["message.EventID"] == 4720)
    ]
)
0

Looks like no new user accounts were created

Answer: 0

Gold

Not that the practice round is done, we’re ready for Hard Mode.

Continued story line

Let’s first talk to the elf again.

Fantastic job! You worked through the logs using the ELK stack like a pro—efficient, quick, and spot-on. Maybe, just maybe, this will turn Santa’s frown upside down!

Up for the real challenge? Take a deep dive into those logs and query your way through the chaos. It might be tricky, but I know your adaptable skills will crack it!

Bravo! You pieced it all together, uncovering the attack path. Santa’s gonna be grateful for your quick thinking and tech savvyness. The North Pole owes you big time!

Question 1

What is the event.EventID number for Sysmon event logs relating to process creation?

Gold starts off where silver stopped, and we’ll have to find an Event ID again. Just like the previous times, we can find the Event ID in Microsoft’s documentation.

Answer: 1

Question 2

How many unique values are there for the ’event_source’ field in all of the logs?

We should know how to use nunique by now.

df["event_source"].nunique()
5

Answer: 5

Question 3

What is the event_source name that contains the email logs?

A quick listing of all event sources will show us the email logs source.

df["event_source"].unique()
array(['AuthLog', 'WindowsEvent', 'GreenCoat', 'SnowGlowMailPxy',
       'NetflowPmacct'], dtype=object)

Answer: SnowGlowMailPxy

Question 4

The North Pole network was compromised recently through a sophisticated phishing attack sent to one of our elves. The attacker found a way to bypass the middleware that prevented phishing emails from getting to North Pole elves. As a result, one of the Received IPs will likely be different from what most email logs contain. Find the email log in question and submit the value in the event ‘From:’ field for this email log event.

Okay, now we’ll have to combine a few things. First, let’s take a look at what the email logs look like.

email_df = df[df["event_source"] == "SnowGlowMailPxy"].T.dropna(how="all").T
email_df
syslog_priversionsyslog_timestamphostnameevent_sourcemessage.Frommessage.Tomessage.Subjectmessage.Message-IDmessage.Return-Pathmessage.Bodymessage.Received_Timemessage.ReceivedIP1message.ReceivedIP2
48667613412024-09-15T08:26:14-04:00SecureElfGwySnowGlowMailPxyelf_user00@northpole.localasnowball04@northpole.localWelcome to the North Pole!<532A9346-9F5F-4C29-BD40-CA171DD0E7DE@SecureEl…elf_user00@northpole.localDear asnowball04,\n\nI wanted to inform you th…2024-09-15 08:26:14-04:00172.24.25.25172.24.25.20
48684313412024-09-15T08:26:17-04:00SecureElfGwySnowGlowMailPxyGingerGem@merry.elveself_user10@northpole.localRequest for Competitor Analysis Report<99712D58-D39D-4186-B1E0-BA34B37D3A83@SecureEl…GingerGem@merry.elvesDear elf_user10,\n\nHope this email finds you …2024-09-15 08:26:17-04:00172.24.25.25172.24.25.20
48694613412024-09-15T08:26:19-04:00SecureElfGwySnowGlowMailPxyasnowball_05@northpole.localwcub303@northpole.localTravel Arrangements - Urgent<5A40805A-532B-4AD0-B05B-25091BBEB757@SecureEl…asnowball_05@northpole.localDear wcub303,\n\nI hope this message finds you…2024-09-15 08:26:19-04:00172.24.25.25172.24.25.20
51691513412024-09-15T08:37:41-04:00SecureElfGwySnowGlowMailPxyelf_user02@northpole.localwcub101@northpole.localMeeting Schedules Update<96D21546-EC3F-4BFE-9358-C7CE74705F83@SecureEl…elf_user02@northpole.localDear wcub101,\n\nI hope this email finds you i…2024-09-15 08:37:41-04:00172.24.25.25172.24.25.20
51715013412024-09-15T08:37:45-04:00SecureElfGwySnowGlowMailPxyelf_user07@northpole.localelf_user07@northpole.localEmployee Surveys - Your Valuable Feedback Matt…<F486377B-82EC-47AC-A096-F0D7CDD239D4@SecureEl…elf_user07@northpole.localDear elf_user07,\n\nI hope this email finds yo…2024-09-15 08:37:45-04:00172.24.25.25172.24.25.20
234192713412024-09-16T12:01:09-04:00SecureElfGwySnowGlowMailPxywcub808@northpole.localwcub303@northpole.localNo Subject<12D146C1-B183-465D-B128-573B0B7A0BAF@SecureEl…wcub808@northpole.localwcub808,\n\nI hope this email finds you ready …2024-09-16 12:01:09-04:00172.24.25.25172.24.25.20
234193213412024-09-16T12:01:14-04:00SecureElfGwySnowGlowMailPxyHollyHelper@stocking.chimneyasnowball_05@northpole.localHealth and Safety Updates: Ensuring a Secure W…<EC9C4C52-2381-4EDA-A7C8-193DCA7C7AE9@SecureEl…NorthPolePostmaster@northpole.exchangeDear asnowball_05,\n\nI hope this email finds …2024-09-16 12:01:14-04:00172.24.25.25172.24.25.20
234193313412024-09-16T12:01:19-04:00SecureElfGwySnowGlowMailPxyTinselTwinkle@stocking.chimneyelf_user06@northpole.localEmployee Surveys - Your Valuable Insights Matter!<F7297E75-ED87-441E-AD5E-E069531907E0@SecureEl…NorthPolePostmaster@northpole.exchangeDear elf_user06,\n\nI hope this email finds yo…2024-09-16 12:01:19-04:00172.24.25.25172.24.25.20
234193613412024-09-16T12:01:24-04:00SecureElfGwySnowGlowMailPxyelf_user02@northpole.localelf_user08@northpole.localUrgent: System Outage Updates<75324EA6-777B-4341-BABB-0A0577906233@SecureEl…elf_user02@northpole.localDear elf_user08,\n\nI hope this email finds yo…2024-09-16 12:01:24-04:00172.24.25.25172.24.25.20
234193913412024-09-16T12:01:28-04:00SecureElfGwySnowGlowMailPxyelf_user05@northpole.localelf_user03@northpole.localPerformance Reviews<9EE973CD-029D-4F86-B3B3-D1A9DCCC74BC@SecureEl…elf_user05@northpole.localDear elf_user03,\n\nI hope this email finds yo…2024-09-16 12:01:28-04:00172.24.25.25172.24.25.20

The question asks us to look at the Received IPs, and we found two columns for that; ReceivedIP1 and ReceivedIP2. Let’s get their value counts.

email_df["message.ReceivedIP1"].value_counts()
message.ReceivedIP1count
172.24.25.251398
email_df["message.ReceivedIP2"].value_counts()
message.ReceivedIP2count
172.24.25.201397
34.30.110.621

The IP 34.30.110.62 shows up only once, so let’s get more information about that email.

email_df[email_df["message.ReceivedIP2"] == "34.30.110.62"]
syslog_priversionsyslog_timestamphostnameevent_sourcemessage.Frommessage.Tomessage.Subjectmessage.Message-IDmessage.Return-Pathmessage.Bodymessage.Received_Timemessage.ReceivedIP1message.ReceivedIP2
67930613412024-09-15T10:36:09-04:00SecureElfGwySnowGlowMailPxykriskring1e@northpole.localelf_user02@northpole.localURGENT!<F3483D7F-3DBF-4A92-813D-4D9738479E50@SecureEl…fr0sen@hollyhaven.snowflakeWe need to store the updated naughty and nice …2024-09-15 10:36:09-04:00172.24.25.2534.30.110.62

We can find the answer in the message.From column.

Answer: kriskring1e@northpole.local

Question 5

Our ElfSOC analysts need your help identifying the hostname of the domain computer that established a connection to the attacker after receiving the phishing email from the previous question. You can take a look at our GreenCoat proxy logs as an event source. Since it is a domain computer, we only need the hostname, not the fully qualified domain name (FQDN) of the system.

Let’s start again by looking at what the GreenCoat data source looks like.

greencoat_df = df[df["event_source"] == "GreenCoat"].T.dropna(how="all").T
greencoat_df
syslog_priversionsyslog_timestamphostnameevent_sourcemessage.timestampmessage.ipmessage.user_identifiermessage.methodmessage.urlmessage.http_protocolmessage.status_codemessage.response_sizemessage.protocolmessage.additional_infomessage.host
8487713412024-09-15T05:57:55-04:00SecureElfGwyGreenCoat2024-09-15T05:57:55-04:00172.24.25.93elf_user03CONNECTdisc601.prod.do.dsp.mp.microsoft.com:443HTTP/1.1200.00.0HTTPSoutgoing via 172.24.25.25SnowSentry
8494213412024-09-15T05:57:56-04:00SecureElfGwyGreenCoat2024-09-15T05:57:56-04:00172.24.25.93elf_user03CONNECTkv601.prod.do.dsp.mp.microsoft.com:443HTTP/1.1200.00.0HTTPSoutgoing via 172.24.25.25SnowSentry
8622213412024-09-15T05:58:26-04:00SecureElfGwyGreenCoat2024-09-15T05:58:26-04:00172.24.25.93elf_user03CONNECTdisc601.prod.do.dsp.mp.microsoft.com:443HTTP/1.1200.00.0HTTPSoutgoing via 172.24.25.25SnowSentry
8748513412024-09-15T05:58:52-04:00SecureElfGwyGreenCoat2024-09-15T05:58:52-04:00172.24.25.93elf_user03CONNECTdisc601.prod.do.dsp.mp.microsoft.com:443HTTP/1.1200.00.0HTTPSoutgoing via 172.24.25.25SnowSentry
8782513412024-09-15T05:58:58-04:00SecureElfGwyGreenCoat2024-09-15T05:58:58-04:00172.24.25.93elf_user03CONNECTdisc601.prod.do.dsp.mp.microsoft.com:443HTTP/1.1200.00.0HTTPSoutgoing via 172.24.25.25SnowSentry
190172713412024-09-16T11:36:26-04:00SecureElfGwyGreenCoat2024-09-16T11:36:26-04:00172.24.25.93elf_user03CONNECTaax.amazon-adsystem.com:443HTTP/1.1200.00.0HTTPSoutgoing via 172.24.25.25SnowSentry
190172813412024-09-16T11:36:26-04:00SecureElfGwyGreenCoat2024-09-16T11:36:26-04:00172.24.25.93elf_user03CONNECThbopenbid.pubmatic.com:443HTTP/1.1200.00.0HTTPSoutgoing via 172.24.25.25SnowSentry
190172913412024-09-16T11:36:26-04:00SecureElfGwyGreenCoat2024-09-16T11:36:26-04:00172.24.25.93elf_user03CONNECTbidder.criteo.com:443HTTP/1.1200.00.0HTTPSoutgoing via 172.24.25.25SnowSentry
190173013412024-09-16T11:36:26-04:00SecureElfGwyGreenCoat2024-09-16T11:36:26-04:00172.24.25.93elf_user03CONNECTfastlane.rubiconproject.com:443HTTP/1.1200.00.0HTTPSoutgoing via 172.24.25.25SnowSentry
190173113412024-09-16T11:36:26-04:00SecureElfGwyGreenCoat2024-09-16T11:36:26-04:00172.24.25.91elf_user01CONNECTx.bidswitch.net:443HTTP/1.1200.00.0HTTPSoutgoing via 172.24.25.25VirtualStation

Okay, we have the message.url column here, but we don’t have a url to search for. Maybe we can find it in the content of the phishing email.

phishing_email = email_df[email_df["message.ReceivedIP2"] == "34.30.110.62"].iloc[0]
phishing_email["message.Body"]
"We need to store the updated naughty and nice list somewhere secure. I posted it here http://hollyhaven.snowflake/howtosavexmas.zip. Act quickly so I can remove the link from the internet! I encrypted it with the password: n&nli$t_finAl1\n\nthx!\nkris\n- Sent from the sleigh. Please excuse any Ho Ho Ho's."

Alright, there is a url there, so let’s search for it in the GreenCoat logs.

greencoat_df[greencoat_df["message.url"] == "http://hollyhaven.snowflake/howtosavexmas.zip"]
syslog_priversionsyslog_timestamphostnameevent_sourcemessage.timestampmessage.ipmessage.user_identifiermessage.methodmessage.urlmessage.http_protocolmessage.status_codemessage.response_sizemessage.protocolmessage.additional_infomessage.host
68836713412024-09-15T10:36:26-04:00SecureElfGwyGreenCoat2024-09-15T10:36:26-04:00172.24.25.12elf_user02GEThttp://hollyhaven.snowflake/howtosavexmas.zipHTTP/1.1200.01098.0HTTPoutgoing via 172.24.25.25SleighRider

Yes, we found it. The hostname is all the way at the end in the message.host column.

Answer: SleighRider

Question 6

What was the IP address of the system you found in the previous question?

We already found the answer for this one in the previous question. But let’s also save the event to a variable; we might need it later.

download_event = greencoat_df[greencoat_df["message.url"] == "http://hollyhaven.snowflake/howtosavexmas.zip"].iloc[0]
download_event["message.ip"]

Answer: 172.24.25.12

Question 7

A process was launched when the user executed the program AFTER they downloaded it. What was that Process ID number (digits only please)?

Let’s start again by looking at the WindowsEvent logs.

events_df = df[df["event_source"] == "WindowsEvent"].T.dropna(how="all").T
events_df
syslog_priversionsyslog_timestamphostnameevent_sourcemessage.Provider_Namemessage.Provider_Guidmessage.EventIDmessage.Versionmessage.Levelmessage.AdditionalInformation_RequestedUPNmessage.UserInformation_UPNmessage.CertificateInformation_CertificateTemplatemessage.AdditionalInformation_CallerComputermessage.CertificateTemplateInformation_CertificateTemplateNamemessage.ModifierInformation_UserNamemessage.ModifierInformation_Computermessage.Details_ModificationTypemessage.Details_NewSecuritySettingsmessage.CallerComputer
213412024-09-15T00:10:01-04:00SleighRider.northpole.localWindowsEventMicrosoft-Windows-PowerShell{a0c1853b-5c40-4b15-8766-3cf1c58f985a}40962.01.04NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
313412024-09-15T00:10:02-04:00SleighRider.northpole.localWindowsEventMicrosoft-Windows-PowerShell{a0c1853b-5c40-4b15-8766-3cf1c58f985a}32784.01.02NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
413412024-09-15T00:10:03-04:00dc01.northpole.localWindowsEventMicrosoft-Windows-PowerShell{a0c1853b-5c40-4b15-8766-3cf1c58f985a}8195.01.05NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
513412024-09-15T00:10:04-04:00SnowSentry.northpole.localWindowsEventNaNNaN4663.01.0NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
613412024-09-15T00:10:11-04:00dc01.northpole.localWindowsEventNaNNaN4663.01.0NaNNaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
234314113412024-09-16T11:14:12-04:00dc01.northpole.localWindowsEventNaNNaN4888.0NaNInformationadministrator@northpole.localNaNNaNNaNNaNNaNNaNNaNNaNNaN
234314213412024-09-16T11:15:12-04:00dc01.northpole.localWindowsEventNaNNaN4886.0NaNInformationNaNnutcrakr@northpole.localElfUsers172.24.25.153NaNNaNNaNNaNNaNNaN
234314313412024-09-16T11:15:12-04:00dc01.northpole.localWindowsEventNaNNaN4864.0NaNInformationNaNNaNNaNNaNElfUsersnutcrakr10.12.25.24Permissions Update[Details not specified in log]172.24.25.153
234314413412024-09-16T11:33:12-04:00SleighRider.northpole.localWindowsEventMicrosoft-Windows-PowerShell{a0c1853b-5c40-4b15-8766-3cf1c58f985a}4103.01.04NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN
234314513412024-09-16T11:33:12-04:00SleighRider.northpole.localWindowsEventMicrosoft-Windows-PowerShell{a0c1853b-5c40-4b15-8766-3cf1c58f985a}4104.01.05NaNNaNNaNNaNNaNNaNNaNNaNNaNNaN

It looks like the hostname column requerest the FQDN, but, luckily, SleighRider is already right there, and we don’t have to look it up. We can use this together with the timestamp of when the user clicked the link to find the processes. There are way to many columns to look at, so let’s also narrow those down to the ones we need.

events_df[
    (events_df["hostname"] == "SleighRider.northpole.local")
    & (events_df["syslog_timestamp"] > download_event["syslog_timestamp"])
    & (events_df["message.EventID"] == 1)
][["syslog_timestamp", "message.User", "message.Image", "message.CommandLine"]]
syslog_timestampmessage.Usermessage.Imagemessage.CommandLine
6952682024-09-15T10:36:36-04:00NORTHPOLE\elf_user02C:\Program Files\Google\Chrome\Application\chr…“C:\Program Files\Google\Chrome\Application\ch…
7037312024-09-15T10:37:02-04:00NORTHPOLE\elf_user02C:\Windows\SysWOW64\dllhost.exe“C:\Windows\SysWOW64\DllHost.exe” /Processid:{…
7095662024-09-15T10:37:13-04:00NORTHPOLE\elf_user02C:\Windows\SysWOW64\dllhost.exe“C:\Windows\SysWOW64\DllHost.exe” /Processid:{…
7125332024-09-15T10:37:20-04:00NT AUTHORITY\SYSTEMC:\Windows\System32\consent.execonsent.exe 8524 558 000001B2CD232F70
7244982024-09-15T10:37:50-04:00NORTHPOLE\elf_user02C:\Users\elf_user02\Downloads\howtosavexmas\ho…“C:\Users\elf_user02\Downloads\howtosavexmas\h…
7539022024-09-15T10:38:22-04:00NT AUTHORITY\SYSTEMC:\Windows\System32\cmd.execmd.exe /c echo ddpvccdbr &gt; \.\pipe\ddpvccdbr
7673292024-09-15T10:38:34-04:00NORTHPOLE\elf_user02C:\Windows\System32\WindowsPowerShell\v1.0\pow…powershell.exe
8430612024-09-15T10:42:00-04:00NT AUTHORITY\SYSTEMC:\Windows\System32\svchost.exeC:\Windows\system32\svchost.exe -k netsvcs -s …
8430622024-09-15T10:42:00-04:00NT AUTHORITY\SYSTEMC:\Windows\servicing\TrustedInstaller.exeC:\Windows\servicing\TrustedInstaller.exe
8430632024-09-15T10:42:00-04:00NT AUTHORITY\SYSTEMC:\Windows\WinSxS\amd64_microsoft-windows-serv…C:\Windows\winsxs\amd64_microsoft-windows-serv…
8528242024-09-15T10:42:37-04:00NT AUTHORITY\SYSTEMC:\Windows\System32 askhostw.exetaskhostw.exe -RegisterDevice -ProtectionState…
8528252024-09-15T10:42:37-04:00NORTHPOLE\elf_user02C:\Windows\System32\smartscreen.exeC:\Windows\System32\smartscreen.exe -Embedding
8675552024-09-15T10:43:33-04:00NT AUTHORITY\SYSTEMC:\Program Files (x86)\Google\Update\GoogleUpd…“C:\Program Files (x86)\Google\Update\GoogleUp…
8788012024-09-15T10:44:09-04:00NT AUTHORITY\SYSTEMC:\Windows\System32\WindowsPowerShell\v1.0\pow…powershell.exe
8797902024-09-15T10:44:15-04:00NT AUTHORITY\SYSTEMC:\Windows\System32\ipconfig.exe“C:\Windows\system32\ipconfig.exe”
8852802024-09-15T10:44:33-04:00NT AUTHORITY\NETWORK SERVICEC:\Windows\System32\gpupdate.exe“gpupdate.exe” /target:computer
9112842024-09-15T10:45:37-04:00NT AUTHORITY\SYSTEMC:\Windows\System32\MoUsoCoreWorker.exeC:\Windows\System32\mousocoreworker.exe -Embed…
9112852024-09-15T10:45:37-04:00NT AUTHORITY\SYSTEMC:\Windows\servicing\TrustedInstaller.exeC:\Windows\servicing\TrustedInstaller.exe
9112862024-09-15T10:45:37-04:00NT AUTHORITY\SYSTEMC:\Windows\WinSxS\amd64_microsoft-windows-serv…C:\Windows\winsxs\amd64_microsoft-windows-serv…
9296612024-09-15T10:46:27-04:00NORTHPOLE\elf_user02C:\Program Files (x86)\Microsoft\Edge\Applicat…“C:\Program Files (x86)\Microsoft\Edge\Applica…
9313752024-09-15T10:46:33-04:00NORTHPOLE\elf_user02C:\Program Files (x86)\Microsoft\Edge\Applicat…“C:\Program Files (x86)\Microsoft\Edge\Applica…
9925512024-09-15T10:49:40-04:00NT AUTHORITY\SYSTEMC:\Program Files (x86)\Microsoft\EdgeUpdate\Mi…“C:\Program Files (x86)\Microsoft\EdgeUpdate\M…
9966152024-09-15T10:50:02-04:00NT AUTHORITY\NETWORK SERVICEC:\Windows\System32\gpupdate.exe“gpupdate.exe” /target:user
9966162024-09-15T10:50:02-04:00NT AUTHORITY\SYSTEMC:\Windows\System32\svchost.exeC:\Windows\system32\svchost.exe -k netsvcs -p …
11841952024-09-16T11:00:21-04:00NT AUTHORITY\SYSTEMC:\Windows\System32\svchost.exeC:\Windows\system32\svchost.exe -k netsvcs -p …
12618042024-09-16T11:04:24-04:00NORTHPOLE\elf_user02C:\Program Files (x86)\Microsoft\Edge\Applicat…“C:\Program Files (x86)\Microsoft\Edge\Applica…
14743832024-09-16T11:15:21-04:00NT AUTHORITY\SYSTEMC:\Windows\System32\svchost.exeC:\Windows\system32\svchost.exe -k netsvcs -p …
16993852024-09-16T11:27:22-04:00NT AUTHORITY\SYSTEMC:\Windows\ZiyfDiiO.exeC:\Windows\ZiyfDiiO.exe
16993942024-09-16T11:27:22-04:00NT AUTHORITY\SYSTEMC:\Windows\SysWOW64\WindowsPowerShell\v1.0\pow…powershell.exe
17035292024-09-16T11:27:36-04:00NT AUTHORITY\SYSTEMC:\Windows\SysWOW64\whoami.exe“C:\Windows\system32\whoami.exe”
17156822024-09-16T11:28:16-04:00NT AUTHORITY\SYSTEMC:\Windows\YdTRctss.exeC:\Windows\YdTRctss.exe
17156902024-09-16T11:28:16-04:00NT AUTHORITY\SYSTEMC:\Windows\SysWOW64\WindowsPowerShell\v1.0\pow…powershell.exe
17552142024-09-16T11:30:21-04:00NT AUTHORITY\SYSTEMC:\Windows\System32\svchost.exeC:\Windows\system32\svchost.exe -k netsvcs -p …
20725332024-09-16T11:43:32-04:00NT AUTHORITY\SYSTEMC:\Program Files (x86)\Google\Update\GoogleUpd…“C:\Program Files (x86)\Google\Update\GoogleUp…
21032862024-09-16T11:45:21-04:00NT AUTHORITY\SYSTEMC:\Windows\System32\svchost.exeC:\Windows\system32\svchost.exe -k netsvcs -p …
21064332024-09-16T11:45:38-04:00NT AUTHORITY\SYSTEMC:\Windows\System32\MoUsoCoreWorker.exeC:\Windows\System32\mousocoreworker.exe -Embed…
21795242024-09-16T11:49:40-04:00NT AUTHORITY\SYSTEMC:\Program Files (x86)\Microsoft\EdgeUpdate\Mi…“C:\Program Files (x86)\Microsoft\EdgeUpdate\M…

Event 724498 looks interesting here because it contains “howtosavexmas”, let’s take a closer look.

events_df.loc[724498].dropna()
PropertyValue
syslog_pri134
version1
syslog_timestamp2024-09-15T10:37:50-04:00
hostnameSleighRider.northpole.local
event_sourceWindowsEvent
message.EventID1.0
message.Version5.0
message.Task1.0
message.OpcodeInfo
message.Keywords-9223372036854775808
message.ThreadID6340.0
message.ChannelMicrosoft-Windows-Sysmon/Operational
message.EventTime2024-09-15 10:37:50
message.HostnameSleighRider.northpole.local
message.EventTypeINFO
message.SeverityValue2.0
message.SeverityINFO
message.SourceNameMicrosoft-Windows-Sysmon
message.ProviderGuid{5770385F-C22A-43E0-BF4C-06F5698FFBD9}
message.OpcodeValue0.0
message.RecordNumber723.0
message.ProcessID10014.0
message.DomainNT AUTHORITY
message.AccountNameSYSTEM
message.UserIDS-1-5-18
message.AccountTypeUser
message.CategoryProcess Create (rule: ProcessCreate)
message.UtcTime2024-09-15T10:37:50-04:00
message.ProcessGuid{face0b26-426e-660c-eb0f-000000000700}
message.EventReceivedTime2024-09-15T10:37:50-04:00
message.SourceModuleNameinSysmon
message.SourceModuleTypeim_msvistalog
message.RuleName-
message.ImageC:\Users\elf_user02\Downloads\howtosavexmas\ho…
message.FileVersion-
message.Description-
message.Product-
message.Company-
message.OriginalFileName-
message.CommandLine“C:\Users\elf_user02\Downloads\howtosavexmas\h…
message.CurrentDirectoryC:\Users\elf_user02\Downloads\howtosavexmas\
message.UserNORTHPOLE\elf_user02
message.LogonGuid{face0b26-426d-660c-650f-7d0500000000}
message.LogonId0x57d0f65
message.TerminalSessionId1.0
message.IntegrityLevelHigh
message.HashesMD5=790F0E0E9DBF7E9771FF9F0F7DE9804C,SHA256=79…
message.ParentProcessGuid{face0b26-e149-6606-9300-000000000700}
message.ParentProcessId5680.0
message.ParentImageC:\Windows\explorer.exe
message.ParentCommandLineC:\Windows\Explorer.EXE
message.ParentUserNORTHPOLE\elf_user02
message.ProcessId8096.0
message.MoreDetailsProcess Create:

Here, we find two process ids, ProcessID and ProcessId, we need the first one.

Answer: 10014

Question 8

Did the attacker’s payload make an outbound network connection? Our ElfSOC analysts need your help identifying the destination TCP port of this connection.

There is also and event id for network communications. I don’t think you saw this coming, but it’s written in Microsoft’s documentation. We can filter on both it and the process id to find the network communications of the process.

events_df[
    (events_df["hostname"] == "SleighRider.northpole.local")
    & (events_df["message.ProcessID"] == 10014)
    & (process_events_df["message.EventID"] == 3)
].T.dropna(how="all").T
syslog_priversionsyslog_timestamphostnameevent_sourcemessage.EventIDmessage.Versionmessage.Taskmessage.Opcodemessage.Keywordsmessage.Initiatedmessage.SourceIsIpv6message.SourceIpmessage.SourceHostnamemessage.SourcePortNamemessage.DestinationIsIpv6message.DestinationIpmessage.DestinationHostnamemessage.DestinationPortmessage.DestinationPortName
13210313412024-09-15T06:15:55-04:00SleighRider.northpole.localWindowsEvent3.05.03.0Info-92233720368547758081.00.0172.24.25.12SleighRider.northpole.local-0.0172.24.25.25SECUREELFGWY808.0-
15437613412024-09-15T06:24:32-04:00SleighRider.northpole.localWindowsEvent3.05.03.0Info-92233720368547758081.00.0172.24.25.12SleighRider.northpole.local-0.0172.24.25.25SECUREELFGWY808.0-
15460413412024-09-15T06:24:38-04:00SleighRider.northpole.localWindowsEvent3.05.03.0Info-92233720368547758081.00.0172.24.25.12SleighRider.northpole.local-0.0172.24.25.25SECUREELFGWY808.0-
15460513412024-09-15T06:24:38-04:00SleighRider.northpole.localWindowsEvent3.05.03.0Info-92233720368547758081.00.0172.24.25.12SleighRider.northpole.local-0.0172.24.25.25SECUREELFGWY808.0-
15472713412024-09-15T06:24:39-04:00SleighRider.northpole.localWindowsEvent3.05.03.0Info-92233720368547758081.00.0172.24.25.12SleighRider.northpole.local-0.0172.24.25.25SECUREELFGWY808.0-
29002813412024-09-15T07:16:29-04:00SleighRider.northpole.localWindowsEvent3.05.03.0Info-92233720368547758081.00.0172.24.25.12SleighRider.northpole.local-0.0172.24.25.25SECUREELFGWY808.0-
48592313412024-09-15T08:26:02-04:00SleighRider.northpole.localWindowsEvent3.05.03.0Info-92233720368547758081.00.0172.24.25.12SleighRider.northpole.local-0.0172.24.25.25SECUREELFGWY143.0imap
48592513412024-09-15T08:26:02-04:00SleighRider.northpole.localWindowsEvent3.05.03.0Info-92233720368547758081.00.0172.24.25.12SleighRider.northpole.local-0.0172.24.25.25SECUREELFGWY143.0imap
48592813412024-09-15T08:26:02-04:00SleighRider.northpole.localWindowsEvent3.05.03.0Info-92233720368547758081.00.0172.24.25.12SleighRider.northpole.local-0.0172.24.25.25SECUREELFGWY143.0imap
50730813412024-09-15T08:34:01-04:00SleighRider.northpole.localWindowsEvent3.05.03.0Info-92233720368547758081.00.0172.24.25.12SleighRider.northpole.local-0.0172.24.25.25SECUREELFGWY143.0imap
50730913412024-09-15T08:34:01-04:00SleighRider.northpole.localWindowsEvent3.05.03.0Info-92233720368547758081.00.0172.24.25.12SleighRider.northpole.local-0.0172.24.25.25SECUREELFGWY143.0imap
50731013412024-09-15T08:34:01-04:00SleighRider.northpole.localWindowsEvent3.05.03.0Info-92233720368547758081.00.0172.24.25.12SleighRider.northpole.local-0.0172.24.25.25SECUREELFGWY143.0imap
72518413412024-09-15T10:37:51-04:00SleighRider.northpole.localWindowsEvent3.05.03.0Info-92233720368547758081.00.0172.24.25.12SleighRider.northpole.local-0.0103.12.187.4319.148.239.35.bc.googleusercontent.com8443.0-
171060613412024-09-16T11:28:02-04:00SleighRider.northpole.localWindowsEvent3.05.03.0Info-92233720368547758081.00.0172.24.25.12SleighRider.northpole.local-0.0172.24.25.153DC01389.0ldap
171060713412024-09-16T11:28:02-04:00SleighRider.northpole.localWindowsEvent3.05.03.0Info-92233720368547758081.00.0172.24.25.12SleighRider.northpole.local-0.0172.24.25.153DC01389.0ldap
171060813412024-09-16T11:28:02-04:00SleighRider.northpole.localWindowsEvent3.05.03.0Info-92233720368547758081.00.0172.24.25.12SleighRider.northpole.local-0.0172.24.25.153DC01389.0ldap
171081513412024-09-16T11:28:03-04:00SleighRider.northpole.localWindowsEvent3.05.03.0Info-92233720368547758081.00.0172.24.25.12SleighRider.northpole.local-0.0172.24.25.153DC01389.0ldap
172524213412024-09-16T11:28:45-04:00SleighRider.northpole.localWindowsEvent3.05.03.0Info-92233720368547758081.00.0172.24.25.12SleighRider.northpole.local-0.0172.24.25.153DC01389.0ldap
172632813412024-09-16T11:28:47-04:00SleighRider.northpole.localWindowsEvent3.05.03.0Info-92233720368547758081.00.0172.24.25.12SleighRider.northpole.local-0.0172.24.25.153DC01389.0ldap
172648813412024-09-16T11:28:48-04:00SleighRider.northpole.localWindowsEvent3.05.03.0Info-92233720368547758081.00.0172.24.25.12SleighRider.northpole.local-0.0172.24.25.153DC01389.0ldap
172659813412024-09-16T11:28:49-04:00SleighRider.northpole.localWindowsEvent3.05.03.0Info-92233720368547758081.00.0172.24.25.12SleighRider.northpole.local-0.0172.24.25.153DC01389.0ldap
172672613412024-09-16T11:28:50-04:00SleighRider.northpole.localWindowsEvent3.05.03.0Info-92233720368547758081.00.0172.24.25.12SleighRider.northpole.local-0.0172.24.25.153DC01389.0ldap
175457613412024-09-16T11:30:20-04:00SleighRider.northpole.localWindowsEvent3.05.03.0Info-92233720368547758081.00.0172.24.25.12SleighRider.northpole.local-0.0172.24.25.153DC01389.0ldap
182002413412024-09-16T11:33:03-04:00SleighRider.northpole.localWindowsEvent3.05.03.0Info-92233720368547758081.00.0172.24.25.12SleighRider.northpole.local-0.0172.24.25.153DC01389.0ldap

One connection jumps out here; 19.148.239.35.bc.googleusercontent.com. It’s different from the rest, and it’s port is 8443.

Answer: 8443

Question 9

The attacker escalated their privileges to the SYSTEM account by creating an inter-process communication (IPC) channel. Submit the alpha-numeric name for the IPC channel used by the attacker.

There is an Event ID for IPC pipes, but if we filter on it, won’t find anything. Instead, we should look at new processes that are created with the system user.

events_df[
    (events_df["hostname"] == "SleighRider.northpole.local")
    & (events_df["message.ProcessID"] == 10014)
    & (events_df["message.EventID"] == 1)
    & (events_df["message.User"] == "NT AUTHORITY\\SYSTEM")
    & (events_df["message.Image"].str.contains(".*(cmd.exe)|(powershell.exe)"))
][["message.Image", "message.CommandLine"]]
message.Imagemessage.CommandLine
25097C:\Windows\System32\WindowsPowerShell\v1.0\pow…“C:\Windows\System32\WindowsPowerShell\v1.0\po…
753902C:\Windows\System32\cmd.execmd.exe /c echo ddpvccdbr &gt; \\.\pipe\ddpvccdbr
878801C:\Windows\System32\WindowsPowerShell\v1.0\pow…powershell.exe
1699394C:\Windows\SysWOW64\WindowsPowerShell\v1.0\pow…powershell.exe
1715690C:\Windows\SysWOW64\WindowsPowerShell\v1.0\pow…powershell.exe

In there, we find a cmd command that connects with a pipe.

Answer: ddpvccdbr

Question 10

The attacker’s process attempted to access a file. Submit the full and complete file path accessed by the attacker’s process.

There is once again an Event ID for attempts to access a file; Windows Security Log Event ID 4663. Let’s filter on that.

events_df[
    (events_df["message.ProcessID"] == 10014)
    & (events_df["message.EventID"] == 4663)
].T.dropna(how="all").T
syslog_priversionsyslog_timestamphostnameevent_sourcemessage.EventIDmessage.Versionmessage.Taskmessage.Opcodemessage.Keywordsmessage.ProcessNamemessage.ObjectServermessage.ObjectTypemessage.ObjectNamemessage.HandleIDmessage.Accessesmessage.AccessMaskmessage.EventReceivedTimemessage.SourceModuleNamemessage.SourceModuleType
234194013412024-09-16T10:45:48-04:00SleighRider.northpole.localWindowsEvent4663.01.012800.0Info-9223372036854775808C:\Users\elf_user02\Downloads\howtosavexmas\ho…SecurityFileC:\Users\elf_user02\Desktop\kkringl315@10.12.2…0x3fcREAD_CONTROL,SYNCHRONIZE,ReadData0x1200892024-09-16T10:45:48-04:00inSecurityim_msvistalog

There is only one result, but its ObjectName is cut off. We can get the full result as follows.

events_df[
    (events_df["message.ProcessID"] == 10014)
    & (events_df["message.EventID"] == 4663)
].iloc[0]["message.ObjectName"]
"C:\Users\elf_user02\Desktop\kkringl315@10.12.25.24.pem"

Answer: C:\Users\elf_user02\Desktop\kkringl315@10.12.25.24.pem

Question 11

The attacker attempted to use a secure protocol to connect to a remote system. What is the hostname of the target server?

If connections are made to connect to a system, there should be some authentication logs. Let’s explore those.

auth_df = df[df["event_source"] == "AuthLog"].T.dropna(how="all").T
auth_df
syslog_priversionsyslog_timestamphostnameevent_sourcemessage.timestampmessage.hostnamemessage.servicemessage.message
013412024-09-15T00:10:01-04:00kringleSSleigHAuthLog2024-09-15T03:10:01.304953-04:00kringleSSleigHCRON[4863]:pam_unix(cron:session): session opened for use…
113412024-09-15T00:10:01-04:00kringleSSleigHAuthLog2024-09-15T03:10:01.314490-04:00kringleSSleigHCRON[4863]:pam_unix(cron:session): session closed for use…
15713412024-09-15T00:17:01-04:00kringleSSleigHAuthLog2024-09-15T03:17:01.331687-04:00kringleSSleigHCRON[4872]:pam_unix(cron:session): session opened for use…
15813412024-09-15T00:17:01-04:00kringleSSleigHAuthLog2024-09-15T03:17:01.341866-04:00kringleSSleigHCRON[4872]:pam_unix(cron:session): session closed for use…
145713412024-09-15T01:17:01-04:00kringleSSleigHAuthLog2024-09-15T04:17:01.457972-04:00kringleSSleigHCRON[4923]:pam_unix(cron:session): session opened for use…
232813113412024-09-16T11:58:01-04:00kringleSSleigHAuthLog2024-09-16T14:58:01.331792-04:00kringleSSleigHCRON[6769]:pam_unix(cron:session): session closed for use…
234184913412024-09-16T11:59:01-04:00kringleSSleigHAuthLog2024-09-16T14:59:01.339409-04:00kringleSSleigHCRON[6777]:pam_unix(cron:session): session opened for use…
234185013412024-09-16T11:59:01-04:00kringleSSleigHAuthLog2024-09-16T14:59:01.345015-04:00kringleSSleigHCRON[6777]:pam_unix(cron:session): session closed for use…
234188513412024-09-16T12:00:01-04:00kringleSSleigHAuthLog2024-09-16T15:00:01.348709-04:00kringleSSleigHCRON[6780]:pam_unix(cron:session): session opened for use…
234188613412024-09-16T12:00:01-04:00kringleSSleigHAuthLog2024-09-16T15:00:01.353084-04:00kringleSSleigHCRON[6780]:pam_unix(cron:session): session closed for use…

We find that most information is stored as text in the message.message column. Let’s look for the IP from the filename we got.

auth_df[auth_df["message.message"].str.contains("10.12.25.24")]
syslog_priversionsyslog_timestamphostnameevent_sourcemessage.timestampmessage.hostnamemessage.servicemessage.message
23476613412024-09-15T06:55:21-04:00kringleSSleigHAuthLog2024-09-15T09:55:21.345567-04:00kringleSSleigHsshd[6005]:Connection from 34.30.110.62 port 39720 on 10….
23482813412024-09-15T06:55:23-04:00kringleSSleigHAuthLog2024-09-15T09:55:23.345567-04:00kringleSSleigHsshd[6006]:Connection from 34.30.110.62 port 39721 on 10….
23501413412024-09-15T06:55:25-04:00kringleSSleigHAuthLog2024-09-15T09:55:25.345567-04:00kringleSSleigHsshd[6007]:Connection from 34.30.110.62 port 39722 on 10….
23513013412024-09-15T06:55:27-04:00kringleSSleigHAuthLog2024-09-15T09:55:27.345567-04:00kringleSSleigHsshd[6008]:Connection from 34.30.110.62 port 39723 on 10….
23517813412024-09-15T06:55:29-04:00kringleSSleigHAuthLog2024-09-15T09:55:29.345567-04:00kringleSSleigHsshd[6009]:Connection from 34.30.110.62 port 39724 on 10….
23530013412024-09-15T06:55:31-04:00kringleSSleigHAuthLog2024-09-15T09:55:31.345567-04:00kringleSSleigHsshd[6010]:Connection from 34.30.110.62 port 39725 on 10….
23535013412024-09-15T06:55:33-04:00kringleSSleigHAuthLog2024-09-15T09:55:33.345567-04:00kringleSSleigHsshd[6011]:Connection from 34.30.110.62 port 39726 on 10….
23539413412024-09-15T06:55:35-04:00kringleSSleigHAuthLog2024-09-15T09:55:35.345567-04:00kringleSSleigHsshd[6012]:Connection from 34.30.110.62 port 39727 on 10….
23542613412024-09-15T06:55:37-04:00kringleSSleigHAuthLog2024-09-15T09:55:37.345567-04:00kringleSSleigHsshd[6013]:Connection from 34.30.110.62 port 39728 on 10….
100186313412024-09-15T10:50:21-04:00kringleSSleigHAuthLog2024-09-15T13:50:21.450567-04:00kringleSSleigHsshd[6110]:Connection from 34.30.110.62 port 39732 on 10….
102004213412024-09-15T10:51:33-04:00kringleSSleigHAuthLog2024-09-15T13:51:33.245567-04:00kringleSSleigHsshd[6115]:Connection from 34.30.110.62 port 39733 on 10….
108583313412024-09-15T10:55:21-04:00kringleSSleigHAuthLog2024-09-15T13:55:21.345567-04:00kringleSSleigHsshd[6125]:Connection from 34.30.110.62 port 41606 on 10….
124276513412024-09-16T11:03:06-04:00kringleSSleigHAuthLog2024-09-16T14:03:06.315201-04:00kringleSSleigHsshd[6301]:Connection from 34.30.110.62 port 58634 on 10….
129013313412024-09-16T11:05:57-04:00kringleSSleigHAuthLog2024-09-16T14:05:57.781687-04:00kringleSSleigHsshd[6425]:Connection from 34.30.110.62 port 48202 on 10….

We find some connections here, and all of them are going to the kringleSSleigH host.

Answer: kringleSSleigH

Question 12

The attacker created an account to establish their persistence on the Linux host. What is the name of the new account created by the attacker?

Let’s take a look at all the unique log messages from kringleSSleigH.

auth_df[auth_df["hostname"] == "kringleSSleigH"]["message.message"].unique()
array(['pam_unix(cron:session): session opened for user root(uid=0) by (uid=0)',
       'pam_unix(cron:session): session closed for user root',
       'uid 1000 is trying to obtain org.freedesktop.packagekit.system-sources-refresh auth (only_trusted:0)',
       'uid 1000 obtained auth for org.freedesktop.packagekit.system-sources-refresh',
       'Connection from 34.30.110.62 port 39720 on 10.12.25.24 port 22 rdomain ""',
       'Failed password for netrider from 34.30.110.62 port 39720 ssh2',
       'Connection from 34.30.110.62 port 39721 on 10.12.25.24 port 22 rdomain ""',
       'Failed password for frostyhacker from 34.30.110.62 port 39721 ssh2',
       'Connection from 34.30.110.62 port 39722 on 10.12.25.24 port 22 rdomain ""',
       'Failed password for cryptocode from 34.30.110.62 port 39722 ssh2',
       'Connection from 34.30.110.62 port 39723 on 10.12.25.24 port 22 rdomain ""',
       'Failed password for shadowseeker from 34.30.110.62 port 39723 ssh2',
       'Connection from 34.30.110.62 port 39724 on 10.12.25.24 port 22 rdomain ""',
       'Failed password for dataphantom from 34.30.110.62 port 39724 ssh2',
       'Connection from 34.30.110.62 port 39725 on 10.12.25.24 port 22 rdomain ""',
       'Failed password for firewallfox from 34.30.110.62 port 39725 ssh2',
       'Connection from 34.30.110.62 port 39726 on 10.12.25.24 port 22 rdomain ""',
       'Failed password for glitchmaster from 34.30.110.62 port 39726 ssh2',
       'Connection from 34.30.110.62 port 39727 on 10.12.25.24 port 22 rdomain ""',
       'Failed password for wiretrace from 34.30.110.62 port 39727 ssh2',
       'Connection from 34.30.110.62 port 39728 on 10.12.25.24 port 22 rdomain ""',
       'Failed password for codecrunch from 34.30.110.62 port 39728 ssh2',
       'Connection from 34.30.110.62 port 39732 on 10.12.25.24 port 22 rdomain ""',
       'error: Received disconnect from 34.30.110.62 port 39732:14: No supported authentication methods available [preauth]',
       'Disconnected from authenticating user kkringl315 34.30.110.62 port 39732 [preauth]',
       'Connection from 34.30.110.62 port 39733 on 10.12.25.24 port 22 rdomain ""',
       'Failed publickey for kkringl315 from 34.30.110.62 port 39733 ssh2: RSA SHA256:ZxnmQ23LgHtXj5987Km3NdjXjUHwVvBr',
       'Received disconnect from 34.30.110.62 port 39733:11: Bye Bye [preauth]',
       'Connection from 34.30.110.62 port 41606 on 10.12.25.24 port 22 rdomain ""',
       'Accepted key RSA SHA256:AbfXsQOO05qHNT98Rhe1B7KzURo0viFfq2/gpAWlP7E found at /home/kkringl315/.ssh/authorized_keys:1',
       'Postponed publickey for kkringl315 from 34.30.110.62 port 41606 ssh2 [preauth]',
       'Accepted publickey for kkringl315 from 34.30.110.62 port 41606 ssh2: RSA SHA256:AbfXsQOO05qHNT98Rhe1B7KzURo0viFfq2/gpAWlP7E',
       'pam_unix(sshd:session): session opened for user kkringl315(uid=1000) by (uid=0)',
       'New session 58 of user kkringl315.',
       'pam_env(sshd:session): deprecated reading of user environment enabled',
       'User child is on pid 6145',
       'Starting session: shell on pts/5 for kkringl315 from 34.30.110.62 port 41606 id 0',
       'pam_unix(sudo:auth): authentication failure; logname=kkringl315 uid=1000 euid=0 tty=/dev/pts/5 ruser=kkringl315 rhost=  user=kkringl315',
       ' kkringl315 : 3 incorrect password attempts ; TTY=pts/5 ; PWD=/opt ; USER=root ; COMMAND=/usr/bin/su',
       'pam_unix(sudo:auth): conversation failed',
       'pam_unix(sudo:auth): auth could not identify password for [kkringl315]',
       ' kkringl315 : TTY=pts/5 ; PWD=/opt ; USER=root ; COMMAND=/usr/bin/su',
       'pam_unix(sudo:session): session opened for user root(uid=0) by kkringl315(uid=1000)',
       '(to root) root on pts/6',
       'pam_unix(su:session): session opened for user root(uid=0) by kkringl315(uid=0)',
       'pam_unix(su:session): session closed for user root',
       'pam_unix(sudo:session): session closed for user root',
       ' kkringl315 : TTY=pts/5 ; PWD=/opt ; USER=root ; COMMAND=/usr/sbin/adduser ssdh',
       'group added to /etc/group: name=ssdh, GID=1002',
       'group added to /etc/gshadow: name=ssdh',
       'new group: name=ssdh, GID=1002',
       'new user: name=ssdh, UID=1002, GID=1002, home=/home/ssdh, shell=/bin/bash, from=/dev/pts/6',
       'pam_unix(passwd:chauthtok): password changed for ssdh',
       "gkr-pam: couldn't update the login keyring password: no old password was entered",
       "changed user 'ssdh' information",
       'members of group users set by root to kkringl315,pmacct,ssdh',
       ' kkringl315 : TTY=pts/5 ; PWD=/opt ; USER=root ; COMMAND=/usr/sbin/usermod -a -G sudo ssdh',
       "add 'ssdh' to group 'sudo'", "add 'ssdh' to shadow group 'sudo'",
       'Received disconnect from 34.30.110.62 port 41606:11: disconnected by user',
       'Disconnected from user kkringl315 34.30.110.62 port 41606',
       'pam_unix(sshd:session): session closed for user kkringl315',
       'Session 58 logged out. Waiting for processes to exit.',
       'Removed session 58.',
       'Connection from 34.30.110.62 port 58634 on 10.12.25.24 port 802 rdomain ""',
       'Postponed publickey for kkringl315 from 34.30.110.62 port 58634 ssh2 [preauth]',
       'Accepted publickey for kkringl315 from 34.30.110.62 port 58634 ssh2: RSA SHA256:AbfXsQOO05qHNT98Rhe1B7KzURo0viFfq2/gpAWlP7E',
       'New session 59 of user kkringl315.', 'User child is on pid 6319',
       'Starting session: shell on pts/5 for kkringl315 from 34.30.110.62 port 58634 id 0',
       ' kkringl315 : TTY=pts/5 ; PWD=/home/kkringl315 ; USER=root ; COMMAND=/usr/bin/crontab -',
       ' kkringl315 : TTY=pts/5 ; PWD=/home/kkringl315 ; USER=root ; COMMAND=/usr/bin/crontab -l',
       ' kkringl315 : TTY=pts/5 ; PWD=/home/kkringl315 ; USER=root ; COMMAND=/usr/sbin/service cron restart',
       ' kkringl315 : TTY=pts/5 ; PWD=/home/kkringl315 ; USER=root ; COMMAND=/usr/bin/cat /etc/crontab',
       ' kkringl315 : TTY=pts/5 ; PWD=/home/kkringl315 ; USER=root ; COMMAND=/usr/bin/cat /var/spool/cron/crontabs/root',
       'Received disconnect from 34.30.110.62 port 58634:11: disconnected by user',
       'Disconnected from user kkringl315 34.30.110.62 port 58634',
       'Session 59 logged out. Waiting for processes to exit.',
       'Removed session 59.',
       'Connection from 34.30.110.62 port 48202 on 10.12.25.24 port 802 rdomain ""',
       'Postponed publickey for kkringl315 from 34.30.110.62 port 48202 ssh2 [preauth]',
       'Accepted publickey for kkringl315 from 34.30.110.62 port 48202 ssh2: RSA SHA256:AbfXsQOO05qHNT98Rhe1B7KzURo0viFfq2/gpAWlP7E',
       'New session 62 of user kkringl315.', 'User child is on pid 6447',
       'Starting session: shell on pts/5 for kkringl315 from 34.30.110.62 port 48202 id 0',
       'error: connect_to dc01.northpole.local: unknown host (Name or service not known)',
       'error: connect_to 10.56.4.53 port 88: failed.',
       'Close session: user kkringl315 from 34.30.110.62 port 48202 id 0',
       'Received disconnect from 34.30.110.62 port 48202:11: disconnected by user',
       'Disconnected from user kkringl315 34.30.110.62 port 48202',
       'Session 62 logged out. Waiting for processes to exit.',
       'Removed session 62.'], dtype=object)

There are manu things happening, but just after the successfull login, we find a line starting with new user.

'new user: name=ssdh, UID=1002, GID=1002, home=/home/ssdh, shell=/bin/bash, from=/dev/pts/6',

In it, we can clearly see the new user name.

Answer: ssdh

Question 13

The attacker wanted to maintain persistence on the Linux host they gained access to and executed multiple binaries to achieve their goal. What was the full CLI syntax of the binary the attacker executed after they created the new user account?

For question 13 we can take another look at the last result. A few lines after the new user event, we find a command.

' kkringl315 : TTY=pts/5 ; PWD=/opt ; USER=root ; COMMAND=/usr/sbin/usermod -a -G sudo ssdh',

Answer: /usr/sbin/usermod -a -G sudo ssdh

Question 14

The attacker enumerated Active Directory using a well known tool to map our Active Directory domain over LDAP. Submit the full ISO8601 compliant timestamp when the first request of the data collection attack sequence was initially recorded against the domain controller.

Back to the Windows event logs. LDAP events are logging using Event ID 2889, so let’s filter on those.

events_df[events_df["message.EventID"] == 2889].T.dropna(how="all").T
syslog_priversionsyslog_timestamphostnameevent_sourcemessage.EventIDmessage.Levelmessage.Keywordsmessage.Computermessage.UserIDmessage.Categorymessage.Descriptionmessage.ServiceNamemessage.Datemessage.LogNamemessage.Sourcemessage.ClientIPaddressmessage.ServicePortmessage.ServiceIpAddressmessage.BindType
234194113412024-09-16T11:10:12-04:00dc01.northpole.localWindowsEvent2889.0InformationClassicdc01.northpole.localelf_user@northpole.localLDAP InterfaceThe following client performed a SASL (Negotia…dc01.northpole.local2024-09-16T11:10:12-04:00Directory ServiceMicrosoft-Windows-ActiveDirectory_DomainService172.24.25.22:18598389.0172.24.25.1530 - Simple Bind that does not support signing
234194213412024-09-16T11:10:12-04:00dc01.northpole.localWindowsEvent2889.0InformationClassicdc01.northpole.localelf_user@northpole.localLDAP InterfaceThe following client performed a SASL (Negotia…dc01.northpole.local2024-09-16T11:10:12-04:00Directory ServiceMicrosoft-Windows-ActiveDirectory_DomainService172.24.25.22:25168389.0172.24.25.1530 - Simple Bind that does not support signing
234194313412024-09-16T11:10:12-04:00dc01.northpole.localWindowsEvent2889.0InformationClassicdc01.northpole.localelf_user@northpole.localLDAP InterfaceThe following client performed a SASL (Negotia…dc01.northpole.local2024-09-16T11:10:12-04:00Directory ServiceMicrosoft-Windows-ActiveDirectory_DomainService172.24.25.22:50183389.0172.24.25.1530 - Simple Bind that does not support signing
234194413412024-09-16T11:10:12-04:00dc01.northpole.localWindowsEvent2889.0InformationClassicdc01.northpole.localelf_user@northpole.localLDAP InterfaceThe following client performed a SASL (Negotia…dc01.northpole.local2024-09-16T11:10:12-04:00Directory ServiceMicrosoft-Windows-ActiveDirectory_DomainService172.24.25.22:57683389.0172.24.25.1530 - Simple Bind that does not support signing
234194513412024-09-16T11:10:12-04:00dc01.northpole.localWindowsEvent2889.0InformationClassicdc01.northpole.localelf_user@northpole.localLDAP InterfaceThe following client performed a SASL (Negotia…dc01.northpole.local2024-09-16T11:10:12-04:00Directory ServiceMicrosoft-Windows-ActiveDirectory_DomainService172.24.25.22:33773389.0172.24.25.1530 - Simple Bind that does not support signing
234313613412024-09-16T11:12:11-04:00dc01.northpole.localWindowsEvent2889.0InformationClassicdc01.northpole.localelf_user@northpole.localLDAP InterfaceThe following client performed a SASL (Negotia…dc01.northpole.local2024-09-16T11:12:11-04:00Directory ServiceMicrosoft-Windows-ActiveDirectory_DomainService172.24.25.22:60776389.0172.24.25.1530 - Simple Bind that does not support signing
234313713412024-09-16T11:12:11-04:00dc01.northpole.localWindowsEvent2889.0InformationClassicdc01.northpole.localelf_user@northpole.localLDAP InterfaceThe following client performed a SASL (Negotia…dc01.northpole.local2024-09-16T11:12:11-04:00Directory ServiceMicrosoft-Windows-ActiveDirectory_DomainService172.24.25.22:37622389.0172.24.25.1530 - Simple Bind that does not support signing
234313813412024-09-16T11:12:11-04:00dc01.northpole.localWindowsEvent2889.0InformationClassicdc01.northpole.localelf_user@northpole.localLDAP InterfaceThe following client performed a SASL (Negotia…dc01.northpole.local2024-09-16T11:12:11-04:00Directory ServiceMicrosoft-Windows-ActiveDirectory_DomainService172.24.25.22:57315389.0172.24.25.1530 - Simple Bind that does not support signing
234313913412024-09-16T11:12:11-04:00dc01.northpole.localWindowsEvent2889.0InformationClassicdc01.northpole.localelf_user@northpole.localLDAP InterfaceThe following client performed a SASL (Negotia…dc01.northpole.local2024-09-16T11:12:11-04:00Directory ServiceMicrosoft-Windows-ActiveDirectory_DomainService172.24.25.22:17963389.0172.24.25.1530 - Simple Bind that does not support signing
234314013412024-09-16T11:12:12-04:00dc01.northpole.localWindowsEvent2889.0InformationClassicdc01.northpole.localelf_user@northpole.localLDAP InterfaceThe following client performed a SASL (Negotia…dc01.northpole.local2024-09-16T11:12:12-04:00Directory ServiceMicrosoft-Windows-ActiveDirectory_DomainService172.24.25.22:51127389.0172.24.25.1530 - Simple Bind that does not support signing

The question is asking for the first one, so we can take the syslog_timestamp of that one.

Answer: 2024-09-16T11:10:12-04:00

Question 15

The attacker attempted to perform an ADCS ESC1 attack, but certificate services denied their certificate request. Submit the name of the software responsible for preventing this initial attack.

Another look at Microsoft’s documentation will tell us that Event ID 4886 is used for denied a certificate requests.

events_df[events_df["message.EventID"] == 4888].T.dropna(how="all").T
syslog_priversionsyslog_timestamphostnameevent_sourcemessage.EventIDmessage.Levelmessage.Keywordsmessage.Computermessage.Categorymessage.Usermessage.Datemessage.LogNamemessage.Sourcemessage.UserInformation_UserNamemessage.CertificateInformation_CertificateAuthoritymessage.CertificateInformation_RequestedTemplatemessage.ReasonForRejectionmessage.AdditionalInformation_RequesterComputermessage.AdditionalInformation_RequestedUPN
234314113412024-09-16T11:14:12-04:00dc01.northpole.localWindowsEvent4888.0InformationAudit Failuredc01.northpole.localCertification Services - Certificate Request D…N/A2024-09-16T11:14:12-04:00SecurityMicrosoft-Windows-Security-Auditingelf_user@northpole.localelf-dc01-SeaAAdministratorKringleGuard EDR flagged the certificate request.10.12.25.24administrator@northpole.local

We can find the EDR that blocked it in the message.ReasonForRejection column.

Answer: KringleGuard

Question 16

We think the attacker successfully performed an ADCS ESC1 attack. Can you find the name of the user they successfully requested a certificate on behalf of?

Another question, another event id. This one oddly doesn’t show on the same page as the previous one, but can be found here.

events_df[events_df["message.EventID"] == 4886].T.dropna(how="all").T
syslog_priversionsyslog_timestamphostnameevent_sourcemessage.EventIDmessage.Levelmessage.Keywordsmessage.Computermessage.Categorymessage.Usermessage.Datemessage.LogNamemessage.Sourcemessage.UserInformation_UserNamemessage.CertificateInformation_CertificateAuthoritymessage.AdditionalInformation_RequesterComputermessage.UserInformation_UPNmessage.CertificateInformation_CertificateTemplatemessage.AdditionalInformation_CallerComputer
234314213412024-09-16T11:15:12-04:00dc01.northpole.localWindowsEvent4886.0InformationAudit Successdc01.northpole.localCertification Services - Certificate IssuanceN/A2024-09-16T11:15:12-04:00SecurityMicrosoft-Windows-Security-Auditingelf_user@northpole.localelf-dc01-SeaA10.12.25.24nutcrakr@northpole.localElfUsers172.24.25.153

We can then find the username in the message.UserInformation_UPN column.

Answer: nutcrakr

Question 17

One of our file shares was accessed by the attacker using the elevated user account (from the ADCS attack). Submit the folder name of the share they accessed.

There is also and Event ID in Microsoft’s documentation for network share access logs. We can combine that with the user we just found to find the shares that were accessed.

events_df[
    (events_df["message.EventID"] == 5140)
    & (events_df["message.SubjectUserName"] == "nutcrakr")
].T.dropna(how="all").T
syslog_priversionsyslog_timestamphostnameevent_sourcemessage.EventIDmessage.Versionmessage.Taskmessage.Opcodemessage.Keywordsmessage.AccessRequestInformation_AccessMaskmessage.IpAddressmessage.IpPortmessage.ShareNamemessage.NetworkInformation_ObjectTypemessage.NetworkInformationmessage.ShareInformation_ShareNamemessage.ShareInformationmessage.ShareLocalPathmessage.ShareInformation_SharePath
154250513412024-09-16T11:18:43-04:00dc01.northpole.localWindowsEvent5140.01.012808.0Info-92143648376000348160x134.30.110.6253378\*\WishListsFile,\*\WishListsNaN??\C:\WishLists??\C:\WishLists
189076213412024-09-16T11:35:58-04:00dc01.northpole.localWindowsEvent5140.01.012808.0Info-92143648376000348160x1fe80::292b:d1:2589:ffa950356\*\SYSVOLFile,\*\SYSVOLNaN??\C:\Windows\SYSVOL\sysvol??\C:\Windows\SYSVOL\sysvol
189121813412024-09-16T11:35:59-04:00dc01.northpole.localWindowsEvent5140.01.012808.0Info-92143648376000348160x1fe80::292b:d1:2589:ffa950356\*\IPC$File,\*\IPC$Share Path:,NaNNaN
209000213412024-09-16T11:44:40-04:00dc01.northpole.localWindowsEvent5140.01.012808.0Info-92143648376000348160x1fe80::292b:d1:2589:ffa950404\*\ADMIN$File,\*\ADMIN$NaN??\C:\Windows??\C:\Windows
209000413412024-09-16T11:44:40-04:00dc01.northpole.localWindowsEvent5140.01.012808.0Info-92143648376000348160x1fe80::292b:d1:2589:ffa950404\*\ADMIN$File,\*\ADMIN$NaN??\C:\Windows??\C:\Windows
211808213412024-09-16T11:46:17-04:00dc01.northpole.localWindowsEvent5140.01.012808.0Info-92143648376000348160x1fe80::292b:d1:2589:ffa950404\*\ADMIN$File,\*\ADMIN$NaN??\C:\Windows??\C:\Windows
223856513412024-09-16T11:53:12-04:00dc01.northpole.localWindowsEvent5140.01.012808.0Info-92143648376000348160x1fe80::292b:d1:2589:ffa950404\*\SYSVOLFile,\*\SYSVOLNaN??\C:\Windows\SYSVOL\sysvol??\C:\Windows\SYSVOL\sysvol

The question is not asking for the share, but for the folder in it. This can be found in the message.ShareInformation_SharePath column.

Answer: WishLists

Question 18

The naughty attacker continued to use their privileged account to execute a PowerShell script to gain domain administrative privileges. What is the password for the account the attacker used in their attack payload?

The attack payload might be referring to a PowerShell script, so let’s take a look at those logs. Event IDs 4103 and 4104 are used for powershell script logging.

events_df[(events_df["message.EventID"] == 4104)]["message.ScriptBlockText"].unique()
array(['quser | Select-String -Pattern ".+"',
       'Get-LocalUser | Where-Object { $_.Enabled -eq $true } | Get-LocalGroupMember',
       'Get-Disk | Select-Object Number, Status, OperationalStatus, TotalSize, PartitionStyle',
       'Get-ChildItem "$env:USERPROFILE\\Downloads\\*" | Where-Object { $_.CreationTime -lt (Get-Date).AddDays(-30) } | Remove-Item',
       'Get-WmiObject Win32_LogicalDisk | Format-Table DeviceID, MediaType, FreeSpace',
       "Get-NetAdapter | Where-Object { $_.Status -eq 'Up' } | Select-Object Name, InterfaceDescription, MacAddress",
       '[int][double]::Parse((Get-WmiObject win32_operatingsystem).LastBootUpTime.Subtract([datetime]::Parse("1970-01-01T00:00:00Z")).TotalSeconds)',
       'certutil -verify -urlfetch certificate.cer',
       'Test-Connection -ComputerName conntest.northpole.local -Count 4',
       'Get-SmbSession | Where-Object { $_.OpenFileCount -gt 0 } | Format-Table SessionId, ClientComputerName',
       '(Get-WmiObject -Query "SELECT * FROM Win32_Printer WHERE Default=$true").Name',
       '(Get-Date) - (gcim Win32_OperatingSystem).LastBootUpTime',
       'Get-Counter -Counter "\\PhysicalDisk(_Total)\\Disk Reads/sec", "\\PhysicalDisk(_Total)\\Disk Writes/sec"',
       'C:\\Windows\\System32\\perfmon /report',
       "Get-Counter '\\Processor(_Total)\\% Processor Time' | Select-Object -ExpandProperty CounterSamples | Select-Object CookedValue",
       'Get-PSDrive C | Select-Object Free,Used',
       'Get-EventLog -LogName Application | Measure-Object -Property Length -Sum | Select-Object Sum',
       '(New-Object -ComObject Microsoft.Update.AutoUpdate).DetectNow()',
       'gpupdate /force',
       "Get-Disk | Where-Object { $_.OperationalStatus -ne 'OK' } | Select-Object Number, Status, OperationalStatus",
       'Get-WmiObject Win32_NetworkProtocol | Select-Object Name, ProtocolID, GuaranteesDelivery, GuaranteesSequencing',
       'Get-WmiObject Win32_BIOS | Select-Object Manufacturer, SMBIOSBIOSVersion, ReleaseDate | Format-List',
       'Add-Type -AssemblyName System.DirectoryServices\n$ldapConnString = "LDAP://CN=Domain Admins,CN=Users,DC=northpole,DC=local"\n$username = "nutcrakr"\n$pswd = \'fR0s3nF1@k3_s\'\n$nullGUID = [guid]\'00000000-0000-0000-0000-000000000000\'\n$propGUID = [guid]\'00000000-0000-0000-0000-000000000000\'\n$IdentityReference = (New-Object System.Security.Principal.NTAccount("northpole.local\\$username")).Translate([System.Security.Principal.SecurityIdentifier])\n$inheritanceType = [System.DirectoryServices.ActiveDirectorySecurityInheritance]::None\n$ACE = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $IdentityReference, ([System.DirectoryServices.ActiveDirectoryRights] "GenericAll"), ([System.Security.AccessControl.AccessControlType] "Allow"), $propGUID, $inheritanceType, $nullGUID\n$domainDirEntry = New-Object System.DirectoryServices.DirectoryEntry $ldapConnString, $username, $pswd\n$secOptions = $domainDirEntry.get_Options()\n$secOptions.SecurityMasks = [System.DirectoryServices.SecurityMasks]::Dacl\n$domainDirEntry.RefreshCache()\n$domainDirEntry.get_ObjectSecurity().AddAccessRule($ACE)\n$domainDirEntry.CommitChanges()\n$domainDirEntry.dispose()\n$ldapConnString = "LDAP://CN=Domain Admins,CN=Users,DC=northpole,DC=local"\n$domainDirEntry = New-Object System.DirectoryServices.DirectoryEntry $ldapConnString, $username, $pswd\n$user = New-Object System.Security.Principal.NTAccount("northpole.local\\$username")\n$sid=$user.Translate([System.Security.Principal.SecurityIdentifier])\n$b=New-Object byte[] $sid.BinaryLength\n$sid.GetBinaryForm($b,0)\n$hexSID=[BitConverter]::ToString($b).Replace(\'-\',\'\')\n$domainDirEntry.Add("LDAP://<SID=$hexSID>")\n$domainDirEntry.CommitChanges()\n$domainDirEntry.dispose()'],
      dtype=object)

On the last line we can find that a username and password are set.

Answer: fR0s3nF1@k3_s

Question 19

The attacker then used remote desktop to remotely access one of our domain computers. What is the full ISO8601 compliant UTC EventTime when they established this connection?

To stay with the same method, there are also Event IDs for RDP logs. We can use Event ID 4642, which is for any login, together with the LogonType to filter on RDP logins.

events_df[
    (events_df["message.EventID"] == 4624)
    & (events_df["message.LogonInformation_LogonType"] == 10)
    & (events_df["message.NewLogon_AccountName"] == "nutcrakr")
].T.dropna(how="all").T
syslog_priversionsyslog_timestamphostnameevent_sourcemessage.EventIDmessage.Versionmessage.Taskmessage.Opcodemessage.Keywordsmessage.NewLogon_NetworkAccountNamemessage.NewLogon_NetworkAccountDomainmessage.NewLogon_LogonGUIDmessage.NetworkInformation_WorkstationNamemessage.NetworkInformation_SourceNetworkAddressmessage.DetailedAuthenticationInformation_LogonProcessmessage.DetailedAuthenticationInformation_AuthenticationPackagemessage.DetailedAuthenticationInformation_TransitedServicesmessage.DetailedAuthenticationInformation_PackageNameNTLMonlymessage.DetailedAuthenticationInformation_KeyLength
188995213412024-09-16T11:35:57-04:00dc01.northpole.localWindowsEvent4624.02.012544.0Info-9214364837600034816--{00000000-0000-0000-0000-000000000000}DC0110.12.25.24User32Negotiate--0.0

We found the log here, but there is something really awful. The last question that asked for a timestamp allowed the existing format, and according to the current question, this one does as well. This is not the case however. This time, we need to convert it to a UTC timestamp.

from datetime import datetime, UTC

datetime.fromtimestamp(
    datetime.fromisoformat("2024-09-16T11:35:57-04:00").timestamp(), UTC
).isoformat(timespec="milliseconds")

Answer: 2024-09-16T15:35:57.000+00:00

Question 20

The attacker is trying to create their own naughty and nice list! What is the full file path they created using their remote desktop connection?

From the previous result, we can grab the login ID to filter on anything that happened in that session. Let’s take a look at the processes that ran.

events_df[
    (events_df["message.LogonId"] == "0xdd425e")
][["message.Image", "message.CommandLine"]]
message.Imagemessage.CommandLine
1891243C:\Windows\System32\TSTheme.exeC:\Windows\system32\TSTheme.exe -Embedding
1891249C:\Windows\System32\rdpclip.exerdpclip
1891280C:\Windows\System32\sihost.exesihost.exe
1891285C:\Windows\System32\svchost.exeC:\Windows\system32\svchost.exe -k UnistackSvc…
1891286C:\Windows\System32\svchost.exeC:\Windows\system32\svchost.exe -k UnistackSvc…
1891288C:\Windows\System32 askhostw.exetaskhostw.exe {222A245B-E637-4AE9-A93F-A59CA11…
1891290C:\Windows\System32\taskhostw.exetaskhostw.exe USER
1891295C:\Windows\System32\ServerManagerLauncher.exeC:\Windows\system32\ServerManagerLauncher.exe
1891304C:\Windows\System32\userinit.exeC:\Windows\system32\userinit.exe
1891591C:\Windows\explorer.exeC:\Windows\Explorer.EXE
1891963C:\Windows\System32\smartscreen.exeC:\Windows\System32\smartscreen.exe -Embedding
1892186C:\Windows\System32\unregmp2.exe“C:\Windows\System32\unregmp2.exe” /FirstLogon
1892187C:\Windows\System32\ie4uinit.exe“C:\Windows\System32\ie4uinit.exe” -UserConfig
1893139C:\Windows\System32\ie4uinit.exeC:\Windows\System32\ie4uinit.exe -ClearIconCache
1893140C:\Windows\System32\rundll32.exerundll32.exe AppXDeploymentExtensions.OneCore….
1893141C:\Windows\System32\ctfmon.exe“ctfmon.exe”
1893143C:\Windows\System32\rundll32.exeC:\Windows\system32\RunDll32.exe C:\Windows\sy…
1893231C:\Windows\System32\unregmp2.exe“C:\Windows\System32\unregmp2.exe” /FirstLogon
1893512C:\Windows\System32\rundll32.exe“C:\Windows\System32\rundll32.exe” “C:\Windows…
1893516C:\Windows\System32\rundll32.exe“C:\Windows\System32\rundll32.exe” “C:\Windows…
1893901C:\Windows\System32\ServerManager.exe“C:\Windows\system32\ServerManager.exe”
1894242C:\Windows\System32\SettingSyncHost.exeC:\Windows\system32\SettingSyncHost.exe -Embed…
1894476C:\Windows\System32\fsquirt.exe“C:\Windows\System32\fsquirt.exe” -Register
1897675C:\Windows\System32\SecurityHealthSystray.exe“C:\Windows\System32\SecurityHealthSystray.exe”
1897676C:\Windows\System32\vm3dservice.exe“C:\Windows\System32\vm3dservice.exe” -u
1898400C:\Program Files\VMware\VMware Tools\vmtoolsd.exe“C:\Program Files\VMware\VMware Tools\vmtoolsd…
1900518C:\Windows\System32\rundll32.exeC:\Windows\System32\rundll32.exe C:\Windows\Sy…
1903852C:\Windows\System32\notepad.exe“C:\Windows\system32\NOTEPAD.EXE” C:\WishLists…
1907971C:\Windows\System32\rundll32.exerundll32.exe AppXDeploymentExtensions.OneCore….
2012271C:\Windows\System32\ApplicationFrameHost.exeC:\Windows\system32\ApplicationFrameHost.exe -…
2118209C:\Windows\System32\TSTheme.exeC:\Windows\system32\TSTheme.exe -Embedding
2118212C:\Windows\System32\taskhostw.exetaskhostw.exe KEYROAMING
2202255C:\Windows\System32\taskhostw.exetaskhostw.exe Install $(Arg0)

Event 1903852 is interesting here, as it shows that Notepad was used. Let’s take a closer look.

events_df.loc[1903852]["message.CommandLine"]
'"C:\\Windows\\system32\\NOTEPAD.EXE" C:\\WishLists\\santadms_only\\its_my_fakelst.txt'

Answer: C:\WishLists\santadms_only\its_my_fakelst.txt

Question 21

The Wombley faction has user accounts in our environment. How many unique Wombley faction users sent an email message within the domain?

Let’s first check what email addresses exist.

email_df["message.From"].value_counts()
message.Fromcount
elf_user04@northpole.local45
elf_user09@northpole.local45
elf_user03@northpole.local44
asnowball08@northpole.local43
elf_user05@northpole.local40
StarlightStrider@nogfest.eggnog1
YuleYodeller@blizzard.north1
frostyMittens@tinsel.town1
SnowySprinter@northstar.nibbles1
TinselTamer@elf.toyshop1

We are quite a few, but the ones ending in “@northpole.local” are from our environment. Let’s filter on those.

email_df[email_df["message.From"].str.endswith("@northpole.local")]["message.From"].value_counts()
message.Fromcount
elf_user09@northpole.local45
elf_user04@northpole.local45
elf_user03@northpole.local44
asnowball08@northpole.local43
elf_user05@northpole.local40
asnowball09@northpole.local39
elf_user10@northpole.local37
elf_user08@northpole.local36
asnowball_05@northpole.local35
wcube311@northpole.local35
elf_user01@northpole.local35
elf_user00@northpole.local34
elf_user02@northpole.local34
elf_user11@northpole.local34
asnowball04@northpole.local33
wcub808@northpole.local33
elf_user07@northpole.local32
wcub303@northpole.local32
elf_user06@northpole.local30
wcub101@northpole.local23
kriskring1e@northpole.local1

Now that we have all local email address, we can infer that the ones starting with “wcub” are from Wombley’s faction. The question asked for local messages, so we also add the domain check for the To field.

len(
    email_df[
        (email_df["message.From"].str.endswith("@northpole.local"))
        & (email_df["message.From"].str.startswith("wcub"))
        & (email_df["message.To"].str.endswith("@northpole.local"))
    ]["message.From"].unique()
)
4

Answer: 4

Question 22

The Alabaster faction also has some user accounts in our environment. How many emails were sent by the Alabaster users to the Wombley faction users?

This question is very similar to the previous one, just replace “wcub” with “asnowball”, and add another To check.

len(
    email_df[
        (email_df["message.From"].str.endswith("@northpole.local"))
        & (email_df["message.From"].str.startswith("asnowball"))
        & (email_df["message.To"].str.endswith("@northpole.local"))
        & (email_df["message.To"].str.startswith("wcub"))
    ]
)
22

Answer: 22

Question 23

Of all the reindeer, there are only nine. What’s the full domain for the one whose nose does glow and shine? To help you narrow your search, search the events in the ‘SnowGlowMailPxy’ event source.

Let’s start by listing all domains which had email activity.

email_df[["message.From", "message.To"]].stack().reset_index()[0].apply(lambda v: v.split("@")[1]).unique()
array(['northpole.local', 'merry.elves', 'santa.hut', 'rud01ph.glow',
       'sleigh.ride', 'blizzard.north', 'cheery.fireplace', 'holly.jolly',
       'icicle.light', 'twilight.star', 'candycane.factory', 'snowy.land',
       'bells.ring', 'elf.toyshop', 'yule.log', 'stocking.chimney',
       'snowflake.spark', 'frosty.north', 'ginger.snap',
       'toytinkers.land', 'mistlebranch.vixen', 'wreath.maker',
       'wicked.snow', 'gingerlane.dancer', 'evergreen.tree',
       'jolly.jingle', 'starlight.tree', 'northstar.nibbles',
       'snowflakekingdom.chill', 'gingerbread.house', 'pine.tree',
       'tinsel.town', 'pr4nc3r.trot', 'twinkle.light', 'nutcracker.tale',
       'reindeer.corral', 'snowdrift.globe', 'nogfest.eggnog',
       'tinsel.wrap', 'c0m3t.halleys', 'reindeers.fly'], dtype=object)

There are multiple reindeer domains in there, but obviously only Rudolph’s nose glows and shines.

Answer: rud01ph.glow

Question 24

With a fiery tail seen once in great years, what’s the domain for the reindeer who flies without fears? To help you narrow your search, search the events in the ‘SnowGlowMailPxy’ event source.

We can use the previous result for this question as well. Comet is the reindeer that fiels without fears.

Answer: c0m3t.halleys

Final elf message

Unbelievable! You dissected the attack chain using advanced analysis—impressive work! With determination like yours, we might just fix the mess and get Santa smiling again.