[W02-1008] GearSoftware Powered Products Local Privilege Escalation (Microsoft Windows Kernel IopfCompleteRequest Integer Overflow)
[ HTML FORMATED Advisory ]
http://www.wintercore.com/advisories/advisory_W021008.html
[TEXT VERSION]
GearSoftware Powered Products Local Privilege Escalation
+ GEARASpiWDM.sys Insecure Method
+ Microsoft Windows Kernel IopfCompleteRequest Integer Overflow
:: Summary
1. Background
2. Non-technical description
3. Technical Description
4. Exploiting it
5. References
6. Affected Products
7. Credits
8. Disclosure Timeline
9. Contact
1. Background
"GEAR Software has set the standard for professional DVD & CD recording
software for more than twenty years. GEAR develops solutions for
professional premastering, DVD editing and authoring, and is also a
leading provider of development tools that enable software companies to
integrate optical recording technology into their own products. GEAR
technology is integrated into solutions from some of the world's most
prominent technology organizations, including Apple, Symantec, Siemens,
Kodak, Philips and Bosch, among many others"
www.gearsoftware.com
2. Non-technical description
Microsoft Windows Kernel is prone to a local privilege escalation due to
an integer overflow error within the IopfCompleteRequest function. This
vulnerability may allow attackers to execute arbitrary code in the
kernel context, thus allowing to escalate privileges to SYSTEM. However,
the attack vector needed for taking advantage of this weakness has not
been identified on a out-of-box Windows installation. Therefore, a
third-party application is, so far, the unique possible attack vector
to exploit this issue.
This advisory covers the attack vector found in a widely extended
licensed application, GearSoftware Recording SDK, which was exposing the
kernel flaw to user-mode attackers through one of its filter drivers:
GEARAspiWDM.sys
Since this driver is a licensed solution, it is bundled with several
well-known products. To clarify as much as possible this vulnerability,
we should distinguish three different elements which make up the problem.
1. The underlying vulnerability: Microsoft Windows Kernel
IopfCompleteRequest Integer Overflow.
2. The Attack Vector: GearAspiWDM.sys Insecure Method.
3. Vulnerable Products: Every GearSoftware powered product that is
bundled with GEARAspiWDM.sys. (e.g Norton 360, Apple iTunes...)
Whilst the underlying vulnerability is, under our point of view, a real
vulnerability, the Attack Vector may or may not be considered a
vulnerability by itself. Note that if we supress the underlying
vulnerability from the equation, then the attack vector turns out to be
practically useless, however by patching only the attack vector we will
always be facing the risk that another one comes to light.On the other
hand, this fact is not impossible but seems very unlikely.
Microsoft, as the vendor affected by the underlying vulnerability, Apple
and Symantec as Vulnerable Products were directly contacted . After
verifying the details provided Microsoft did not consider this flaw
elegible for a patch. Therefore,with the help of the US-CERT, Symantec,
Apple, GearSoftware and Wintercore were coordinated during the process
of resolving this issue by patching GEARAspiWDM.sys driver.
The final outcome is that the Attack Vector has been patched although
the underlying vulnerability still remains unpatched.
3. Technical Description.
The problem lies in how the stack locations are traversed while trying
to complete an IRP. Let's see
lkd> dt nt!_IRP
[...]
+0x022 StackCount : Char *signed*
+0x023 CurrentLocation : Char *signed*
[...]
Module: ntoskrnl.exe
Version: XP SP2
.text:0040CC01
.text:0040CC01 ; __fastcall IopfCompleteRequest(x, x)
.text:0040CC01 @IopfCompleteRequest@8 proc near ; CODE XREF:
IoPerfCompleteRequest(x,x)+88p
.text:0040CC01 ;
IoPerfCompleteRequest(x,x)+B8p ...
.text:0040CC01
.text:0040CC01 var_C = dword ptr -0Ch
.text:0040CC01 var_8 = dword ptr -8
.text:0040CC01 var_1 = byte ptr -1
.text:0040CC01
.text:0040CC01
.text:0040CC01 mov edi, edi
.text:0040CC03 push ebp
.text:0040CC04 mov ebp, esp
.text:0040CC06 sub esp, 10h
.text:0040CC09 push ebx
.text:0040CC0A push esi
.text:0040CC0B mov esi, ecx
.text:0040CC0D mov cl, [esi+23h] ; Irp->CurrentLocation
.text:0040CC10 mov [ebp+var_8], edx
.text:0040CC13 mov dl, [esi+22h] ; Irp->StackCount
.text:0040CC16 xor ebx, ebx
.text:0040CC18 inc dl ; Irp->StackCount+1
.text:0040CC1A cmp cl, dl
.text:0040CC1C push edi
.text:0040CC1D mov [ebp+var_C], ebx
.text:0040CC20 jg sub_444F81
.text:0040CC26 cmp word ptr [esi], 6 ; Irp->Type == IO_TYPE_IRP
.text:0040CC2A jnz sub_444F81
.text:0040CC30 mov edi, [esi+60h] ; Irp->CurrentStackLocation
.text:0040CC33 inc cl
.text:0040CC35 cmp cl, dl
.text:0040CC37 lea eax, [edi+24h]
.text:0040CC3A mov [esi+23h], cl ; Irp->CurrentLocation++
.text:0040CC3D mov [esi+60h], eax
;Irp->Tail->Overlay.CurrentStackLocation++
.text:0040CC40 jg short loc_40CCA6
.text:0040CC42 add edi, 3
{...}
.text:0040CC8D
.text:0040CC8D loc_40CC8D: ; CODE XREF: IopfCompleteRequest(x,x)+13Cj
.text:0040CC8D add dword ptr [esi+60h], 24h ; StackLocation++
.text:0040CC91 mov eax, [esi+60h]
.text:0040CC94 add edi, 24h
;Irp->Tail.Overlay.CurrentStackLocation++
.text:0040CC97 inc byte ptr [esi+23h] ; Irp->CurrentLocation++
.text:0040CC9A mov dl, [esi+22h] ; Irp->StackCount
.text:0040CC9D mov cl, [esi+23h] ; Irp->CurrentLocation
.text:0040CCA0 inc dl
.text:0040CCA2 cmp cl, dl ; if CurrentLocation <= StackCount+1
.text:0040CCA4 jle short loc_40CC45 ; Signed comparison - FLAW -
pStack = IoGetCurrentIrpStackLocation( Irp )
for( pStack,
Irp->Tail.Overlay.CurrentStackLocation++
Irp->CurrentLocation++;
Irp->CurrentLocation <= (CHAR) (Irp->StackCount + 1);
pStack++,
Irp->Tail.Overlay.CurrentStackLocation++
Irp->CurrentLocation++ )
{
...
}
Well, let's imagine an IRP where the StackCount and CurrentLocation = =
0x7e (pretty unusual but possible indeed)
After the first iterate within the for(){...} , CurrentLocation will be
0x80 which is a negative value so Irp->CurrentLocation <= (CHAR)
(Irp->StackCount+1) becomes TRUE.Hence, remaining iterations will be
running out of allocated memory, traversing arbitrary and invalid stack
locations.
4. Exploiting it.
Digging into the for{} loop we found out the following:
Module: ntoskrnl.exe
XP SP2 (32-bit)
.text:0040CD30 loc_40CD30: ; CODE XREF:
IopfCompleteRequest(x,x)+4B47j
.text:0040CD30 push dword ptr [edi+1Dh]
.text:0040CD33 push esi
.text:0040CD34 push eax
.text:0040CD35 call dword ptr [edi+19h]
.text:0040CD38 cmp eax, 0C0000016h
.text:0040CD3D jnz loc_40CC8D ; StackLocation++
pStack->CompletionRoutine(...)
We must note that once the flaw has been triggered the for{} is
traversing invalid stack locations where *(edi+19h) points to
undetermined memory. We also have to take into account the internals of
the IO Manager where the memory allocated for the IRPs is zeroed.
Therefore, it has been proven that by allocating user-mode memory at 0x0
we can control the function pointer dereferenced.
However, that's not always true since we may be traversing uninitialized
memory that holds random values. For that cases, it is also possible to
seed the memory by issuing FSCTL/IOCTL requests before triggering the
flaw,thus we can assure a high reliability exploiting this flaw.
Anyway, the hardest task is to discover a suitable attack vector since
you need to force a huge driver stack. The patched driver was found
implementing an insecure method by which, an unlimited number of calls
to IoAttachDevice (TargetDevice is also user-controlled) were available
from user-land, simply by issuing an IOCTL request.Since GearspiWDM.sys
is signed in Vista 64-bit, it is possible to bypass certain kernel
restrictions by exploiting this issue sucessfully.
The driver's insecure method is exposed via the following "free-for-all"
device:
+ "\\.\GEARAspiWDMDevice"
The flaw lies within the handler for the IOCTL = = 0x222020
Module: GEARspiWDM.sys
(32-bit)
.text:000114B2 loc_114B2: ; CODE XREF: sub_1137E+7Bj
.text:000114B2 cmp [ebp+var_1], 0
.text:000114B6 jz short loc_114CC
.text:000114B8 cmp [edi+54h], ecx
.text:000114BB jz short loc_114CC
.text:000114BD push ebx
.text:000114BE mov ecx, edi
.text:000114C0 call sub_11CA2 ; IRP_MJ_DEVICE_CONTROL Dispatch Routine
{...}
.text:00011CA2 mov eax, [esp+arg_0]
.text:00011CA6 mov edx, [eax+60h]
.text:00011CA9 mov edx, [edx+0Ch]
.text:00011CAC push esi
.text:00011CAD mov esi, 222010h
.text:00011CB2 cmp edx, esi
.text:00011CB4 ja short loc_11CF7
.text:00011CB6 jz short loc_11CEF
.text:00011CB8 sub edx, 222000h
.text:00011CBE jz short loc_11CE7
{...}
.text:00011D10 loc_11D10: ; CODE XREF:
sub_11CA2+65j
.text:00011D10 push eax ; DeviceObject
.text:00011D11 call sub_11B90
||
\/
Module: GEARspiWDM.sys
(32-bit)
.text:00011B90 ; int __stdcall sub_11B90(PDEVICE_OBJECT DeviceObject)
.text:00011B90 sub_11B90 proc near ; CODE XREF:
sub_11CA2+6Fp
.text:00011B90
.text:00011B90 TargetDevice = UNICODE_STRING ptr -10h
.text:00011B90 var_8 = dword ptr -8
.text:00011B90 var_4 = dword ptr -4
.text:00011B90 DeviceObject = dword ptr 8
.text:00011B90
.text:00011B90 push ebp
.text:00011B91 mov ebp, esp
.text:00011B93 sub esp, 10h
.text:00011B96 mov eax, [ebp+DeviceObject]
.text:00011B99 mov eax, [eax+3Ch]
.text:00011B9C push ebx
.text:00011B9D xor ebx, ebx
.text:00011B9F cmp eax, ebx
.text:00011BA1 push edi
.text:00011BA2 mov edi, ecx
.text:00011BA4 mov [ebp+var_8], eax
.text:00011BA7 mov [ebp+DeviceObject], ebx
.text:00011BAA jnz short loc_11BB6
.text:00011BAC mov eax, 0C000000Dh
.text:00011BB1 jmp loc_11C9C
.text:00011BB6 ;
---------------------------------------------------------------------------
.text:00011BB6
.text:00011BB6 loc_11BB6: ; CODE XREF:
sub_11B90+1Aj
.text:00011BB6 push eax ; SourceString
.text:00011BB7 lea eax, [ebp+TargetDevice]
.text:00011BBA push eax ; DestinationString
.text:00011BBB call ds:RtlInitUnicodeString
{...}
.text:00011C3E lea edi, [esi+10h]
.text:00011C41 push edi ; AttachedDevice
.text:00011C42 lea eax, [ebp+TargetDevice]
.text:00011C45 push eax ; TargetDevice ;
user-controlled
.text:00011C46 push [ebp+DeviceObject] ; SourceDevice
.text:00011C49 call ds:IoAttachDevice
5. References
GearSoftware Updated Drivers:
http://www.gearsoftware.com/support/drivers.cfm
KB-CERT: http://www.kb.cert.org/vuls/id/146896
Symantec:
http://www.symantec.com/avcenter/security/Content/2008.10.07a.html
Apple: http://support.apple.com/kb/HT3025
6. Affected Products
Product/File
Vulnerable Version
GearAspiWDM.sys
< 2.011.2 (32-bit) < 2.008.2.1 (64-bit)
Microsoft Windows Kernel All versions 32/64-bit + 2000 + 2003 + XP + Vista
Apple iTunes 7.x
Symantec Norton 360 2.0 and earlier
Symantec Norton Ghost 14.0 and earlier
Symantec Norton Save and Restore 2.0 and earlier
Symantec Backup Exec System Recovery 6.x, 7.x and 8.x
7. Credits
Vulnerability discovered and researched by Ruben Santamarta,
Wintercore.
8. Disclosure Timeline
11/14/2007 - Microsoft Contacted
12/26/2007 - Symantec Contacted
12/26/2007 - Apple Contacted
10/07/2008 - Coordinated Disclosure
9. Contact
Wintercore
Agustin de Betancourt, 21. 8th Floor.
28003 Madrid.
Spain.
Phone: +(34) 91 395 63 40
contact (at) wintercore (dot) com [email concealed]
www.wintercore.com
--
Wintercore
Agustin de Betancourt, 21. 8th Floor.
28003 Madrid. Spain.
Phone: +(34) 91 395 63 40
www.wintercore.com