UMDF 드라이버에서 클라이언트 가장 처리

이 항목에서는 UMDF(User-Mode Driver Framework) 드라이버가 UMDF 버전 2부터 보호된 리소스에 액세스하는 방법을 설명합니다.

UMDF 드라이버는 일반적으로 LocalService 계정으로 실행되며 보호된 파일 또는 기타 보호된 리소스와 같은 사용자 자격 증명이 필요한 파일 또는 리소스에 액세스할 수 없습니다. UMDF 드라이버는 일반적으로 클라이언트 애플리케이션과 디바이스 간에 흐르는 명령 및 데이터에서 작동합니다. 따라서 대부분의 UMDF 드라이버는 보호된 리소스에 액세스하지 않습니다.

그러나 일부 드라이버는 보호된 리소스에 액세스해야 할 수 있습니다. 예를 들어 UMDF 드라이버는 클라이언트 애플리케이션이 제공하는 파일에서 디바이스에 펌웨어를 로드할 수 있습니다. 파일에는 권한이 없는 사용자가 파일을 수정하고 디바이스를 제어하지 못하도록 하는 ACL(액세스 제어 목록)이 있을 수 있습니다. 아쉽게도 이 ACL은 UMDF 드라이버가 파일에 액세스하는 것을 방지합니다.

프레임워크는 드라이버가 드라이버의 클라이언트를 가장하고 보호된 리소스에 대한 클라이언트의 액세스 권한을 얻을 수 있도록 하는 가장 기능을 제공합니다.

가장 사용

UMDF 드라이버의 설치 패키지와 클라이언트 애플리케이션 모두 다음과 같이 프레임워크의 가장 기능을 사용하도록 설정해야 합니다.

  • UMDF 드라이버 설치 패키지의 INF 파일에는 UmdfImpersonationLevel 지시문이 포함되어야 하며 허용되는 최대 가장 수준을 설정해야 합니다. 가장은 INF 파일에 UmdfImpersonationLevel 지시문이 포함된 경우에만 사용하도록 설정됩니다. 가장 수준을 설정하는 방법에 대한 자세한 내용은 INF 파일에서 WDF 지시문 지정을 참조하세요.

  • 클라이언트 애플리케이션은 각 파일 핸들에 대해 허용되는 가장 수준을 설정해야 합니다. 애플리케이션은 Microsoft Win32 CreateFile 함수의 QoS(서비스 품질) 설정을 사용하여 허용되는 가장 수준을 설정합니다. 이러한 설정에 대한 자세한 내용은 Windows SDK 설명서에서 CreateFiledwFlagsAndAttributes 매개 변수를 참조하세요.

I/O 요청에 대한 가장 처리

UMDF 드라이버 및 프레임워크는 다음 순서로 I/O 요청에 대한 가장을 처리합니다.

  1. 드라이버는 WdfRequestImpersonate 메서드를 호출하여 필요한 가장 수준 및 EvtRequestImpersonate 콜백 함수를 지정합니다.

  2. 프레임워크는 요청된 가장 수준을 확인합니다. 요청된 수준이 UMDF 드라이버의 설치 패키지 및 클라이언트 애플리케이션에서 허용하는 수준보다 크면 가장 요청이 실패합니다. 그렇지 않으면 프레임워크는 클라이언트를 가장하고 EvtRequestImpersonate 콜백 함수를 즉시 호출합니다.

EvtRequestImpersonate 콜백 함수는 보호된 파일 열기와 같이 요청된 가장 수준이 필요한 작업만 수행해야 합니다.

프레임워크는 드라이버의 EvtRequestImpersonate 콜백 함수가 프레임워크의 개체 메서드를 호출하는 것을 허용하지 않습니다. 이렇게 하면 드라이버가 가장 수준을 다른 드라이버 콜백 함수 또는 다른 드라이버에 노출하지 않습니다.

가장 좋은 방법은 드라이버가 해당 요청에 대해 WdfRequestImpersonate를 호출하기 전에 I/O 요청 취소를 사용하도록 설정해서는 안 됩니다.

WdfRequestImpersonate 메서드는 드라이버가 요청하는 가장 수준만 부여합니다.

드라이버 스택 아래로 자격 증명 전달

드라이버가 WdfRequestTypeCreate 형식의 I/O 요청을 받으면 드라이버가 드라이버 스택 아래로 I/O 요청을 커널 모드 드라이버로 전달할 수 있습니다. 커널 모드 드라이버에는 WdfRequestImpersonate 가 UMDF 드라이버에 제공하는 가장 기능이 없습니다.

따라서 커널 모드 드라이버가 클라이언트의 사용자 자격 증명(드라이버 호스트 프로세스의 자격 증명)을 수신하도록 하려면 드라이버가 WdfRequestSend를 호출하여 만들기 요청을 I/O 대상으로 보낼 때 WDF_REQUEST_SEND_OPTION_IMPERSONATE_CLIENT 플래그를 설정해야 합니다. Send 메서드는 드라이버가 WDF_REQUEST_SEND_OPTION_IMPERSONATION_IGNORE_FAILURE 플래그를 설정하지 않는 한 가장 시도가 실패할 경우 오류 코드를 반환합니다.

다음 예제에서는 UMDF 드라이버가 WDF_REQUEST_SEND_OPTION_IMPERSONATE_CLIENT 플래그를 사용하여 I/O 대상에 파일 만들기 요청을 보내는 방법을 보여 줍니다. 드라이버의 INF 파일에는 위에서 설명한 대로 UmdfImpersonationLevel 지시문도 포함되어야 합니다.

WDFIOTARGET iotarget;
WDF_REQUEST_SEND_OPTIONS options;
NTSTATUS status;
WDF_REQUEST_PARAMETERS params;
ULONG sendFlags;  
 
WDF_REQUEST_PARAMETERS_INIT(&params);
WdfRequestGetParameters(Request, &params);
   
sendFlags = WDF_REQUEST_SEND_OPTION_SYNCHRONOUS;
if (params.Type == WdfRequestTypeCreate) {
    sendFlags |= WDF_REQUEST_SEND_OPTION_IMPERSONATE_CLIENT;
}
   
WDF_REQUEST_SEND_OPTIONS_INIT(&options, sendFlags);
if (WdfRequestSend(Request,
                   iotarget,
                   &options
                   ) == FALSE) {
    status = WdfRequestGetStatus(Request);
}

드라이버는 I/O 대상에 요청을 보내기 전에 WdfRequestImpersonate 를 호출할 필요가 없습니다.

하위 수준 드라이버도 요청을 전달하면 클라이언트의 가장 수준이 드라이버 스택 아래로 이동합니다.

보안 위협 감소

"권한 상승" 공격의 가능성을 줄이려면 다음을 수행해야 합니다.

  • 가장을 사용하지 않도록 합니다.

    예를 들어 가장을 사용하여 드라이버에서 사용해야 하는 파일을 열지 않도록 클라이언트 애플리케이션은 파일을 열고 I/O 작업을 사용하여 파일 내용을 드라이버에 보낼 수 있습니다.

  • 드라이버에 필요한 가장 낮은 가장 수준을 사용합니다.

    드라이버의 INF 파일에서 가장 수준을 최대한 낮게 설정합니다. 드라이버에 가장이 필요하지 않은 경우 INF 파일에 UmdfImpersonationLevel 지시문을 포함하지 마세요.

  • 공격자가 드라이버를 악용할 기회를 최소화합니다.

    EvtRequestImpersonate 콜백 함수에는 가장이 필요한 작업만 수행하는 코드의 작은 섹션이 포함되어야 합니다. 예를 들어 드라이버가 보호된 파일에 액세스하는 경우 파일 핸들을 열 때만 가장해야 합니다. 파일에서 읽거나 파일에 쓰는 데 가장이 필요하지 않습니다.