Query Details

Unofficial Win Get Source Added

Query

let OfficialSources = dynamic([
	"winget.azureedge.net",
	"cdn.winget.microsoft.com"
]);
let AppInstallerPolicyKey = "SOFTWARE\\Policies\\Microsoft\\Windows\\AppInstaller";
// CLI source add
let CliSourceAdd =
	DeviceProcessEvents
	| where FileName =~ "winget.exe"
	| where ProcessCommandLine has_all ("source", "add")
	// Filter direkt auf der CommandLine anwenden, um False Positives bei offiziellen Quellen zu verhindern
	| where not(ProcessCommandLine has_any (OfficialSources))
	// Regex angepasst für -n OR --name und -a OR --arg
	| extend SourceName = extract(@"(?i)(?:--name|-n)\s+(\S+)", 1, ProcessCommandLine)
	| extend SourceUrl  = extract(@"(?i)(?:--arg|-a)\s+(\S+)", 1, ProcessCommandLine)
	| extend SignalType = "CLI_SourceAdd"
	| extend RegistryKey = "", RegistryValueName = "", RegistryValueData = "";
// DSC / PowerShell COM
let DscSourceAdd =
	DeviceProcessEvents
	| where FileName in~ ("powershell.exe", "pwsh.exe")
	| where ProcessCommandLine has_any ("Microsoft.WinGet.DSC", "WinGetPackageSource", "Add-WinGetSource")
	| where ProcessCommandLine has_any ("Add-WinGetSource", "Ensure", "Add")
	| where not(ProcessCommandLine has_any (OfficialSources))
	| extend SourceName = extract(@"(?i)Name\s*=\s*['""]?(\S+?)['""]?[\s,\)]", 1, ProcessCommandLine)
	| extend SourceUrl  = extract(@"(?i)Argument\s*=\s*['""]?(\S+?)['""]?[\s,\)]", 1, ProcessCommandLine)
	| extend SignalType = "DSC_SourceAdd"
	| extend RegistryKey = "", RegistryValueName = "", RegistryValueData = "";
// Registry AdditionalSources changes
let RegAdditionalSources =
	DeviceRegistryEvents
	| where RegistryKey has AppInstallerPolicyKey
	| where RegistryKey has "AdditionalSources"
	| where ActionType in ("RegistryKeyCreated", "RegistryValueSet")
	| extend SourceName = extract(@"AdditionalSources\\(\d+)", 1, RegistryKey)
	| extend SourceUrl  = tostring(RegistryValueData)
	// Falls die Registry-Daten eine offizielle Quelle enthalten, ausschliessen
	| where not(SourceUrl has_any (OfficialSources))
	| extend SignalType = "Reg_AdditionalSources"
	| extend ProcessCommandLine = InitiatingProcessCommandLine;
// Policy enable additional sources
let RegEnableAdditional =
	DeviceRegistryEvents
	| where RegistryKey has AppInstallerPolicyKey
	| where RegistryValueName =~ "EnableAdditionalSources"
	| where ActionType == "RegistryValueSet"
	| where tolong(RegistryValueData) == 1
	| extend SourceName = "", SourceUrl = ""
	| extend SignalType = "Reg_PolicyManipulation_EnableAdditionalSources"
	| extend ProcessCommandLine = InitiatingProcessCommandLine;
// Policy disable hash validation
let RegHashOverride =
	DeviceRegistryEvents
	| where RegistryKey has AppInstallerPolicyKey
	| where RegistryValueName =~ "EnableHashOverride"
	| where ActionType == "RegistryValueSet"
	| where tolong(RegistryValueData) == 1
	| extend SourceName = "", SourceUrl = ""
	| extend SignalType = "Reg_PolicyManipulation_EnableHashOverride"
	| extend ProcessCommandLine = InitiatingProcessCommandLine;
union
	CliSourceAdd,
	DscSourceAdd,
	RegAdditionalSources,
	RegEnableAdditional,
	RegHashOverride
| project
	Timestamp,
	DeviceName,
	AccountName,
	SignalType,
	SourceName,
	SourceUrl,
	RegistryKey,
	RegistryValueName,
	RegistryValueData,
	ProcessCommandLine,
	ReportId,
	DeviceId
| sort by Timestamp desc

About this query

Unofficial WinGet Source Added

Query Information

MITRE ATT&CK Technique(s)

Technique IDTitleLink
T1105Ingress Tool Transferhttps://attack.mitre.org/techniques/T1105/
T1059Command and Scripting Interpreterhttps://attack.mitre.org/techniques/T1059/

Description

This rule detects when a new WinGet package source is added from an unofficial URL, either via the winget.exe command-line interface or through PowerShell using WinGet DSC (Desired State Configuration) cmdlets. Adversaries may add custom package sources to distribute malicious software or maintain persistence

Author <Optional>

Defender XDR

Explanation

This KQL (Kusto Query Language) query is designed to detect when an unofficial WinGet package source is added to a system. WinGet is a package manager for Windows, and adding unofficial sources can be a security risk as it might allow the installation of malicious software.

Here's a simplified breakdown of what the query does:

  1. Official Sources List: It defines a list of official WinGet sources to differentiate between legitimate and potentially malicious sources.

  2. CLI Source Addition Detection: It checks for the use of winget.exe to add a new source via the command line. It filters out any additions that match the official sources to avoid false positives.

  3. PowerShell DSC Source Addition Detection: It looks for the use of PowerShell commands related to WinGet DSC (Desired State Configuration) to add new sources, again excluding official sources.

  4. Registry Changes Detection: It monitors changes in the Windows Registry related to WinGet sources, specifically looking for new sources added under the "AdditionalSources" key. It excludes any changes that involve official sources.

  5. Policy Manipulation Detection:

    • Enable Additional Sources: Detects if the policy to enable additional sources is turned on in the registry.
    • Disable Hash Validation: Detects if the policy to disable hash validation is turned on, which could allow unverified software to be installed.
  6. Data Union and Projection: It combines the results from all these checks and projects relevant information such as the timestamp, device name, account name, type of signal (indicating the method of source addition), source name, source URL, registry details, and command line used.

  7. Sorting: Finally, it sorts the results by timestamp in descending order to show the most recent events first.

Overall, this query helps in identifying potentially unauthorized or malicious modifications to WinGet package sources on a device, which could be indicative of an attack or compromise.

Details

Benjamin Zulliger profile picture

Benjamin Zulliger

Released: June 24, 2026

Tables

DeviceProcessEventsDeviceRegistryEvents

Keywords

DeviceProcessEventsRegistryCommandLineKeyValueNameDataAccountReportIdTimestampSignalTypeSourceUrl

Operators

letdynamic=~has_allnothas_anyextendextractin~unionprojectsort bydesctolong

MITRE Techniques

Actions

GitHub