[ purple team / detection engineering / research ]52.2297° N —  21.0122° Elast push 2026-10-17

See
the
signal.

Detection rules, incident playbooks and field notes from people who read the logs for a living. Built in the open, tested against real telemetry.

~/entropy — siem · publish telemetryingest ok · today
Events · 119d14▲ +14 / 30d
Detections08▲ +8 / 30d
Intel05▲ +5 / 30d
Field notes01▲ +1 / 30d
event volume · daily · utc
click a spike → events for that daywindow 119d · last ingest 2026-10-17
2026-10-17 · article — Choosing a SIEM by what you already run 2026-10-17 · article — How long should a passphrase be? It depends on where the hash ends up 2026-10-17 · article — What a SIEM costs you in people, not licenses 2026-10-17 · article — Which logs do you actually have? 2026-10-17 · blog — A web tool that can't phone home: connect-src 'none' 2026-10-17 · download — log-source-inventory.yml

01 — Who we are

A small purple team that writes down everything it learns. No vendor slides, no fear marketing — just detections that fire, attacks replayed in a lab to prove it, playbooks that work at 3 a.m., and the reasoning behind all of it.

/ 0x01

Detect

SIEM rule engineering for Wazuh, Sentinel and Defender — mapped to MITRE ATT&CK, tuned against noise.

/ 0x02

Respond

Incident playbooks and automation that turn an alert into a decision in minutes, not meetings.

/ 0x03

Harden

Baselines for endpoints and cloud tenants, plus awareness material people actually read.

/ 0x04

Validate

Adversary emulation in a lab with public tools: run the technique, check that the rule fires, fix what it misses.

03 — Blog

Field
notes

Shorter, rougher, faster. What broke this week, what we tuned, what we'd do differently.

04 — Solutions

The
armory

log-source-inventory.yml

yaml · 238 lines · 10.6 KB
# =============================================================================
# Log source inventory — template
#
# Companion to:
#   https://entropywatch.dev/articles/which-logs-do-you-actually-have/
# License: CC BY 4.0 — ENTROPY//WATCH
# Template version: 2026-10-17
#
# HOW TO USE
#   1. Write your questions first (section `questions`). Every source you list
#      should answer at least one of them; every question should have a source.
#   2. One entry per SOURCE TYPE, not per host ("Windows domain controllers",
#      not "DC01", "DC02"). List hosts only where coverage differs.
#   3. Fill a field only after you have checked it on a real system. Unknown is
#      a valid answer: write `unknown`, not a guess.
#   4. Copy every gap you find into `gaps` and rank it.
#
# BEFORE YOU USE
#   - ADAPT `questions` to your environment and threat model.
#   - ADAPT `retention_target_days` per source: how far back YOUR incidents need
#     to look, plus any legal or contractual requirement. Write down why.
#   - DELETE the example entries (marked `example: true`) once you have your own.
#     Every hostname, domain and IP below is a documentation placeholder.
#   - Treat the finished file as sensitive: it is a map of what you can and
#     cannot see. Do not publish your filled-in copy.
# =============================================================================
 
as_of: YYYY-MM-DD          # date of the last full review
owner: ""                  # person or team who keeps this file current
review_every: quarterly    # and after any SIEM, agent or audit-policy change
 
# -----------------------------------------------------------------------------
# 1. Questions an investigation must be able to answer
#    Start here. Sources exist to answer questions, not the other way round.
# -----------------------------------------------------------------------------
questions:
  - id: Q1
    ask: "Who logged on where, when, and how (interactive, network, remote)?"
    typical_sources: [domain controllers, Windows Security on members, Entra ID sign-ins, VPN, Linux auth]
  - id: Q2
    ask: "What ran on this machine, with which command line, started by what?"
    typical_sources: [Windows Security 4688 with command line, Sysmon, EDR, Linux auditd]
  - id: Q3
    ask: "What did this machine talk to outside the network?"
    typical_sources: [firewall allow + deny, DNS queries, web proxy, EDR network events]
  - id: Q4
    ask: "What changed in identity and privileges (accounts, groups, roles, MFA)?"
    typical_sources: [domain controllers, Entra ID audit log, cloud control-plane logs]
  - id: Q5
    ask: "What was read, sent or shared from mail and SaaS?"
    typical_sources: [Microsoft 365 unified audit log, mailbox audit, SaaS admin logs]
  - id: Q6
    ask: "Who changed the infrastructure (cloud resources, servers, network devices)?"
    typical_sources: [Azure Activity log, AWS CloudTrail, network device AAA/config logs, Linux sudo]
 
# -----------------------------------------------------------------------------
# 2. Sources — one entry per source type
#
# Field reference
#   name                   what the source is
#   category               identity | endpoint | server | network | email_saas | cloud | application
#   answers                question ids from section 1
#   systems                scope: how many systems, which are NOT covered
#   records                what is actually enabled (audit subcategories, event types)
#   local_retention        how far back the log on the system itself reaches TODAY
#   central                where it is forwarded (null if nowhere)
#   central_retention_days how long the central copy is kept, per storage tier
#   retention_target_days  what you need (see BEFORE YOU USE)
#   volume_gb_per_day      measured, not estimated; null until measured
#   time                   time source and timezone of the timestamps
#   collection             agent | syslog | API | none — and what alerts if it stops
#   owner                  who can change the logging config
#   verified               YYYY-MM-DD + how (command, query, test event)
#   known_gaps             free text; copy each one into section 3
# -----------------------------------------------------------------------------
sources:
 
  - name: "Windows domain controllers — Security log"
    example: true
    category: identity
    answers: [Q1, Q4]
    systems: "all DCs in corp.example (DC01, DC02)"
    records:
      - "Advanced Audit Policy per `auditpol /get /category:*` (paste or attach output)"
      - "Account Logon / Kerberos Authentication Service: Success and Failure"
      - "Account Management / Security Group Management: Success"
    local_retention: "unknown — check: Get-WinEvent -LogName Security -MaxEvents 1 -Oldest"
    central: "SIEM via agent"
    central_retention_days: { hot: null, archive: null }
    retention_target_days: null
    volume_gb_per_day: null
    time: "domain time hierarchy (PDC emulator → external NTP); timestamps UTC in SIEM"
    collection: "agent; alert if no events for 1 h: not yet"
    owner: "AD team"
    verified: "YYYY-MM-DD — test failed logon seen in SIEM as 4771 / 4625"
    known_gaps:
      - "Security log max size never changed from default — check `wevtutil gl Security`"
 
  - name: "Windows member servers and workstations — Security + Sysmon"
    example: true
    category: endpoint
    answers: [Q1, Q2]
    systems: "all domain-joined Windows; NOT covered: kiosk machines outside the domain"
    records:
      - "4688 process creation — is 'Include command line in process creation events' enabled?"
      - "Sysmon config version: ''"
    local_retention: unknown
    central: "SIEM via agent"
    central_retention_days: { hot: null, archive: null }
    retention_target_days: null
    volume_gb_per_day: null
    time: "domain time; check skew on laptops off the network"
    collection: "agent"
    owner: "endpoint team"
    verified: ""
    known_gaps: []
 
  - name: "Linux servers — auth, sudo, auditd"
    example: true
    category: server
    answers: [Q1, Q2, Q6]
    systems: "SRV-APP01..SRV-APP12; NOT covered: appliances without agent support"
    records:
      - "auth / secure log via rsyslog or journald"
      - "auditd rules per `auditctl -l` (empty output = no rules loaded)"
    local_retention: "check logrotate config and `journalctl --disk-usage`"
    central: "SIEM via syslog"
    central_retention_days: { hot: null, archive: null }
    retention_target_days: null
    volume_gb_per_day: null
    time: "chrony/NTP; check whether syslog timestamps carry a timezone"
    collection: "syslog; a stopped forwarder is silent — nothing alerts"
    owner: "platform team"
    verified: ""
    known_gaps: []
 
  - name: "Perimeter firewall"
    example: true
    category: network
    answers: [Q3]
    systems: "fw01 (HQ), fw02 (branch)"
    records:
      - "deny: yes"
      - "allow: unknown — many policies log denies only"
      - "NAT translations: unknown (needed to map public IP back to an internal host)"
    local_retention: unknown
    central: "SIEM via syslog from 192.0.2.10"
    central_retention_days: { hot: null, archive: null }
    retention_target_days: null
    volume_gb_per_day: null
    time: "check device NTP and the timezone in the syslog header"
    collection: syslog
    owner: "network team"
    verified: ""
    known_gaps: []
 
  - name: "DNS — internal resolvers"
    example: true
    category: network
    answers: [Q3]
    systems: "Windows DNS on DC01, DC02"
    records:
      - "query logging: off unless enabled (Windows DNS analytic/debug logging is off by default)"
    local_retention: n/a
    central: null
    central_retention_days: { hot: null, archive: null }
    retention_target_days: null
    volume_gb_per_day: null
    time: ""
    collection: none
    owner: "AD team"
    verified: ""
    known_gaps:
      - "No record of which host resolved which domain"
 
  - name: "Microsoft 365 — unified audit log, Entra ID sign-in and audit logs"
    example: true
    category: email_saas
    answers: [Q1, Q4, Q5]
    systems: "tenant contoso.example"
    records:
      - "unified audit log: on? (check in the Purview portal)"
      - "sign-in and audit logs exported to SIEM: which categories?"
    local_retention: "depends on license — check current Microsoft documentation"
    central: "SIEM via API connector"
    central_retention_days: { hot: null, archive: null }
    retention_target_days: null
    volume_gb_per_day: null
    time: "UTC"
    collection: "API; connector health alert: unknown"
    owner: "M365 admins"
    verified: ""
    known_gaps: []
 
# -----------------------------------------------------------------------------
# 3. Gaps — ranked
#    impact: which question goes unanswered, for which systems
#    fix_cost: low (config change) | medium (new collection/storage) | high (new product or project)
# -----------------------------------------------------------------------------
gaps:
  - id: G1
    example: true
    source: "Windows domain controllers — Security log"
    question: Q1
    finding: "Local Security log reaches back N hours on DC01 at Monday peak"
    impact: "If forwarding stops, logon history older than N hours is lost"
    fix: "Raise max log size; add an alert on forwarding silence"
    fix_cost: low
    owner: "AD team"
    status: open        # open | planned | fixed | accepted
    accepted_reason: ""
 
# -----------------------------------------------------------------------------
# 4. Verification commands (read-only)
# -----------------------------------------------------------------------------
checks:
  windows:
    - cmd: "auditpol /get /category:*"
      shows: "which audit subcategories are enabled (run elevated)"
    - cmd: "wevtutil gl Security"
      shows: "maxSize and retention of the Security log"
    - cmd: "Get-WinEvent -LogName Security -MaxEvents 1 -Oldest | Select-Object TimeCreated"
      shows: "how far back the local Security log reaches right now"
  linux:
    - cmd: "auditctl -s"
      shows: "whether auditd is enabled and how many events it lost"
    - cmd: "auditctl -l"
      shows: "loaded audit rules; 'No rules' means nothing beyond defaults"
    - cmd: "journalctl --disk-usage"
      shows: "space used by the journal"
    - cmd: "journalctl -o short-iso | head -n 1"
      shows: "oldest journal entry still on disk"
  siem_microsoft_sentinel:
    - query: "union withsource=SourceTable * | where TimeGenerated > ago(7d) | summarize LastEvent = max(TimeGenerated) by SourceTable | sort by LastEvent asc"
      shows: "tables that went quiet first (expensive on big workspaces: narrow the time range)"
  siem_wazuh:
    - cmd: "/var/ossec/bin/agent_control -l"
      shows: "agents and their status (Active, Disconnected, Never connected)"
sha256 1804a7264e8a1344270ebe2b91340571eef9d25f4e39d6ccd50110eb8a2e778d
05 — Tools

Browser
tools

Small tools for analysts, each on its own subdomain with its own strict CSP. They run in your browser and send nothing anywhere.