← Back to blog

The Grid (PowerShell)

Challenge

  • Event: SANS NetWars — PowerShell
  • Category: PowerShell / DFIR
  • Setting: a restricted PowerShell terminal on “The Grid” laser-research host (Ctrl+C and endless loops are blocked)

Writeup

Process triage

The first task is to identify and stop a set of suspect processes, capturing the owning user of each before terminating them in order:

$processNames = @('circuitrix', 'byteflow', 'glowpath', 'netrider')

# Resolve each process to its owner via WMI
Get-Process |
  Where-Object { $processNames -contains $_.Name } |
  Select-Object Name, @{
    Name       = "Username";
    Expression = { (Get-WmiObject Win32_Process -Filter "ProcessId = $($_.Id)" |
                    Select-Object -ExpandProperty GetOwner).User }
  } | Format-Table -AutoSize

# Stop them in the specified order
foreach ($name in $processNames) {
    Stop-Process -Name $name -Force -ErrorAction SilentlyContinue
}

Event-log analysis

A serialized event log (EventLog.xml, CLIXML from Export-Clixml) holds Sysmon records. The goal is the event that appears exactly once — found by grouping on the Id property and keeping the singleton:

$xml = [xml](Get-Content -Path "/etc/systemd/system/timers.target.wants/EventLog.xml")
$xml.Objs.Obj |
  ForEach-Object { $_.Props.I32 | Where-Object { $_.N -eq "Id" } } |
  Group-Object -Property InnerText |
  Where-Object { $_.Count -eq 1 } |
  ForEach-Object {
    $uniqueId = $_.Name
    $xml.Objs.Obj |
      Where-Object { $_.Props.I32.InnerText -eq $uniqueId } |
      Select-Object -First 1 -ExpandProperty Props
  }

The records are Microsoft-Windows-Sysmon/Operational events (e.g. Network connection detected) running as S-1-5-18 (SYSTEM) on host gridresearch.

The laser Web API

The final stage is a local Flask service (Werkzeug/3.0.3) controlling the “Laser Power Supply.” The terminal’s MOTD points at it:

(Invoke-WebRequest -Uri http://localhost:1225/).RawContent          # API help
(Invoke-WebRequest -Uri http://localhost:1225/api/on).RawContent    # -> "Laser Power Supply Turned On"

An attacker had altered the laser settings through this API and left a calling card at /home/callingcard.txt. Following those clues, the correct settings are re-applied via the API to drive the laser back to the target output of 5 Mega-Megajoules per liter, completing the mission.