Defeating Kernel Native API Hookers by Direct KiServiceTable Restoration

http://blog.naver.com/lsc3762/90014446734

Defeating Kernel Native API Hookers by Direct KiServiceTable Restoration

유저모드 API 호출
- 유저모드 Win32 어플리케이션은 여러 dll이 익스포트하는 api를 호출해서 시스템 서비스를 요청한다.
- 예를들어 오픈된 파일이나 파이프, 디바이스에 쓸려면 kernel32.dll이 익스포트하는 WriteFile api를 이용한다.
- WriteFile api는 다시 ntdll.dll이 익스포트하는 NtWriteFile/ZwWriteFile native api를 호출한다.
- ntdll.dll에서 NtWriteFile과 ZwWriteFile은 같은 코드를 포인트한다.
- 실제 작업은 커널모드에서 이뤄지므로 NtWriteFile/ZwWriteFile은 INT 0x2E 소프트웨어 인터럽트를 이용하여 커널코드로 이동하는
최소한의 코드만 갖는다.
- win2k에서 NtWriteFile/ZwWriteFile의 디스어셈블은 다음과 같다.
MOV EAX, 0EDh
LEA EDX, DWORD PTR SS:[ESP+4]
INT 2E
RETN 24
- 0xED는 커널 함수의 위치를 갖는 KiServiceTable의 인덱스에 이용되는 시스템 서비스 넘버이다.
- WinXP에서 디스어셈블은 다음과 같다.
MOV EAX, 112h
MOV ED, 7FFE0300h
CALL DWORD PTR DS:[EDX]
RETN 24
- 7FFE0300h은 다음 함수에 대한 포인터이다.
MOV EDX, ESP
SYSENTER
[열기]

[ System Service Dispatcher ]
- INT 2E에 대한 ISR(Interrupt Service Routine)은 KiSystemService이다.
- KiSystemService는 파라미터를 검사한후 SSDT(System Service Dispatch Table, KiServiceTable)의 엔트리를 확인해서 해당 시스템
서비스를 호출한다.
--------------------------------
0x00 NtAcceptConnectPort
--------------------------------
0x01 NtAccessCheck
--------------------------------
0x02 NtAccessCheckAndAuditAlarm
--------------------------------
.............................
--------------------------------
0xED NtWriteFile
--------------------------------
...........................
--------------------------------

[ KeServiceDescriptorTable ]
- KiServiceTable은 커널에서 익스포트되있지 않다.
- 그러나 주소는 KeServiceDescriptorTable로 알수 있다.(KeServiceDescriptorTable.ServiceDescriptor[0].KiServiceTable)
typedef struct ServiceDescriptorTable {
SDE ServiceDescriptor[4];
} SDT;

typedef struct ServiceDescriptorEntry {
PDWORD KiServiceTable;
PDWORD CounterTableBase;
DWORD ServiceLimit; // KiServiceTable의 엔트리 갯수
PBYTE ArgumentTable;
} SDE;
- ServiceDescriptor[1], [2], [3]은 사용되지 않는다.

[ Kernel Native API Hookers ]
- 커널에 로드되는 디바이스 드라이버는 KiServiceTable의 엔트리를 수정할수 있다.
- 자신의 디바이스 드라이버내의 후킹함수를 포인트하도록 수정한다.
- 보통, 원래 native api를 호출할수 있도록 원래 엔트리를 기억해둔다.

NTSYSAPI NTSTATUS NTAPI NtXXXHook(...)
{
ManipulateInputParameters(...);
NtXXXOriginal(...);
ManipulateReturnBuffers(...);
return;
}

- KiServiceTable 엔트리 수정은 보통 DriverEntry()에서 한다.

#define SYSTEMSERVICE(_api) KeServiceDescriptorTable.ServceDescriptor[0].ServiceTable[*(DWORD *)((unsigned char *)_api+1)]
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
system service number
// 원래 함수 포인터를 기억
NtWriteFileOrig=(NTWRITEFILE)(SYSTEMSERVICE(ZwWriteFile));

// 후킹함수인 NtWriteFileHook()을 포인트하도록 KiServiceTable 엔트리를 수정
(NTWRITEFILE(SYSTEMSERVICE(ZwWriteFile))=NtWriteFileHook;

[ 프로세스 숨기기 ]
- 유저모드 프로그램은 프로세스 리스트를 얻기위해 ToolHelp.dll이 익스포트하는 api를 이용한다.
- 이 api는 ntdll.dll에서 익스포트하는 Nt/ZwQuerySystemInformation()을 호출한다.
- 유저모드 프로그램에서 첫번째 파라미터를 SystemProcessAndThreadsInformation로 줘서 직접 Nt/ZwQuerySystemInformation()을 호출
할수도 있다.
- 커널 루트킷은 NtQuerySystemInformation()을 후킹해서 첫번째 파라미터가 SystemProcessAndThreadInformation인지 검사한다.
- 그런다음 리턴된 버퍼에서 프로세스를 숨긴후 콜러에게 리턴해준다.
NTSYSAPI NTSTATUS NTAPI NtQuerySystemInformationHook(IN ULONG SystemInformationClass,
IN OUT PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength OPTIONAL)
{
nts=NtQuerySystemInformationOrig(...);
if((nts==STATUS_SUCCESS) && (SystemInformationClass==SystemProcesAndThreadsInformation)) {
ManipulateReturnBuffers(SystemInformation, ...);
}
return nts;
}

- 리턴된 버퍼는 다음과 같은 구조체 배열이다.
typedef struct _SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryDelta; // 다음 엔트리 오프셋
ULONG ThreadCount; // 스레드 갯수
ULONG Reserved[6];
LARGE_INTEGER CreateTime; // 프로세스 생성시간
LARGE_INTEGER UserTime; // 유저모드에서 쓰인 시간
LARGE_INTEGER KernelTime; // 커널모드에서 쓰인 시간
UNICODE_STRING ProcessName; // 프로세스 이름
KPRIORITY BasePriority; // base process priority
ULONG ProcessId; // pid
ULONG InheritedFromProcessId; // ppid
.........
SYSTEM_THREAD_INFORMATION Threads[1];
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;

[ 로드된 드라이버 숨기기 ]
- 보통 자기 자신을 숨기는데 쓰인다.
- 유저모드 프로그램은 첫번째 파라미터로 SystemModuleInformation을 줘서 Nt/ZwQuerySystemInformation()을 호출해서 로드된 드라이버
목록을 구할수 있다.
typedef NTSYSAPI NTSTATUS (*ZWQUERYSYSTEMINFORMATION)(IN ULONG SystemInformationClass, IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength, OUT PULONG ReturnLength OPTIONAL);
- 두번째 파라미터에 아웃풋 버퍼를 줘서 받는다.
- 이 버퍼의 첫번째 DWORD값은 리턴된 배열 엔트리 갯수이다. 그다음 나머지 바이트는 다음과 같은 구조체 배열이다.
typedef struct _SYSTEM_MODULE_INFORMATION {
ULONG Reserved[2];
PVOID ImageBase;
ULONG ImageSize;
ULONG Flags;
USHORT Index;
USHORT Unknown;
USHORT LoadCount;
USHORT ModuleNameOffset;
CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION;

[ 파일 숨기기 ]
- 루트킷은 NtQueryDirectoryFile()을 후킹한다.

- 어떻게 시스템 서비스 후킹을 탐지할수 있을까?
SSDT는 커널 이미지 바깥쪽을 포인트하는 엔트리를 갖는다.
Nt/ZwQuerySystemInformation()으로 드라이버 목록과 베이스 주소를 알수 있다.
80400000 001A2340 - \WINNT\System32\ntoskrnl.exe
80062000 00010460 - \WINNT\System32\hal.dll
ED410000 00003000 - \WINNT\System32\BOOTVID.DLL
BFFD8000 00028000 - ACPI.sys
ED5C8000 00001000 - \WINNT\System32\DRIVERS\WMILIB.SYS

kd> d KeServiceDescriptorTable
8046dfa0 b8 42 47 80 00 00 00 00-f8 00 00 00 9c 46 47 80 .BG..........FG. ServiceDescriptor[0]
8046dfb0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ ServiceDescriptor[1]
8046dfc0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ ServiceDescriptor[2]
8046dfd0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................ ServiceDescriptor[3]

kd> d 804742b8
804742b8 52 dd 49 80 c1 f6 4a 80-3a 04 4b 80 b8 d5 50 80 R.I...J.:.K...P.
804742c8 70 04 4b 80 a2 ce 45 80-be f7 50 80 fe f7 50 80 p.K...E...P...P.
804742d8 38 4a 49 80 f2 a9 50 80-d8 de 4a 80 2d d8 4f 80 8JI...P...J.-.O.
804742e8 49 a6 4a 80 df 4d 49 80-ca b8 44 80 3d 7e 4c 80 I.J..MI...D.=~L.
804742f8 74 ee 5b f7 a9 94 4b 80-e0 db 4f 80 1a 19 40 80 t.[...K...O...@.
80474308 1c 04 4d 80 76 95 41 80-86 6d 4f 80 8e 35 49 80 ..M.v.A..mO..5I.
80474318 a8 f9 44 80 57 07 4b 80-d5 e2 49 80 75 dc 49 80 ..D.W.K...I.u.I.
80474328 a0 92 46 80 84 4b 4f 80-d2 35 49 80 40 92 4c 80 ..F..KO..5I.@.L.

KiserviceTable내의 주소값으로 시스템 서비스를 후킹하는 드라이버를 알수 있다.
80400000 - \WINNT\System32\ntoskrnl.exe
80062000 - \WINNT\System32\hal.dll
....
BF8B3000 - \SystemRoot\System32\Drivers\Cdfs.SYS
BF6F4000 - \SystemRoot\System32\Drivers\Fastfat.SYS
BF74F000 - \SystemRoot\System32\DRIVERS\ipsec.sys
F75BA000 - \SystemRoot\System32\DRIVERS\KProcCheck.sys
F75BE000 * \SystemRoot\System32\DRIVERS\gotr.sys

[ KProcCheck POC ]
C:\>kproccheck -t
KProcCheck Version 0.1 Proof-of-Concept by SIG^2 (www.security.org.sg)

Checks SDT for Hooked Native APIs

ZwAllocateVirtualMemory 10 \SystemRoot\System32\DRIVERS\gotr.sys [F75BEE74]
ZwCreateFile 20 \SystemRoot\System32\DRIVERS\gotr.sys [F75BEA85]
ZwCreateKey 23 \SystemRoot\System32\DRIVERS\gotr.sys [F75BEC5E]
ZwCreateProcess 29 \SystemRoot\System32\DRIVERS\gotr.sys [F75BEDB7]
ZwDeleteFile 34 \SystemRoot\System32\DRIVERS\gotr.sys [F75BE80C]
ZwGetTickCount 4C \SystemRoot\System32\DRIVERS\gotr.sys [F75BEE27]
ZwLoadDriver 55 \SystemRoot\System32\DRIVERS\gotr.sys [F75BEBF2]
ZwQueryDirectoryFile 7D \SystemRoot\System32\DRIVERS\gotr.sys [F75BE6E8]
ZwQuerySystemInformation 97 \SystemRoot\System32\DRIVERS\gotr.sys [F75BE623]
ZwSetInformationFile C2 \SystemRoot\System32\DRIVERS\gotr.sys [F75BE8A8]

Number of Service Table entries hooked = 10

- NtQuerySystemInformation(SystemModuleInformation, ...)이 후킹됐을수 있으므로 다른 방법으로 로드된 드라이버를 구한다.
- 직접 PsLoadedModuleList를 트래버스해서 구한다.
- Win2k 커널에서 PsLoadedModuleList는 다음과 같은 doubly linked-list의 시작이다.
struct {
LIST_ENTRY link; // Flink, Blink
BYTE unknown1[16];
DWORD ImageBase;
DWORD EntryPoint;
DWORD ImageSize;
UNICODE_STRING DrvPath;
UNICODE_STRING DrvName;
....
}

그러나 PsLoadedModuleList는 익스포트되 있지 않다. 그러므로 익스포트된 함수 MmGetSystemRoutineAddress()부터 다음과 같은
인스트럭션이 나올때 까지 스캐닝해서 주소를 찾는다.
8b35b8e14680 mov esi,[nt!PsLoadedModuleList (8046e1b8)]
81feb8e14680 cmp esi,0x8046e1b8

Nt/ZwquerySystemInformation(SystemModuleInformatin, ...)과 위에서 찾은 값을 비교해서 숨겨진 드라이버를 찾을수 있다.
C:\>kproccheck -d
KProcCheck Version 0.1 Proof-of-Concept by SIG^2 (www.security.org.sg)

80400000 - \WINNT\System32\ntoskrnl.exe
80062000 - \WINNT\System32\hal.dll
F7410000 - \WINNT\System32\BOOTVID.DLL
F7000000 - pci.sys
F7010000 - isapnp.sys
F7500000 - intelide.sys
F7280000 - \WINNT\System32\DRIVERS\PCIIDEX.SYS
F7288000 - MountMgr.sys
BFFE3000 - ftdisk.sys
...
BF6F4000 - \SystemRoot\System32\Drivers\Fastfat.SYS
BF74F000 - \SystemRoot\System32\DRIVERS\ipsec.sys
F75BA000 - \SystemRoot\System32\DRIVERS\KProcCheck.sys
F75BE000 * \SystemRoot\System32\DRIVERS\gotr.sys --[Hidden]--

Total number of drivers = 73

[ 후킹된 엔트리 복원 ]
- 어떻게 원래 값을 알수 있을까?
- KiServiceTable의 복사본은 ntoskrnl.exe에서 찾을수 있다.
.data:004742B8 off_0_4742B8 dd offset sub_0_49DD52 ; DATA XREF: sub_0_55A996
.data:004742BC dd offset sub_0_4AF6C1
.data:004742C0 dd offset sub_0_4B043A
.data:004742C4 dd offset sub_0_50D5B8
.data:004742C8 dd offset sub_0_4B0470
.data:004742CC dd offset sub_0_45CEA2
.data:004742D0 dd offset sub_0_50F7BE
.data:004742D4 dd offset sub_0_50F7FE
.data:004742D8 dd offset NtAddAtom
.data:004742DC dd offset sub_0_50A9F2
.data:004742E0 dd offset NtAdjustPrivilegesToken
.data:004742E4 dd offset sub_0_4FD82D
.data:004742E8 dd offset sub_0_4AA649
.data:004742EC dd offset NtAllocateLocallyUniqueId

- 드라이버를 로드하거나 유저모드에서 직접 \device\physicalmemory에 써서 후킹을 복원할수 있다.
- \device\physicalmemory는 커널 메모리를 포함한 피지컬 메모리에 유저모드 프로그램이 읽거나 쓸수 있게 해준다.

[ SDTrestore POC ]
- physical 메모리를 보기위해 \device\physicalmemory를 이용하는건 Mark Russinovich가 Physmem 툴에서 처음 사용되었다.
90210 - \device\physicalmemory에 써서 GDT call gate를 인스톨한다. ActiveprocessLinks에서 자신의 EPROCESS 구조체를 언링킹해서
프로세스를 숨긴다.
crazylord - "playing with windows /dev/(k)mem", \device\physicalmemory에 써서 GDT call gate를 인스톨한후 ActiveProcessLinks를
트래버싱해서 프로세스 목록을 구한다.
다음은 어떻게 어드민 권한을 가진 유저모드 프로그램이 피지컬 메모리에 읽고 쓸수 있는 권한을 갖을수 있는지 설명한다.
1. ntdll.dll에서 익스포트하는 NtOpenSection() native api에 SECTION_MAP_READ | SECTION_MAP_WRITE access flag를 줘서
\device\physicalmemory 핸들을 구한다. 이건 보통 어드미니스트레이터가 \device\physicalmemory에 SECTION_MAP_WRITE 억세스
권한이 없으므로 실패한다.
2. NtOpenSection()에 READ_CONTROL | WRITE_DAC access flag로 피지컬메모리 핸들을 구한다. 이건 피지컬메모리 오브젝트에 새 DACL을
추가해준다.
3. 어드민이 SECTION_MAP_WRITE access권한을 가질수 있도록 피지컬메모리에 DACL을 추가한다.
4. 다시 피지컬메모리 핸들을 구한다.

피지컬메모리에 쓸려면 프로그램은 피지컬메모리 페이지를 자신의 버츄얼 어드레스 공간에 맵핑해야한다.
ntStatus=_NtMapViewOfSection(
hPhyMem, // \device\physicalmemory handle
(HANDLE)-1, // OUT- physical memory가 맵핑될 virtual memory(paging file)
0,
*length,
&viewBase, // IN/OUT- 맵핑될 physical memory address(page aligned)
length, // IN/OUT- 맵핑된 physical memory size
ViewShare,
0,
PAGE_READWRITE
);

KiServiceTable을 복원할려면 ntoskrnl.exe 커널 파일 이미지에서 KiServiceTable의 위치와 physical memory 주소를 알아야 한다.
win2k, winxp, 서비스팩에 따라 다르므로 이 주소들을 하드코딩할수 없다.
NtmapViewOfSection()에서 페이지를 맵핑하는데 virtual address가 아니라 physical memory address를 이용한걸 기억하라.
win2k에서 커널 베이스 주소는 가상메모리의 0x80400000이다.
win2k 커널의 physical memory 주소는 0x400000이다.

- 디스크 이미지에서 KiServiceTable의 주소 구하기
ntoskrnl.exe를 dll로 로드한후 익스포트 테이블에서 KeServiceDescriptorTable의 오프셋을 구한다.
ServiceDescriptorTable을 갖고있는 physical page로 맵핑한다.
PhyaddrserviceDescriptorTable=kernelPhysicalBaseAddr+offset_of_KeServiceDescriptroTable
맵핑된 페이지에서 KiServiceTable 주소를 구한다.
이것은 커널영역에서 KiServiceTable의 virtual address(0x804742b8)일 것이다.
kd> d KeServiceDescriptorTable
8046dfa0 b8 42 47 80 00 00 00 00-f8 00 00 00 9c 46 47 80 .BG..........FG.
8046dfb0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
8046dfc0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
8046dfd0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
8046dfe0 20 f1 df ff 00 00 00 00-00 00 00 00 00 00 00 00 ...............
8046dff0 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
8046e000 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................

커널 파일 이미지의 오프셋으로 변경한다.
serviceTableOffset=serviceTableVirtualAddr-kernelVirtualBaseAddr(0x80400000)
이렇게해서 KiServiceTable의 복사본의 오프셋을 알수 있다.
그러나 이 방법은 실행중인 커널의 KiServiceTable의 오프셋이 디스크 이미지 내의 오프셋과 같아야 한다.
루트킷이나 다른 보안프로그램이 KiServiceTable을 재배치한다면 이 방법은 안된다.
rootkit.com의 90210이 디스크 이미지에서 KiServiceTable 위치를 찾는 보다 나은 방법을 제시했다.
KiServiceTable은 KeServiceDescriptorTable의 복사본 실행이 설정됐을때 KiInitSystem에서 참조된다.
INIT:0055AA65 mov eax, offset dword_0_482258
INIT:0055AA6A mov ds:KeServiceDescriptorTable, offset KiServiceTable
INIT:0055AA74 mov ds:dword_0_48225C, eax

그런데 KiInitSystem은 익스포트되있지 않으므로 다음과 같은 인스트럭션을 ntoskrnl.exe에서 스캔해서 찾아야 한다.
mov KeServiceDescriptorTable, imm32

relocation table이 참조하는 위치만 스캔하므로 이 방법이 보다 효과적이고 믿을만 하다.
이 테이블에서 각 엔트리에 대해 KeServiceDescriptorTable을 참조하는지 검사한다.
참조한다면 인스트럭션이 mov KeServiceDescriptorTable, imm32 인지 검사한다.

- KiServiceTable 패치
디스크상의 KiServiceTable의 복사본의 위치를 찾은후에 실행중인 커널의 KiServiceTable을 갖고있는 피지컬 페이지로 맵핑하고 다른
엔트리를 패치한다.
패치하기 전에 먼저 값을 커널의 virtual address로 바꿔줘야한다.
for(DWORD i=0; i<sdtCount; i++) {
if((kernelServiceTable[i]-kernelVirtualBase+peXH2.imageBase)!=fileServiceTable[i]) {
kernelServiceTable[i]=fileServiceTable[i]-peXH2imageBase+kernelVirtualBase;
printf("[+] Patched SDT entry %.2X to %.8X\n", i, kernelServiceTable[i]);
}
}

Native API Hookers 예제
커널 루트킷- NT Rootkit, HE4Hook
보안 툴- Sebek Win32, DiamondCS Process Guard, Kerio Personal Firewall 4

HE4Hook은 다음과 같이 파일을 숨긴다.
1. 다음과 같은 시스템 서비스를 후킹한다.
ZwCreateFile 20 --[hooked by unknown at 81222476]--
ZwOpenFile 64 --[hooked by unknown at 812224A8]--
ZwQueryDirectoryFile 7D --[hooked by unknown at 812224D2]--
2. 또는 파일 시스템 드라이버의 콜백 테이블을 후킹한다.
1번 방법은 KiServiceTable 엔트리를 복원해서 쉽게 제거할수 있다.

Sebek은 하니팟에서 주로 사용하는 콘솔 로거이다.
cmd.exe의 인풋, 아웃풋을 캡쳐하고 로깅서버에 udp 패킷으로 보낸다.
cmd.exe 세션을 암호화해서 로깅할수 있다.
다음과 같은 시스템 서비스를 후킹한다.
ZwClose 18 SEBEK.sys [F729A092]
ZwCreateFile 20 SEBEK.sys [F729A98C]
ZwCreateKey 23 SEBEK.sys [F729AD10]
ZwEnumerateKey 3C SEBEK.sys [F729AE02]
ZwEnumerateValueKey 3D SEBEK.sys [F729AA50]
ZwOpenFile 64 SEBEK.sys [F729A8E6]
ZwOpenKey 67 SEBEK.sys [F729AD88]
ZwQueryDirectoryFile 7D SEBEK.sys [F729A4CC]
ZwQuerySystemInformation 97 SEBEK.sys [F729A5F0]
ZwReadFile A1 SEBEK.sys [F7299CF0]
ZwRequestWaitReplyPort B0 SEBEK.sys [F7299F14]
ZwSecureConnectPort B8 SEBEK.sys [F7299FE6]
ZwWriteFile ED SEBEK.sys [F7299D48]
sebek.sys를 숨기기 위해(anti-detection), sebek.sys를 로드하는 레지스트리키를 숨기기 위해(anti-detection), cmd.exe를 로그하기 위해
ZwReadFile/ZwWriteFile을 후킹한다.
역쉬 쉽게 무력화할수 있다.

DiamondCS Process Guard
프로세스 종료, 서스펜드, 악의적인 커널 드라이버가 로딩하는걸 보호하는 보안툴이다.
ZwCreateFile 20 \??\C:\WINNT\System32\drivers\procguard.sys [F7392D8A]
ZwCreateKey 23 \??\C:\WINNT\System32\drivers\procguard.sys [F7391F98]
ZwCreateThread 2E \??\C:\WINNT\System32\drivers\procguard.sys [F73924FC]
ZwOpenFile 64 \??\C:\WINNT\System32\drivers\procguard.sys [F7392C62]
ZwOpenKey 67 \??\C:\WINNT\System32\drivers\procguard.sys [F7391F64]
ZwOpenProcess 6A \??\C:\WINNT\System32\drivers\procguard.sys [F739289E]
ZwOpenThread 6F \??\C:\WINNT\System32\drivers\procguard.sys [F73926F8]
ZwRequestWaitReplyPort B0 \??\C:\WINNT\System32\drivers\procguard.sys [F7390AE6]
ZwSetValueKey D7 \??\C:\WINNT\System32\drivers\procguard.sys [F739224E]
ZwWriteVirtualMemory F0 \??\C:\WINNT\System32\drivers\procguard.sys [F7392A40]

Kerio Personal Firewall 4
알려지지않은 또는 새로운 또는 수정된 프로그램이 실행될때마다 유저에게 프로세스를 실행할 것인지 묻는다.
ZwCreateFile 20 \SystemRoot\system32\drivers\fwdrv.sys [BFBD3830]
ZwCreateProcess 29 \SystemRoot\system32\drivers\fwdrv.sys [BFBD3380]
ZwCreateThread 2E \SystemRoot\system32\drivers\fwdrv.sys [BFBD35E0]
ZwResumeThread B5 \SystemRoot\system32\drivers\fwdrv.sys [BFBD3630]

Native API 후킹 보안툴
KiServiceTable을 복원해서 무력화시킬수 있다.
이걸 방지하기 위해 추가적으로 다음과 같은게 필요하다.
- NtLoadDriver를 후킹해서 드라이버가 로딩되는걸 막는다.
- SystemInformationClass=SystemLoadAndCallImage[13]으로 NtSetSystemInformation을 후킹해서 드라이버 로딩을 막는다.
- ZwOpenSection을 후킹해서 \device\physicalmemory로 write access를 막는다.
- 심볼릭 링크를 통해 \device\physicalmemory로 write access를 막는다.

후킹을 하지않는 루트킷
FU 루트킷
- PsLoadedModuleList에서 언링킹을 해서 드라이버를 숨긴다.
- ActiveprocessLinks에서 언링킹을 해서 프로세스를 숨긴다.

Process Hide- phide
- ActiveProcessLinks에서 언링킹을 해서 프로세스를 숨긴다. 드라이버를 인스톨할 필요없이 GDT call gate를 통해 한다.

이런류의 루트킷은 KiServiceTable을 복원하는 방법으로 무력화시킬수 없다.

결론
Sysem Service 후킹에 기반한 커널 루트킷은 KiServiceTable을 복원해서 무력화시킬수 있다.
요즘 루트킷들은 후킹을 사용하지않고 탐지하고 무력화하기가 힘들다.
보안툴은 시스템 서비스 후킹에 의존해선 안된다.

이 글과 관련있는 글을 자동검색한 결과입니다 [?]

by narumee | 2008/01/16 12:00 | └Windows Internals | 트랙백(3) | 덧글(0)

트랙백 주소 : http://octet.egloos.com/tb/1296572
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Tracked from Generic effe.. at 2008/07/19 11:53

제목 : Effexor withdrawall.
Effexor alcohol abuse. Baby effexor. Effexor xr. Effexor. Effexor withdrawal symptoms....more

Tracked from Phentermine .. at 2009/02/02 20:39

제목 : Phentermine florida.
Online phentermine. Phentermine. Buy phentermine diet pill. Cheapest phentermine online....more

Tracked from Order cialis.. at 2009/02/08 00:57

제목 : Cialis without prescription.
Order cialis without a prescription. Discount cialis free prescription....more

:         :

:

비공개 덧글

◀ 이전 페이지          다음 페이지 ▶