скрипт, наглядно выводящий форматированные время, 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 (4455 Загрузок)
результатом выполнения такого скрипта из командной строки «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-адрес. Также, из-за отбора в диапазоне дат данные в результат выводятся в возрастающем порядке, т.е. последние события будут в конце файла, что не очень удобно. Добавил комментарии в код.