AppLocker・App Control for Business(WDAC)与业务应用分发 ── 在被「执行控制」拦截之前

· · Windows, 安全, 信息系统, AppLocker, WDAC, Smart App Control, 代码签名, 部署

「安装到客户的电脑上之后,应用却启动不了。双击也没有任何反应」──在受托开发的 Windows 应用分发中,收到这类咨询的频率正在上升。调查原因后发现,连错误对话框都不弹出就把应用拦下来的元凶,正是客户端正在推进导入的应用执行控制

Windows 中有多种机制,用来只允许运行指定的应用。AppLockerApp Control for Business(长期以来被称为 WDAC = Windows Defender Application Control),以及面向个人用户的Smart App Control。在安全对策的语境中,多是从「导入方」角度进行的解说,本文则换一个视角,从制作并分发应用的一方来梳理。内容包括自家业务应用在客户环境中被拦截的典型模式、被拦截时查看哪些日志可以确定原因,以及开发・分发方可以提前采取的措施。同时,也会整理从信息系统部门角度考虑在自家电脑导入执行控制时的要点。

1. 先说结论

  • 执行控制要区分为 4 种来考虑。发出警告、让用户自行选择的SmartScreen,以用户/组为单位进行规则控制的AppLocker,以整台机器为对象的App Control for Business,以及面向个人自动生效的Smart App Control(见第 2 章的判断表)。
  • 「AppLocker 是 Enterprise 专用」这一常识已经过时。自 KB 5024351 起,在 Windows 10 版本 2004 及更高版本,以及所有 Windows 11 中,强制执行都不再需要特定版本。1
  • App Control for Business 可在 Windows 10/11 的所有客户端版本以及 Windows Server 2016 及更高版本中使用。微软建议,如果可行,应优先使用 App Control 而非 AppLocker。2
  • 分发方对策的核心是代码签名。不仅是 exe,还要对包括 DLL 在内的所有二进制文件和安装程序,以一致的发行者信息进行签名(第 5 章)。随着 Smart App Control 的普及,未签名的应用在个人电脑上也可能无法运行。3
  • 拦截的证据可以通过事件日志确定。AppLocker 是「AppLocker - EXE and DLL」日志的事件 8004,App Control 是「CodeIntegrity - Operational」日志的事件 3077,是最核心的证据(第 4 章的判断表)。45
  • PowerShell 脚本有时不是被「拦截」,而是「以受限模式执行」。在 App Control 环境中,不符合策略的脚本会以约束语言模式(Constrained Language Mode)运行,因此会出现「能运行,但部分处理会失败」这种难以察觉的故障方式。5
  • 导入方应从审核模式开始。AppLocker 与 App Control 都提供不拦截、只记录「原本应该被拦截的内容」的模式,对应的事件是 8003 和 3076。45

2. 区分四种机制

首先看一下整体地图。由于名称相近容易混淆,这里按照「谁来管理」「以什么为单位」「如何生效」来区分。

机制 对象 生效方式 管理者
SmartScreen 主要是已下载的文件 警告(默认情况下用户可以绕过,但也有禁止绕过的管理策略) OS 默认
Smart App Control Windows 11 的个人使用电脑 自动拦截(根据签名与云端评估判定) OS(自动)
AppLocker 域内/受管理的电脑 通过规则允许/拒绝。可以按用户・组单位区分 信息系统部门
App Control for Business(原 WDAC) 受管理的电脑 通过规则允许/拒绝。应用于整台机器・全部用户 信息系统部门

2.1. SmartScreen ── 唯一以「警告」拦下的机制

SmartScreen 是一种「对评价不佳的内容发出警告」的机制,默认情况下用户可以绕过。不过在受管理的环境中,有时会启用禁止绕过警告本身的策略,此时 SmartScreen 实质上也会起到拦截的作用(这一话题已在「Windows SmartScreen 与代码签名」中讨论过)。

从分发方的角度看,SmartScreen 的特点在于即使没有编写规则的管理员,它也默认生效,以及拦截的理由不是策略,而是「评价」。因此应对方式也与其他三种机制不同——不是请客户编写许可规则,而是要靠签名与评价的积累来解决。以下 2.2〜2.4 是拦截而非警告的机制。

2.2. AppLocker ── 可按用户单位控制的资深机制

AppLocker 是 Windows 7 中引入的执行控制机制,可根据代码签名证书的属性(发行者)、源自签名元数据的文件属性(原始文件名・版本)或哈希值,以及文件路径来定义规则。策略既可以应用于整台计算机,也可以应用于特定的用户・组2

版本要求是最容易被误解的地方。当前的文档说得很明确:自 KB 5024351 起,在 Windows 10 版本 2004 及更高版本,以及所有 Windows 11 中,强制执行 AppLocker 策略都不再需要特定版本。在更早的版本(2004 之前的 Windows 10,包括 Windows Server 2019)中,仍保留着以往的限制:通过组策略分发的强制执行仅限 Enterprise 和 Server 版本,通过 MDM 分发则所有版本均可。1

把「Pro 版能做什么」拆分为能否创建规则创建的规则是否实际生效(被强制执行)这两个方面来梳理,就是下表这样。正是因为这两者是不同的事情,才导致过时的常识一直流传至今。1

环境 创建・编辑规则 强制执行创建的规则
Windows 11(包括 Pro 在内的所有版本) 可以 可以(自 KB 5024351 起,无版本要求)
Windows 10 版本 2004 及更高版本 + KB 5024351(包括 Pro 在内的所有版本) 可以 可以(无版本要求)
Windows 10 版本 2004 之前 / 至 Windows Server 2019 可以 通过组策略分发的策略仅限 Enterprise 和 Server 版本。通过 MDM 分发则所有版本均可
Windows 8.1 Pro 可以 不可以(可以创建,但不会被强制执行)

「在 Pro 环境下连创建都做不到」是常见的误解,但创建这一步在任何版本下都可以进行。以前有区别的是强制执行这一步,而且如果通过 MDM 分发,当时 Pro 版就已经可以强制执行。可以应用的规则类型(可执行文件・Windows 安装程序・脚本・DLL・打包应用)不会因版本而改变。1 另外,无论哪个版本,只要 Application Identity 服务(AppIDSvc)没有运行,规则就不会被评估(见第 6 章)。

不过 AppLocker 有一个重要的附加说明。微软官方明确指出,AppLocker不满足作为安全功能的服务标准(MSRC 的 servicing criteria)。也就是说,即便发现了绕过方法,它本身也不会被当作安全漏洞来处理。2

2.3. App Control for Business ── 作为安全功能的正选

App Control for Business 是当初在 Windows 10 中以「Device Guard」「可配置代码完整性(WDAC)」名义登场的机制的现行名称。策略应用于整台机器,会影响该设备上的所有用户。可以作为规则依据的有:签名证书的属性、文件属性或哈希值、微软 Intelligent Security Graph(ISG)的评估结果、发起安装的进程(受管理的安装程序,Managed Installer)、文件路径(Windows 10 1903 及更高版本),以及启动来源进程。2

这一机制是按照 MSRC 服务标准所定义的安全功能来设计的。适用条件也很宽松,在 Windows 10/11 的任意客户端版本,或 Windows Server 2016 及更高版本中都可以创建・应用策略。分发方式可以使用 Intune 等 MDM、Configuration Manager 以及 PowerShell。也可以通过组策略分发,但仅限于在 Windows Server 2016/2019 上运行的单一策略格式。2

关于应该使用哪一种,微软的指导方针很明确。只要能用 App Control 实现,就应该使用它,因为 App Control 在持续改进,而 AppLocker 虽然仍会收到安全修复,但不再添加新功能。AppLocker 适合的场景是:混用旧版 Windows 且想分发相同策略的情况、共享电脑中需要按用户・组区分不同规则的情况,以及作为 App Control 的补充、追加用户单位限制的情况。2

2.4. Smart App Control ── 个人电脑上「自动」启用的执行控制

Smart App Control 是 Windows 11 面向个人用户的保护功能。当尝试运行应用时,云端安全服务会确认能否对该应用的安全性做出预测,从而拦截被判定为具有恶意的应用,以及没有有效签名、无法确认信任的应用。新电脑会从评估模式开始,由 Windows 自动判断该功能是否适合该用户,从而决定启用还是禁用(对于像开发者这类容易频繁被拦截的用户,会被自动关闭)。3

对分发方而言,这一点的含义很简单:即使是不受企业管理的电脑,也就是小型企业或个体经营者客户的电脑,如今也已进入默认就带有执行控制的时代。即便没有任何管理员编写过策略,未签名的应用也可能被拦截。微软面向开发者的指导中,也把用有效证书为应用签名列为避免被拦截的方法。3

3. 你的应用被拦截的典型模式

以下按原因罗列受托开发・打包分发现场实际会踩到的模式。

模式 会发生什么 根本原因
exe 签了名但 DLL 未签名 主体启动后立即崩溃/按功能单位失败 在启用了 DLL 规则的环境中,所有二进制文件都是验证对象
自解压压缩包或临时文件夹解压 解压到 %TEMP% 的 exe 无法启动 在路径规则的允许范围(Program Files 等)之外执行
自动更新替换了新版本 更新后无法启动 在采用哈希规则运维的客户环境中,每次更新哈希都会变化
只对安装程序签名,MSI 未签名 安装本身失败 MSI・脚本同样是控制对象(归属于「AppLocker - MSI and Script」日志)
内置的 PowerShell 脚本无法运行 应用能启动,但部分功能失败 在 App Control 环境中,策略之外的脚本会以约束语言模式运行5
插件・扩展 DLL 事后追加 只有新增模块无法运行 事后加入的 DLL 未包含在允许规则中
安装到可写文件夹 依环境不同,时而能运行时而不能 路径规则通常是在「不允许用户可写路径」这一前提下设计的

这些模式的共同结构是:「分发方没有稳定提供允许执行一方所依赖的依据(签名・路径・哈希)」。即使客户的信息系统部门想要编写发行者规则,如果只有部分二进制文件带有签名,就只能改用哈希规则,而哈希规则会在你每次发布更新版本时失效。表面上看拦截的责任在导入方,但实际上让规则容易失效的原因往往出在分发方这一边的情况并不少见。

4. 用日志确定发生了什么

「无法启动」的原因是否出在执行控制上,不需要靠猜测,可以通过事件日志来确定。需要查看的位置分为两套体系。

4.1. AppLocker 的事件

查看事件查看器中的 应用程序和服务日志\Microsoft\Windows\AppLocker 下的内容。4 为第一次打开的读者写明具体的查找方式。

事件查看器(在开始菜单搜索「事件查看器」,或通过「运行」执行 eventvwr.msc)> 应用程序和服务日志 > Microsoft > Windows > AppLocker > EXE and DLL / MSI and Script / Packaged app-Deployment / Packaged app-Execution

在英文环境下则是 Applications and Services Logs > Microsoft > Windows > AppLocker。如果不想在 GUI 中一层层点选,可以以管理员身份打开 PowerShell,用下面这一行读取(委托客户操作时,把这一行直接给对方也是最快的方法)。

# 提取最近24小时内AppLocker的拦截(8004)与审核(8003)记录
Get-WinEvent -FilterHashtable @{
    LogName   = 'Microsoft-Windows-AppLocker/EXE and DLL'
    Id        = 8003, 8004
    StartTime = (Get-Date).AddDays(-1)
} | Format-List TimeCreated, Id, Message
日志 事件 含义
EXE and DLL 8002 被允许并执行
EXE and DLL 8003 审核模式:如果强制执行则会被拦截
EXE and DLL 8004 已被拦截(强制模式)
MSI and Script 8005 / 8006 / 8007 脚本・MSI 的允许/审核/拦截
Packaged app 8020〜8025 打包应用(MSIX/AppX)的允许/审核/拦截
8008 不支持 AppLocker 的 SKU

事件中会记录目标文件的路径、是允许还是拦截、所应用规则的种类(路径・哈希・发行者)与规则名称,以及规则所属用户/组的 SID。4 不过在解读时需要注意。在白名单型运维中,多数拦截并不是「命中了某条拒绝规则」,而是没有命中任何允许规则的隐式拒绝。这种情况下,8004 能确定的只有「被拦截的事实与目标文件」,规则名称并不能提供线索。当命中明确的拒绝规则时,规则名称本身就是原因;而在隐式拒绝的情况下,就需要与当前应用的策略进行对照,去查找「缺少了哪条允许规则」。

4.2. App Control for Business(WDAC)的事件

App Control 的拦截会出现在另一个位置,即 应用程序和服务日志\Microsoft\Windows\CodeIntegrity\Operational。exe・DLL・驱动程序的控制记录在这里,MSI・脚本・COM 的控制则记录在前面提到的「AppLocker - MSI and Script」日志中,两者是这样分工的。5

事件查看器 > 应用程序和服务日志 > Microsoft > Windows > CodeIntegrity > Operational(英文环境下为 Applications and Services Logs > Microsoft > Windows > CodeIntegrity > Operational)

# 汇总查看App Control的拦截(3077)・审核(3076)以及对应的签名信息(3089)
Get-WinEvent -FilterHashtable @{
    LogName   = 'Microsoft-Windows-CodeIntegrity/Operational'
    Id        = 3076, 3077, 3089
    StartTime = (Get-Date).AddDays(-1)
} | Sort-Object TimeCreated | Format-List TimeCreated, Id, Message

在「不清楚是被哪种机制拦截的」这种状态下,把这两个日志按相同时间范围排列对照,是最可靠的做法。

日志 事件 含义
CodeIntegrity - Operational 3076 审核模式的主要拦截事件:如果强制执行则会被拦截
CodeIntegrity - Operational 3077 强制模式的主要拦截事件:未通过策略而被拦截
CodeIntegrity - Operational 3089 被拦截(或审核拦截)文件的签名信息。通过相关 ID 与 3076/3077 对照
CodeIntegrity - Operational 3033 因签名失效・过期等原因导致的拦截(有时会与 3077 同时出现)
AppLocker - MSI and Script 8028 / 8029 脚本・MSI 的审核/拦截
AppLocker - MSI and Script 8036 COM 对象的拦截
AppLocker - MSI and Script 8039 / 8040 打包应用的审核/拦截

3089 容易被忽视,但十分重要。它会为文件的每个签名生成一条记录,未签名文件则会生成一条签名数为 0 的记录。「明明已经签名却被当作未签名处理」「残留着旧证书的签名」这类分发方的问题,都可以在这里确定5

脚本的行为有其特有的注意事项。事件 8029 表示「脚本被拦截」,但实际的强制执行由脚本宿主一侧的行为决定,例如 PowerShell 并不会完全停止不符合策略的脚本,而是以约束语言模式(Constrained Language Mode)执行它。5 由于 .NET 对象的创建会受到广泛限制,因此会出现「脚本本身能运行,但中途某一行会失败」这种不上不下的故障方式。如果应用中内置了脚本,不了解这种故障方式会让排查耗时更久(脚本签名的实务参见「PowerShell 的执行策略与脚本签名」)。

另外,「AppLocker - MSI and Script」日志在 Windows Server Core 版本中并不存在5 在排查部署于服务器上的应用时,请记住这一点。

5. 分发方的对策 ── 把应用做成「便于编写规则」的样子

与其等被拦截之后再应对,正确的做法是在分发时就让客户的信息系统部门能够编写稳定的允许规则。要做的事情并不多。

  1. 对所有二进制文件进行 Authenticode 签名。不仅是 exe,还包括自行构建的 DLL、安装程序(MSI/安装用 exe)以及内置脚本。发行者规则以签名元数据(发行者・产品名・文件名・版本)为依据,因此只要签了名,就能让对方编写出「无论版本如何,都允许该发行者的该产品」这种经得起更新考验的规则2 证书请选择由受信任的证书颁发机构签发、基于 RSA 的证书。自签名证书或企业内部 CA 的证书,在不信任该 CA 的客户电脑上无法生效,Smart App Control 也不支持。而且 Smart App Control 的签名检查不支持 ECC(椭圆曲线)签名,因此如果用 ECC 证书签名,在个人电脑上可能会被当作等同于未签名处理。6 App Control 也存在同样的限制,基于签名者的规则仅支持 RSA(最大 4096 位),无法通过发行者规则允许 ECDSA 签名的文件(对应的 3089 签名信息事件中会出现 VerificationError = 23)。7 如果因为「ECC 更新更强」而选择它,从执行控制的角度来看反而会适得其反。
  2. 务必附加时间戳。这样即使证书过期,签名的有效性也能得到保留。签名的具体操作步骤以及与 SmartScreen 的关系,已整理在另一篇文章中。
  3. 保持发行者信息与文件版本资源的稳定。更新证书时,如果主体(组织名)发生变化,发行者规则就会失效。如果要更改公司名称的写法或证书的获取渠道,请在发布说明中提前告知客户。另一个容易被忽略的地方是,发行者规则中的「产品名」「原始文件名」「版本」是从各文件的版本资源(程序集信息)中获取的,而不是从证书中获取。如果把这些字段留空,或者每次发布时都更改产品名或可执行文件名,即便签名者相同,按产品・文件单位收窄的规则也会失效。
  4. 让可执行文件的存放位置贴近标准。安装到 Program Files 下,废止那种在运行时把 exe/DLL 解压到 %TEMP%%APPDATA% 再启动的设计。因为在可写位置执行的设计,与路径规则型环境从根本上就水土不服。
  5. 重新审视自动更新的设计。对更新程序本身也进行签名,让更新成为「用已签名的二进制文件替换已签名的二进制文件」这样一个闭合的流程。如果通过 Intune 或 Configuration Manager 分发,只要客户端把该分发代理配置为受管理的安装程序(Managed Installer),就可以实现允许经由该安装程序进入的二进制文件这一运维方式。这并非自动生效,而是以管理员一侧的明确配置为前提,但只要准备好支持静默安装的 MSI,就可以把这一选项交给客户(自动更新的安全设计参见「自动更新的安全性」)。
  6. 提前准备好被拦截时的信息提供方案。在「导入操作手册」中明确写出签名主体、执行所需的二进制文件清单、安装目标路径,客户的信息系统部门光靠这些信息就能编写规则。出现问题时,只要指定第 4 章中的事件 ID 请对方确认,一次往返沟通就够了。

以上 6 点,作为应对 Smart App Control 的准备也同样有效。经过签名并积累了良好评价的二进制文件,也更不容易被个人电脑上的自动拦截误伤。3

5.1. 初次获取代码签名证书时

如果只停留在「那就签名吧」这句话上就无法前进,因此这里写明在还没有证书的情况下,下一步该怎么做。

证书的选择方式。可以使用的是由公共证书颁发机构(商业 CA)签发的代码签名证书。自签名证书或企业内部 CA 的证书,在不信任该 CA 的客户电脑上无法验证,因此不能用于分发物。公共 CA 的证书分为进行企业实在性认证的OV,以及审核更严格的EV,但从 AppLocker 或 App Control 发行者规则的角度看,两者都能以同样的方式编写规则。App Control 虽然提供了「强制要求 EV 签名」的规则选项(Required:EV Signers),但文档中明确写明目前尚不受支持,因此就执行控制而言,目前没有理由专门选择 EV。7

费用的考虑方式。金额会因 CA 和有效期而不同,因此前提是需要各自获取报价,但只要了解一下费用构成的结构,就更容易进行比较。自 2023 年 6 月 1 日起,根据 CA/Browser Forum 的标准,无论 OV 还是 EV,都必须在相当于 FIPS 140-2 二级或更高等级的硬件(HSM 或 USB 令牌)中生成并保存私钥8 也就是说,费用不仅包括「证书本体」,还包括「令牌或 HSM,或者 CA 提供的云签名服务的使用费」。如果想在 CI/CD 中实现自动签名,比起物理令牌,云签名服务更容易配置,因此在获取报价时,请连同签名的运维方式一并咨询。

最简的签名命令。使用 Windows SDK 中自带的 signtool

:: 进行签名(用SHA-256计算哈希,并附加RFC 3161时间戳)
signtool sign /fd sha256 /tr <时间戳服务器的URL> /td sha256 /a MyApp.exe

:: 确认签名(按Authenticode策略验证,并显示详细信息)
signtool verify /pa /v MyApp.exe

/fd 是文件的哈希算法,/tr 是 RFC 3161 时间戳服务器的 URL,/td 是时间戳的哈希算法,/a 表示从证书存储区自动选择合适的证书。时间戳服务器的 URL 请使用购买证书的 CA 所提供的地址。如果用令牌或 HSM 中的密钥签名,CSP/KSP 的指定方式会记载在 CA 的操作手册中。DLL 和安装程序也可以用同一条命令签名,因此在构建的最后统一执行一次是最可靠的做法。

更新证书时会破坏什么。发行者规则依据的是签名的发行者信息(证书链与主体)。因此,以下这些变更会在不知不觉中让客户端的规则不再匹配。

  • 更改了公司名称的写法(例如把证书主体从 Komura Soft LLC 改为 合同会社小村软件)。即使是同一家公司,字符串不同也意味着是不同的发行者。
  • 更换了 CA。App Control 的 Publisher 级别规则是「中间 CA(PCA)证书 + 叶证书的 CN」的组合,因此一旦 CA 变了,PCA 也会随之变化,从而无法匹配。7
  • 更改了可执行文件名或产品名。FilePublisher 级别的规则除了上述内容之外,还包含原始文件名(OriginalFileName)和最低版本号。7

无论哪种情况,症状都是一样的——表现为从替换成更新版本的那一刻起,只在那个环境中应用无法启动。而且从客户的角度看,这只是「更新之后就坏了」,很难意识到原因出在签名上。更新或更改证书时,请在发布说明中并列写出新旧签名信息(主体、颁发 CA),以便客户的信息系统部门能够追加规则。

6. 导入方(信息系统部门)的要点

关于在自家电脑上导入执行控制的一方所需的步骤,本文只在范围内梳理要点。

  1. 选择技术。原则上首选 App Control for Business。在需要按用户单位控制的共享电脑,或混用旧版操作系统的环境中,并用 AppLocker。2 对于像 Kiosk 终端这类固定用途的电脑,先用外壳限制(「Windows 的 Kiosk 模式与已分配的访问权限」)收窄范围之后再考虑,规则会更简单。
  2. 务必从审核模式开始。如果是 AppLocker 的「仅审核」,事件 8003・8006 会记录「如果强制执行本应被拦截的内容」;如果是 App Control 的审核模式,则是事件 3076・8028。45 先收集到业务运转一整轮之后再切换为强制执行,这一流程与 SMB 签名或 NTLM 限制完全相同。另外,如果使用 AppLocker,有一个前提条件:AppLocker 的策略如果 Application Identity 服务(AppIDSvc)没有运行就不会被评估,即便设为审核模式也不会产生事件。在开始审核之前,请在目标终端上将该服务配置为自动启动。
  3. 把例外做成台账。对于那些仍以未签名状态继续使用的老旧业务应用,只能以哈希规则的方式登记为例外。这份清单本身就是「早晚应该更换」的列表,请与资产管理关联起来,每年进行一次审视。

关于第 2 步「从审核模式开始」,为了不必再跳转到其他文章查阅,这里把最基本的流程放在此处。

AppLocker 的情况(3 个步骤)

  1. 启用审核模式。在组策略管理编辑器(本地则用 secpol.msc)中打开 计算机配置 > 策略 > Windows 设置 > 安全设置 > 应用程序控制策略 > AppLocker,右键点击 AppLocker,选择属性。对每个规则集合(可执行文件、Windows 安装程序、脚本、打包应用)勾选「配置」,并选择「仅审核」。同时为各个集合创建默认规则,并在目标终端上将 Application Identity 服务(AppIDSvc)配置为自动启动(如果该服务未运行,策略就不会被评估,也不会产生事件)。
  2. 收集事件。收集 Microsoft-Windows-AppLocker/EXE and DLL 的事件8003(exe/DLL)和 MSI and Script8006(脚本・MSI),直到业务运转一整轮为止。4 这里需要注意。第 4 章的 PowerShell 命令把日志名固定为「EXE and DLL」,因此原样使用无法收集到脚本和 MSI 的 8006。既然日志是分开的,就需要像下面这样分两路来运行。

     # 在审核模式下,从两个日志中收集"如果强制执行本应被拦截的内容"
     $since = (Get-Date).AddDays(-7)
     $collections = @(
         @{ LogName = 'Microsoft-Windows-AppLocker/EXE and DLL';    Id = 8003 }
         @{ LogName = 'Microsoft-Windows-AppLocker/MSI and Script'; Id = 8006 }
     )
     foreach ($c in $collections) {
         Get-WinEvent -FilterHashtable ($c + @{ StartTime = $since }) -ErrorAction SilentlyContinue |
             Select-Object TimeCreated, LogName, Id, Message
     }
    

    由于在一条对应事件都没有的日志上执行 Get-WinEvent 会返回错误,所以加上了 -ErrorAction SilentlyContinue。如果打包应用也是控制对象,请按同样的形式追加 Packaged app-Deployment / Packaged app-Execution。请确认是否连月度・年度批处理也一并采集到了。

  3. 切换为强制执行。先把 8003 和 8006 中出现的内容纳入允许规则,然后在同一个属性画面中改为「强制执行规则」。切换之后,监控8004(exe/DLL 的拦截)和8007(脚本・MSI 的拦截)。

App Control for Business 的情况流程也是一样的,先在策略 XML 中加入规则选项 3(Enabled:Audit Mode)并进行分发(可通过 App Control Policy Wizard,或 Set-RuleOption cmdlet 进行设置),收集30768028之后,再删除该选项切换为强制执行。微软也建议先用 Enabled:Audit Mode 确认影响。7

7. 总结

  • 执行控制要区分「警告」的 SmartScreen 与「拦截」的 AppLocker / App Control for Business / Smart App Control(不过 SmartScreen 在禁止绕过警告的管理策略下,也会实质性地起到拦截的作用)。
  • AppLocker 的版本限制已经放宽(Windows 10 2004 及更高版本・Windows 11 全部版本),App Control 本来就可以在所有客户端版本中使用。「我们的客户用的是 Pro,跟这个没关系」这种说法已经不再成立。12
  • 由于 Smart App Control 的出现,即使是无人管理的个人电脑,如今也带有执行控制。未签名的分发物,仅凭这一点就可能无法运行。3
  • 拦截的确定要靠事件日志。AppLocker 是 8004(EXE and DLL 日志),App Control 则是 3077 与签名信息的 3089(CodeIntegrity - Operational 日志),是最核心的证据。45
  • 分发方的对策包括:对所有二进制文件进行一致的签名、附加时间戳、使用标准的安装位置、已签名的自动更新,以及在导入操作手册中提供信息。把应用做成客户容易编写规则的样子,就是拦截对策的全部内容。
  • 导入方应先用审核模式(8003 / 3076)收集一整轮数据,再切换为强制执行。这一流程与其他安全加固措施相同。

相关文章

相关咨询领域

合同会社小村软件承接在执行控制环境(AppLocker / App Control for Business)下运行的业务应用开发・改进、内置代码签名的分发与自动更新设计,以及客户环境中应用无法启动问题的调查。

参考链接

  1. Microsoft Learn, Requirements to use AppLocker。关于自 KB 5024351 起,在 Windows 10 版本 2004 及更高版本以及所有 Windows 11 中,强制执行 AppLocker 策略不再需要特定版本;在早于版本 2004 的 Windows(包括 Windows Server 2019)中,通过组策略分发的策略仅支持 Enterprise 与 Server 版本,通过 MDM 分发的策略则支持所有版本;在 Windows 10/11 与 Windows Server 2012 R2 及更高版本中可以配置・强制执行打包应用・可执行文件・Windows 安装程序・脚本・DLL 规则等内容。  2 3 4 5

  2. Microsoft Learn, App Control and AppLocker Overview。关于 App Control for Business 在 Windows 10 中引入,并按照 MSRC(Microsoft Security Response Center)服务标准所定义的安全功能进行设计;它最初作为 Device Guard 的一部分,以「可配置代码完整性」的名义发布;App Control 策略应用于整台机器,会影响设备上的所有用户;规则的依据包括签名证书的属性・源自签名元数据的文件属性或哈希・Intelligent Security Graph 的评估结果・受管理的安装程序・文件路径(Windows 10 1903 及更高版本)・启动来源进程;App Control 策略可以在 Windows 10/11 的任意客户端版本或 Windows Server 2016 及更高版本中创建・应用,可以通过 MDM(Intune 等)・Configuration Manager・PowerShell 分发,组策略分发仅限于在 Windows Server 2016/2019 上运行的单一策略格式;AppLocker 在 Windows 7 中引入,不满足作为安全功能的服务标准;AppLocker 策略可以应用于整台计算机或个别用户・组,规则的依据是签名证书的属性・文件属性・路径;如果可行应优先使用 App Control 而非 AppLocker,App Control 在持续改进,而 AppLocker 仅接收安全修复、不再新增功能;AppLocker 适合的场景是操作系统混用环境与共享电脑中按用户・组区分策略,也可以作为 App Control 的补充使用等内容。  2 3 4 5 6 7 8 9

  3. Microsoft Support, What is Smart App Control?。关于 Smart App Control 在 Windows 11 中,于应用执行时确认基于云的安全服务能否对该应用的安全性做出确信的预测,从而拦截被判定为具有恶意的应用,以及没有有效签名、无法确认信任的应用;新环境会从评估模式开始,对于容易频繁遇到拦截的用户(如开发者),Windows 会自动关闭 Smart App Control;判定同时使用云端评估与应用是否具有有效签名两方面;面向开发者的指导中提到用有效证书为应用签名;以及该功能会与其他安全软件并行运行等内容。  2 3 4 5

  4. Microsoft Learn, Using Event Viewer with AppLocker。关于 AppLocker 的事件日志中会记录目标文件的路径・是允许还是拦截・规则种类(路径・哈希・发行者)・规则名称・规则所属用户/组的 SID;事件 8002 表示 exe/DLL 被允许,8003 表示审核模式下”如果强制执行则会被拦截”,8004 表示强制模式下 exe/DLL 被拦截,8005〜8007 表示脚本・MSI 的允许/审核/拦截,8020〜8025 与打包应用相关,8008 表示不支持 AppLocker 的 SKU;以及”AppLocker - EXE and DLL”日志可能产生大量事件,需要注意采集配置等内容。  2 3 4 5 6 7

  5. Microsoft Learn, Understanding App Control event IDs。关于 App Control 的事件记录在”CodeIntegrity - Operational”(exe・DLL・驱动程序的控制与策略应用)和”AppLocker - MSI and Script”(MSI・脚本・COM 对象的控制)这两处;事件 3076 是审核模式的主要拦截事件,表示如果强制执行本应被拦截,3077 是强制模式的主要拦截事件;3089 是针对被拦截或审核拦截文件的每个签名生成的签名信息事件,未签名文件会生成一条签名数为 0 的记录,可通过相关 Activity ID 与 3076/3077 等对照;3033 表示因签名失效・过期等原因导致的拦截;8028/8029 表示脚本・MSI 的审核/拦截,实际的强制执行由脚本宿主控制,例如 PowerShell 会以约束语言模式(Constrained Language Mode)执行不被 App Control 策略允许的脚本;8036 表示 COM 对象的拦截,8039/8040 表示打包应用的审核/拦截;以及”AppLocker - MSI and Script”的事件不包含在 Windows Server Core 版本中等内容。  2 3 4 5 6 7 8 9 10

  6. Microsoft Learn, Code signing for Smart App Control。关于 Smart App Control 允许以基于 RSA 的数字证书签名的应用程序执行,以及 Smart App Control 的签名检查不支持椭圆曲线密码(ECC)签名等内容。 

  7. Microsoft Learn, Understand App Control for Business policy rules and file rules。关于 App Control 的策略规则选项 3 为”Enabled:Audit Mode”,会记录策略如果强制执行本应被拦截的应用程序・二进制文件・脚本;要切换到强制模式需要删除该选项;微软建议先在审核模式下验证新策略;规则选项的更改可使用 App Control Policy Wizard 或 Set-RuleOption cmdlet;规则选项 8”Required:EV Signers”目前尚不受支持;基于签名者的规则仅支持 RSA(最大 4096 位),不支持 ECDSA 等 ECC 算法,如果尝试用 ECC 签名允许,对应的 3089 签名信息事件中会出现 VerificationError = 23;文件规则级别的 Publisher 是”PCA 证书(通常位于根证书下一级)+ 叶证书的 CN”的组合,FilePublisher 则是在此基础上加上已签名文件的 FileName 属性(默认为资源头中的 OriginalFileName)与最低版本号等内容。  2 3 4 5

  8. CA/Browser Forum, Code Signing Baseline Requirements。关于代码签名证书的私钥,自 2023 年 6 月 1 日起签发的证书,无论 EV 还是非 EV,都要求在满足 FIPS 140-2 二级或 Common Criteria EAL4+ 及以上标准的硬件加密模块(HSM 或令牌)中生成・保存密钥对,并使私钥处于无法导出的状态等内容。 

共享相同标签的最新文章。可以围绕相近的主题进一步加深理解。

与本文相近的主题页面。以本文为起点,可以进一步了解相关服务和其他文章。

本文与以下服务页面相关联,欢迎从最接近的入口查看。

常见问题

汇总了咨询这一主题时常见的问题。

AppLocker 在 Pro 版本中不能用吧?
这一常识已经过时了。自 KB 5024351 起,在 Windows 10 版本 2004 及更高版本,以及所有 Windows 11 中,强制执行 AppLocker 策略已不再需要特定版本。过去「仅 Enterprise 与 Server 版本支持通过组策略分发进行强制执行」这一限制,仅适用于早于版本 2004 的 Windows 10 以及 Windows Server 2019 及更早版本(在这种情况下,如果通过 MDM 分发,则所有版本均可使用)。即使在以中小企业 Pro 版终端为主的环境中,现在 AppLocker 也已成为可选项。
代码签名证书应该买 EV 的吗?
从 AppLocker 或 App Control for Business 的发行者规则(publisher rule)角度来看,无论是 OV(企业实在认证)证书还是 EV 证书,都可以创建基于签名者信息的规则。另外,「使用 EV 证书从一开始就不会出现 SmartScreen 警告」这一理解已经过时,目前即使是 EV 签名的文件,也需要像 OV 一样以信誉积累为前提来考虑(这一论点已在另一篇文章「Windows SmartScreen 与代码签名」中整理)。比证书种类更重要的是,不仅是 exe,还要包括 DLL 与安装程序在内的所有二进制文件,以一致的主体(subject)进行签名,附加时间戳,并在证书更新时保持发行者信息的稳定。发行者规则正是依赖这些签名者信息编写的,如果每次发布时签名状态都发生变化,客户端的规则就会失效。
客户环境中我方应用似乎被拦截了,但日志里什么都找不到,应该看哪里?
原因大多是要查看的日志分成了两套体系。AppLocker 对 exe/DLL 的拦截,会出现在「AppLocker - EXE and DLL」日志的事件 8004(审核模式下为 8003)中,脚本与 MSI 则出现在「AppLocker - MSI and Script」日志的 8007(同为 8006)中。另一方面,App Control for Business(WDAC)的拦截会出现在「CodeIntegrity - Operational」日志的事件 3077(审核模式下为 3076)中,对应的签名信息则记录在 3089 中。此外,如果脚本・MSI・COM 被 App Control 拦截,会出现在「AppLocker - MSI and Script」日志的 8029・8036・8040 中。在不清楚是哪种机制在起作用的情况下进行排查时,请把 CodeIntegrity - Operational 与 AppLocker 下的日志按时间对照着查看。
要让我方应用不被 Smart App Control 拦截,需要做什么?
实质上就是代码签名。Smart App Control 在应用执行时,会通过云端安全服务确认能否对该应用的安全性做出预测,以及应用是否具有有效签名,从而拦截被判定为具有恶意的应用,以及未签名、无法确认信任的应用。微软在面向开发者的说明中,也提到了用有效证书为应用签名。不过需要注意签名算法,Smart App Control 的签名检查不支持椭圆曲线密码(ECC)签名,只有用基于 RSA 的证书签名的应用才能被允许执行。Smart App Control 并非企业管理功能,而是面向 Windows 11 个人用户的保护机制,其启用与禁用由评估模式自动决定,因此从分发方的角度看,安全的做法是按「未签名的可执行文件在个人 PC 上可能无法运行」这一前提来处理。

作者简介

本文作者的个人简介页面。

Go Komura

小村软件有限公司 代表

以 Windows 软件开发、技术咨询与故障排查为中心,擅长难以复现的故障调查,以及既有资产仍在运行的项目。

返回博客列表