세션0(session 0) 격리 윈도우 서비스에 미치는 영향
윈도우XP, Server 2003을 포함한 이전 버전에서는 모든 서비스가 같은 세션 0에서 실행 되었습니다. 세션 0에서 실행되는 서비스들과 유저 애플리케이션은 보안적인 문제가 있을 수 있었습니다. 서비스는 상승된 권한(Privilege)에서 실행되었으며 이러한 서비스들은 권한 상승을 노리는 악성프로그램에 대한 타겟이 되었기 때문입니다.
윈도우 비스타(Server 2008) 이후 버전에서는 세션0에서 실행되는 서비스들을 격리시키고 세션0를 비 대화식(noninteractive)형태로 만들어 보안적인 위협에 대응하게 되었습니다. 시스템 프로세스들과 서비스들은 오직 세션 0에서 실행 됩니다. 세션 0는 비디오 드라이버에 엑세스 할 수 없기 때문에 그래픽 처리를 할 수 없습니다. 만약 세션 0에서 디스플레이 해상도와 컬러Depth를 구하면 1920*1200에 32비트를 리턴 할 것 입니다.
세션1에 로그인하는 첫 유저를 시작으로 세션은 1, 2, 3 순차적으로 부여됩니다. 이러한 동작방식은 서비스들이 유저세션과 절대로 같은 세션에서 실행되지 않는 것을 뜻 합니다. 이렇게 함으로써 어플리케이션 코드에 의한 공격을 방어 할 수 있게 되었습니다.
서비스와 서비스 호스트된 드라이버들에게 영향
영향받는 대상
서비스로서 설치된 애플리케이션과 드라이버들은 다음과 같은 영향을 받게 됩니다. 어떤 드라이버는 운영체제의 서비스나 세션0에서 실행되는 프로세스에서 로드되기도합니다. 그리고 이러한 드라이버들은 세션 0격리 문제의 영향을 받게 됩니다. 영향 받는 드라이버의 예는 다음과 같습니다.
- 스풀러(Spooler)서비스로부터 로드된 프린터 드라이버
- 유저모드 드라이버 프레임워크(UMDF)로 작성된 모든 드라이버(이러한 UMDF드라이버는 세션0에서 실행되는 프로세스로부터 호스트 되기 때문)
잠재된 이슈들
사용자가 세션0에서 실행되고 있다고 가정된 서비스와 서비스에 의해 호스트된 드라이버의 모든 기능들은 Windows Vista 이후 버전에서 올바르게 동작하지 않습니다. 이러한 상황이 발생 할 수 있는 예는 다음과 같습니다.
- 서비스가 메시지박스 같은 UI를 세션 0에서 생성하려고 시도할 때 올바르게 동작 하지 않을 수 있습니다. 유저는 세션 0에서 실행 되고 있기 때문에 절대로 UI를 볼 수 없습니다. 그러므로 입력을 서비스에게 줄 수 도 없습니다. 서비스는 유저의 응답을 받알 수 없어 이러한 상황에서 멈출 수 있습니다.
- 서비스가 SendMessage, PostMessage와 같은 윈도우 메시지 관련 함수 애플리케이션과 통신하려는 목적으로 사용하려고 할 때 올바르게 동작하지 않을 수 있습니다. 애플리케이션은 다른 세션에서 실행 중이므로 서로 다른 메시지 큐를 갖고 있습니다. 때문에 메시지는 절대로 애플리케이션 창에 도달 할 수 없습니다. 마찬가지로 애플리케이션도 윈도우 메시지를 통해 서비스와 통신 할 수 없습니다.
- 서비스가 세션0에서 실행되기 때문에 명명된 오브젝트들은 보통 \BaseNamedObjects\로 생성되거나 만들집니다. 그러나 서비스와 같은 세션에서 실행되거나 Local\ Prefix로 열리거나 만들어진 오브젝트와 동기화하는 유저 애플리케이션을 가정해본다면 더 이상 유저어플리케이션은 기대 한대로 동작 할 수 없을 것입니다. 그 이유는 Local\ Prefix는 생성열기 요청이 세션에 고유하고, 오브젝트는 \BaseNamedObject\가 아니라 애플리케이션이 요청한 \sessions\[세션id]\BaseNamedObjects에 있기 때문입니다. 유저애플리케이션과 서비스가 동기화하기 위한 올바른 방법은 \BaseNamedObject\를 사용하지 않고 명시적으로 Global\ Prefix를 사용하는 것입니다.
서비스와 서비스 호스트된 드라이버의 가이드라인
윈도우 Vista이상의 버전에서 서비스 호스트된 드라이버는 다음과 같은 가이드라인에 따라야합니다.
- 윈도우 메시지로 통신하는 것 보다 RCP나 명명된 파이프를 이용하는 클라이언트/서버 매커니즘을 사용하여야 합니다.
- 서비스가 필요로 하는 유저인터페이스를 구현할 때에는 다음과 같이 해야합니다.
- WTSSendMessage 함수를 이용하여 간단한 메시지 박스를 유저 바탕화면에 띄울 수 있습니다. 서비스가 사용자 알림이나 간단한 요청에 대한 응답을 할 수 있도록 합니다.
- 좀 더 복잡한 상호작용을 위해 개발자는 UI를 유저 세션에서 동작하는 에이전트를 만들어야 합니다. 에이전트는 RPC나 명명된 파이프를 통해 서비스와 통신할 수 있습니다.
- 디스플레이 속성에 대한 쿼리는 세션 0가 아닌 유저세션에서 실행 되어야 합니다. 그 이유는 해상도와 컬러 depth는 실제 디스플레이속성과 다르게 보고 될 수 있기 때문입니다.
- 어떠한 명명된 오브젝트를 하던 명시적으로 Local\ 이나 Global\ 네임스페이스를 사용해야 합니다. 이러한 오브젝트 들은 이벤트나, 메모리맵 등 서비스가 만들 수 있는 모든 것을 말합니다. 만약 오브젝트가 유저애플리케이션으로 부터 접근 가능하여야 한다면 반드시 Global\네입스페이스를 사용하여 다른 세션에서 접근 가능하도록 해야합니다. 다음은 마이크로소프트 Win32 함수 중에서 명명된 오브젝트를 허용하는 함수입니다. OpenEvent, OpenMutex, OpenSemaphore, OpenWaitableTimer, OpenJobObject, OpenFileMapping 이러한 함수를 사용할 때에는 현재 세션 내에서 명명된 객체에 대해 접근할 수 있도록 해줘야 합니다.
- 윈도우 비스타 이후 버전에서 올바르게 동작하는지 드라이버를 테스트 해봐야 합니다. 만약 불가능 하다면 다수의 유저가 로그온한 FUS가 활성화된 XP환경에서 테스트 해봐야 합니다. 만약 순차적으로 로그온한 사용자에서 드라이버가 올바르게 동작 한다면 세션 0의 분리에 영향을 받지 않는 드라이버 입니다. 단 이 테스트가 감지하지 못하는 상황은 세션0에서 비디오 드라이버가 존재하지 않는 상황에 대한 문제 입니다.
참고
'개발 > Windows' 카테고리의 다른 글
Python2.x 에서 error: Microsoft Visual C++ 9.0 is required. (0) | 2020.06.05 |
---|---|
WFP (Windows Filtering Platform) 이란 ? (0) | 2020.05.07 |
Memory Mapped File (MMF) Global로 명명할 때 권한 / winapi (0) | 2020.04.03 |
윈도우10에서 CreateRemoteThread를 이용한 DLL Injection (0) | 2020.04.01 |
Hyper-V 2세대 VM에서 Com Port 활성화 하기 / Windbg (0) | 2020.03.27 |
댓글