elastic / elastic/detection-rules

[New hunt] Novel TLS Destination Domain from a Build Host

Open
#6,604 0 comments 0 reactions 0 assignees View on GitHub
community
Dominant language
Python
Stars
2.7k
Forks
696
Avg merge
4d 17h
Merged PRs (30d)
87

Description

## Description

Identifies TLS connections to a destination domain that is rare fleet-wide, a signal for build/CI hosts whose expected egress is normally limited to a small set of known package registries and infrastructure endpoints. A supply-chain compromise (e.g. a malicious npm postinstall script) commonly needs to phone home to a C2/exfil destination distinct from the legitimate registry traffic surrounding it.

**Scoped down deliberately, and disclosed as such**: this validates the *destination-novelty* component of a broader "CI-runner beaconing" idea; it does **not** independently test true beacon periodicity/jitter (that needs either the ML Beaconing package or a much longer observation window than a single lab session can produce). Proposed as a hunt, not an alerting rule, for exactly that reason: treat a match as "worth checking for a beacon pattern," not confirmation of one.

**Behavior-based** (destination rarity), anomaly-driven.

**Real testing performed, with a real mid-build correction**: first attempted this using raw destination IPs. Found empirically that a single real `npm install` touches many different, rapidly-rotating registry CDN IPs (12 distinct IPs for one install of a single package), which would make an IP-keyed novelty hunt hopelessly noisy on entirely legitimate traffic. Switched to `tls.client.server_name` (the TLS SNI hostname) instead, confirmed empirically domain-stable (`registry.npmjs.org` stayed a single constant string across the same install that produced a dozen different IPs). Real test data: a real `npm install axios` (legitimate, `registry.npmjs.org` SNI) alongside a real `curl` to `icanhazip.com` (the stand-in "beacon-like" novel destination), both genuinely captured via a real Packetbeat TLS-module instance. Combined with a constructed-but-realistic 10-host common-pattern baseline for `registry.npmjs.org`/`telemetry.elastic.co` to actually exercise the `hosts <= 2` rarity threshold, which a single-host lab can't otherwise demonstrate honestly. Result: matched exactly the real, rare `icanhazip.com`; both the allowlisted registry domain and the constructed common-pattern domain were correctly excluded.

## Target Huntset
network

## Target hunt Type
ES|QL

## Query

```esql
FROM logs-network_traffic.tls-*
| WHERE @timestamp > NOW() - 7 day AND tls.client.server_name IS NOT NULL
AND NOT tls.client.server_name IN ("registry.npmjs.org", "registry.yarnpkg.com", "nodejs.org", "pypi.org", "files.pythonhosted.org")
| STATS cc = COUNT(), hosts = COUNT_DISTINCT(agent.id) BY tls.client.server_name
| WHERE hosts <= 2
| SORT cc ASC
| LIMIT 100
```

## Related issues or PRs
None yet. Part of a small ongoing batch from a personal detection-gap research project (real-telemetry validated throughout).

## References
- https://attack.mitre.org/techniques/T1071/001/
- https://attack.mitre.org/techniques/T1102/

## Redacted Example Data

Real true positive (a genuinely rare destination from a build-host-like process):
```json
{
"tls": { "client": { "server_name": "icanhazip.com" } },
"agent": { "id": "build-host-01" }
}
```

Real negative control (legitimate npm registry traffic, domain-stable despite resolving to many different, rotating CDN IPs, which is exactly why this hunt keys on SNI rather than destination IP):
```json
{
"tls": { "client": { "server_name": "registry.npmjs.org" } },
"agent": { "id": "build-host-01" }
}
```

Known false-positive class (documented in the hunt's own notes): a developer workstation has much higher legitimate destination diversity than a CI runner. Scope this hunt to known CI/build hosts (via agent policy or host tag) before running fleet-wide.

Contributor guide

Open the contributing guide

Research direction

Start with the supplied ES|QL query and the network target huntset, checking how the destination-novelty logic and exclusions are represented in this repository. Validate the query against the described legitimate and rare-destination examples; done means the hunt is added with its stated scope, threshold, and false-positive limitation preserved.

Written by the indexing model from the issue text.

Assessment

Domain
security
Issue type
Feature
Difficulty
3/5
Estimated time
1-2 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
66/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.