<<< Date Index >>>     <<< Thread Index >>>

[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