Azure WireServer HTTP Request from Unexpected User Agent

Identifies HTTP requests to Azure WireServer (168.63.129.16) for GoalState, certificates, versions, or HostGAPlugin vmSettings that do not use a known guest-agent user agent. These requests retrieve transport certificates and extension protectedSettings, including embedded SAS URLs. Azure Linux Agent, Windows guest agent, and related platform UAs are excluded. Requests with no user agent are also excluded; that pattern is common for the Windows guest agent.

Elastic rule (View on GitHub)

  1[metadata]
  2creation_date = "2026/08/17"
  3integration = ["network_traffic"]
  4maturity = "production"
  5updated_date = "2026/08/17"
  6
  7[rule]
  8author = ["Elastic"]
  9description = """
 10Identifies HTTP requests to Azure WireServer (168.63.129.16) for GoalState, certificates, versions, or HostGAPlugin
 11vmSettings that do not use a known guest-agent user agent. These requests retrieve transport certificates and extension
 12protectedSettings, including embedded SAS URLs. Azure Linux Agent, Windows guest agent, and related platform UAs are
 13excluded. Requests with no user agent are also excluded; that pattern is common for the Windows guest agent.
 14"""
 15false_positives = [
 16    """
 17    Custom health checks that call HostGAPlugin /versions or /vmSettings with curl. Exclude the specific user agent or
 18    host group after validating the script.
 19    """,
 20]
 21from = "now-9m"
 22index = ["logs-network_traffic.http*"]
 23language = "eql"
 24license = "Elastic License v2"
 25name = "Azure WireServer HTTP Request from Unexpected User Agent"
 26note = """## Triage and analysis
 27
 28### Investigating Azure WireServer HTTP Request from Unexpected User Agent
 29
 30Network Packet Capture with HTTP decoding on ports 80 and 32526 shows the URI that Elastic Defend network events
 31lack. The match is the WireServer path or query, not a scripting-tool user-agent allowlist.
 32
 33- `url.query` contains `comp=versions` (discovery)
 34- `url.query` contains `comp=goalstate` (incarnation, container, extension list, statusUploadBlob pointer)
 35- `url.query` contains `comp=certificates` (often with request header `x-ms-guest-agent-public-x509-cert`)
 36- `destination.port == 32526` and `url.path` in `/versions`, `/vmSettings`
 37
 38Excluded user agents from lab guest-agent traffic: `WALinuxAgent/*`, `VMAgent/*`, `Python-urllib/*`,
 39`cpprestsdk/*`, `ACMS/*`, and a missing user agent (Windows guest agent). Curl and Windows PowerShell are not
 40excluded and will fire.
 41
 42`/vmSettings` response bodies are often dropped when they exceed keyword `ignore_above`. The URI, port, and user
 43agent are sufficient. Do not enable body capture to chase this rule.
 44
 45### Possible investigation steps
 46
 47- Confirm `url.path`, `url.query`, `destination.port`, and `user_agent.original`.
 48- GoalState (`comp=goalstate`) is reconnaissance; `comp=certificates` means the client presented a transport
 49  certificate. Look on the host for `openssl req ... LinuxTransport` or a stolen `.crt`/`.key`.
 50- Correlate with endpoint network events from the same `host.name` to `168.63.129.16` and process start events for
 51  openssl cms decrypt.
 52- Search StorageRead platform logs for anonymous or SAS GetBlob against the same storage account after the scrape.
 53
 54### False positive analysis
 55
 56- Administrative curl or other non-agent clients against WireServer during incident response. Exclude the specific
 57  user agent or host after the change window.
 58- A new Microsoft guest-agent build with an unfamiliar user agent will fire until that UA is excluded.
 59- Omitting the user agent looks like the Windows guest agent and is not matched. Do not treat a missing UA as
 60  suspicious on its own.
 61
 62### Response and remediation
 63
 64- Isolate the VM, rotate secrets recovered from vmSettings, and review extension protectedSettings.
 65- Enable Metadata Security Protocol in audit or enforce mode to restrict WireServer callers.
 66"""
 67references = [
 68    "https://cybercx.com.au/blog/azure-ssrf-metadata/",
 69    "https://www.netspi.com/blog/technical-blog/cloud-pentesting/decrypting-vm-extension-settings-with-azure-wireserver/",
 70    "https://cloud.google.com/blog/topics/threat-intelligence/escalating-privileges-azure-kubernetes-services",
 71    "https://learn.microsoft.com/en-us/azure/virtual-network/what-is-ip-address-168-63-129-16",
 72]
 73risk_score = 47
 74rule_id = "359b5925-a625-4803-90d2-19e44a37d98e"
 75setup = """## Setup
 76
 77Deploy the [Network Packet Capture](https://www.elastic.co/docs/reference/integrations/network_traffic) integration
 78via Fleet on Azure virtual machines. Default HTTP port lists do not include HostGAPlugin.
 79
 80Required integration settings:
 81
 82- Enable **Capture HTTP Traffic**.
 83- Set HTTP ports to include **80** (WireServer GoalState, versions, certificates) and **32526** (HostGAPlugin
 84  `/versions`, `/vmSettings`). Without 32526, HostGAPlugin requests are invisible.
 85- Enable **Monitor Processes** so HTTP events include `process.*` when available.
 86- Optional: **Send all headers** to retain `x-ms-version` and `x-ms-guest-agent-public-x509-cert` for investigation.
 87  The rule matches URI, port, and user agent, not the certificate PEM.
 88- Do not enable request or response body capture for this rule. `/vmSettings` bodies are large and often dropped;
 89  other WireServer XML is not required for the match.
 90"""
 91severity = "medium"
 92tags = [
 93    "Domain: Cloud",
 94    "Domain: Network",
 95    "OS: Linux",
 96    "OS: Windows",
 97    "Platform: Azure",
 98    "Use Case: Threat Detection",
 99    "Tactic: Credential Access",
100    "Tactic: Discovery",
101    "Data Source: Network Packet Capture",
102    "Resources: Investigation Guide",
103]
104timestamp_override = "event.ingested"
105type = "eql"
106
107query = '''
108network where event.module == "network_traffic" and
109destination.ip == "168.63.129.16" and
110user_agent.original != null and
111not user_agent.original : (
112  "WALinuxAgent*",
113  "VMAgent*",
114  "Python-urllib*",
115  "cpprestsdk*",
116  "ACMS/*"
117) and
118(
119  url.query : ("*comp=versions*", "*comp=goalstate*", "*comp=certificates*") or
120  (destination.port == 32526 and url.path : ("/versions", "/vmSettings"))
121)
122'''
123
124
125[[rule.threat]]
126framework = "MITRE ATT&CK"
127[[rule.threat.technique]]
128id = "T1552"
129name = "Unsecured Credentials"
130reference = "https://attack.mitre.org/techniques/T1552/"
131[[rule.threat.technique.subtechnique]]
132id = "T1552.005"
133name = "Cloud Instance Metadata API"
134reference = "https://attack.mitre.org/techniques/T1552/005/"
135
136
137
138[rule.threat.tactic]
139id = "TA0006"
140name = "Credential Access"
141reference = "https://attack.mitre.org/tactics/TA0006/"
142[[rule.threat]]
143framework = "MITRE ATT&CK"
144[[rule.threat.technique]]
145id = "T1082"
146name = "System Information Discovery"
147reference = "https://attack.mitre.org/techniques/T1082/"
148
149
150[rule.threat.tactic]
151id = "TA0007"
152name = "Discovery"
153reference = "https://attack.mitre.org/tactics/TA0007/"

Triage and analysis

Investigating Azure WireServer HTTP Request from Unexpected User Agent

Network Packet Capture with HTTP decoding on ports 80 and 32526 shows the URI that Elastic Defend network events lack. The match is the WireServer path or query, not a scripting-tool user-agent allowlist.

  • url.query contains comp=versions (discovery)
  • url.query contains comp=goalstate (incarnation, container, extension list, statusUploadBlob pointer)
  • url.query contains comp=certificates (often with request header x-ms-guest-agent-public-x509-cert)
  • destination.port == 32526 and url.path in /versions, /vmSettings

Excluded user agents from lab guest-agent traffic: WALinuxAgent/*, VMAgent/*, Python-urllib/*, cpprestsdk/*, ACMS/*, and a missing user agent (Windows guest agent). Curl and Windows PowerShell are not excluded and will fire.

/vmSettings response bodies are often dropped when they exceed keyword ignore_above. The URI, port, and user agent are sufficient. Do not enable body capture to chase this rule.

Possible investigation steps

  • Confirm url.path, url.query, destination.port, and user_agent.original.
  • GoalState (comp=goalstate) is reconnaissance; comp=certificates means the client presented a transport certificate. Look on the host for openssl req ... LinuxTransport or a stolen .crt/.key.
  • Correlate with endpoint network events from the same host.name to 168.63.129.16 and process start events for openssl cms decrypt.
  • Search StorageRead platform logs for anonymous or SAS GetBlob against the same storage account after the scrape.

False positive analysis

  • Administrative curl or other non-agent clients against WireServer during incident response. Exclude the specific user agent or host after the change window.
  • A new Microsoft guest-agent build with an unfamiliar user agent will fire until that UA is excluded.
  • Omitting the user agent looks like the Windows guest agent and is not matched. Do not treat a missing UA as suspicious on its own.

Response and remediation

  • Isolate the VM, rotate secrets recovered from vmSettings, and review extension protectedSettings.
  • Enable Metadata Security Protocol in audit or enforce mode to restrict WireServer callers.

References

Related rules

to-top