• 【微软漏洞分析】MS15-010 CNG 安全功能绕过漏洞 - CVE-2015-0010


    MS15-010

    CVE-2015-0010 微软漏洞描述

    下一代密码术 ( CNG ) 内核模式驱动程序 (cng.sys) 无法正确验证和强制执行模拟级别时,它存在安全功能绕过漏洞。攻击者可以通过诱使用户运行特制的应用程序来利用此漏洞,该应用程序旨在导致 CNG 不正确地验证模拟级别,从而可能使攻击者获得对超出本地用户访问级别的信息的访问权限。该安全更新通过更正内核模式驱动程序验证和实施模拟级别的方式来解决该漏洞。

    此漏洞已公开披露。它已被分配通用漏洞和暴露编号CVE-2015-2010。

    漏洞作者分析

    函数 CryptProtectMemory 允许应用程序为以下三种情况之一加密内存:进程、登录会话和计算机。当使用登录会话选项(CRYPTPROTECTMEMORY_SAME_LOGON 标志)时,加密密钥是根据登录会话标识符生成的,这是为了在同一登录中运行的进程之间共享内存。由于这也可用于将数据从一个进程发送到另一个进程,因此它支持从模拟令牌中提取登录会话 ID。

    问题是 CNG.sys 中的实现在捕获登录会话 id(使用 SeQueryAuthenticationIdToken)时不检查令牌的模拟级别,因此普通用户可以在标识级别模拟并解密或加密该登录会话的数据。

    CryptProtectMemory 是一个 API,您应该使用它来保护临时数据,例如内存中的密码或加密密钥。内存的实际密钥存储在内核中,因此用户模式程序不应直接访问它。保护分为三个级别:

    1. 仅当前进程
    2. 当前登录会话
    3. 当前计算机

    此问题仅影响 2,如果您使用与另一个登录会话(例如本地系统的会话)绑定的令牌进行模拟,您可以加密和解密内存。内核驱动程序缺少模拟级别检查,因此普通系统用户可以在标识级别模拟并解密在本地系统登录会话中加密的数据。此模拟级别不为普通用户提供任何额外的权限。
    问题描述没有提供可访问加密数据的具体示例,但它可能会在许多地方泄漏,例如共享内存部分或临时文件。因此,问题的最终严重性取决于哪些数据可以被解密或加密,以及您可以用它做什么(想想数据是否是另一个用户的密码)。

    补丁分析

    我们这里以windows 7的x86的补丁分析,补丁解开之后的目录列表如下:
    在这里插入图片描述
    因为MS15-010涉及到多个漏洞,我们这里的CVE-2015-0010仅仅涉及到lsa,查看lsa的目录的文件列表如下:
    在这里插入图片描述

    重点查看补丁文件为:

    • \x86\lsa_6.1.7601.18719
      • cng.sys

    cng.sys

    主要包括一个更新函数:

    1. CngEncryptMemory

    CngEncryptMemory

    更新前

    int __stdcall CngEncryptMemory(void *a1, unsigned int a2, int a3, int a4)
    {
    	......
    	struct _SECURITY_SUBJECT_CONTEXT SubjectContext;
    	......
        SeCaptureSubjectContext(&SubjectContext);
        SeLockSubjectContext(&SubjectContext);
        v5 = SubjectContext.ClientToken;
        if ( !SubjectContext.ClientToken )
          v5 = SubjectContext.PrimaryToken;
        v6 = SeQueryAuthenticationIdToken(v5, &AuthenticationId);
        SeUnlockSubjectContext(&SubjectContext);
        SeReleaseSubjectContext(&SubjectContext);
    	......
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    更新后

    int __stdcall CngEncryptMemory(void *a1, unsigned int a2, int a3, int a4)
    {
      ......
      struct _SECURITY_SUBJECT_CONTEXT SubjectContext;
      ......
      SeCaptureSubjectContext(&SubjectContext);
      SeLockSubjectContext(&SubjectContext);
      v5 = SubjectContext.ClientToken;
      if ( !SubjectContext.ClientToken )
      {
        v5 = SubjectContext.PrimaryToken;
        goto LABEL_14;
      }
      if ( SubjectContext.ImpersonationLevel > SecurityIdentification )
      {
    LABEL_14:
        v6 = SeQueryAuthenticationIdToken(v5, &AuthenticationId);
        goto LABEL_15;
      }
      v6 = -1073741659;
    LABEL_15:
      SeUnlockSubjectContext(&SubjectContext);
      SeReleaseSubjectContext(&SubjectContext);
      if ( v6 < 0 )
        return v6;
      ......
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    重点分析

    SeQueryAuthenticationIdToken这个函数是这个漏洞的关键,反编译ntoskrnl.exe之后看一下这个函数的代码:

    NTSTATUS __stdcall SeQueryAuthenticationIdToken(PACCESS_TOKEN Token, PLUID AuthenticationId)
    {
      *AuthenticationId = (struct _LUID)*((_QWORD *)Token + 3);
      return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    这个函数的执行非常简单,也符合作者的说法,它没有做任何模拟级别的判断,只是从Token所在的地址的偏移地址上找到AuthenticationId字段。

    这是一个漏洞攻击面,下一个漏洞分析,还会介绍一个类似的漏洞。

    我们在理解Windows的安全体系的时候,要仔细分析,它有多个层面多个维度的安全防护。工程师在写代码的时候,他不一定能过理解所有层面所有维度的安全防护方案。

    参考

    https://bugs.chromium.org/p/project-zero/issues/detail?id=128

    https://learn.microsoft.com/en-us/security-updates/SecurityBulletins/2015/ms15-010

    Security Update for Windows 7 (KB3023562)
    https://www.microsoft.com/en-us/download/details.aspx?id=45600

  • 相关阅读:
    哦麦艾斯!AI设计的丑衣服将引领时尚?数据结构与算法代码面试题;将文件藏在图片里的隐写工具;蒙古语语音合成语料库
    Spring | 事务没有生效导致数据没有持久化的探究
    【Linux】生产消费模型 + 线程池
    用友BIP开发者生态亮相华为全联接大会
    Python基础入门例程16-NP16 发送offer(列表)
    C++设计模式|创建型 4.建造者模式
    torch.optim 之 Algorithms (Implementation: for-loop, foreach, fused)
    php运行原理详细说明
    ​ModbusTCP转Profibus-DP从站网关把modbus的数据传到300plc上的应用方法​​
    PCL ICP点云精配准(点到面)
  • 原文地址:https://blog.csdn.net/fastergohome/article/details/127692431