가장
일부 파일 시스템은 원래 호출자를 대신하여 작업을 수행하는 것이 유용할 수 있습니다. 예를 들어 네트워크 파일 시스템은 적절한 자격 증명을 사용하여 후속 작업을 수행할 수 있도록 파일을 열 때 호출자의 보안 정보를 캡처해야 할 수 있습니다. 이 유형의 기능이 파일 시스템 내에서뿐만 아니라 특정 애플리케이션 모두에서 유용한 다른 많은 특별한 경우는 의심의 여지가 없습니다.
가장에 필요한 주요 루틴은 다음과 같습니다.
PsImpersonateClientSeImpersonateClientEx--는 가장을 시작합니다. 특정 스레드가 표시되지 않는 한 가장은 현재 스레드 컨텍스트에서 수행됩니다.
PsRevertToSelf -- 현재 스레드 컨텍스트 내에서 가장을 종료합니다.
PsReferencePrimaryToken -- 지정된 프로세스에 대한 기본(프로세스) 토큰에 대한 참조를 보유합니다. 이 함수는 시스템의 모든 프로세스에 대한 토큰을 캡처하는 데 사용할 수 있습니다.
PsDereferencePrimaryToken -- 이전에 참조된 기본 토큰에 대한 참조를 해제합니다.
SeCreateClientSecurityFromSubjectContext--는 주체 컨텍스트에서 가장하는 데 유용한 클라이언트 보안 컨텍스트를 반환합니다(예: IRP_MJ_CREATE 처리하는 동안 FSD에 제공됨).
SeCreateClientSecurity -- 시스템에 있는 기존 스레드의 보안 자격 증명을 기반으로 클라이언트 보안 컨텍스트를 만듭니다.
ImpersonateSecurityContext -- 커널 보안 서비스인 ksecdd.sys 내의 보안 컨텍스트를 가장합니다.
RevertSecurityContext -- 커널 보안 서비스인 ksecdd.sys 내에서 가장을 종료합니다.
가장은 구현하기 위한 직선입니다. 다음 코드 예제에서는 기본 가장을 보여 줍니다.
NTSTATUS PerformSpecialTask(IN PFSD_CONTEXT Context)
{
BOOLEAN CopyOnOpen;
BOOLEAN EffectiveOnly;
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel;
NTSTATUS Status;
PACCESS_TOKEN oldToken;
//
// We need to perform a task in the system process context
//
if (NULL == Context->SystemProcess) {
return STATUS_NO_TOKEN;
}
//
// Save the existing token, if any (otherwise NULL)
//
oldToken = PsReferenceImpersonationToken(PsGetCurrentThread(),
&CopyOnOpen,
&EffectiveOnly,
&ImpersonationLevel);
Status = PsImpersonateClient( PsGetCurrentThread(),
Context->SystemProcess,
TRUE,
TRUE,
SecurityImpersonation);
if (!NT_SUCCESS(Status)) {
if (oldToken)
PsDereferenceImpersonationToken(oldToken);
return Status;
}
//
// Perform task - whatever it is
//
//
// Restore to previous impersonation level
//
if (oldToken) {
Status = PsImpersonateClient(PsGetCurrentThread(),
oldToken,
CopyOnOpen,
EffectiveOnly,
ImpersonationLevel);
if (!NT_SUCCESS(Status)) {
//
// This is bad - we can't restore, we can't leave it this way
//
PsRevertToSelf();
}
PsDereferenceImpersonationToken(oldToken);
} else {
PsRevertToSelf();
}
return Status;
}
파일 시스템 개발자가 사용할 수 있는 이 가장 코드에는 다양한 변형이 있지만 이 방법은 이 기술에 대한 기본 설명을 제공합니다.