An analysis for the problem of y pterminating hidden orphan processes on Windows NTAhmed SallamChief Software Architect
f
© 2007 McAfee, Inc.
McAfee AVERT Labs
Agenda2
• Technical background— Active process listActive process list— Process enumeration— The “system” process
P t i ti— Process termination
• The rootkits challenge— Orphan hidden process— Orphan hidden process— Hidden process detection— The challenge of terminating hidden orphan processes
Th l ti— The solution— Suggestions to Microsoft
10/5/2007
Active Process List4
• EPROCESS: kernel structure to represent every running process• ActiveProcessList: links allocated EPROCESS structures together• ActiveProcessLinks: a structure of two pointers inside EPROCESS:
— Flink: Pointer to the ActiveProcessLinks of next process— Blink: pointer to the ActiveProcessLinks of previous processBlink: pointer to the ActiveProcessLinks of previous process
• PsActiveProcessHead: head pointer of ActiveProcessList, points to:— Flink: pointer to the ActiveProcessLinks of the first process in the
ActiveProcessListActiveProcessList— Blink: pointer to the ActiveProcessLinks of the last process in the
ActiveProcessList
10/5/2007
Process enumeration5
S dFi t Last
FlinkBlink
Second process
FlinkBlink
First process
FlinkBlink
PsActiveProcessHead
FlinkBlink
Last process
• Windows enumerate processes by traversing the Active Process List starting from the PsActiveProcessHead
10/5/2007
The “System” process6
• Represents the Windows system kernel• ”System” process is the first process in the ActiveProcessListSystem process is the first process in the ActiveProcessList
— “System”_eprocess ->ActiveProcessLinks.Blink = nt!PsActiveProcessHead— PsActiveProcessHead->Flink = “system”_eprocess->ActiveProcessLinks
Dumping PsActiveProcessHeadkd> dd P A ti P H dkd> dd PsActiveProcessHead 805604d8 81bcc8b8 819d5e28
Dumping system process ActiveProcessLinks: (81bcc830)p g y p ( )Kd> dt _eprocess 81bcc830+0x088 ActiveProcessLinks : _LIST_ENTRY [ 0x819510a8 - 0x805604d8 ]
10/5/2007
Process deletion, stack frame7
• nt!PspProcessDelete • nt!ObpRemoveObjectRoutine+0xdd • nt!ObfDereferenceObject+0x5d • nt!ObpCloseHandleTableEntry+0x153 • nt!ObpCloseHandle+0x85 • nt!NtClose+0x19 (FPO: [1,0,0])• nt!KiSystemService+0xc4 • SharedUserData!SystemCallStub+0x4 • ntdll!ZwClose+0xc • kernel32!CloseHandle+0x4d• services!ScDeleteImageRecord+0x16 • services!ScRemoveService+0x84 • services!RemovalThread+0x9 • kernel32!BaseThreadStart+0x37
10/5/2007
Process deletion, remarks9
• PspProcessDelete removes the deleted EPROCESS structure from the Active Process List
• PspProcessDelete does not check if the process is already in the list!
• Does that create a problem? Let’s see!
10/5/2007
Manipulating the Active Process List11
• Rootkits conceals the presence of their processes• Rootkits remove their EPROCESS structure from ActiveRootkits remove their EPROCESS structure from Active
Process List (DMKO) becoming orphan processes• Windows kernel does not care about orphan processes:
— Continue execution, scheduler does not care— Continue own and manage resources, object manager does not care
• So orphan processes are hidden and still can run perfectly!So orphan processes are hidden and still can run perfectly!
10/5/2007
Detection of hidden processes12
• Many known techniques to detect EPROCESS structures removed from Active Process List
• Basic idea is to intercept a kernel function called by the hidden process and then examine the Cid and EPROCESSEPROCESS:
— Interception of I/O functions— Traversing of kernel scheduler lists— Interception of object manager functions— Interception of file system or network functions
• Detection is not sufficient termination is required too• Detection is not sufficient, termination is required too
10/5/2007
Process termination13
• NtTerminateProcess is the kernel provided function• NtTerminateProcess:NtTerminateProcess:
— Enumerates threads by calling PsGetNextProcessThread — Terminates each thread by calling PspTerminateThreadByPointer
Cl h dl t bl b lli ObCl P H dl T bl— Clear process handle table by calling ObClearProcessHandleTable— Dereference EPROCESS object by calling ObfDereferenceObject
• ObfDereferenceObject calls ObpRemoveObjectRoutinej p jwhich calls PspProcessDelete
• None of these steps verify if process is in the list or not!?• Is it safe to call NtTerminateProcess for orphan processes?
10/5/2007
Termination of orphan processes14
• PspProcessTerminate uses ActiveProcessLinks pointers of the process without any verification
• Two side effects:— Some rootkits maliciously modify the
ActiveProcessLinks such that termination of the hiddenActiveProcessLinks such that termination of the hidden process destroys the Active Process List
— Since the time the rootkit has been made hidden there may have been other created or deleted processes changing the previous order of the orphan process in the listthe list
• End result Active Process List becomes invalid!
10/5/2007
Use case15
• Rootkit process is the last process in the list• Rootkit process ActiveProcessLinks.Flink points to the PsActiveProcessHead• Rootkit removes its EPROCESS structure from the Active Process List• System starts a new process, which could be the Rootkit Detective• Rootkit Detective detects the hidden process • Rootkit Detective calls ZwTerminateProcess to terminate the hidden process• ZwTerminateProcess calls PspProcessDelete internally• PspProcessDelete adjusts the next process ActiveProcessLinks.Blink
(b k d li k) t i t t th i(backward link) to point to the new previous process• But the next process of the hidden process is the PsActiveProcessHead, which
results in the PsActiveProcessHead->Blink to point to the wrong process, and the ActiveProcessList gets corruptedthe ActiveProcessList gets corrupted
10/5/2007
The current solution 17
• Reinsert the hidden process at the end of the list— The ActiveProcessLinks.Flink of the inserted hidden process to point to
PsActiveProcessHead— The ActiveProcessLinks.Blink of the inserted hidden process to point
to the current last process in the ActiveProcessList (pointed to by P A ti P H d Bli k)PsActiveProcessHead.Blink)
— The PsActiveProcessHead.Blink (current last process in the list) to point to the ActiveProcessLinks of the inserted hidden processThe ActiveProcessLinks FLink of the last process (pointed to by— The ActiveProcessLinks.FLink of the last process (pointed to by PsActiveProcessHead.Blink) in the list to point to the inserted hidden process’s ActiveProcessLinks
• Call NtTerminateProcessCall NtTerminateProcess
Patent pending
10/5/2007
p g
Suggestion to Microsoft18
• Verify if a process is in the Active Process List before:— Allocating more resources for the processAllocating more resources for the process— Executing the process threads— Terminating the processg p
• Apply same checks to other system objects (device drivers)• Allow security companies to enumerate and release
d b hresources owned by orphan processes• Vista 32 bits still has the same issue!
10/5/2007
Conclusion19
• Microsoft can simply handle rootkits attacks by applying some simple checks inside the kernel to:p
— Pause the execution of the hidden processes— Allow security companies to safely terminate hidden processes
PatchG ard ma not be the best sol tion ☺• PatchGuard may not be the best solution ☺
10/5/2007
Top Related