PowerShell и другие скрипты

28.5.2009

Улучшенные сообщения о сканировании портов от ISA Server 2004-2006

Рубрика: ISA — Метки: , , , — Xaegr @ 11:40

Итак, обещанный сценарий, с комментариями :) О том как его использовать, можно прочитать здесь.

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
}            

Файл сценария можно загрузить отсюда.

Комментарии (3) »

  1. [...] разумеется следует В следующем посте я приведу текст сценария с комментариями. [...]

    Уведомление от Улучшенные сообщения о сканировании портов от ISA Server 2004-2006 « PowerShell и другие скрипты — 28.5.2009 @ 11:42

  2. Нужная штука.
    Спасибо!

    Комментарий от Pavel Shumarov — 29.5.2009 @ 16:17

  3. Павел, спасибо! :)

    Комментарий от Xaegr — 29.5.2009 @ 16:50


RSS-лента комментариев к этой записи. URI для обратной ссылки

Оставить комментарий

Блог на WordPress.com.