⚠️ Legal Disclaimer: The companies, organizations, domain names, email addresses, people, places, and events depicted in the KC7 Cyber Game data sets and other materials created by the KC7 Foundation are fictitious. No association with any real company, organization, domain name, email address, person, place, or event is intended or should be inferred._

The Madam C.J. Walker Manufacturing Company

The year is 2323. Washington D.C.has been split into several districts, some districts inhabited, some are simply abandoned relics of the past. Where there is life, there is a sprawling metropolis!

Within the industrial district, the Madam C.J. Walker Manufacturing Company stands as a defiant beacon of hope within the industrial distict. Once celebrated for its exceptional hair care and beauty products, tailored for those forgotten by society, it now serves as a last bastion of resilience.

MCJWalkerLogo

The Walker Manufacturing Company is leading the economic resurgence of the city. Several years ago, it embarked on a mission to manufacture generators that bring energy to the most desolate parts of the city at a fraction of the typical cost. This new energy source has sparked economic growth in the most underserved areas. However, the reduced cost of energy is perceived as a threat to the profits of the local mafia, which has amassed its wealth by controlling the expensive fuel supply chain. There are also rumors circulating about Walker Manufacturing Company's ambitious plan to engineer a floating electric scooter, a disruptive innovation that could revolutionize the transportation sector.

You're hired!

🥳 Today is your first day as a Junior Security Operations Center (SOC) Analyst with our company. Your primary job responsibility is to defend Madam C.J. Walker Manufacturing Company and our employees from malicious cyber actors.

The Walker Manufacturing Company has a series of key partners who contribute to the success of our business:

Partner NameRelationship
scavengers-r-us.orgScavengers-R-Us is a resourceful group of scavengers who explore the abandoned city, searching for valuable items, salvageable materials, and useful resources to repurpose and trade. They play a vital role in recycling and sustaining the ecosystem within the city.
apoc-energies.comApoc-Energies specializes in harnessing renewable energy sources within the abandoned city. They repurpose old power infrastructure, set up solar panels, wind turbines, and other sustainable energy solutions to provide power to various facilities and settlements, contributing to a greener and self-sufficient environment.
newworldurbanplanners.orgNew World Urban Planners are dedicated to revitalizing the abandoned city. They create and implement strategic plans for reconstructing the city's infrastructure, developing sustainable communities, and designing functional spaces to attract new settlers and breathe life back into the city.

The Walker Manufacturing Company has been laser-focused on broadening our customer base. Recently, though, we have been getting a lot of attention. All this extra attention has brought along some unwelcome visitors- cyber attackers! That’s why we’ve hired you! To help keep us safe!

Like all good companies, Madam C.J. Walker Manufacturing Company collects log data about the activity our employees perform on the corporate network. These security audit logs are stored in Azure Data Explorer (ADX) - a data storage service in Azure (Microsoft’s cloud). You will use the Kusto Query Language (KQL) to parse through various types of security logs. By analysing these logs, you can help us determine whether we’re being targeted by malicious actors.

You can find full documentation on ADX here: https://docs.microsoft.com/en-us/azure/data-explorer/kusto/query/tutorial?pivots=azuredataexplorer

Objectives

🧠 By the end of your first day on the job, you should be able to:

  • Use the Azure Data Explorer
  • Use multiple data sets to answer targeted questions
  • Investigate cyber activity in logs including: email, web traffic, and server logs
  • Use multiple techniques to track the activity of APTs (Advanced Persistent Threats)
  • Use third party data sets to discover things about your attackers
  • Make recommendations on what actions a company can take to protect themselves

The attackers have gotten a head start, so let's not waste any more time... let's get to work!

You can find all the links you need here: scoreboard.kc7cyber.com/modules/defcon. However, you will answer all the question on the CTFRoom scoreboard.

Legend

🎯Key Point – Occasionally, you will see a dart emoji with a “key point.” These signal explanations of certain concepts that may enhance your understanding of key cybersecurity ideas that are demonstrated in the game.

🤔Question – “Thinking” emojis represent questions that will enable you to demonstrate mastery of the concepts at hand. You can earn points by entering your responses to questions from section 3 in the scoring portal available at kc7cyber.com/scoreboard.

🤫 Hint – “Whisper” emojis represent in-game hints. These hints will guide you in the right direction in answering some of the questions.

Section 1: The Walkthrough

Getting Set Up in Azure Data Explorer (ADX)

ADX is the primary tool used in the Madam C.J. Walker Manufacturing Company SOC for data exploration and analysis. The great thing about ADX is that it is used by cyber analysts at many of the smallest and largest organizations in the world.

Let’s get you logged in and started with ADX:

  1. Go to the Madam C.J. Walker Manufacturing Company training module at kc7cyber.com/modules/defcon

On the training module page, you’ll see a button that says Get the Data. Click this and it will redirect you to ADX! (Note: You’ll probably be asked to login with a Microsoft account. You can use an existing personal or organization-issued Microsoft account, or create a new one for free.)

Once you login, you should see a cluster called “kc7001.eastus” has already been added to your account.

cluster

Data in ADX is organized in a hierarchical structure which consists of clusters, databases, and tables.

hierarchy

All of Madam C.J. Walker Manufacturing Company’s security logs are stored in a single database – the CJWalker database.

  1. Select your database.
    • Expand the dropdown arrow next to the CJWalker.
    • Click on the CJWalker database. Once you’ve done this, you should see the database highlighted- this means you’ve selected the database and are ready to query the tables inside.

Note: It’s very important that you use the CJWalker for all questions while you’re investigating activity at Madam C.J. Walker Manufacturing Company! If you choose the wrong database, you won’t be able to answer questions correctly.

The big space to the right of your cluster list is the query workspace. That’s where you’ll actually write the queries used to interact with our log data.

workspace

Currently, you’ll see there’s a message there welcoming you to Madam C.J. Walker Manufacturing Company! Click the blue Run button above the query workspace to run your first query! Once you’ve done that, you can erase the welcome message by highlighting it and pressing backspace or delete on your keyboard.

Okay, enough introductions… let’s get your hands on the data.

First Look at the data...

The CJWalker database contains nine tables. Tables contain many rows of similar data. For security logs, a single row typically represents a single thing done by an employee or a device on the network at a particular time.

We currently have nine types of log data. As you’ll see in ADX, each log type corresponds to a table that exists in the CJWalker database:

Table NameDescription
EmployeesContains information about the company’s employees
EmailRecords emails sent and received by employees
InboundNetworkEventsRecords inbound network events including browsing activity from the Internet to devices within the company network
OutboundNetworkEventsRecords outbound network events including browsing activity from within the company network out to the Internet
AuthenticationEventsRecords successful and failed logins to devices on the company network. This includes logins to the company’s mail server.
FileCreationEventsRecords files stored on employee’s devices
ProcessEventsRecords processes created on employee’s devices
PassiveDns (External)Records IP-domain resolutions
SecurityAlertsRecords security alerts from an employee’s device or the company’s email security system

🎯Key Point – Over the Horizon (OTH) data: One of the tables listed above is not like the others – PassiveDns. Rather than being an internal security log, PassiveDns is a data source that we’ve purchased from a 3rd party vendor. Not all malicious cyber activity happens within our company network, so sometimes we depend on data from other sources to complete our investigations.

You’ll learn more about how to use each of these datasets in just a minute. First, let’s just run some queries so you can practice using KQL and ADX.

KQL 101

Type the following query in the workspace to view the first rows in the Employees table. Press “run” or “shift + enter” to execute the query.

Employees
| take 10

take 10 command

This query has a few parts. Let’s take a moment to break each of them down:

Diagram
Description automatically generated with low confidence

Query ComponentDescription
Table NameThe table name specifies which table/data source the query will pull data from. All queries must start with a table.
Pipe character (|)The pipe character indicates the start of a new part of the query. A pipe will be added automatically after typing a table name and pressing enter. You can also add a pipe character manually by holding shift and pressing the backslash (\) key. That’s the one just below the backspace key.

The take operator is a powerful tool you can use to explore rows in a table, and therefore better understand what kinds of data are stored there.

🎯Key Point – What to do when you don’t know what to do: Whenever you are faced with an unfamiliar database table, the first thing you should do is sample its rows using the take operator. That way, you know what fields are available for you to query and you can guess what type of information you might extract from the data source.

The Employees table contains information about all the employees in our organization. In this case, we can see that the organization is named “Madam C.J. Walker Manufacturing Company” and the domain is “mcjwalker.com”.

  1. 🤔 Try it for yourself! Do a take 10 on all the other tables to see what kind of data they contain.

Make sure you record your answer to all the questions from KQL 101 in the scoreboard at kc7cyber.com/scoreboard

You can easily write multiple queries in the same workspace tab. To do this, make sure to separate each query by an empty line. Notice below how we have separated the queries for the Employees, Email, and OutboundNetworkEvents tables by adding empty lines between them.

Email
| take 10

Employees
| take 10

OutboundNetworkEvents
| take 10

When you have multiple queries, it’s important to tell ADX which query you want to run. To choose a query, just click on any line that is part of that query.

Finding Out “How Many”: The count Operator

We can use count to see how many rows are in a table. This tells us how much data is stored there.

Employees
| count
  1. 🤔How many employees are in the company?

Filtering Data With the where Operator

So far, we’ve run queries that look at the entire contents of the table. Often in cybersecurity analysis, we only want to look at data that meets a set of conditions or criteria. To accomplish this, we apply filters to specific columns.

We can use the where operator in KQL to apply filters to a particular field. For example, we can find all the employees with the name “Sherrell” by filtering on the name column in the Employees table.

where statements are written using a particular structure. Use this helpful chart below to understand how to structure a where statement.

wherefieldoperator"value"
wherenamehas"Sherrell"
Employees
| where name has "Sherrell"

The has operator is useful here because we’re looking for only a partial match. If we wanted to look for an employee with a specific first and last name (an exact match), we’d use the == operator:

Employees
| where name == "Sherrell Dorsey"
  1. 🤔 Each employee at Madam C.J. Walker Manufacturing Company is assigned an IP address. Which employee has the IP address: “10.10.0.1”?

Here are some additional operators we like to use (**this might be useful later ;) ):

OperatorDescriptionCase-SensitiveExample (yields true)
==EqualsYes"aBc" == "aBc"
!=Not equalsYes"abc" != "ABC"
=~EqualsNo"abc" =~ "ABC"
containsRight-hand-side (RHS) occurs as a subsequence of left-hand-side (LHS)No"FabriKam" contains "BRik"
hasRHS is a whole term in LHSNo"North America" has "america"
has_allSame as has but works on all of the elementsNo"North and South America" has_all("south", "north")
has_anySame as has but works on any of the elementsNo"North America" has_any("south", "north")
inEquals to any of the elementsYes"abc" in ("123", "345", "abc")

While performing their day-to-day tasks, Walker Manufacturing Company employees send and receive emails. A record of each of these emails is stored in the Email table.

🎯Key Point – User Privacy and Metadata: As you can imagine, some emails are highly sensitive. Instead of storing the entire contents of every email sent and received within the company in a database that can be easily accessed by security analysts, we only capture email metadata.

Email metadata includes information like: the time the email was sent, the sender, the recipient, the subject line, and any links the email may contain. Storing only email metadata, rather than entire contents, helps protect the privacy of our employees, while also ensuring that our security analysts can keep us safe. Sometimes even metadata can reveal sensitive information, so it’s important that you don’t talk about log data with other employees outside the SOC.

We can find information about the emails sent or received by a user by looking for their email address in the sender and recipient fields of the Email table. For example, we can use the following query to see all the emails sent by “Sherrell Dorsey”:

Email
| where sender == "sherrell_dorsey1@mcjwalker.com"
  1. 🤔 How many emails did Wayne Sutton, the Marketing Coordinator, receive?

Easy as 1, 2, 3… Compound Queries and the distinct Operator

We can use the distinct operator to find unique values in a particular column. We can use the following query to determine how many of the organization’s users sent emails.

Email
| where sender has "mcjwalker.com"
| distinct sender
| count

This is our first time using a multi-line query with multiple operators, so let’s break it down:

In line 2, we take the Email table and filter the data down to find only those rows with “mcjwalker.com” in the sender column.

In line 3, we add another pipe character ( | ) and use the distinct operator to find all the unique senders. Here, we aren’t finding the unique senders for all of the email senders, but only the unique senders that are left after we apply the filter looking for rows with “mcjwalker.com” in the sender column.

Finally, in line 4, we add another pipe character ( | ) and then use the count operator to count the results of lines 1-3 of the query.

  1. 🤔 How many distinct senders were seen in the email logs from scavengers-r-us.org?

Tracking Down a Click: OutboundNetworkEvents Data

When employees at Madam C.J. Walker Manufacturing Company browse to a website from within the corporate network, that browsing activity is logged. This is stored in the OutboundNetworkEvents table, which contains records of the websites browsed by each user in the company. Whenever someone visits a website, a record of it is stored in the table. However, the user’s name is not stored in the table, only their IP address is recorded. There is a 1:1 relationship between users and their assigned IP addresses, so we can reference the Employees table to figure out who browsed a particular website. When a user visits a site, sometimes data from a lot of other sources are loaded as well. For example, images, assets, and other content may be hosted on content delivery network (CDN), which is used to deliver and load content quickly on a website. Sometimes, advertisements will also load from a particular website as well.

If we want to figure out what websites Felecia Hatcher visited, we can find their IP address from the Employees table.

Employees
| where name == "Felecia Hatcher"

The query above tells us their IP address is “10.10.0.79”. We can take their IP address and look in the OutboundNetworkEvents table to determine what websites they visited.

OutboundNetworkEvents
| where src_ip == "10.10.0.79"
  1. 🤔 How many unique websites did “Patricia Robinson” visit?

What’s in a Name? All about Passive DNS Data

Although domain names like “google.com” are easy for humans to remember, computers don’t know how to handle them. So, they convert them to machine readable IP addresses. Just like your home address tells your friends how to find your house or apartment, an IP address tells your computer where to find a page or service hosted on the internet.

🎯Key Point – Practice Good OPSEC: If we want to find out which IP address a particular domain resolves to, we could just browse to it. But, if the domain is a malicious one, you could download malicious files to your corporate analysis system or tip off the attackers that you know about their infrastructure. As cybersecurity analysts, we must follow procedures and safeguards that protect our ability to track threats. These practices are generally called operational security, or OPSEC.

To eliminate the need to actively resolve (that is- directly browse to or interact with a domain to find it’s related IP address) every domain we’re interested in, we can rely on passive DNS data. Passive DNS data allows us to safely explore domain-to-IP relationships, so we can answer questions like:

  • Which IP address does this domain resolve to?
  • Which domains are hosted on this IP address?
  • How many other IPs have this domain resolved to?

These domain-to-IP relationships are stored in our PassiveDns table.

  1. 🤔 How many domains in the PassiveDns records contain the word “power”? (hint: use the contains operator instead of has. If you get stuck, do a take 10 on the table to see what fields are available.)
  2. 🤔 What IP starting with a 196. did the domain “critical-power.net” resolve to (enter any one of them)?

🤯Let statements – making your life a bit easier:

Sometimes we need to use the output of one query as the input for a second query. The first way we can do this is by manually typing the results into the next query.

For example, what if we want to look at all the web browsing activity from employees named “James”?

First, you would need to go into the Employees table and find the IP addresses used by these employees.

Employees
| where name has "James"

Then, you could manually copy and paste these IPs into a query against the OutboundNetworkEvents table. Note that we can use the in operator to choose all rows that have a value matching any value from a list of possible values. In other words, the == (comparison) operator looks for an exact match, while the in operator checks for any values from the list

OutboundNetworkEvents
| where src-ip in ("192.168.1.132",
    "192.168.3.128",
    "192.168.1.70",
    "192.168.1.92",
    "192.168.0.147",
    "192.168.1.50",
    "192.168.0.163",
    "192.168.2.200")

Although this is a valid way to get the information you need, it may not be as elegant (or timely) if you had 100 or even 1000 employees named “James.”

We can accomplish this in a more elegant way by using a let statement, which allows us to assign a name to an expression or a function. We can use a let statement here to save and give a name to the results of the first query so that the values can be re-used later. That means we don’t have to manually type or copy and paste the results repeatedly.

let james_ips = 
Employees
| where name has "James"
| distinct ip_addr;
OutboundNetworkEvents
| where src_ip in (james_ips)

On the left of the let statement is the variable name (“james_ips” in this case). The variable name can be whatever we want, but it is helpful to make it something meaningful that can help us remember what values it is storing.

let james_ips = 
Employees
| where name has "James"
| distinct ip_addr;
OutboundNetworkEvents
| where src_ip in (james_ips)

On the right side of the let statement in the expression you are storing. In this case, we use the distinct operator to select values from only one column – so they are stored in an array – or list of values.

let james_ips = 
Employees
| where name has "James"
| distinct ip_addr;
OutboundNetworkEvents
| where src_ip in (james_ips)

The let statement is concluded by a semi-colon.

let james_ips = 
Employees
| where name has "James"
| distinct ip_addr;
OutboundNetworkEvents
| where src_ip in (james_ips)

After we store the value of a query into a variable using the let statement, we can refer to it as many times as we like in the rest of the query. The stored query does not show any output. Remember, however, that your KQL query must have a tabular statement – which means that you must have another query following your let statement.

  1. 🤔 How many unique URLs were browsed by employees named “Karen”?

🎯Key Point – Pivoting: Part of being a great cyber analyst is learning how to use multiple data sources to tell a more complete story of what an attacker has done. We call this “pivoting.” We pivot by taking one known piece of data in one dataset and looking in a different dataset to learn something we didn’t already know. You practiced this here when we started in one dataset – the Employees table – and used knowledge from there to find related data in another source – OutboundNetworkEvents.

Section 2: Start Hunting!

You’ve finished your training and you’re ready to get to work protecting Madam C.J. Walker Manufacturing Company.

Work with your team to complete as many challenge questions from the remaining sections in the scoreboard as possible! The goal is to score as many points as you can. There are a lot of questions (the attackers have been busy), so you probably won’t be able to answer them all. Just do as many as you can!

As you answer the questions, we will take you on a journey exploring the data and discovering what actions the adversaries have taken. However, you should remember that this is only one of many paths you can take through the data. As you go, don’t forget to pay attention to the details along the way. What patterns do the attackers exhibit that could help you track them better? Do they like to use certain words, themes? Or do they make mistakes? Keeping track of these patterns will help you build the full picture of what happened.

Use the provided Actor Preview document to keep track of what you know about the attacker. Building a good profile, timelining the attacker’s activity, and forming a list of indicators of compromise (IOCs) will help you keep track of the attacker. KC7 models some of the techniques used by these attackers from real-world threat actors, so it may be a helpful resource for you in the future when you are investigating a real security incident.

Now, get out there and keep us safe! The whole company is counting on you. No pressure😊.

Nice to Know

Here are some things that might be helpful to know as we explore the CJWalker Database:

Business hours

We operate our business from 9am to 5pm, 7 days a week. We should roughly expect to see all legitimate business activity within that timeframe (with some exceptions, of course). Let's be vigilant about any activity that occurs on the network while everyone sleeps ;)

Pay attention to the IT Workers

Our IT staff at Walker Manufacturing Computer are granted elevated privileges on machines across the company in order to fulfill their duties. As a result, it can be concerning when their machines get compromised. We are a security-aware organization, so we do not grant local administrative privileges to users on their computers. However, each laptop and desktop at company is provisioned with a separate local administrative account - which looks something like "marketing_local_admin." These administrator accounts are provisioned with the same username and password per department. For example, all employees in the Marketing department have a local administrator account with the username "marketing_local_admin" and the same password.

We use Active Directory

We utilize Active Directory, a directory service developed by Microsoft for Windows networks. It provides us with a centralized and standardized system for managing and organizing network resources, such as user accounts, computers, groups, and other network objects.

Unfortunately, compromising the Active Directory Domain Controller would give an adversary credentials for all accounts on our network and enable them to cause severe harm.

Alerts and Alert Fatigue

In the CJWalker database, we have access to a SecurityAlerts table that shows suspicious security events that have occurred on the network. This can be a great place to begin searching for malicious activity. However, we need to be aware that some of these alerts are false positives, which means they may indicate non-malicious activity. Let's be careful not to waste too much time chasing after these.

Resources

Understanding KQL operators: https://learn.microsoft.com/en-us/azure/data-explorer/kusto/query/datatypes-string-operators