1

Тема: WMI: Блокировка IP флудера

Всем привет! Давно не приходилось браться за vbscript, но сразу вспомнил домен данного форума, которым раньше активно пользовался. Комрады, прошу Вашей помощи!

Есть Win Serv 2008 R2, в силу некоторых обстоятельств, с установленным на нем вебсервером хостящий сайт. Сайт не особо важный и посещаемый, но нашелся ^%&#@^, который кладет его когда захочет.

Кладет его гет запросами, апач похоже захлебывается, пытаясь дать на каждый запрос ошибку 403. Вот что в логах:

94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283
94.180.132.30 - - [19/Feb/2016:16:20:00 +0300] "GET / HTTP/1.1" 403 283

Почитав про работу апача на win serv, не нашел ничего, что решило бы проблему. Все мнения сводятся примерно к одному, что веб сервер на винде обречен страдать от такой фигни, тк все это из-за особенностей стека вин сервера.

В таком случае, решил реализовать такой алгоритм при помощи vbs.

Скрипт будет мониторить лог файл апача, и например держать в памяти 50-500 последних строк лог файла. Далее, он анализирует этот массив, и если фиксируется присутствие флуда, создает либо локальную политику сервера, которая будет блокировать IP флудера, ну или еще что-то.

Как считаете, может такая мера сработать?

2

Re: WMI: Блокировка IP флудера

Ganzales
Немного некропостинга, плюс слегка оффтоп(с учётом запроса решения на WMI), но возможно вам пригодится мой вариант. У меня похожая ситуация - Windows Server 2003 Web Edition на хостинге(не особо загружен работой), соответственно пришлось озаботиться защитой RDP.
Для автоматизации использовал LogParser(для анализа логов безопасности на предмет брутфорса), и netsh для добавления правил блокировки. В Local Security Policy заранее было создан список правил(BruteForce) с запретом доступа(по всем протоколам/портам). Кстати, LogParser умеет работать и с текстовыми логами, так что может быть вы сможете его задействовать для работы с логом апача. В таком случае вам требуется только переписать функцию GetIPsFromLog под апач, поправить белый список, и создать список блокирующих правил в политике.
Скрипт проверяет лог безопасности(с начала текущих суток), если кол-во неудачных попыток авторизации больше 5 и IP не в белом списке, то он(IP) добавляется в запрещающее правило(если он ещё не там).

Option Explicit
' константы для работы с текстовыми файлами
Const ForReading = 1 :  Const ForWriting = 2 :  Const ForAppending = 8
Const TristateUseDefault = -2 :  Const TristateTrue = -1 :  Const TristateFalse = 0

' в NETSH регистр имён правил, списков и политик имеет значение!
Const FilterListName = "BruteForce" ' имя списка фильтров для добавления туда IP

' белый список - эти IP блочить нельзя!
Dim dWLIP : Set dWLIP = CreateObject("Scripting.Dictionary")
'dWLIP.Add "IP", "Description"
dWLIP.Add "1.2.3.6", "MyOffice Gate#1"
dWLIP.Add "1.2.3.9", "MyOffice Gate#1"

' LOG-файл
Dim WshShell, fso, BasePath
Set WshShell = WScript.Createobject("WScript.Shell")
Set fso = WScript.Createobject("Scripting.FileSystemObject")
BasePath = WshShell.CurrentDirectory
Dim logfile, LogTS
logfile = "auto_ban.log"
logfile = fso.BuildPath(BasePath,logfile)
If Not fso.FileExists(logfile) Then
  fso.CreateTextFile logfile, False,False
End If
Set LogTS = fso.GetFile(logfile).OpenAsTextStream(ForAppending, TristateFalse)
LogEcho String(80,"#"), True, True
LogEcho NOW & "|Session started; FilterList is: " & FilterListName, True, True

' подгружаем список ранее заблокированных адресов
Dim dBLIP : Set dBLIP = GetBlackList(FilterListName, dWLIP)
LogEcho NOW & "|Curent BL Loaded; " & dBLIP.Count & " entries.", True, True

Dim i ' десятилетия на рынке счётчиков для циклов

' получаем список нарушителей из журнала(Log Parser)
Dim dIntruders : Set dIntruders = GetIPsFromLog(dWLIP)

LogEcho NOW & "|Curent Intruders Loaded; " & dIntruders.Count & " entries.", True, True
' Проходим по списку и что-нибудь делаем
Dim BadGuys : BadGuys = dIntruders.Keys
Dim BadGuy
For i = LBound(BadGuys) To UBound(BadGuys)
  ' пробиваем по BL
  BadGuy = CStr(BadGuys(i))
  If dBLIP.Exists(BadGuy) Then
      LogEcho NOW & "|" & BadGuy & " is already in BL", True, True
    Elseif dWLIP.Exists(BadGuy) Then
      LogEcho NOW & "|" & BadGuy & " in WL!!! Ahtung!!!", True, True
    ElseIf GetCount(dIntruders(BadGuy)) > 5 Then  
      'блокируемс
      LogEcho NOW & "|" & BadGuy & ": Adding to the filterlist.", False, True
      If Not AddIPtoBL(BadGuy, dIntruders(BadGuy), FilterListName) Then
          LogEcho NOW & "|" & BadGuy & ": Error while adding to the filterlist.", True, True
          wscript.quit
        Else
          LogEcho NOW & "|" & BadGuy & ": Successfully added to the filterlist.", True, True
      End If
    Else
      wscript.echo "Count too small"
  End If
Next  

'###############################################################################
'######################### FUNCTIONS AND SUBROUTINES ###########################
'###############################################################################
' получение списка внёсённых в BL IP
Function GetBlackList(FLName, WIP) 'return Dictionary
  Dim WshShell : Set WshShell = WScript.CreateObject("WScript.Shell")
  Dim oExec : Set oExec = WshShell.Exec("netsh ipsec static show filterlist name=" & FLName & _
                                        " level=verbose format=table")
  Dim StdIn : Set StdIn = oExec.StdOut
  
  Dim NetshString : NetshString = StdIn.ReadAll 
  
  ' Выцепляем из выхлопа netsh адреса(кроме масок и IP сервера)
  Dim f_regEx : Set f_regEx = New RegExp
  Dim f_Match, f_Matches
  f_regEx.Ignorecase = True
  f_regEx.Global = True

  f_regEx.Pattern = "[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}"
  Set f_Matches = f_regEx.Execute(NetshString)
  
  Set GetBlackList = CreateObject("Scripting.Dictionary")
  'Проверка на валидность IP тут не требуется - во-первых, эти IP уже проверены;
  'во-вторых, в дальнейшем они используются только для проверки на наличие в BL добавляемых IP
  For Each f_Match In f_Matches
    f_Match = CStr(f_Match)
    If StrComp(f_Match, "255.255.255.255", 1) <> 0 And StrComp(f_Match, "0.0.0.0", 1) _ 
      And (Not GetBlackList.Exists(f_Match)) And (Not WIP.Exists(f_Match)) Then 
        GetBlackList.Add f_Match, f_Match
    End If
  Next
End Function


' список IP, замеченных в брутфорсе
Function GetIPsFromLog(WIP)
  Dim oLogQuery, oEventLogInput
  Set oLogQuery = CreateObject("MSUtil.LogQuery")
  Set oEventLogInput = CreateObject("MSUtil.LogQuery.EventLogInputFormat")
  
  Dim sQRY
  sQRY = "SELECT EXTRACT_TOKEN(strings, 11, '|') AS IP, COUNT(IP) AS Cntr, " & _
            "MIN(TimeWritten) AS FirstDate, MAX(TimeWritten) AS LastDate " & _
            "FROM security WHERE EventID = 529 " & _
            "AND TimeWritten >= TO_LOCALTIME(SUB(SYSTEM_TIMESTAMP(), TIMESTAMP('01-02', 'MM-dd'))) " & _
            "GROUP BY IP " & _
            "ORDER BY LastDate DESC"
  
  Dim oRecordSet, oRecord, IP, Descr
  Set oRecordSet = oLogQuery.Execute (sQRY, oEventLogInput)
  Set GetIPsFromLog = CreateObject("Scripting.Dictionary")  
  Do While Not oRecordSet.atEnd
  	Set oRecord = oRecordSet.getRecord
    IP = CStr(oRecord.getValue(0))
    wscript.echo "do: " & IP
    If StrComp(IP, "255.255.255.255", 1) <> 0 And StrComp(IP, "0.0.0.0", 1) _ 
      And (Not WIP.Exists(IP)) Then
        Descr = " Count: " & CStr(oRecord.getValue(1)) & _
                "; First Event: " & CStr(oRecord.getValue(2)) & _
                "; Last Event: "  & CStr(oRecord.getValue(3)) 
        GetIPsFromLog.Add IP, Descr
        WScript.Echo "Client IP Address: " & oRecord.getValue(0) & Descr
        
    End If
  	oRecordSet.moveNext
  Loop

End Function

' Add IP to IP Security Policy Filter List
Function AddIPtoBL(IP, Descr, FLName)
  Dim WshShell : Set WshShell = WScript.CreateObject("WScript.Shell")          
  Dim ExecString : ExecString = "netsh ipsec static add filter filterlist=" & FLName & _
                                        " srcaddr=Me dstaddr=" & IP & _
                                        " description=""" & Descr & """"
  LogEcho ExecString, True, True
  Dim oExec : Set oExec = WshShell.Exec(ExecString)
  Dim StdIn : Set StdIn = oExec.StdOut
  Dim NetshString : NetshString = StdIn.ReadAll 
  If InStr(NetshString, "ERR") = 0 And oExec.ExitCode = 0 Then
      wscript.echo "IP added to BL."
      AddIPtoBL = True
    Else
      wscript.echo "Something wrong.."
      AddIPtoBL = False
  End If
End Function
'###############################################################################
Function GetCount(SString)
  Dim f_regEx : Set f_regEx = New RegExp
  Dim f_Match, f_Matches
  f_regEx.IgnoreCase = True
  f_regEx.Global = True
  f_regEx.Pattern = "Count: ([\d]+);"
  Set f_Matches = f_regEx.Execute(SString)
  GetCount = CInt(f_Matches(0).SubMatches(0))
End Function       
                                        
Sub LogEcho(s_Text, s_Log, s_Echo) ' эхо + запись в лог
 If s_Log Then LogTS.WriteLine s_Text
 If s_Echo Then wscript.echo s_Text
End Sub

P.S. Изначально мне было интересно, сколько правил осилит политика... Код работает с декабря 2013, текущее кол-во блоков - 7049. Пока проблем не наблюдается. Если кому-то интересен список(сразу добавить в блокировку), в прилагаемом файле список текущих правил. Последний рекордсмен за 5 минут(частота запуска скрипта) успел 420 попыток предпринять .

Post's attachments

ip_list.7z 45.92 kb, 4 downloads since 2016-05-11 

You don't have the permssions to download the attachments of this post.