PoC CSC1 – Identifiera okända enheter

I SANS kritiska säkerhetskontroller är den första kontrollen “Inventera och hantera tillåtna och otillåtna enheter”. För att få bättre kontroll över sitt nätverk, vill man kunna säkerställa att det bara finns betrodda enheter inkopplade och att man får larm om en obehörig enhet ansluter. Samtidigt vill man få kontroll över att processen för att registrera klienter i CMDB efterlevs. Vårt exempel är ett alternativ till om man inte kan eller vill köra 802.1x (eller som ett komplement till 802.1X). Det kan även användas för att verifiera att endast registrerade gäster ansluter sig till ett gäst-nät.

I den här bloggposten publicerar vi ett proof-of-concept som bygger på följande princip.
Vi har byggt ett Powershell skript som inventerar registrerade enheter med aktiva lån från en DHCP server.

  • Dessa enheter jämförs sedan mot en Microsoft Deployment Toolkit (MDT) databas där enheternas MAC-adresser finns registrerade, samt en extern CSV lista över övriga behöriga enheter som inte är deployade; t.ex. mobiltelefoner och pekplattor.
  • De enheter som inte kunnat verifieras genererar ett ”Unknown Computer” event i eventloggen för möjlighet till övervakning och automatiska larm.

Källan DHCP kan med fördel bytas ut mot t.ex. en switch för att omfatta också adresser som inte registreras i DHCP. MDT-databasen skulle också kunna vara annan valfri CMDB källa så som t.ex. Service Manager.

Function Get-DHCPLease {
[CmdletBinding()]
param
(
[PSCustomObject]$DHCPLeases,
[parameter(Mandatory = $true)]
[String]
$ComputerName,
[parameter(Mandatory = $false)]
[String]
$ScopeId = ""
)
# Verify if ScopeId has been defined, if not retrieve all scopes
If ($ScopeId -eq "") {
$Measure = Measure-Command { $DHCPLeases += Get-DhcpServerv4Scope -ComputerName $ComputerName -ErrorAction SilentlyContinue | Get-DhcpServerv4Lease -ComputerName $ComputerName | Where AddressState -eq Active | Select ClientId,IPAddress,HostName,LeaseExpiryTime }
Write-Verbose "Retrieved`t$($DHCPLeases.count) Active DHCP leases from server '$($DHCPServer)' in $($Measure.Milliseconds) milliseconds"
} Else {
$Measure = Measure-Command { $DHCPLeases += Get-DhcpServerv4Scope -ComputerName $ComputerName -ScopeId $ScopeId -ErrorAction SilentlyContinue | Get-DhcpServerv4Lease -ComputerName $ComputerName | Where AddressState -eq Active | Select ClientId,IPAddress,HostName,LeaseExpiryTime }
Write-Verbose "Retrieved`t$($DHCPLeases.count) Active DHCP leases from server '$($DHCPServer)' and ScopeId '$($DHCPScopeId)' in $($Measure.Milliseconds) milliseconds"
}
Return $DHCPLeases
}
Function Add-EventLog {
[CmdletBinding()]
param
(
[parameter(Mandatory = $true)]
[System.String]
$ClientId,
[parameter(Mandatory = $true)]
[System.String]
$IPAddress,
[parameter(Mandatory = $true)]
[System.String]
$HostName,
[parameter(Mandatory = $true)]
[System.String]
$LeaseExpiryTime
)
# Create Event Log Source information if it does not exist
Try {
If (!([System.Diagnostics.EventLog]::SourceExists("Unknown Device"))) { New-EventLog –LogName Application –Source “Unknown Device” }
} Catch { Write-Verbose "Could not create new Event Source";Break }
Try {
# Define parameters to be written to the Event Log entry
$Properties = @{
Message = "ClientId: $ClientId`r`nIPAddress: $IPAddress`r`nHostName: $HostName`r`nLeaseExpiryTime: $LeaseExpiryTime"
LogName = "Application"
Source = "Unknown Device"
EntryType = "Warning"
EventId = "1234"
Category = "0"
}
# Create a new Event Log entry
Write-EventLog @Properties -ErrorAction Stop
} Catch { Write-Error "Failed to create Event Log for unknown device $($ClientId) and IPAddress $($IPAddress)";Write-Error $_.Exception.Message }
}
Function Get-UnknownDevice {
[CmdletBinding()]
param
(
[parameter(Mandatory = $true)]
[System.String]
$DHCPServer,
[parameter(Mandatory = $false)]
[System.String]
$DHCPScopeId = "",
[parameter(Mandatory = $true)]
[System.String]
$SQLServerInstance,
[parameter(Mandatory = $true)]
[System.String]
$SQLDatabase,
[parameter(Mandatory = $true)]
[System.String]
$Whitelist,
[parameter(Mandatory = $false)]
[Switch]
$LogEvent
)
# Import SQL Server Powershell Module if needed
If (-Not(Get-Module SQLPS)) {
$Measure = Measure-Command { Import-Module SQLPS -DisableNameChecking -Verbose:$false | Out-Null }
Write-Verbose "Imported Powsershell Module SQLPS in $($Measure.Milliseconds) milliseconds"
Write-Verbose "--------------------------------------------------------------"
}
# SQL Server options
[String]$SQLQuery= "SELECT OSDComputerName,MacAddress FROM dbo.ComputerSettings"
# Declare objects for processing
[PSCustomObject]$Measure = Measure-Command { $WhitelistCSV = Import-Csv $Whitelist -ErrorAction SilentlyContinue | Select ClientId,HostName }
Write-Verbose "Retrieved`t$($WhitelistCSV.count) devices from whitelist file '$($Whitelist)' in $($Measure.Milliseconds) milliseconds"
[PSCustomObject]$DHCPLeases = Get-DHCPLease -ComputerName $DHCPServer -ScopeId $DHCPScopeId
[PSCustomObject]$Measure = Measure-Command { $MDTComputerObjects = Invoke-Sqlcmd –ServerInstance $SQLServerInstance –Database $SQLDatabase –Query $SQLQuery -ErrorAction SilentlyContinue }
Write-Verbose "Retrieved`t$($MDTComputerObjects.count) computer objects from the '$($SQLDatabase)' database on server '$($SQLServerInstance)' in $($Measure.Milliseconds) milliseconds"
# Declare variable to determine number of unknown devices
[int]$KnownDevices = 0
[int]$UnknownDevices = 0
# Verify each active DHCP lease
$Measure = Measure-Command {
ForEach ($DHCPLease in $DHCPLeases) {
# Replace separator to match information in MDT database
$ClientId = $DHCPLease.ClientId.Replace("-",":")
# Check if device exist in the MDT database or in Whitelist CSV
If ((!($MDTComputerObjects.MacAddress -Like '*' + $ClientId.ToUpper() + '*')) -And ($ClientId -NotIn $WhitelistCSV.ClientId)) {
$UnknownDevices += 1
# Add unidentified device to the Event Log
If ($LogEvent) {
$MeasureEvent += Measure-Command {
Try {
Add-EventLog -ClientId $DHCPLease.ClientId -IPAddress $DHCPLease.IPAddress -HostName $DHCPLease.HostName -LeaseExpiryTime $DHCPLease.LeaseExpiryTime
} Catch { Write-Error "Failed to create Event Log for unknown device $($DHCPLease.ClientId) and IPAddress $($DHCPLease.IPAddress)";Write-Error $_.Exception.Message }
}
}
} Else { $KnownDevices += 1 }
}
}
# Write verbose status information
Write-Verbose "Identified`t$($KnownDevices) known devices based on MAC address in $([math]::Round(($Measure.Milliseconds-$MeasureEvent.Milliseconds)/2)) milliseconds"
If ($LogEvent) { Write-Verbose "Determined`t$($UnknownDevices) unknown devices based on MAC address and added them to the Event Viewer Application log in $([math]::Round((($Measure.Milliseconds-$MeasureEvent.Milliseconds)/2)+$MeasureEvent.Milliseconds)) milliseconds" }
Else { Write-Verbose "Determined`t$($UnknownDevices) unknown devices based on MAC address in $([math]::Round($Measure.Milliseconds/2)) milliseconds" }
# Remove SQL Server Powershell Module from memory
If (Get-Module SQLPS) {
Set-Location $env:SystemDrive
Write-Verbose "--------------------------------------------------------------"
$Measure = Measure-Command { Remove-Module SQLPS -Verbose:$false | Out-Null }
Write-Verbose "Removed Powsershell Module SQLPS in $($Measure.Milliseconds) milliseconds"
}
}
Get-UnknownDevice -DHCPServer 10.101.0.27 -DHCPScopeId 10.101.0.0 -SQLServerInstance 'ADLSESTODEP001\SQLEXPRESS' -SQLDatabase MDT -Whitelist 'C:\Temp\DHCPLeases.csv' -Verbose -LogEvent

Om ni har några frågor om skriptet eller andra frågor om SANS kritiska säkerhetskontroller så kontakta gärna oss på Addlevel!

Med vänliga hälsningar,

Peter Ericsson

Posted in CSC, Security.