커널 모드 후킹 – SSDT 후킹

커널 모드 후킹 – SSDT 후킹

SSDT 후킹 역시 위 엔프로텍트를 이용하여 진행해 보도록 하겠다.

그럼 바로 분석에 들어가자.

// 먼저 SSDT의 주소를 확인하기 위해 KeServiceDescriptorTable를 확인하자. 첫번째 메모리 주소가 SSDT는 위치이다.

kd> dd KeServiceDescriptorTable

8055c220 804e46a8 00000000 0000011c 80512088

8055c230 00000000 00000000 00000000 00000000

8055c240 00000000 00000000 00000000 00000000

8055c250 00000000 00000000 00000000 00000000

8055c260 00002730 bf80c0b6 00000000 00000000

8055c270 f8a11a80 f7169b60 81d940f0 81d940f0

8055c280 00000000 00000000 00000000 00000000

8055c290 b6929ec0 01ccfc05 00000000 00000000

// 2부에서 애기 했듯이 SSDT는 2가지의 테이블을 가지고 있는데, 바로 쉐도우 테이블이 있다. 이 테이블도 함께 확인해 보면 같은 영역을 가르키는 것을 알 수 있다.

kd> dd KeServiceDescriptorTableShadow

8055c1e0 804e46a8 00000000 0000011c 80512088

8055c1f0 bf999b80 00000000 0000029b bf99a890

8055c200 00000000 00000000 00000000 00000000

8055c210 00000000 00000000 00000000 00000000

8055c220 804e46a8 00000000 0000011c 80512088

8055c230 00000000 00000000 00000000 00000000

8055c240 00000000 00000000 00000000 00000000

8055c250 00000000 00000000 00000000 00000000

// dds 명령을 이용하여 11c(KeServiceDescriptorTable의 개수, 284) 만큼 출력하라는 의미이다.

kd> dds 804e46a8 L11c

804e46a8 80591df5 nt!NtAcceptConnectPort

804e46ac 8057b0f1 nt!NtAccessCheck

804e46b0 80589999 nt!NtAccessCheckAndAuditAlarm

804e46b4 80593130 nt!NtAccessCheckByType

804e46b8 8058fa83 nt!NtAccessCheckByTypeAndAuditAlarm

804e46bc 8063a07e nt!NtAccessCheckByTypeResultList

804e46c0 8063c207 nt!NtAccessCheckByTypeResultListAndAuditAlarm

804e46c4 8063c250 nt!NtAccessCheckByTypeResultListAndAuditAlarmByHandle

804e46c8 8057c6e4 nt!NtAddAtom

804e46cc 8064b047 nt!NtQueryBootOptions

804e46d0 80639835 nt!NtAdjustGroupsToken

804e46d4 8058f0a1 nt!NtAdjustPrivilegesToken

804e46d8 8063197c nt!NtAlertResumeThread

804e46dc 8057cbcd nt!NtAlertThread

804e46e0 8058a928 nt!NtAllocateLocallyUniqueId

804e46e4 806288ff nt!NtAllocateUserPhysicalPages

804e46e8 805df3c9 nt!NtAllocateUuids

804e46ec 8056afc3 nt!NtAllocateVirtualMemory

804e46f0 805db767 nt!NtAreMappedFilesTheSame

…중략

// 백신을 설치한 이후에도 몇몇 테이블 주소를 변경된 것을 확인할 수 있다.

kd> dds 804e46a8 L11c

804e46a8 80591df5 nt!NtAcceptConnectPort

804e46ac 8057b0f1 nt!NtAccessCheck

804e46b0 80589999 nt!NtAccessCheckAndAuditAlarm

804e46b4 80593130 nt!NtAccessCheckByType

804e46b8 8058fa83 nt!NtAccessCheckByTypeAndAuditAlarm

804e46bc 8063a07e nt!NtAccessCheckByTypeResultList

804e46c0 8063c207 nt!NtAccessCheckByTypeResultListAndAuditAlarm

804e46c4 8063c250 nt!NtAccessCheckByTypeResultListAndAuditAlarmByHandle

804e46c8 8057c6e4 nt!NtAddAtom

804e46cc 8064b047 nt!NtQueryBootOptions

804e46d0 80639835 nt!NtAdjustGroupsToken

804e46d4 8058f0a1 nt!NtAdjustPrivilegesToken

804e46d8 8063197c nt!NtAlertResumeThread

804e46dc 8057cbcd nt!NtAlertThread

804e46e0 8058a928 nt!NtAllocateLocallyUniqueId

804e46e4 806288ff nt!NtAllocateUserPhysicalPages

804e46e8 805df3c9 nt!NtAllocateUuids

804e46ec f8819e40*** ERROR: Module load completed but symbols could not be loaded for TKPcFtHk.sys

TKPcFtHk+0x1e40

804e46f0 805db767 nt!NtAreMappedFilesTheSame

804e46f4 805a44ba nt!NtAssignProcessToJobObject

…중략

804e4888 8057a0e5 nt!NtOpenMutant

804e488c 805973a9 nt!NtOpenObjectAuditAlarm

804e4890 f8819dc0 TKPcFtHk+0x1dc0

804e4894 8056fef5 nt!NtOpenProcessToken

804e4898 805700ee nt!NtOpenProcessTokenEx

804e489c 80572fd7 nt!NtOpenSection

804e48a0 805a0fc5 nt!NtOpenSemaphore

…중략

// 내용이 많아 중략하였다.
KeServiceDescriptorTable을 아래와 같이 x 명령을 이용하여서도 확인할 수 있다.

kd> x nt!KeServiceDescriptorTable

8055c220 nt!KeServiceDescriptorTable = <no type information>

// 위 출력된 값과 아래 모듈의 범위값에 해당하는지 비교하여 보면 쉽게 확인할 수 있다.

kd> lm t n

start end module name

7c930000 7c9cb000 ntdll ntdll.dll Mon Apr 14 11:26:22 2008 (4802C0CE)

804d9000 806efd80 nt ntoskrnl.exe Mon Apr 14 04:27:39 2008 (48025EAB)

806f0000 80703d00 hal halacpi.dll Mon Apr 14 03:31:27 2008 (4802517F)

bf800000 bf9c2800 win32k win32k.sys Mon Apr 14 04:29:46 2008 (48025F2A)

bf9c3000 bf9d4600 dxg dxg.sys Mon Apr 14 03:38:27 2008 (48025323)

bf9d5000 bf9e50c0 VBoxDisp VBoxDisp.dll Fri Feb 18 01:46:28 2011 (4D5D50E4)

f555d000 f559da80 HTTP HTTP.sys Mon Apr 14 03:53:48 2008 (480256BC)

f57d6000 f5800180 kmixer kmixer.sys Mon Apr 14 03:45:07 2008 (480254B3)

f5801000 f5823d00 aec aec.sys Fri May 25 04:53:32 2007 (4655ED3C)

…(중략)

[실습] SSDT 후킹 분석

!chkimg를 이용한 후킹 탐지

Windbg에는 모듈에서 제공하는 함수들이 정상적으로 SSDT에 등록되어 있는지 유무를 확인하는 확장명령을 제공하는데 이를 이용하여 효과적으로 SSDT 후킹 유무를 확인 할 수 있다.

// chkimg를 이용하여 쉽게 모듈 범위 이외에 사용되는 SSDT 테이블 리스트를 확인할 수 있다. 그럼 커널 명령으로 주로 이용되는 Ntoskrnl에 대해 확인해 보자.

kd> !chkimg ntoskrnl -d

804e46ec-804e46ef 4 bytes – nt!KiServiceTable+44

    [ c3 af 56 80:50 23 8d f8 ]

804e477c-804e477f 4 bytes – nt!KiServiceTable+d4 (+0x90)

    [ 3f 06 59 80:40 24 8d f8 ]

804e478c-804e478f 4 bytes – nt!KiServiceTable+e4 (+0x10)

    [ cd d1 65 80:30 29 8d f8 ]

804e47b8-804e47bb 4 bytes – nt!KiServiceTable+110 (+0x2c)

    [ e0 35 57 80:a0 28 8d f8 ]

804e4890-804e489b 12 bytes – nt!KiServiceTable+1e8 (+0xd8)

    [ c7 37 57 80 f5 fe 56 80:c0 22 8d f8 d0 27 8d f8 ]

804e48a8-804e48ab 4 bytes – nt!KiServiceTable+200 (+0x18)

    [ bd c1 58 80:70 25 8d f8 ]

804e48cc-804e48cf 4 bytes – nt!KiServiceTable+224 (+0x24)

    [ b1 3c 57 80:60 27 8d f8 ]

804e49fc-804e49ff 4 bytes – nt!KiServiceTable+354 (+0x130)

    [ df fc 62 80:50 26 8d f8 ]

804e4a9c-804e4aa3 8 bytes – nt!KiServiceTable+3f4 (+0xa0)

    [ c1 18 63 80 5e 24 5e 80:b0 26 8d f8 00 27 8d f8 ]

804e4aac-804e4ab3 8 bytes – nt!KiServiceTable+404 (+0x10)

    [ e0 42 58 80 85 d8 57 80:60 22 8d f8 f0 25 8d f8 ]

804e4afc-804e4aff 4 bytes – nt!KiServiceTable+454 (+0x50)

    [ 20 04 58 80:d0 23 8d f8 ]

// 변조된 주소의 값을 확인해보면, TKPcFtHk가 이용하고 있는 것으로 나타난다.

kd> dds 804e46ec

804e46ec f88d2350 TKPcFtHk+0x2350

804e46f0 805db767 nt!NtAreMappedFilesTheSame

804e46f4 805a44ba nt!NtAssignProcessToJobObject

804e46f8 804e4cb4 nt!NtCallbackReturn

804e46fc 8064b05b nt!NtModifyBootEntry

804e4700 805cbb06 nt!NtCancelIoFile

804e4704 804eefac nt!NtCancelTimer

804e4708 8056b66f nt!NtClearEvent

804e470c 805698dd nt!NtClose

804e4710 8058f50f nt!NtCloseObjectAuditAlarm

804e4714 8065093c nt!NtCompactKeys

804e4718 8058b718 nt!NtCompareTokens

804e471c 80592b3d nt!NtCompleteConnectPort

804e4720 80650ba9 nt!NtCompressKey

804e4724 805899eb nt!NtConnectPort

804e4728 804e3ff2 nt!NtContinue

804e472c 8065c054 nt!NtCreateDebugObject

804e4730 805a4882 nt!NtCreateDirectoryObject

804e4734 8056f57a nt!NtCreateEvent

804e4738 8064b14c nt!NtCreateEventPair

804e473c 8056edc0 nt!NtCreateFile

804e4740 80593389 nt!NtCreateIoCompletion

804e4744 805ad1b0 nt!NtCreateJobObject

804e4748 80631e27 nt!NtCreateJobSet

804e474c 8057265d nt!NtCreateKey

804e4750 805db658 nt!NtCreateMailslotFile

804e4754 8057a037 nt!NtCreateMutant

804e4758 80585f3f nt!NtCreateNamedPipeFile

804e475c 805bddb7 nt!NtCreatePagingFile

804e4760 805995b1 nt!NtCreatePort

804e4764 805b335a nt!NtCreateProcess

804e4768 80581c60 nt!NtCreateProcessEx

// 그 외 주소들도 확인해 보면 TKPcFtHk가 이용하고 있는것으로 나타난다.

kd> dds 804e477c

804e477c f88d2440 TKPcFtHk+0x2440

804e4780 805a05e5 nt!NtCreateTimer

804e4784 805aab58 nt!NtCreateToken

804e4788 805dd124 nt!NtCreateWaitablePort

804e478c f88d2930 TKPcFtHk+0x2930

804e4790 8065d327 nt!NtDebugContinue

804e4794 80568410 nt!NtDelayExecution

804e4798 80589485 nt!NtDeleteAtom

804e479c 8064b05b nt!NtModifyBootEntry

804e47a0 805da00b nt!NtDeleteFile

804e47a4 805972be nt!NtDeleteKey

804e47a8 8063c2ab nt!NtDeleteObjectAuditAlarm

804e47ac 80594d50 nt!NtDeleteValueKey

804e47b0 80590fad nt!NtDeviceIoControlFile

804e47b4 805c0f81 nt!NtDisplayString

804e47b8 f88d28a0 TKPcFtHk+0x28a0

804e47bc 8057efe1 nt!NtDuplicateToken

804e47c0 8064b047 nt!NtQueryBootOptions

804e47c4 80572d64 nt!NtEnumerateKey

804e47c8 8064aad3 nt!NtEnumerateSystemEnvironmentValuesEx

804e47cc 8059266b nt!NtEnumerateValueKey

804e47d0 80627720 nt!NtExtendSection

804e47d4 805b2b3e nt!NtFilterToken

804e47d8 8058b9a8 nt!NtFindAtom

804e47dc 80589602 nt!NtFlushBuffersFile

804e47e0 80579693 nt!NtFlushInstructionCache

804e47e4 805de590 nt!NtFlushKey

804e47e8 8059cccc nt!NtFlushVirtualMemory

804e47ec 80629163 nt!NtFlushWriteBuffer

804e47f0 80628cb4 nt!NtFreeUserPhysicalPages

804e47f4 8056b8ed nt!NtFreeVirtualMemory

804e47f8 8057cab5 nt!NtFsControlFile

…중략

// 해당 모듈에 대한 정보를 확인해 보자. 프로그램을 보호하기 위해서 관련정보를 표시하지 않는다.

kd> lmvm TKPcFtHk

start end module name

f88d0000 f88d4e00 TKPcFtHk (no symbols)

Loaded symbol image file: TKPcFtHk.sys

Image path: TKPcFtHk.sys

Image name: TKPcFtHk.sys

Timestamp: Fri Sep 23 09:26:01 2011 (4E7BD219)

CheckSum: 000071F1

ImageSize: 00004E00

Translations: 0000.04b0 0000.04e4 0409.04b0 0409.04e4

// 모듈 정보를 세부적으로 표시하는 확장명령을 사용하여도, 큰 정보는 얻을 수 없다.

kd> !lmi TKPcFtHk

Loaded Module Info: [tkpcfthk]

Module: TKPcFtHk

Base Address: f8928000

Image Name: TKPcFtHk.sys

Machine Type: 332 (I386)

Time Stamp: 4e7bd219 Fri Sep 23 09:26:01 2011

Size: 4e00

CheckSum: 71f1

Characteristics: 102

Debug Data Dirs: Type Size VA Pointer

CODEVIEW 6d, 3850, 3850 RSDS – GUID: {D766B70F-277D-4423-B2EA-DD070939D0DA}

Age: 1, Pdb: h:\17440~1.wor\2ada3~1.sou\engdev~3\branches\if2e25~1.01_\bin\free\i386\TKPcFtHk.pdb

Image Type: MEMORY – Image read successfully from loaded memory.

Symbol Type: NONE – PDB not found from symbol server.

Load Report: no symbols loaded

// 인터넷으로 검색해본 결과 해당 모듈이 잉카 인터넷 필터 드라이버임을 확인할 수 있었다. 이제 해당 드라이버가 후킹한 시스템 서비스 코드를 되돌려 보자. !chkimg –f 옵션을 이용하여 쉽게 되돌릴 수 있다.

kd> !chkimg ntoskrnl -f

Warning: Any detected errors will be fixed to what we expect!

60 errors (fixed): ntoskrnl (804e46ec-804e4aff)

// 재확인 해보면 더 이상 후킹된 코드가 없음을 확인할 수 있다.

kd> !chkimg ntoskrnl -d

0 errors : ntoskrnl

[실습] !chkimg 명령을 이용하여 NTDll의 후킹된 함수들을 교정하였다

Facebook Comments

Leave A Reply

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다.