скрипт, наглядно выводящий форматированные время, IP-адреса и имена хостов, с которых неудачно пытались подключиться к Windows 2003 RDP-серверу согласно виндовому журналу событий. Для отслеживания таких попыток, необходимо включить аудит отказов во входе в систему для локальной политики аудита в параметрах безопасности (делается через оснастку secpol.msc, например). Скрипт будет полезен для открытых кишками наружу серверов терминалов.
В скрипте сразу предусмотрена возможность не выводить определенные адреса/имена хостов, или целые «диапазоны» (сравниваются строки а не маски).
'Event code 529 'кодировка ISO 8859-2 'Event code 529 ' '(0) Сбой входа в систему: '(1) Причина: неизвестное имя пользователя или неверный пароль '(2) Пользователь: user '(3) Домен: Domain '(4) Тип входа: 7 '(5) Процесс входа: User32 '(6) Пакет проверки: Negotiate '(7) Рабочая станция: workstation '(8) Имя вызывающего пользователя: user$ '(9) Домен вызывающего: Domain '(10) Код входа вызывающего: (0x0,0x3E7) '(11) Код процесса вызывающего: 2804 '(12) Промежуточные службы: - '(13) Адрес сети источника: 127.0.0.1 '(14) Порт источника: 123456 Dim ArrayOfValues(14) Dim ArrayOfIPExclusions(2) ArrayOfIPExclusions(0) = "192.168.0." ArrayOfIPExclusions(1) = "10.0." ArrayOfIPExclusions(2) = "10.10.10." Dim ArrayOfHOSTExclusions(0) ArrayOfHOSTExclusions(0) = "admin.max.org.ua" Set HOSTSDictionary = CreateObject("Scripting.Dictionary") strComputer = "." set objShell = createobject("wscript.shell") Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") Set dtmStartDate = CreateObject("WbemScripting.SWbemDateTime") Set dtmEndDate = CreateObject("WbemScripting.SWbemDateTime") DateStart = Now() - 120 DateStop = Now() dtmStartDate.SetVarDate DateStart, True dtmEndDate.SetVarDate DateStop, True Set colLoggedEvents = objWMIService.ExecQuery _ ("Select * from Win32_NTLogEvent Where Logfile = 'Security' AND EventCode = '529' AND EventType = 5 AND TimeWritten >= '" _ & dtmStartDate & "' AND TimeWritten "" then SplittedRow = Split(row, ":") ArrayOfValues(currentValue) = Trim(Replace(SplittedRow(1), Chr(9), "")) currentValue = currentValue + 1 end if Next IPExistsInExclusions = 0 IP = ArrayOfValues(13) 'сравним со списком IP адресов, которые исключаем из вывода скрипта for each row in ArrayOfIPExclusions if InStr(IP, row) > 0 then IPExistsInExclusions = 1 exit for end if next if IPExistsInExclusions = 0 then HOSTExistsInExclusions = 0 'если IP содержит лишние знаки имя хоста узнавать не будем strhost = " " if objRegEx.Replace(IP, "") = "..." then 'проверим, не получали ли мы имя хоста по этому IP раньше if HOSTSDictionary.Exists(IP) = false then 'http://social.technet.microsoft.com/Forums/en-US/ITCG/thread/f21292fd-e9d7-4a57-a14e-31461aeab905/ strParams = "%comspec% /c nslookup " & IP Set objExecObj = objShell.exec(strParams) do while not objExecObj.StdOut.AtEndOfStream strText = objExecObj.StdOut.Readline() if instr(strText, "Server") then strServer = trim(replace(strText,"Server:","")) elseif instr (strText, "Name") Then strhost = trim(replace(strText,"Name:","")) end if loop HOSTSDictionary.Add IP, strhost 'если получали - просто подставим это имя хоста else HOSTSDictionary.Exists(IP) strhost = HOSTSDictionary.Item(IP) end if 'сравним со списком хостов, которые исключаем из вывода скрипта for each row in ArrayOfHOSTExclusions if InStr(LCase(strhost), row) > 0 then HOSTExistsInExclusions = 1 exit for end if next end if if HOSTExistsInExclusions = 0 then IP = IP & Left(" ", 15 - Len(IP)) strhost = strhost & Left(" ", 40 - Len(strhost)) Wscript.Echo objDay & "." & objMonth & "." & objYear & " " & Mid(objEvent.TimeWritten, 9, 2) & ":" & Mid(objEvent.TimeWritten, 11, 2) & ":" & Mid(objEvent.TimeWritten, 13, 2) & "; IP: " & IP & " (" & strhost & "); user: " & ArrayOfValues(2) end if end if 'Wscript.Echo "Record Number: " & objEvent.RecordNumber 'Wscript.Echo "Source Name: " & objEvent.SourceName 'Wscript.Echo "Time Written: " & objEvent.TimeWritten 'Wscript.Echo "Event Type: " & objEvent.Type 'Wscript.Echo "User: " & objEvent.User Next
скачать: rdp.vbs (4329 Загрузок)
результатом выполнения такого скрипта из командной строки «cscript rdp.vbs > rdp.txt», будет файл, примерно такого содержания:
01.12.2012 13:53:25; IP: xx.xx.xx.xx (xx.xx.xx.xx.internet.net ); user: Администратор 01.12.2012 12:45:30; IP: xx.xx.xx.xx (xx.xx.xx.xx.internet.net ); user: Администратор 23.11.2012 18:06:23; IP: xx.xx.xx.xx (xx-xx-xx-xx-gprs.telefona.net ); user: user2 20.11.2012 14:25:25; IP: xx.xx.xx.xx (xx-xx-xx-xx-gprs.telefona.net ); user: user1 19.11.2012 17:48:20; IP: xx.xx.xx.xx (server17.max.org.ua ); user: Администратор
подчеркну, что скрипт необходимо сохранять в кодировке ISO 8859-2, или же скачать готовый файл выше.
кстати, хорошей идеей было бы прикручивание утилиты Whois от Марка Руссиновича, которая отображала бы данные по IP адресу в той же строке. Велкам в комментарии 🙂
UPD 05.12.12. Прикрутил получение имени хоста по IP если оно доступно, а также возможность исключить из вывода определенные имена хостов. Текст скрипта а также файл обновлены.
UPD 13.09.13. Добавил в запрос выборку в определенном интервале дат. В примере выбираются события за последние 120 дней. Оптимизировал процесс получения имени хоста — если оно уже было получено для IP-адреса то повторно запрашиваться не будет, а будет взято из соответствия. Также предусмотрел ситуацию, когда в поле IP события может попасть вовсе не IP-адрес. Также, из-за отбора в диапазоне дат данные в результат выводятся в возрастающем порядке, т.е. последние события будут в конце файла, что не очень удобно. Добавил комментарии в код.