В статье "Определение членства в группах" (http://www.osp.ru/text/302/3430275/), я описывал сценарий, позволяющий быстро выполнять периодический аудит состава ключевых локальных и глобальных группах на ваших серверах. Данный инструмент предоставит вам хорошие "снимки" членства в группах, пригодные, например, для ежеквартального аудита, но не поможет при необходимости отслеживания ежедневных изменений состава групп, связанных с добавлениями или удалениями из групп учетных записей. Разумеется, в процессе аудита хорошо иметь возможность выявления пользовательских учетных записей с излишне широкими полномочиями, но лучше заранее и максимально быстро обнаруживать потенциальные проблемы.
Сравнение списков
В сценарии GroupMembershipTracker.bat (листинг 3), используются утилиты Local и Global, которые входят в состав пакетов Microsoft Windows 2000 Server Resource Kit и Microsoft Windows NT Server 4.0 Resource Kit. С их помощью периодически формируется список членов групп на данный момент времени, после чего сценарий сравнивает данный список с тем, который был получен ранее.
Далее с помощью команды Findstr выполняется построчное сравнение содержимого старого и нового файлов. При выявлении любого несовпадения (если в группу был добавлен либо удален пользователь) посылается уведомление. Отмечу, что GroupMembershipTracker .bat не только посылает уведомляющее сообщение, но и создает журнальный файл timestamped log, поэтому есть возможность просматривать полную историю изменений. Если же изменения не обнаружены, то не требуется и уведомление.
Предполагается, что с помощью данного сценария вы будете следить за составом ключевых групп администраторов, а не групп, в которые входят сотни членов. Разумеется, GroupMembershipTracker .bat можно использовать и для этих целей, но при этом необходимо понимать, что его выполнение в данном случае потребует времени. В большинстве доменов и OU обычно имеется от 6 до 10 ключевых групп, таких как Domain Admins, OU Admins, GPO Admins, Local PC Admins, а также других групп с административными полномочиями, действующими по всему домену, состав которых требует постоянного пристального внимания.
Использование утилиты Blat
Blat - это свободно распространяемая утилита, позволяющая отсылать почтовые сообщения из сценариев командной строки. Применительно к GroupMembershipTracker.bat, Blat позволяет организовать отсылку уведомления по почте при появлении новой группы в списке слежения за локальными или глобальными группами. Данную утилиту можно загрузить по адресу: http://www.interlog.com/~tcharron/blat.html. В сценарии GroupMembershipTracker.bat показан синтаксис вызовы Blat для взаимодействия с серверами SMTP, не требующими аутентификации. Использование ключей аутентификации –u и –pw описывается в документации по данной утилите.
Резюме
Файл GroupMembershipTracker.bat совместим с системами Windows XP, Windows 2000 и Windows NT 4.0. Для того чтобы подготовить сценарий GroupMembershipTracker.bat к запуску в своей инфраструктуре выполните следующие действия:
- Поместите файл сценария в выделенный каталог того сервера или рабочей станции, с которых вы собираетесь запускать данный сценарий по расписанию.
- Определите, какие локальные и глобальные группы вы собираетесь контролировать. Создайте соответствующие входные файлы, localgroups.txt и globalgroups.txt и поместите их в тот же каталог, в котором находится файл GroupMembershipTracker.bat. Если вы собираетесь работать только с локальными, но не глобальными группами или наоборот, то не нужно создавать пустой входной файл. Сценарий просто не найдет отсутствующий входной файл и перейдет к следующему.
- Настройте файл GroupMembershipTracker.bat для работы в своей среде. В Листинге 1 показано, в какие именно строки кода потребуется внести изменения. Во-первых, задайте имя домена, в котором находятся интересующие вас группы. Если нужно отслеживать группы более чем в одном домене, тогда придется запускать несколько экземпляров сценария или модифицировать его код так, чтобы он мог работать с несколькими доменами. Затем необходимо указать в начале сценария корректные почтовые адреса To и From, которые будет использовать Blat для отправки уведомлений по почте. В строку To может быть включено несколько адресов получателей, каждый из которых должен отделяться друг от друга запятой, но без пробелов. И последнее, что следует сделать - это указать имя сервера SMTP, который будет использоваться утилитой Blat для отправки уведомлений.
- Убедитесь, что все используемые в сценарии утилиты (now.exe, local.exe, global.exe и blat.exe) находятся в том же каталоге, из которого будет запускаться сценарий. Как показано в Листинге 2, сценарий записывает данные о размещении каталогов в переменную %~dp1. Знак процента (%) указывает на то, что это заменяемый параметр. Что касается обозначения ~dp1, то оно предписывает механизму сценария считывать букву, обозначающую диск (d) и путь (p). Соответственно, если полный путь к сценарию C:AdminScriptsGroupMembershipTracker.bat, то в этом случае переменная %~dp1 содержит информацию о размещении каталога C:AdminScripts. Таким образом, если вы размещаете утилиты не в том же самом каталоге, в котором находится файл сценария, либо хотите разместить входные файлы в каком-либо другом месте, то нужно внести в код Листинга 2 изменения и указать правильный путь к каталогу с утилитами.
- Проверьте работу сценария в ручном режиме и убедитесь, что он должным образом отслеживает изменения, вносимые в группы, фиксирует их в файле журнала и отсылает соответствующие уведомления. Для каждой из групп, которую вы выбрали для наблюдений, сценарий создает временный каталог, поэтому у вас есть возможность сравнить результаты предыдущего выполнения сценария с вновь полученными результатами. По-видимому, лучше создать одну или две тестовые группы (чтобы не трогать "рабочие" группы вашей инфраструктуры), в которых проводить эксперименты по включению и исключению из них пользователей для проверки работы механизма уведомлений.
- Продумайте, как часто вы собираетесь запускать сценарий. В принципе, в расписании можно задать периодичность запуска величиной в одну или несколько минут, но, вероятно, вполне достаточно запускать данную процедуру один или два раза в день. Для создания расписания запуска сценария воспользуйтесь Планировщиком заданий (Task Scheduler).
Изначально данный сценарий разрабатывался с целью отслеживания внесения непреднамеренных изменений в состав групп. Если же вы хотите выявлять нарушения в системе безопасности или ситуации, связанные с предумышленными изменениями членства в группах, которые влекут за собой дисциплинарное наказание или увольнение сотрудника, тогда нужно иметь в виду ряд дополнительных аспектов. В данном случае, по-видимому, придется запускать данный сценарий на компьютере или сервере с достаточно малой периодичностью, при этом желательно ограничить круг лиц, знающих о его существовании и месте размещения. Если пользователь имеет доступ к месту размещения файлов состояния групп, а также право вносить изменения (Change), то, в принципе, он может соответствующим образом отредактировать эти файлы, скрыв, таким образом, внесенные изменения. Для того чтобы иметь возможность четко отслеживать подобные преднамеренные действия имеет смысл использовать данный сценарий в сочетании с процедурами аудита и мониторинга журнала безопасности.
Сценарий GroupMembershipTracker.bat дает возможность контролировать состав ключевых групп в ИТ-инфраструктуре. При этом уменьшается количество неприятных сюрпризов, выявляемых в процессе аудита, а еще вы получаете "лишнюю пару глаз", следящих за составом групп, что позволяет быть уверенным что в вашем домене или OU нет нарушений требований безопасности, связанных с некорректным членством пользователей в группах.
Листинг 1. Основные параметры настройки
Set Domain=London
Set Recipients=FredSmith@yourcompany.com
Set From=CindyWong@yourcompany.com
Set Mailserver=mailserver.yourcompany.com
Листинг 2. Конфигурирование пути к месту размещения утилит
BEGIN COMMENT
:: Данный код размещается в модуле:routine сценария. Если утилиты
:: размещены не в том каталоге из которого запускается сценарий,
:: подставьте вместо =%~dp1 полный путь к месту размещения утилит.
END COMMENT
Set FolderLocation=%~dp1
Листинг 3. Файл GroupMembershipTracker.bat
:: Create a folder and place this script in that folder.
:: Create two input text files for local and glabal groups you want to monitor.
:: These should be named LocalGroups.txt and GlobalGroups.txt.
:: Put on group per line in each file.
:: Note: If you don't have all local or all global groups to track you need not create the input file.
:: The script will fail quietly if it can't find an input file and move on.
:: Locate these two files in the same folder you previously created.
:: If the Now.exe, Local.exe and Global.exe tools from the Resource Kit and the Blat freeware utility
:: are not available locally, you will need to configure the path to these in the code.
Set Domain=London
Set Recipients=FredSmith@yourcompany.com
Set From=CindyWong@yourcompany.com
Set Mailserver=mailserver.yourcompany.com
:: ******************************************************************************
:: The only configuration required below this point is the path to the Local Global and Blat utilities.
:: If these are in the path, no changes are needed.
:: ******************************************************************************
call :routine %0
EXIT
:routine
Set FolderLocation=%~dp1
if exist "%FolderLocation%mailcontents.txt" del "%FolderLocation%mailcontents.txt"
:: Run first against Local groups and then another run against Global groups
For /D %%i in (Local Global) do (Set GrpType=%%i) & (Call :Getmem)
:: If there is a mailcontents files this indicates a mail message needs to be sent.
if exist "%FolderLocation%mailcontents.txt" Call :Blat
ECHO Run complete
GOTO :EOF
:Getmem
for /f "tokens=*" %%i in (%FolderLocation%%GrpType%Groups.txt) do (set Group=%%i) & (Call :Next)
GOTO :EOF
:Next
:: Cleanup any new files that might be in the folder.
:: Delete any old sendmail file.
if exist "%FolderLocation%%Group%-%GrpType%-new.txt" del "%FolderLocation%%Group%-%GrpType%-new.txt"
if exist "%FolderLocation%sendmail.txt" del "%FolderLocation%sendmail.txt"
:: Run the Local and global commands to get a list of the current group members
:: Note: If these don't exist on the node the script runs on be sure to change the path to their remote location.
if "%GrpType%"=="Local" for /F "tokens=*" %%i in ('Local.exe "%Group%" %Domain% ^| sort') do echo %%i>>
"%FolderLocation%%Group%-%GrpType%-new.txt"
if "%GrpType%"=="Global" for /F "tokens=*" %%i in ('Global.exe "%Group%" %Domain% ^| sort') do echo %%i>>
"%FolderLocation%%Group%-%GrpType%-new.txt"
if not exist "%FolderLocation%%Group%-%GrpType%-old.txt" ECHO %Group% group has been added to membership tracking list.
Comparison will occur on the next script run. >>"%FolderLocation%sendmail.txt" && Call :createmail
:: Test to see if there is an old file for comparison - If there is, compare it with the new file just created above.
if exist "%FolderLocation%%Group%-%GrpType%-old.txt" Call :Complist
:: Test to be sure there is a previous file for comparison - If there is create a mail mesage
if exist "%FolderLocation%%Group%-%GrpType%-old.txt" if exist "%FolderLocation%sendmail.txt" Call :createmail
if exist "%FolderLocation%%Group%-%GrpType%-old.txt" del "%FolderLocation%%Group%-%GrpType%-old.txt"
move "%FolderLocation%%Group%-%GrpType%-new.txt" "%FolderLocation%%Group%-%GrpType%-old.txt"
goto :EOF
:Complist
For /F "tokens=*" %%i in ('sort ^< "%FolderLocation%%Group%-%GrpType%-old.txt"') do (set oldline=%%i) & (call :Testold)
Goto :Reverse
:Testold
Set newline=
for /f "tokens=*" %%i in ('findstr /B /E /C:"%oldline%" "%FolderLocation%%Group%-%GrpType%-new.txt"') do (Set newline=%%i)
If Defined newline goto :next1
@ECHO %oldline% has been deleted from the group>>"%FolderLocation%sendmail.txt"
:next1
Goto :EOF
:Reverse
For /F "tokens=*" %%i in ('sort ^< "%FolderLocation%%Group%-%GrpType%-new.txt"') do (set newline=%%i) & (call :Testnew)
Goto :EOF
:Testnew
Set oldline=
for /f "tokens=*" %%i in ('findstr /B /E /C:"%newline%" "%FolderLocation%%Group%-%GrpType%-old.txt"') do (Set oldline=%%i)
If Defined oldline goto :next2
@ECHO %newline% has been added to the group>>"%FolderLocation%sendmail.txt"
:next2
Goto :EOF
:Blat
:: Note: If Blat is not in the path be sure to change the path to the remote location.
blat.exe "%FolderLocation%mailcontents.txt" -s "Group membership changes" -server %Mailserver% -f %From% -t %Recipients%
Goto :EOF
:createmail
:: This will create the e-mail and log file output
:: Note: If Now.exe is not in the path be sure to change the path to the remote location.
Now>>"%FolderLocation%runninglog.txt"
ECHO A change has been detected in the membership of the %Group% group>>"%FolderLocation%runninglog.txt"
ECHO.>>"%FolderLocation%runninglog.txt"
:: ECHO Individual(s) whose status has changed:>>"%FolderLocation%runninglog.txt"
TYPE "%FolderLocation%sendmail.txt">>"%FolderLocation%runninglog.txt"
ECHO.>>"%FolderLocation%runninglog.txt"
ECHO Previous group membership:>>"%FolderLocation%runninglog.txt"
TYPE "%FolderLocation%%Group%-%GrpType%-old.txt">>"%FolderLocation%runninglog.txt"
ECHO.>>"%FolderLocation%runninglog.txt"
ECHO Current group membership:>>"%FolderLocation%runninglog.txt"
TYPE "%FolderLocation%%Group%-%GrpType%-new.txt">>"%FolderLocation%runninglog.txt"
:: Note: If Now.exe is not in the path be sure to change the path to the remote location.
Now>>"%FolderLocation%mailcontents.txt"
ECHO A change has been detected in the membership of the %Group% group>>"%FolderLocation%mailcontents.txt"
ECHO.>>"%FolderLocation%mailcontents.txt"
:: ECHO Individual(s) whose status has changed:>>"%FolderLocation%mailcontents.txt"
TYPE "%FolderLocation%sendmail.txt">>"%FolderLocation%mailcontents.txt"
ECHO.>>"%FolderLocation%mailcontents.txt"
ECHO Previous group membership:>>"%FolderLocation%mailcontents.txt"
TYPE "%FolderLocation%%Group%-%GrpType%-old.txt">>"%FolderLocation%mailcontents.txt"
ECHO.>>"%FolderLocation%mailcontents.txt"
ECHO Current group membership:>>"%FolderLocation%mailcontents.txt"
TYPE "%FolderLocation%%Group%-%GrpType%-new.txt">>"%FolderLocation%mailcontents.txt"
ECHO.>>"%FolderLocation%mailcontents.txt"
Goto :EOF