Skip content
LRQA Cyber Labs

McAfee File Lock Driver - Kernel Stack Based BOF

Kyriakos Economou Senior R&D team member at Nettitude.
  • CVE: CVE-2015-8773
  •  Vendor: McAfee – Intel Security
  •  Reported by: Kyriakos Economou
  •  Date of Release: 26/01/2016
  •  Date of Fix: N/A
  •  Affected Products: Multiple
  •  Affected Version: McPvDrv.sys v4.6.111.0
  •  Fixed Version: N/A

Description:
McAfee File Lock Driver does not handle correctly GUIDs of the encrypted vaults, which allows to crash the host by crafting a specific IOCTL with a malformed Vault GUID which is used to identify an object of FILE_DEVICE_DISK DeviceType, causing a kernel stack based buffer overflow.
We have verified this issue in the lastest McAfee File Lock v5.x which ships with McAfee total protection suite. However, other products that include this package will also be affected.
Vulnerable module: McPvDrv.sys v4.6.111.0
Earlier versions of this kernel driver are probably affected by the same issue.
Impact:
The return address is protected by a security cookie, so exloiting this issue further than crashing the host doesn’t seem to be possible.
Technical Details:
GUID example:
867ba474 34 00 65 00 39 00 38 00 37 00 66 00 61 00 34 00 2d 00 39 00 66 00 38 00 4.e.9.8.7.f.a.4.-.9.f.8.
867ba48c 33 00 2d 00 34 00 30 00 61 00 64 00 2d 00 61 00 61 00 31 00 66 00 2d 00 3.-.4.0.a.d.-.a.a.1.f.-.
867ba4a4 62 00 35 00 33 00 65 00 61 00 35 00 64 00 63 00 00 00 00 00 00 00 00 00 b.5.3.e.a.5.d.c……..
Parsing GUID:
95e77094 8b4d08 mov ecx,dword ptr [ebp+8] <– Pointer to Vault’s GUID (unicode)
95e77097 0fb701 movzx eax,word ptr [ecx] <– start reading GUID
95e7709a 83c40c add esp,0Ch
95e7709d 6685c0 test ax,ax
95e770a0 7426 je McPvDrv+0x30c8 (95e770c8)
95e770a2 0fb7c0 movzx eax,ax
95e770a5 8d957cffffff lea edx,[ebp-84h] <— load to EDX the stack buffer address
95e770ab eb03 jmp McPvDrv+0x30b0 (95e770b0)
95e770ad 8d4900 lea ecx,[ecx]
95e770b0 663d2d00 cmp ax,2Dh <— check if it is ‘-‘ character
95e770b4 7406 je McPvDrv+0x30bc (95e770bc)
95e770b6 668902 mov word ptr [edx],ax <— if not write the character in the stack buffer
95e770b9 83c202 add edx,2 <– increase buffer index by 2
95e770bc 0fb74102 movzx eax,word ptr [ecx+2] <— get next character
95e770c0 83c102 add ecx,2
95e770c3 6685c0 test ax,ax
95e770c6 75e8 jne McPvDrv+0x30b0 (95e770b0) <— loop if not x00x00
Specifying a long GUID through a crafted IOCTL overflows the kernel stack based buffer.
The next algorithm is vulnerable as well to stack based buffer overflow, and it overflows stack based buffer again used by another function, assuming that the GUID was not long enough to overwrite the stack cookie, but long enough to allow the execution flow to go on and trigger this bug later.
Device Name example:
a4a2fa30 68 4f ac 85 29 2b e3 82 02 0d b4 82 01 00 00 00 00 00 00 00 5c 00 hO..)+……………
a4a2fa46 44 00 65 00 76 00 69 00 63 00 65 00 5c 00 4d 00 63 00 50 00 65 00 D.e.v.i.c.e..M.c.P.e.
a4a2fa5c 72 00 73 00 6f 00 6e 00 61 00 6c 00 56 00 61 00 75 00 6c 00 74 00 r.s.o.n.a.l.V.a.u.l.t.
a4a2fa72 73 00 5c 00 4d 00 63 00 50 00 76 00 44 00 72 00 76 00 7b 00 34 00 s..M.c.P.v.D.r.v.{.4.
a4a2fa88 65 00 39 00 38 00 37 00 66 00 61 00 34 00 39 00 66 00 38 00 33 00 e.9.8.7.f.a.4.9.f.8.3.
a4a2fa9e 34 00 30 00 61 00 64 00 61 00 61 00 31 00 66 00 62 00 35 00 33 00 4.0.a.d.a.a.1.f.b.5.3.
a4a2fab4 65 00 61 00 35 00 64 00 63 00 7d 00 00 00 00 00 b7 16 37 a4 d8 fa e.a.5.d.c.}…….7…
DeviceName/GUID concatenation:
95e770dc b90c000000 mov ecx,0Ch
95e770e1 be70eae795 mov esi,offset McPvDrv+0xaa70 (95e7ea70)
95e770e6 f3a5 rep movs dword ptr es:[edi],dword ptr [esi]
95e770e8 8bc3 mov eax,ebx
95e770ea 66a5 movs word ptr es:[edi],word ptr [esi]
95e770ec 83c0fe add eax,0FFFFFFFEh
95e770ef 90 nop
95e770f0 668b4802 mov cx,word ptr [eax+2]
95e770f4 83c002 add eax,2
95e770f7 6685c9 test cx,cx
95e770fa 75f4 jne McPvDrv+0x30f0 (95e770f0)
95e770fc 8b0d70ece795 mov ecx,dword ptr [McPvDrv+0xac70 (95e7ec70)]
95e77102 8908 mov dword ptr [eax],ecx
95e77104 8b1574ece795 mov edx,dword ptr [McPvDrv+0xac74 (95e7ec74)]
95e7710a 895004 mov dword ptr [eax+4],edx
95e7710d 8b0d78ece795 mov ecx,dword ptr [McPvDrv+0xac78 (95e7ec78)]
95e77113 894808 mov dword ptr [eax+8],ecx
95e77116 8b157cece795 mov edx,dword ptr [McPvDrv+0xac7c (95e7ec7c)]
95e7711c 89500c mov dword ptr [eax+0Ch],edx
95e7711f 668b0d80ece795 mov cx,word ptr [McPvDrv+0xac80 (95e7ec80)]
95e77126 8bfb mov edi,ebx
95e77128 66894810 mov word ptr [eax+10h],cx
95e7712c 83c7fe add edi,0FFFFFFFEh
95e7712f 90 nop
95e77130 668b4702 mov ax,word ptr [edi+2]
95e77134 83c702 add edi,2
95e77137 6685c0 test ax,ax
95e7713a 75f4 jne McPvDrv+0x3130 (95e77130)
95e7713c 8b1560ece795 mov edx,dword ptr [McPvDrv+0xac60 (95e7ec60)]
95e77142 8d857cffffff lea eax,[ebp-84h]
95e77148 8917 mov dword ptr [edi],edx
95e7714a 8bd0 mov edx,eax
95e7714c 8d642400 lea esp,[esp]
95e77150 668b08 mov cx,word ptr [eax]
95e77153 83c002 add eax,2
95e77156 6685c9 test cx,cx
95e77159 75f5 jne McPvDrv+0x3150 (95e77150)
95e7715b 8bfb mov edi,ebx
95e7715d 2bc2 sub eax,edx
95e7715f 83c7fe add edi,0FFFFFFFEh
95e77162 668b4f02 mov cx,word ptr [edi+2]
95e77166 83c702 add edi,2
95e77169 6685c9 test cx,cx
95e7716c 75f4 jne McPvDrv+0x3162 (95e77162)
95e7716e 8bc8 mov ecx,eax
95e77170 c1e902 shr ecx,2
95e77173 8bf2 mov esi,edx
95e77175 f3a5 rep movs dword ptr es:[edi],dword ptr [esi]
95e77177 8bc8 mov ecx,eax
95e77179 83e103 and ecx,3
95e7717c 83c3fe add ebx,0FFFFFFFEh
95e7717f f3a4 rep movs byte ptr es:[edi],byte ptr [esi]
95e77181 8bfb mov edi,ebx
95e77183 668b4702 mov ax,word ptr [edi+2]
95e77187 83c702 add edi,2
95e7718a 6685c0 test ax,ax
95e7718d 75f4 jne McPvDrv+0x3183 (95e77183)
95e7718f a150ece795 mov eax,dword ptr [McPvDrv+0xac50 (95e7ec50)]
95e77194 8b4dfc mov ecx,dword ptr [ebp-4]
95e77197 8907 mov dword ptr [edi],eax
The function above concatenates L”DeviceMcPersonalVaultsMcPvDrv” with the specified GUID that was read from the previous function.
It is used by a call to IoCreateDevice in order to create a FILE_DEVICE_DISK DeviceType.
DeviceName Example: L”DeviceMcPersonalVaultsMcPvDrv{4e987fa49f8340adaa1fb53ea5dc}”
Since the concatenation happens again inside a stack based buffer, it is possible to cause a buffer overflow.
Return addresses for both functions are protected by a stack cookie, so exploiting this issue further than a BSoD is probably not possible.
Disclosure Log:
Vendor Contacted: 16/09/2015
Request for feedback: 21/09/2015 – No response
Request for feedback: 08/10/2015 – No response
Request for feedback: 13/01/2016 – No response
Public Disclosure: 26/01/2016
Copyright:
Copyright © Nettitude Limited 2016, All rights reserved worldwide.
Disclaimer:
The information herein contained may change without notice. Any use of this information is at the user’s risk and discretion and is provided with no warranties. Nettitude and the author cannot be held liable for any impact resulting from the use of this information.
To contact Nettitude’s editor, please email media@nettitude.com

Latest Cyber Labs articles