Skip to main content

Lab 7.1: Enumeration of Windows Services

Learning Objectives​

By the end of this lab, you will be able to:

  • Enumerate all services on a Windows system
  • Identify vulnerable services
  • Understand security risks related to services
  • Create service audit reports

Estimated Duration​

40 minutes

Prerequisites​

  • Windows 10/11 VM
  • Administrator rights
  • Basic PowerShell knowledge

Professional Context​

Service enumeration is essential for:

  • Security audits
  • Persistent malware detection
  • Performance optimization
  • Regulatory compliance

Part 1: Basic Enumeration​

Step 1.1: Use services.msc​

  1. Open services.msc
  2. Observe the list of services
  3. Sort by "Status" to see active services

Question 1: How many services are running?

Step 1.2: PowerShell Enumeration​

# All services
Get-Service | Measure-Object

# Running services
Get-Service | Where-Object {$_.Status -eq "Running"} | Measure-Object

# Stopped services
Get-Service | Where-Object {$_.Status -eq "Stopped"} | Measure-Object

Question 2: How many services are stopped?

Step 1.3: Service Details​

# View details
Get-Service | Select-Object Name, DisplayName, Status, StartType |
Sort-Object Status -Descending |
Format-Table -AutoSize

Part 2: Advanced Enumeration with WMI​

Step 2.1: Detailed Information​

WMI provides more information than Get-Service:

Get-WmiObject Win32_Service | Select-Object `
Name,
DisplayName,
State,
StartMode,
@{N='Account';E={$_.StartName}},
PathName |
Format-Table -AutoSize

Step 2.2: Services by Execution Account​

# Group by account
Get-WmiObject Win32_Service |
Group-Object StartName |
Select-Object Count, Name |
Sort-Object Count -Descending

Question 3: Which account runs the most services?

Step 2.3: LocalSystem Services (high privilege)​

# Services running as LocalSystem
Get-WmiObject Win32_Service |
Where-Object {$_.StartName -eq "LocalSystem"} |
Select-Object Name, DisplayName, State, PathName |
Format-Table -AutoSize

Question 4: How many services run as LocalSystem?


Part 3: Vulnerability Detection​

Step 3.1: Unquoted Service Paths​

Paths with spaces without quotes are vulnerable:

# Detect unquoted paths
Get-WmiObject Win32_Service | Where-Object {
$_.PathName -notmatch '^"' -and
$_.PathName -match ' ' -and
$_.PathName -notmatch '^[A-Za-z]:\\Windows'
} | Select-Object Name, PathName

Explanation: If a service has the path C:\Program Files\App\service.exe, Windows will search in order:

  1. C:\Program.exe
  2. C:\Program Files\App\service.exe

An attacker can place C:\Program.exe to hijack execution.

Step 3.2: Permissions on Executables​

# Check service binary permissions
Get-WmiObject Win32_Service | ForEach-Object {
$serviceName = $_.Name
$path = $_.PathName

# Extract executable path
if ($path -match '^"([^"]+)"') {
$exePath = $matches[1]
} elseif ($path -match '^(\S+)') {
$exePath = $matches[1]
} else {
$exePath = $path
}

if (Test-Path $exePath -ErrorAction SilentlyContinue) {
$acl = Get-Acl $exePath -ErrorAction SilentlyContinue

# Check if non-admin users have write rights
$vulnerable = $acl.Access | Where-Object {
($_.IdentityReference -match "Users|Everyone|Authenticated") -and
($_.FileSystemRights -match "Write|Modify|FullControl")
}

if ($vulnerable) {
[PSCustomObject]@{
Service = $serviceName
Path = $exePath
VulnerableACL = $true
}
}
}
} | Format-Table -AutoSize

Step 3.3: Services with Suspicious Paths​

# Services in unusual paths
Get-WmiObject Win32_Service | Where-Object {
$_.PathName -match "\\Temp\\" -or
$_.PathName -match "\\AppData\\" -or
$_.PathName -match "\\Downloads\\" -or
$_.PathName -match "\\Desktop\\"
} | Select-Object Name, DisplayName, PathName

Question 5: Are there any services in suspicious paths?


Part 4: Dependency Analysis​

Step 4.1: Critical Services​

# Services on which others depend
Get-Service | ForEach-Object {
$service = $_
$dependents = Get-Service -DependentServices $service.Name -ErrorAction SilentlyContinue

if ($dependents.Count -gt 0) {
[PSCustomObject]@{
Service = $service.DisplayName
DependentCount = $dependents.Count
Dependents = ($dependents.DisplayName -join ", ")
}
}
} | Where-Object {$_.DependentCount -gt 0} |
Sort-Object DependentCount -Descending |
Select-Object -First 10

Step 4.2: Dependency Chain​

# View dependencies of a specific service
$serviceName = "Dnscache"

Write-Host "=== $serviceName ===" -ForegroundColor Cyan
Write-Host "`nRequired services:" -ForegroundColor Yellow
Get-Service $serviceName -RequiredServices | Select-Object DisplayName, Status

Write-Host "`nDependent services:" -ForegroundColor Yellow
Get-Service $serviceName -DependentServices | Select-Object DisplayName, Status

Part 5: Audit Report​

Step 5.1: Complete Audit Script​

# Service audit script
$reportPath = "$env:USERPROFILE\Desktop\audit_services.txt"

$report = @"
================================================================================
WINDOWS SERVICES AUDIT REPORT
$(Get-Date -Format "yyyy-MM-dd HH:mm:ss")
================================================================================

SUMMARY
------
"@

# Statistics
$allServices = Get-WmiObject Win32_Service
$running = ($allServices | Where-Object {$_.State -eq "Running"}).Count
$stopped = ($allServices | Where-Object {$_.State -eq "Stopped"}).Count
$auto = ($allServices | Where-Object {$_.StartMode -eq "Auto"}).Count

$report += @"

Total services: $($allServices.Count)
Running: $running
Stopped: $stopped
Automatic start: $auto

SERVICES BY EXECUTION ACCOUNT
-------------------------------
"@

$byAccount = $allServices | Group-Object StartName | Sort-Object Count -Descending
foreach ($group in $byAccount) {
$report += "`n$($group.Name): $($group.Count)"
}

# Unquoted paths
$unquoted = $allServices | Where-Object {
$_.PathName -notmatch '^"' -and
$_.PathName -match ' ' -and
$_.PathName -notmatch '^[A-Za-z]:\\Windows'
}

$report += @"

POTENTIAL VULNERABILITIES
---------------------------
Unquoted paths: $($unquoted.Count)
"@

if ($unquoted) {
foreach ($svc in $unquoted) {
$report += "`n - $($svc.Name): $($svc.PathName)"
}
}

# Suspicious paths
$suspect = $allServices | Where-Object {
$_.PathName -match "\\(Temp|AppData|Downloads|Desktop)\\"
}

$report += "`n`nServices in suspicious paths: $($suspect.Count)"
if ($suspect) {
foreach ($svc in $suspect) {
$report += "`n - $($svc.Name): $($svc.PathName)"
}
}

$report += @"

================================================================================
END OF REPORT
================================================================================
"@

# Save
$report | Out-File $reportPath -Encoding UTF8
Write-Host "Report saved: $reportPath" -ForegroundColor Green

# Display
$report

Step 5.2: Run the Audit​

# Run the script
.\audit_services.ps1

Deliverables​

  1. Answers to the 5 questions

  2. Audit report generated by the script

  3. Screenshots:

    • services.msc
    • PowerShell enumeration result
    • Potentially vulnerable services
  4. Analysis (1 page):

    • Key observations
    • Identified risks
    • Recommendations

Evaluation Criteria​

CriteriaPoints
Basic enumeration20%
WMI enumeration20%
Vulnerability detection30%
Audit report30%

Reference Commands​

# Services
Get-Service
Get-WmiObject Win32_Service

# Filtering
Where-Object {$_.Status -eq "Running"}

# Selection
Select-Object Name, DisplayName, Status

# Grouping
Group-Object StartName

# ACL
Get-Acl path

Lab developed as part of the Operating Systems course - MODULE 7