Итак, обещанный сценарий, с комментариями
О том как его использовать, можно прочитать здесь.
param ( [switch]$CreateDatabase, #Включить поиск соответствующих событий в журнале и на их данных создать стартовую базу $Exclude="192.168.*", #Адреса подпадающие под эту маску будут игнорироваться. $DataFile="e:\scripts\Intruders.csv", #Файл журнала $SmtpServer="192.168.1.1", #SMTP сервер для отправки оповещений $ReportTo="Admin@Domain.ru", #Почтовый адрес администратора которому будут приходить оповещения $Sender = "Intrusion-ISA@Domain.ru" #Адрес отправителя ) #Если файл журнала не существует... if (-not (Test-Path $DataFile)) { #... то создаем новый и записываем в него заголовки столбцов Set-Content -Path $DataFile -Value 'Time,IP,Name,Attack,Network,Owner,Country' } #Функция для получения информации Whois #Использует утилиту whosip.exe (http://www.nirsoft.net/utils/whosip.html) function Get-Whois ($ip) { #Создаем пустой объект $result = New-Object PSObject #Разбирая вывод whosip.exe наполняем объект свойствами c:\scripts\whosip.exe $ip | where { $_ -match "(.+?): *(.+)" } | foreach { $result | Add-Member noteProperty ($matches[1] -replace " ") $matches[2]} #Возвращаем результат $result } #Функция выполняющая основную работу Function Audit-PortScan ( $Event, #Объект события Windows [switch]$Verbose, #Ключ указывает на необходимость вывода дополнительной информации на экран $Wait = 0, #Интервал который необходимо подождать перед обработкой следующего события [switch]$Report #Отправить отчет ) { #Вытаскиваем IP-адрес подозреваемого из текста события в переменную $Intruder $Intruder = $Event.Message -replace '^.+address ([\d\.]+)\..*$','$1' #В зависимости от ID события, помещаем в переменную $Attack соответствующее значение switch ($Event.EventId) { 15104 { # Well known port scan $Attack = "WellKnownPortScan" break } 15105 { # All port scan $Attack = "AllPortScan" break } 15108 { # Spoof $Attack = "Spoof" break } 15113 { # Connection limit exceeded $Attack = "Spoof" #Тут текст сообщения немного отличается, поэтому перезаписываем $Intruder $Intruder = $Event.Message -replace '^.+client: ([\d\.]+)\s.*$','$1' break } default { #Unknown #Если атака неизвестного ранее типа, то записываем сообщение о ней в отладочный лог $Attack = "Unknown" add-content e:\scripts\pfdebug.log ("" + $Event.EventId + ": " + $Event.Message) break } } #Если $Intruder пустой - значит по каким то причинам не удалось разобрать сообщение, записываем в лог ошибок if (-not $Intruder) {add-content e:\scripts\pfdebug.log "Error - empty intruder: '$($event.message)'"} #Если включен вывод отладочной информации - выводим на экран обрабатываемый IP. if ($Verbose) {write-host "Processing ip $Intruder `t" -n} if ($Intruder -like $Exclude) { if ($Verbose) {write-host "Excluded (local)"} return } #Получаем информацию whois в объект $Whois $Whois = Get-Whois $Intruder #Пытаемся разрешить IP адрес в имя с помощью утилиты nslookup.exe $Name = $(if ((nslookup $Intruder 2>$null)[3] -match "name:\s+(\S+)"){$matches[1]}else{""}) #Помещаем время генерации события в переменную $Time в формате UTC (чтобы легче было парсить обратно$Time = $Event.TimeGenerated.ToFileTimeUtc() #Если необходимо отправить отчет, то составляем сообщение if ($Report) { $Message = @" Attack of type $Attack performed from:`n$Intruder ($Name)`n Whois information:`n $([string]::join("`n",(e:\scripts\whosip.exe $Intruder|?{$_}))) `n `n "@ #Получаем объекты предыдущих атак из этой сети в переменную $Prev из файла журнала $Prev = @(import-csv $DataFile | where {$_.Network -eq $Whois.NetworkName}) if ($Prev) { #Дополняем текст сообщения информацией о предыдущих атаках из этой сети $Message += "`nThere is $($Prev.Count) scans from this network in database:`n" $Prev | foreach { $Message += "$([datetime]::FromFileTimeUTC($_.Time))" $Message += " `t$($_.Attack) from `t$($_.IP) ($($_.Name))`n" } } else { $Message += "There is no portscans from this network in database." } #Отправляем сообщение c:\scripts\Send-SmtpMail.ps1 -Server $SmtpServer -to $ReportTo -From $Sender -Subject "Intrusion Detected" -Body $Message } #Дописываем в журнал информацию об обработанном событии Add-Content -Path $DataFile -Value ("$Time,$Intruder,$Name,$Attack,$($Whois.NetworkName),$($Whois.OwnerName),$($Whois.Country)") #Фух. Я замучился комментировать... Интересно, кто-нибудь будет это читать?
if($Verbose) { if ($Whois.NetworkName) { write-host "Ok " -f "Green" -n write-host "[$Attack]`t$Name" -f "Gray" } else { write-host "Error" -f "Red" } } sleep $Wait } #Если необходимо создать стартовую базу if ($CreateDatabase) { #Получаем все подходящие события из журнала Windows и обрабатываем их Get-EventLog -LogName "application" | where {$_.Source -eq "Microsoft Firewall" -and $_.Category -eq "Packet Filter"} | foreach {Audit-PortScan $_ -Verbose -Wait 3} } else { #Иначе, обрабатываем только последнее событие $LastEvent = Get-EventLog -LogName "application" -Newest 10 | where {$_.Source -eq "Microsoft Firewall" -and $_.Category -eq "Packet Filter"} | select -First 1 Audit-PortScan $LastEvent -Report }
Файл сценария можно загрузить отсюда.









[...] разумеется следует В следующем посте я приведу текст сценария с комментариями. [...]
Уведомление от Улучшенные сообщения о сканировании портов от ISA Server 2004-2006 « PowerShell и другие скрипты — 28.5.2009 @ 11:42
Нужная штука.
Спасибо!
Комментарий от Pavel Shumarov — 29.5.2009 @ 16:17
Павел, спасибо!
Комментарий от Xaegr — 29.5.2009 @ 16:50