В статье "Определение членства в группах" (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 к запуску в своей инфраструктуре выполните следующие действия:

  1. Поместите файл сценария в выделенный каталог того сервера или рабочей станции, с которых вы собираетесь запускать данный сценарий по расписанию.
  2. Определите, какие локальные и глобальные группы вы собираетесь контролировать. Создайте соответствующие входные файлы, localgroups.txt и globalgroups.txt и поместите их в тот же каталог, в котором находится файл GroupMembershipTracker.bat. Если вы собираетесь работать только с локальными, но не глобальными группами или наоборот, то не нужно создавать пустой входной файл. Сценарий просто не найдет отсутствующий входной файл и перейдет к следующему.
  3. Настройте файл GroupMembershipTracker.bat для работы в своей среде. В Листинге 1 показано, в какие именно строки кода потребуется внести изменения. Во-первых, задайте имя домена, в котором находятся интересующие вас группы. Если нужно отслеживать группы более чем в одном домене, тогда придется запускать несколько экземпляров сценария или модифицировать его код так, чтобы он мог работать с несколькими доменами. Затем необходимо указать в начале сценария корректные почтовые адреса To и From, которые будет использовать Blat для отправки уведомлений по почте. В строку To может быть включено несколько адресов получателей, каждый из которых должен отделяться друг от друга запятой, но без пробелов. И последнее, что следует сделать - это указать имя сервера SMTP, который будет использоваться утилитой Blat для отправки уведомлений.
  4. Убедитесь, что все используемые в сценарии утилиты (now.exe, local.exe, global.exe и blat.exe) находятся в том же каталоге, из которого будет запускаться сценарий. Как показано в Листинге 2, сценарий записывает данные о размещении каталогов в переменную %~dp1. Знак процента (%) указывает на то, что это заменяемый параметр. Что касается обозначения ~dp1, то оно предписывает механизму сценария считывать букву, обозначающую диск (d) и путь (p). Соответственно, если полный путь к сценарию C:AdminScriptsGroupMembershipTracker.bat, то в этом случае переменная %~dp1 содержит информацию о размещении каталога C:AdminScripts. Таким образом, если вы размещаете утилиты не в том же самом каталоге, в котором находится файл сценария, либо хотите разместить входные файлы в каком-либо другом месте, то нужно внести в код Листинга 2 изменения и указать правильный путь к каталогу с утилитами.
  5. Проверьте работу сценария в ручном режиме и убедитесь, что он должным образом отслеживает изменения, вносимые в группы, фиксирует их в файле журнала и отсылает соответствующие уведомления. Для каждой из групп, которую вы выбрали для наблюдений, сценарий создает временный каталог, поэтому у вас есть возможность сравнить результаты предыдущего выполнения сценария с вновь полученными результатами. По-видимому, лучше создать одну или две тестовые группы (чтобы не трогать "рабочие" группы вашей инфраструктуры), в которых проводить эксперименты по включению и исключению из них пользователей для проверки работы механизма уведомлений.
  6. Продумайте, как часто вы собираетесь запускать сценарий. В принципе, в расписании можно задать периодичность запуска величиной в одну или несколько минут, но, вероятно, вполне достаточно запускать данную процедуру один или два раза в день. Для создания расписания запуска сценария воспользуйтесь Планировщиком заданий (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