본문 바로가기

My Study/Programming&Theory

ObRegisterCallbacks 사용해보기

NTSTATUS ObRegisterCallbacks(

  _In_   POB_CALLBACK_REGISTRATION CallBackRegistration,

  _Out_  PVOID *RegistrationHandle

);


이 함수는 스레드와 프로세스 핸들 작업에 대한 콜백 루틴을 등록할 수 있는 함수입니다.

그것도 Pre 콜백과 Post 콜백을 전부 등록할 수 있죠.


아쉬운 점이 있다면 Windows Vista SP1 부터 이 함수를 사용할 수 있습니다.


이 함수를 사용하면 여러가지 작업을 할 수 있는데 x64 시스템에서 유용하게 사용될 수 있습니다.

x64 시스템에선 Patch Guard 라는 OS 보호 메커니즘 때문에 SSDT 후킹이라던지 inline 후킹을 하기 애매합니다. 특히 악성코드라면 모를까 기업들 제품에선 Patch Guard를 무력화 시키면서까지 커널 후킹을 할 순 없습니다. 하지만 후킹은 할 수 없지만 프로세스는 보호해야하는 짐은 여전히 가지고 있습니다. 그래서 사용하는 함수가 위 함수입니다.


CallBackRegistration 인자를 적절히 초기화 시켜주면 모든 준비가 끝나게 되는데요.



아래와 같이 초기화를 시켜주면 끝납니다.


중간에 있는 g_RegContext는 콜백 루틴이 호출되면 인자로 들어가게 되는데 저기 적힌 PID들은 ..일단 보호할 프로세스의 PID를 하드코딩 해주었습니다. 실제로 만들 땐 유저와 통신해 보호할 PID를 받아와서 셋팅해주면 되겠죠.

또한 Altitude 값을 설정해주는 부분이 있는데 저 부분 때문에 혹시 이거 미니필터  형식으로 로드해야되는건줄 알았지만 그냥 저렇게 값 넣고 일반 드라이버 로드 하듯 로드하면 됩니다.



이렇게 ObRegisterCallbacks 함수를 호출해주면 됩니다.


전 위 코드에서 Pre와 Post 콜백 둘다 등록했습니다. 먼저 Pre 콜백 루틴입니다. ( 클릭하면 크게 보임 )



위 코드에선 현재 접근되는 오브젝트의 핸들을 가진 프로세스가 우리가 보호하려는 프로세스이면 해당 핸들의 접근 권한 값을 바꾸는 것입니다. 현재는 프로세스가 종료되지 않게끔 PROCESS_TERMINATE 값만 없애주고 있는데 추가적으로 아래 주석으로 처리된 플래그 값들을 조작해주시면 여러가지 방어를 할 수 있습니다.


그리고 Post루틴에선 조금 더 재미있는 것을 해보았습니다.



딱 봐도 무슨 코드인지 아실 것 입니다. EPROCESS 의 링크를 끊어서 제가 원하는 프로세스를 숨기는 것입니다. DKOM 루트킷 방식이네요. ㅎㅎ


그 외에도 제 프로세스가 아닌 다른 프로세스의 커널 오브젝트에도 접근할 수 있으므로 더욱 잼나는 일을 할 수 있습니다.


그런데 저렇게 코드를 작성해 놓고 컴파일을 하고 커널에 로드하면 ObRegisterCallbacks 함수가 STATUS_ACCESS_DENIED 이라는 값을 리턴하게 됩니다. 이는 "Kernel Data and Filtering Support for Windows Server 2008" 이라는 문서를 보면 답이 나와있습니다.


챕터 4인 요구사항과 제약사항 부분입니다.

악성 소프트웨어에 의해 API 함수가 잘못 사용되어지는 것을 막기위해 API를 안정적으로 사용할 수 있도록 몇가지 요구조건이 필요합니다. 그리고 API에서 필터링 가능한 단계에선 몇 가지 제약이 정의되어 집니다.  


여기선 64bit에만 국한되지 않고 32bit 와 64bit 시스템에서 새로운 API를 사용하는 커널 모드 소프트웨어는 디지널 서명이 되야합니다. 마찬가지로 커널 모드 소프트웨어로 구성 또는 제공 정책이 있는 유저 코드 또한 디지털 서명이 되어 있어야합니다.


ISV는 MS에 마소에 제출하는 것 없이 자기 코드에 서명할 수 있습니다.

모든 ISV 커널과 유저 모드 모듈은 링크 시 /integritycheck 와 함께 링크 되어져야하고 참조된 코드에 대해서 로드 할 때 메모리 관리자는 서명 체크를 합니다.. 만약 ISV를 수동으로 활성화 하려면 OptionalHeader.DllCharacteristics 필드에 IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY ( 0x0800 ) 을 셋 해야됩니다.


뭐라뭐라 되어 있는데 그냥 링크 옵션에 /integritycheck 옵션을 주면 됩니다. 그러고 끝이냐? 아닙니다. 저 옵션을 주고나서 컴파일할 경우 ObRegisterCallbacks 의 STATUS_ACCESS_DENIED 값은 해결됬지만 드라이버 사이닝이 해결되지 않았습니다.

당연히 올바른 인증서로 서명도 해주셔야합니다.


위 코드를 테스트할 땐 전 그냥 "드라이버 서명 사용 안함" 으로 부팅해서 테스트 했습니다.


마지막으로 저 Pre와 Post 콜백 루틴이 실행되는 시기는?


그냥 콜스택만 보여주겠습니다.


Pre 콜백 루틴 호출됬을 때 콜스택

00 8c5f88b0 831278f8 여기서 Pre 콜백 호출!!

01 8c5f88f8 83127ae5 nt!ObpCallPreOperationCallbacks+0x163

02 8c5f8940 830768a6 nt!ObpPreInterceptHandleCreate+0x6f

03 8c5f89a0 830cefde nt!ObpCreateHandle+0x219

04 8c5f8b20 830cf043 nt!ObOpenObjectByPointerWithTag+0xc1

05 8c5f8b48 830cce02 nt!ObOpenObjectByPointer+0x24

06 8c5f8cfc 830d555e nt!PsOpenProcess+0x231

07 8c5f8d1c 82e9742a nt!NtOpenProcess+0x2d

08 8c5f8d1c 772564f4 nt!KiFastCallEntry+0x12a



Post 콜백 루틴 호출됬을 때 콜스택

00 8c3f48f8 830e971f 여기서 Post 콜백 호출!!

01 8c3f4914 830e9c04 nt!ObpCallPostOperationCallbacks+0x2b

02 8c3f4944 83038ac1 nt!ObpPostInterceptHandleCreate+0x55

03 8c3f49a0 83090fde nt!ObpCreateHandle+0x434

04 8c3f4b20 83091043 nt!ObOpenObjectByPointerWithTag+0xc1

05 8c3f4b48 8308ee02 nt!ObOpenObjectByPointer+0x24

06 8c3f4cfc 8309755e nt!PsOpenProcess+0x231

07 8c3f4d1c 82e5942a nt!NtOpenProcess+0x2d

08 8c3f4d1c 77c364f4 nt!KiFastCallEntry+0x12a

09 000bf318 77c351dc ntdll!KiFastSystemCallRet

0a 000bf31c 75ff91b6 ntdll!NtOpenProcess+0xc


'My Study > Programming&Theory' 카테고리의 다른 글

Windows 7 x86 Bypass UAC  (12) 2013.01.14
ObCreateObjectType & ObjectType  (8) 2012.12.31
Red-Black Tree - 3  (1) 2012.12.24
FltCancelFileOpen 궁금증  (4) 2012.12.20
Red-Black Tree - 2  (0) 2012.12.19