Что мы знаем про сессии и сервисы в Windows? Да практически ничего, кроме того, что они существуют. Что это за сущности, с чем их едят заматерелые хакеры? Как можно оценить сессию с точки зрения обеспечения защищенности и безопасности в Windows? Сегодня мы об этом и поговорим, попытаемся, так сказать, пролить свет на эту загадку.

 

WARNING

Вся информация предоставлена исключительно в ознакомительных целях. Ни редакция, ни автор не несут ответственности за любой возможный вред, причиненный материалами данной статьи.

 

Что имеем?

Как я неоднократно говорил, отсутствие в свободном доступе достаточного/исчерпывающего количества информации относительно какой-либо технологии Windows — однозначный признак того, что архитекторы и разработчики системы хотят сохранить в тайне ее детали, поскольку их раскрытие может скомпрометировать всю систему безопасности. Так, например, обстоят дела с RPC или PatchGuard.

Аналогичная ситуация складывается с сессиями в Windows. Многие айтишники что-то там про них слышали, еще меньшей части компьютерного народа знакомо слова «Session 0».

Понятие «сессии» на самом деле не так сложно. Можно говорить о ней, как о некоем временном промежутке работы совокупности программ для одного пользователя. Но при этом сессии являются важной частью обеспечения безопасности системы и защиты пользовательских данных. Это словно оболочка, связывающая все действия пользователя, запущенные программы и сам десктоп.

Рассмотрим все это поподробнее.

 

Что такое «Сессия»?

Windows изначально проектировалась как многопользовательская система. И это было сделано путем реализации так называемых «терминальных сессий». Здесь надо помнить про то, что «терминальная сессия» и «сессия с момента захода в систему через winlogon.exe» — немного разные вещи. Терминальные сессии создаются и управляются сессионным менеджером smss.exe — процессом, который стартует в системе одним из первых. Winlogon-сессии и процессы как бы «живут внутри» терминальной сессии.

Для того, чтобы получить ID-номер терминальной сессии можно использовать функцию LsaGetLogonSessionData с последующим перечислением Winlogon-сессии посредством функции LsaEnumerateLogonSessions. Также можно получить ID сессии путем вызова GetTokenInformation с параметром TokenSessionId, после получения первичного токена процесса (функция OpenProcessToken). У сессии есть ряд своих приватных структур, которые используются для управления памятью.

У сессии есть свое адресное пространство, которое содержит копии данных, модифицированных драйвером графической подсистемы Win32k.sys, саму копию Win32k.sys, а также немодифицированные данные и различные драйвера, загруженные сессией. У сессии есть пространство вьюшек — виды десктопа.

И, разумеется, у сессии есть свой пул памяти. Между сессиями всех пользователей можно взаимодействовать на программном уровне. Это делается посредством пайпов, сокетов и глобальных эвентов. А вот посылать месседжи в другую сессию не выйдет.

Примечателен и любопытен с точки зрения системной безопасности тот факт, что до появления Windows Vista системные сервисы, winlogon.exe и клиент-серверная подсистема csrss.exe (о которой я уже не раз писал), стартовали как часть «нулевой сессии» («Session 0») вместе с первым залогиневшимся клиентом, а все последующие залогинившиеся пользователи нумеровались как «Session 1», «Session 2», и т.д. Кстати, сколько у нас там сейчас в интернете остается пользователей ХР? ;).

Так было до Windows Vista...
Так было до Windows Vista…

А теперь самое интересное — эта ситуация стала напоминать забавную историю «кто первый встал — того и тапки», т.е. первый же залогинившийся в систему юзер получал привилегии «Session 0», т.е. мог запросто получить системные права, ведь важнейшие системные сервисы оказывались по соседству с простыми пользовательскими приложениями, такими правами не наделенными. Чем это грозило? Например, злобными shatter-аттаками, когда окну посылается сообщение (да-да, с использованием функции SendMessage) с ядерной начинкой внутри в виде шеллкода, повышающего привилегии. Можно было получить доступ к расшаренным секциям системных процессов, если те были неправильно защищены. Можно было скомпрометировать объекты «\BaseNamedObjects» (кто не знает — в гугл). Одним словом, способов в очередной раз поиздеваться над системой было предостаточно.

Однако, с выпуском Windows Vista, данную лавочку прикрыли. «Session 0» была надежно изолирована от пользовательских приложений. Так думали в Microsoft :).

А так стало после...
А так стало после…

По-другому думал неугомонный румын («цыган», хотел написать ;)) Алекс Ионеску, которого очень хорошо знают все, кто хоть как-то связан с системным программированием и разработкой ОС по типу Windows. Действительно талантливый чувак, один из разработчиков ReactOS, если мне не изменяет память. Пытливый Ионеску нарыл способ приаттачиться в «Session 0». Способ хоть и весьма условный, однако работающий. В Windows 7 эта проблема была окончательно устранена.

 

Интерактивные сервисы — казнь египетския на голову Microsoft

Windows для прикладных и системных тру-кодеров предоставляет возможность создания сервисов — программ, крутящихся на заднем фоне, особо не мешающих пользователям и что-то там потихоньку считающих. Кто не в теме — в качестве некоего аналога могу привести демоны в *nix-like операционных системах. Ничего сложного в создании Win сервисов нет, документации полно, примеров еще больше, и ими активно пользуются как честные программисты, так и малварщики.

Есть такая возможность создания интерактивного сервиса — с флагом SERVICE_INTERACTIVE_PROCESS при вызове функций CreateService() или ChangeServiceConfig().

Когда менеджер сервисов (services.exe) создает процесс для интерактивного сервиса (сорри за тавтологию :), он присоединяет его к «Winsta0» (начальной рабочей станции, о них — ниже), а не к рабочей станции самого процесса. Чтобы сделать этого, процесс сервиса должен иметь права SYSTEM, потому что потом ему придется взаимодействовать с интерактивным десктопом и самим пользователем. Это может привести к очень плачевным результатам — атакам на повышение привилегий, основываясь на том, что интерактивные процессы функционируют в системе с правами SYSTEM и привилегиями «trusted computing base» (TCB).

Изоляция «Session 0» может привести к проблеме с сервисами, которым необходимо отображение пользовательского интерфейса. Поскольку сервис теперь выполняется в другой сессии (по сравнению с десктопом), пользовательский интерфейс не будет виден конечным пользователям и интерактивный сервис может оказаться в «зависшем» состоянии.

«Пусть говорят!»
«Пусть говорят!»

В Windows Vista решение этой проблемы состоит в том, что пользователям предоставляется возможность временного переключения в «Session 0» для взаимодействия с интерактивным сервисом.

В общем, намудрили товарищи из Microsoft, не смогли переплюнуть золотое правило: «Когда нельзя, но очень хочется, тогда можно».

 

Осторожно, двери закрываются! Следующая станция… «Windows»?

Да-да, системным кодерам должно быть знакомо понятие WindowStation (CreateWindowStation()). Зачем оно нужно? Ну хотя бы для того, чтобы всегда иметь ввиду, что если твой код должен быть внедрен в системный процесс или сервис (посредством подмены контекста потока), он выполняться не будет в силу несоответствия WindowStation, потому у как юзермодных приложений это будет «\Windows\WindowStations\WinSta0», а у сервиса — «\Windows\WindowStations\Service-0x0-3e7$». Это надо обязательно иметь в виду, например при создании кейлоггеров.

Станция Windows
Станция Windows

Как можно получить полный доступ к интерактивной рабочей станции и десктопу «winsta0\default»? Смотрим код:

winstaHandle = OpenWindowStation("winsta0", FALSE, 
WINSTA_ACCESSCLIPBOARD   | 
WINSTA_ACCESSGLOBALATOMS | 
WINSTA_CREATEDESKTOP | 
WINSTA_ENUMDESKTOPS  | 
WINSTA_ENUMERATE | 
WINSTA_EXITWINDOWS   | 
WINSTA_READATTRIBUTES| 
WINSTA_READSCREEN| 
WINSTA_WRITEATTRIBUTES)) ;
SetProcessWindowStation(winstaHandle);
desktopHandle = OpenDesktop("default", 0, FALSE, 
DESKTOP_CREATEMENU | 
DESKTOP_CREATEWINDOW | 
DESKTOP_ENUMERATE| 
DESKTOP_HOOKCONTROL  | 
DESKTOP_JOURNALPLAYBACK | 
DESKTOP_JOURNALRECORD | 
DESKTOP_READOBJECTS | 
DESKTOP_SWITCHDESKTOP | 
DESKTOP_WRITEOBJECTS));

ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb= sizeof(STARTUPINFO);
si.lpDesktop = "winsta0\\default";
if (!CreateProcessAsUser(
 hToken,
 NULL,
 "cmd.exe",
 NULL,
 NULL,
 FALSE,
 NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE,
 NULL,
 NULL,
 &si,
 &pi
 ));

Полный вариант кода ты сможешь найти здесь — http://support.microsoft.com/kb/165194

 

INFO

Единственный способ что-то сделать вне своей терминальной сессии — это запустить отдельный процесс в этой сессии посредством CreateProcessAsUser с нужным токеном

 

WWW

Как всегда MSDN тебе на помощь — http://msdn.microsoft.com/en-us/library/windows/desktop/ms687105(v=vs.85).aspx

 

Подытожим…

Тема сессий, рабочих станций и сервисов в Windows далеко не изучена. Уверен, что там если покопаться хорошенько — не одну химеру на свет божий можно будет вытащить.

Отношения между сессиями, Станциями Windows и Десктопами  Windows
Отношения между сессиями, Станциями Windows и Десктопами Windows

В погоне за безопасностью команда Windows хорошенько постаралась осложнить жизнь как простым программистам, так и мальварщикам. С выходом операционок Windows Vista+, начали успешно отваливаться многие коммерческие VNC-решения, перестали работать кейлоггеры. И все это — в силу попыток изолировать рабочие станции, десктопы и сессии друг от друга.

Засим закончу. Удачного компилирования и да пребудет с тобой Сила!

 

Оставить мнение

Check Also

SHA 2017. Репортаж с самого яркого хакерского ивента этого лета

Still Hacking Anyway 2017 — это фестиваль, на котором собрались четыре тысячи хакеров со в…