Kernel Pool Exploitation on Windows 7 , # Angielskie Ebooki

[ Pobierz całość w formacie PDF ]
//-->Kernel Pool Exploitation on Windows 7Tarjei Mandtkernelpool@gmail.comAbstract.In Windows 7, Microsoft introducedsafe unlinkingto ad-dress the growing number of security bulletins affecting the Windowskernel. Prior to removing an entry from a doubly-linked list, safe un-linking aims to detect memory corruption by validating the pointers toadjacent list entries. Hence, an attacker cannot easily leverage generictechniques in exploiting pool overflows or other pool corruption vulner-abilities. In this paper, we show that in spite of the security measuresintroduced, Windows 7 is still susceptible to generic kernel pool attacks.In particular, we show that the pool allocator may under certain condi-tions fail to safely unlink free list entries, thus allowing an attacker tocorrupt arbitrary memory. In order to thwart the presented attacks, wepropose ways to further harden and enhance the security of the kernelpool.Keywords:kernel pool, safe unlinking, exploitation1IntroductionAs software bugs are hard to completely eliminate due to the complexity ofmodern day computing, vendors are doing their best to isolate and prevent ex-ploitation of security vulnerabilities. Mitigations such as DEP and ASLR havebeen introduced in contemporary operating systems to address a variety of com-monly used exploitation techniques. However, as exploit mitigations do not ad-dress the root cause of security vulnerabilities, there will always be edge casescenarios where they fall short. For instance, DEP alone is easily circumventedusing return-oriented programming (ROP) [15]. Furthermore, novel techniquesleveraging the capabilities of powerful application-embedded scripting enginesmay bypass DEP and ASLR completely [4].A complementary approach to exploit mitigations is privilege isolation. Byimposing restrictions on users and processes using the operating system’s built-in security mechanisms, an attacker cannot easily access and manipulate systemfiles and registry information in a compromised system. Since the introductionof user account control (UAC) in Vista, users no longer run regular applicationswith administrative privileges by default. Additionally, modern browsers [2] anddocument readers [13][12] use ”sandboxed” render processes to lessen the impactof security vulnerabilities in parsing libraries and layout engines. In turn, thishas motivated attackers (as well as researchers) to focus their efforts on privilegeescalation attacks. By executing arbitrary code in the highest privileged ring,operating system security is undermined.Privilege escalation vulnerabilities are in most cases caused by bugs in theoperating system kernel or third party drivers. Many of the flaws originate inthe handling of dynamically allocatedkernel poolmemory. The kernel pool isanalogous to the user-mode heap and was for many years susceptible to genericwrite-4 attacks abusing the unlink operation of doubly-linked lists [8][16]. Inresponse to the growing number of kernel vulnerabilities, Microsoft introducedsafe unlinkingin Windows 7 [3]. Safe unlinking ensures that the pointers toadjacent pool chunks on doubly-linked free lists are validated before a chunk isunlinked.An attacker’s goal in exploiting pool corruption vulnerabilities is to ulti-mately execute arbitrary code in ring 0. This often starts with an arbitrarymemory write or n-byte corruption at a chosen location. In this paper, we showthat in spite of the security measures introduced, the kernel pool in Windows 7is still susceptible to generic1attacks. In turn, these attacks may allow an at-tacker to fully compromise the operating system kernel. We also show that safeunlinking, designed to remediate write-4 attacks, may under certain conditionsfail to achieve its goals and allow an attacker to corrupt arbitrary memory. Inorder to thwart the presented attacks, we conclusively propose ways to furtherharden and enhance the security of the kernel pool.The rest of the paper is organized as follows. In Section 2 we elaborate onthe internal structures and changes made to the Windows 7 (and Vista) kernelpool. In Section 3 and 4 we discuss and demonstrate practical kernel pool attacksaffecting Windows 7. In Section 5 we discuss counter-measures and propose waysto harden the kernel pool. Finally, in Section 6 we provide a conclusion of thepaper.2Kernel Pool InternalsIn this section, we elaborate on the kernel pool management structures and algo-rithms involved in the allocation and deallocation of pool memory. Understand-ing kernel pool behavior is vital in properly assessing its security and robustness.For brevity, we assume the x86 architecture (32-bit). However, most structuresare applicable to AMD64/x64 (64-bit). Notable differences in the kernel poolbetween x86 and x64 architectures are discussed in Section 2.9.2.1Non-Uniform Memory ArchitectureFor every new version of Windows, the memory manager is enhanced to bet-ter support the Non-Uniform Memory Architecture (NUMA), a memory designarchitecture used in modern multi-processor systems. NUMA dedicates differ-ent memory banks to different processors, allowing local memory to be accessedmore quickly, while remote memory is accessed more slowly. The processors andmemory are grouped together in smaller units callednodes,defined by theKNODEstructure in the executive kernel.1Applicable to any n-byte pool corruption vulnerability.typedef struct _KNODE{/*0x000*/union _SLIST_HEADER PagedPoolSListHead;/*0x008*/union _SLIST_HEADER NonPagedPoolSListHead[3];/*0x020*/struct _GROUP_AFFINITY Affinity;/*0x02C*/ULONG32ProximityId;/*0x030*/UINT16NodeNumber;/*0x032*/UINT16PrimaryNodeNumber;/*0x034*/UINT8MaximumProcessors;/*0x035*/UINT8Color;/*0x036*/struct _flags Flags;/*0x037*/UINT8NodePad0;/*0x038*/ULONG32Seed;/*0x03C*/ULONG32MmShiftedColor;/*0x040*/ULONG32FreeCount[2];/*0x048*/struct _CACHED_KSTACK_LIST CachedKernelStacks;/*0x060*/LONG32ParkLock;/*0x064*/ULONG32NodePad1;/*0x068*/UINT8_PADDING0_[0x18];} KNODE, *PKNODE;On multi-node systems (nt!KeNumberNodes>1), the memory manager willalways try to allocate from the ideal node. As such,KNODEprovides informationas to where local memory is found in theColorfield. This value is an array indexused by the allocation and free algorithms to associate nodes with its preferredpool. Additionally,KNODEdefines four singly-linked per-node lookaside lists forfree pool pages (discussed in Section 2.6).2.2System Memory PoolsAt system initialization, the memory manager creates dynamically sized mem-ory pools according to the number of system nodes. Each pool is defined by apool descriptor (discussed in Section 2.3), a management structure that trackspool usage and defines pool properties such as the memory type. There are twodistinct types of pool memory:pagedandnon-paged.Paged pool memory can be allocated and accessed from any process con-text, but only at IRQL<DPC/dispatch level. The number of paged poolsin use is given bynt!ExpNumberOfPagedPools.On uniprocessor systems, four(4) paged pool descriptors are defined, denoted by indices 1 through 4 in thent!ExpPagedPoolDescriptorarray. On multiprocessor systems, one (1) pagedpool descriptor is defined per node. In both cases, an additional paged pool de-scriptor is defined for prototype pools / full page allocations, denoted by index 0innt!ExpPagedPoolDescriptor.Hence, in most desktop systems five (5) pagedpool descriptors are defined.Non-paged pool memory is guaranteed to reside in physical memory at alltimes. This is required by threads executing at IRQL>=DPC/dispatch level(such as interrupt handlers), as page faults cannot be timely satisfied. The num-ber of non-paged pools currently in use is given bynt!ExpNumberOfNonPagedPools.On uniprocessor systems, the first index of thent!PoolVectorarray points tothe non-paged pool descriptor. On multiprocessor systems, each node has its ownnon-paged pool descriptor, indexed by thent!ExpNonPagedPoolDescriptorar-ray.Additionally,sessionpool memory (used bywin32k)is used for session spaceallocations and is unique to each user session. While non-paged session memoryuse the global non-paged pool descriptor(s), paged session pool memory hasits own pool descriptor defined innt!MM SESSION SPACE.To obtain the sessionpool descriptor, Windows 7 parses the associatednt!EPROCESSstructure (of thecurrently executing thread) for the session space structure, and subsequentlyfinds the embedded paged pool descriptor.2.3Pool DescriptorMuch like the user-mode heap, every kernel pool requires a management struc-ture. Thepool descriptoris responsible for tracking the number of running allo-cations, pages in use, and other information regarding pool usage. It also helpsthe system to keep track of reusable pool chunks. The pool descriptor is definedby the following structure (nt!POOLDESCRIPTOR).typedef struct _POOL_DESCRIPTOR{/*0x000*/enum _POOL_TYPE PoolType;union {/*0x004*/struct _KGUARDED_MUTEX PagedLock;/*0x004*/ULONG32NonPagedLock;};/*0x040*/LONG32RunningAllocs;/*0x044*/LONG32RunningDeAllocs;/*0x048*/LONG32TotalBigPages;/*0x04C*/LONG32ThreadsProcessingDeferrals;/*0x050*/ULONG32TotalBytes;/*0x054*/UINT8_PADDING0_[0x2C];/*0x080*/ULONG32PoolIndex;/*0x084*/UINT8_PADDING1_[0x3C];/*0x0C0*/LONG32TotalPages;/*0x0C4*/UINT8_PADDING2_[0x3C];/*0x100*/VOID**PendingFrees;/*0x104*/LONG32PendingFreeDepth;/*0x108*/UINT8_PADDING3_[0x38];/*0x140*/struct _LIST_ENTRY ListHeads[512];} POOL_DESCRIPTOR, *PPOOL_DESCRIPTOR;The pool descriptor holds several important lists used by the memory man-ager. Thedelayed free list,pointed to byPendingFrees,is a singly-linked listof pool chunks waiting to be freed. It is explained in detail in Section 2.8. TheListHeadsis an array of doubly-linked lists of free pool chunks of the samesize. Unlike the delayed free list, the chunks in theListHeadslists have beenfreed and can be allocated by the memory manager at any time. We discuss theListHeadsin the following section.2.4ListHeads Lists (Free Lists)TheListHeadslists, or free lists, are ordered in size of 8-byte granularity andused for allocations up to 4080 bytes2. The free chunks are indexed into the List-Heads array byblock size,computed as the requested number of bytes roundedup to a multiple of 8 and divided by 8, orBlockSize = (NumberOfBytes+0xF)>> 3.The rounding is performed to reserve space for thepool header,a structurepreceding all pool chunks. The pool header is defined as follows on x86 Windows.typedef struct _POOL_HEADER{union {struct {/*0x000*/UINT16/*0x000*/UINT16/*0x002*/UINT16/*0x002*/UINT16};/*0x000*/ULONG32};union {/*0x004*/ULONG32struct {/*0x004*/UINT16/*0x006*/UINT16};};} POOL_HEADER, *PPOOL_HEADER;PreviousSize : 9;PoolIndex : 7;BlockSize : 9;PoolType : 7;Ulong1;PoolTag;AllocatorBackTraceIndex;PoolTagHash;The pool header holds information necessary for the allocation and free algo-rithms to operate properly.PreviousSizeindicates the block size of the preced-ing pool chunk. As the memory manager always tries to reduce fragmentationby merging bordering free chunks, it is typically used to locate the pool headerof the previous chunk.PreviousSizemay also be zero, in which case the poolchunk is located at the beginning of a pool page.PoolIndexprovides the index into the associated pool descriptor array, suchasnt!ExpPagedPoolDescriptor.It is used by the free algorithm to make surethe pool chunk is freed to the proper pool descriptorListHeads.In Section 3.4,we show how an attacker may corrupt this value in order to extend a pool headercorruption (such as a pool overflow) into an arbitrary memory corruption.As its name suggests,PoolTypedefines a chunk’s pool type. However, it alsoindicates if a chunk is busy or free. If a chunk is free,PoolTypeis set to zero. Onthe other hand, if a chunk is busy,PoolTypeis set to its descriptor’s pool type (a2The remaining page fragment cannot be used if requested bytes exceed 4080. [ Pobierz całość w formacie PDF ]
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • klobuckfatima.xlx.pl