본문 바로가기
카테고리 없음

x64에서 프로세스 보호

by 호야호잇 2018. 5. 18.

일부 보안 제품의 경우 자사 프로세스들을 보호하기 위해 여러가지 방법들을 사용합니다.

 

그 중 가장 많이 사용되는 방법중 하나가 SSDT 후킹입니다. 그런데 이 방법은 64비트 윈도우에서는 패치가드로 인해 사용할 수 없죠.

 

물론 패치가드를 무력화 또는 우회하는 기법들도 계속 발전하고 있지만 안정성은 보장할 수 없습니다.

 

이번 포스팅에서는 기본적으로 제공되는 방법으로 간단히 프로세스를 보호하는 방법에 대해 끄적여 보겠습니다.

 

우선 어떤 행동으로부터 특정 프로세스를 보호할지 생각해보죠.

 

가장 우선 막아야할 행동으로는 프로세스 종료시키기와 해당 프로세스 가상 메모리 변조를 들 수 있습니다.

 

API로 예를 들면 TerminateProcess와 WriteProecssMemory 라고 할 수 있습니다.

 

물론 유저레벨에서 글로벌 후킹을 통해 수행할 수 있겠지만 그런 무식한 방법은 버리죠.

 

nt 커널에서 익스포트하고 있는 ObRegisterCallbacks 를 이용하면 쉽게 구현 가능합니다.

 

이전에 소개해드린 프로세스 실행 차단 콜백과 유사하다고 생각하시면 됩니다.

 

이 DDI는 x86, x64에서 모두 사용가능하다는 장점이 있습니다. 단점은 Vista sp1과 Windows 2008 이후 운영체제에서만 가능하단 점입니다.

 

ObRegisterCallback은 프로세스 오브젝트와 쓰레드 오브젝트의 Pre / Post Operation 시점에 콜백을 받게 해주는 역할을 합니다. 핸들 생성 혹은 복사 모두에 대해 콜백을 받을 수 있습니다.

 

우리가 관심을 가질 부분은 Pre 시점 콜백입니다.

 

Pre 시점 콜백의 원형은 요렇게 생겼습니다. (http://msdn.microsoft.com/en-us/library/ff557745(VS.85).aspx)

 

OB_PREOP_CALLBACK_STATUS ObjectPreCallback(
  __in  PVOID RegistrationContext,
  __in  POB_PRE_OPERATION_INFORMATION OperationInformation
);

 

이중 두번째 파라미터를 보면 되겠습니다.

 

typedef struct _OB_PRE_OPERATION_INFORMATION {
  OB_OPERATION          Operation;
  union {
    ULONG  Flags;
    struct {
      ULONG KernelHandle:1;
      ULONG Reserved:31;
    };
  };
  PVOID                        Object;
  POBJECT_TYPE          ObjectType;
  PVOID                        CallContext;
  POB_PRE_OPERATION_PARAMETERS Parameters;
} OB_PRE_OPERATION_INFORMATION, *POB_PRE_OPERATION_INFORMATION;

 

이 구조체의 필드중 Parameters 필드를 조작하면 우리가 원하는 결과를 얻을 수 있습니다.

 

해당 OB_PRE_OPERATION_PARAMETERS 구조체는 Create / Duplicate 정보를 담고 있습니다.

 

각 operation에 따라 처리를 해주면 되죠.

 

일반적으로 OpenProcess등을 통해 핸들을 생성할 경우 Create 쪽 정보를 보면 됩니다.

 

OB_PRE_OPERATION_PARAMETERS 구조체의 Create 쪽 필드의 구조체는 요렇게 생겼습니다.

 

typedef struct _OB_PRE_CREATE_HANDLE_INFORMATION {
  ACCESS_MASK DesiredAccess;
  ACCESS_MASK OriginalDesiredAccess;
} OB_PRE_CREATE_HANDLE_INFORMATION, *POB_PRE_CREATE_HANDLE_INFORMATION;

 

OriginalDesiredAccess 필드는 operation을 요청할 당시에 지정된 ACCESS_MASK입니다.

 

우리는 OriginalDesiredAccess 정보를 바탕으로 DesiredAccess 필드를 조작하면 되겠습니다.

 

간단한 테스트용 드라이버를 만들어서 실제 보호를 해보도록 하겠습니다.

 

Windows 7 x64 머신에 메모장을 하나 실행시켜두고 이 메모장 프로세스를 보호해보죠.

 

 

해당 메모장 프로세스에 로드된 DLL 정보들도 잘 나옵니다.

 

이제 이 메모장을 보호해보죠.

 

프로세스 오브젝트의 Pre Operation 콜백을 등록하고 이 콜백은 대강 요렇게 구성했습니다.

 

OB_PREOP_CALLBACK_STATUS
ObjectPreCallback(
    IN PVOID  pRegistrationContext,
    IN POB_PRE_OPERATION_INFORMATION  pOperationInformation
    )
{
    HANDLE pid = PsGetProcessId((PEPROCESS)pOperationInformation->Object);
    if (pid == (HANDLE)2824)
    {
        if (pOperationInformation->Operation == OB_OPERATION_HANDLE_CREATE)
        {
            if ((pOperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess & PROCESS_TERMINATE) == PROCESS_TERMINATE)
            {
                pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_TERMINATE;
            }
            if ((pOperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess & PROCESS_VM_OPERATION) == PROCESS_VM_OPERATION)
            {
                pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_VM_OPERATION;
            }
            if ((pOperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess & PROCESS_VM_READ) == PROCESS_VM_READ)
            {
                pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_VM_READ;
            }
            if ((pOperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess & PROCESS_VM_WRITE) == PROCESS_VM_WRITE)
            {
                pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess &= ~PROCESS_VM_WRITE;
            }
        }
    }

    return OB_PREOP_SUCCESS;
}

 

프로세스 ID는 하드코딩했습니다. ㅋㅋ

 

ACCESS_MASK중 보호 프로세스를 건드릴만한 것중 일부를 제거하도록 구성했습니다.

 

요렇게 해서 드라이버를 타겟 머신에 로드 후 프로세스 익스플로러로 메모장을 보면 요렇게 됩니다.

 

 

DLL 정보가 나오지 않습니다~!

 

Kill 시도를 해볼까요.

 

 

 

보호되었습니다.^^

 

더 재미난 일들도 할 수 있습니다. 한번 해보세요^^

 

그럼 즐프하세요~