Реализация защиты на уровне сетевых сервисов
Почти все сетевые сервисы, такие как сервис рабочей станции (LanMan Workstation), сервис сервера (LanMan Server), сервис оповещений (alerter), сервис сообщений (messenger), обозреватель сети (Computer Browser), DHCP client содержатся в одном ЕХЕ-файле с именем services. Остальные исполняются в собственных процессах, например, wins.exe (WINS SERVER), dns.exe (Domain Name System (DNS) Server), rpcss.exe (RFC and Distribute COM Services), locator.exe (RFC locator), nddeagnt.exe (Network DDE Agent), tapisrv.exe (Microsoft Windows Telephony Server), rassrv.exe (Remote Access Server Supervisor).
Сетевой сервис – это серверный процесс. Некоторые сетевые сервисы выполняются в фоновом режиме, в то время как другие предоставляют API через соответствующие DLLs клиентской стороны, например:
- tapi32.dll (Microsoft Windows Telephony API Client DLL) предоставляет приложениям взаимодействие с tapisrv.exe;
- библиотека rassapi.dll (Remote Access Admin APIs dll) может использоваться приложениями для конфигурирования RAS сервера (rassrv.exe);
- библиотека netapi32.dll (Net Win32 API DLL) используется приложениями для взаимодействия с browser, workstation, server, alerter, messenger, replicator; и т.д.
Сервисы, имеющие собственные API, для обмена данными со своими клиентами обычно используют механизм RPC. При этом для реализации RPC-запросов между процессами, исполняющимися на одной машине, в действительности используется механизм LPC.
Если клиентский процесс и процесс сетевого сервиса не находятся на одном компьютере, то контролировать передачу данных между этими процессами можно с помощью вмешательства в исполнение функций библиотеки rpcrt4.dll. Этот метод был подробно описан выше.
Чтобы контролировать передачу данных между клиентским процессом и процессом сетевого сервиса, исполняющимися на одной машине, нужно вмешаться в механизм LPC. В общих чертах он выглядит следующим образом: после, того как клиентский запрос к сервису перехватится заглушкой в DLL клиентского процесса, эта заглушка упакует параметры вызова, необходимые процедуре сервиса. Затем LPC обеспечит механизм передачи данных клиентского процесса процессу сетевого сервиса с помощью разделяемой памяти или с помощью посылки сообщения в очередь сообщений. Затем после того как процедура сервиса выполнит необходимую обработку, LPC возвратит результаты обработки обратно клиентскому процессу с помощью тех же механизмов.
LPC при своей работе создает и использует объекты-порты (port object), которые в качестве атрибутов имеют описатель секции (описатель совместно используемой памяти) и указатель на очередь сообщений. Объект-порт ассоциируется с серверным процессом и обеспечивает выполнение сервисов для клиентского процесса. Объект-порт как бы представляет канал для передачи сообщений между клиентским и серверным процессами. Серверный процесс определяет для связи с собой именованный объект-порт (порт соединения), а когда клиентский процесс свяжется с этим именованным портом, серверный процесс создаст два неименованных объекта-порта (порты связи) для взаимодействия.
API, необходимое для получения доступа к сервисам LPC, не документировано. Скорее всего, заглушка в клиентской DLL получает обслуживание LPC через прерывание int 2E с помощью вызова функций: NtlmpersonateClientOfPort, NtAccept ConnectPort, NtCompleteConnectPort, NtCreatePort, NtReplyWaitReceive Port, NtReplyWaitReplyPort, NtRequestPort, NtConnectPort, NtReplyPort, NtRequest WaitReplyPort и т.п., предоставляемых библиотекой ntdll.dll. В результате чего обработчик прерывания 2Е (диспетчер системных сервисов) использует таблицу распределения системных сервисов (KeServiceDescriptorTable) для вызова соответствующих сервисов LPC из ntoskrnl.exe. Следовательно, для перехвата обращений к сервису LPC, можно воспользоваться методом перехвата обращений к системным сервисам, который будет рассмотрен ниже. Тем самым будет получен доступ к данным, передаваемым от клиентских процессов серверным процессам, в том числе и процессам сетевых сервисов.