First Commit
ci / go (push) Waiting to run
ci / go-db (agent) (push) Waiting to run
ci / go-db (config) (push) Waiting to run
ci / go-db (db) (push) Waiting to run
ci / go-db (evidence) (push) Waiting to run
ci / go-db (llmrec) (push) Waiting to run
ci / go-db (server) (push) Waiting to run
web / web (push) Waiting to run
docs / links (push) Canceled after 0s
detections / detections (push) Canceled after 0s

This commit is contained in:
dela
2026-10-09 08:38:16 +08:00
commit 0335d572de
756 changed files with 201663 additions and 0 deletions
+90
View File
@@ -0,0 +1,90 @@
# ARTEX detection rules (Suricata / network)
English · [한국어](README.ko.md)
> 한국어: 이 디렉터리는 [방어·탐지 가이드(docs/defense-ko.md)](../../docs/defense-ko.md) 2·4절의
> 네트워크 관측 지문을 실제로 배포 가능한 [Suricata](https://suricata.io) 규칙으로 옮긴 것입니다.
> 로그·호스트 계층은 [`../sigma/`](../sigma/)(Sigma)가 담당합니다. 모든 규칙은 자신이 소유하거나
> 서면 허가를 받은 시스템을 지키는 **방어·탐지 목적에만** 사용하십시오. 한국어 전체 문서는
> **[README.ko.md](README.ko.md)** 를 보십시오.
The network-layer companion to the [Sigma rules](../sigma/). These [Suricata](https://suricata.io)
signatures cover the two ARTEX artifacts that are observable on the wire, and every indicator is grounded in a
string or behaviour verified in this repository's source, not inferred. The host, log, and SIEM layers live
under [`../sigma/`](../sigma/); the defense guide ([Korean](../../docs/defense-ko.md) ·
[English](../../docs/defense-en.md)) explains the full picture.
## Rules — [`artex.rules`](artex.rules)
- **sid 1000001** — `ARTEX enrichment prober User-Agent`. An inbound HTTP `GET` whose User-Agent starts with
`artex-enrich/` — the asset-enrichment prober (`enrich/enrich.go:233`). The single-request presence
indicator. `classtype: attempted-recon`.
- **sid 1000002** — `ARTEX enrichment prober high-rate enumeration`. The same User-Agent crossing a
`detection_filter` rate of **30 requests in 300 s per source** — the machine-speed velocity a single-hit
rule misses. Mirrors the Sigma correlation `artex_enrich_scan_velocity`. `classtype: attempted-recon`.
- **sid 1000003** — `ARTEX worker WebFetch User-Agent`. An inbound HTTP request whose User-Agent starts with
`norma/` — the norma SDK's WebFetch tool (`github.com/Autumn-27/norma/tool/webfetch.go`). This UA is hardcoded across all norma
versions (v0.1.0–v0.4.3, verified) and reaches the target through the recording proxy, which does not
modify request headers (`traffic/traffic.go`). Unlike the enrich prober, this fires during the **attack
phase** (active vulnerability probing). `classtype: attempted-recon`.
## Scope and honesty — read before deploying
- **Two ARTEX User-Agents are network-observable.** The enrich prober sends `artex-enrich/1.0`
(`enrich/enrich.go:233`) during reconnaissance; the norma SDK's WebFetch tool sends `norma/0.4`
(`github.com/Autumn-27/norma/tool/webfetch.go`) during the attack phase. The recording proxy (`traffic/traffic.go`) does not
modify request headers, so both UAs reach the target on the wire. Other worker tools (Bash subprocesses
like `curl`, `nmap`) use their own User-Agents — detect those with generic scanner signatures and the
behavioural SIEM rules under [`../sigma/`](../sigma/).
- **The User-Agent is only visible in plaintext.** It appears where traffic is plaintext HTTP or inspected at
a TLS-terminating proxy / WAF. End-to-end TLS encrypts it, so deploy these where you actually see the HTTP
request buffer.
- **A static User-Agent can be changed** by the operator, so its absence does **not** mean safety. The durable
signal is behaviour — rate and breadth — which is why sid 1000002 (and the Sigma correlation layer) key on
velocity, and why pure web multi-stage detection needs base rules specific to your environment.
- **Deliberately omitted.** The self-update User-Agent `artex-selfupdate` travels over HTTPS to GitHub and is
not network-observable (TLS SNI alone is too common to alert on). The audit-control marker is an
operator-side log artifact, not target-facing traffic — detect it with
[`../sigma/artex_guard_audit_framing.yml`](../sigma/artex_guard_audit_framing.yml). The server port `:8787`
and recording proxy `127.0.0.1:8788` (`cmd/artex/main.go`) are host-forensic (`ss`/`netstat`), not a
network signature.
## Validate and test
Validated with Suricata 8. The load test needs no traffic and always runs:
```sh
# syntax + engine load test (expect: "Configuration provided was successfully loaded")
docker run --rm -v "$PWD/detections/suricata":/r -w /r jasonish/suricata:latest \
suricata -T -S artex.rules -l /tmp --init-errors-fatal
```
`--init-errors-fatal` makes a rule that parses but fails to initialise a hard error too, so the load test
cannot pass with a silently dropped signature.
To confirm the rules actually fire, a reproducible regression test lives in
[`../tests/suricata/`](../tests/suricata/). It runs this same load check first, then synthesizes a
deterministic capture with scapy, runs `suricata -r` over it, and asserts the alert counts — needing only
Docker:
```sh
detections/tests/suricata/run.sh
```
It asserts that sid 1000001 fires exactly once per probe (35 over a 35-flow capture), that sid 1000002
trips past the 30-in-300 s rate (**5** alerts on Suricata 8.0.7, flows 31–35), and that the same capture
with a benign browser User-Agent produces **0** alerts — confirming the signatures are specific. See
[`../tests/README.md`](../tests/README.md). To check against your own traffic instead, capture a loopback
`curl -A 'artex-enrich/1.0'` against a local server and read the alerts:
```sh
suricata -r enrich.pcap -S artex.rules -l out && \
grep -c '"signature_id":1000001' out/eve.json # presence: one per probe
```
## Contributing
Detection contributions are welcome. New rules should keep every indicator grounded in an observable fact,
state limitations in a comment, pass `suricata -T` cleanly, and avoid any content that reads as attack
guidance. See [`../../CONTRIBUTING.en.md`](../../CONTRIBUTING.en.md) and the Sigma layer in
[`../sigma/`](../sigma/) / [`../README.md`](../README.md).