Skip to content

A 90-minute SOC workshop: ingest, curate and share IOCs - #478

Merged
righel merged 9 commits into
mainfrom
docs/soc-workshop
Oct 23, 2026
Merged

righel merged 9 commits into
mainfrom
docs/soc-workshop

Conversation

@righel

@righel righel commented Oct 15, 2026

Copy link
Copy Markdown
Collaborator

Adds tutorial/workshop.md, a hands-on workshop guide in the style of tutorial.md. It follows one scenario: ACME Bank's SOC handling a phishing campaign against its treasury team.

Time Module Lab
0:10 Ingest An uploaded (offline) freetext feed, a batch-imported vendor report, and what normalisation refangs and flags
0:30 Curate Confidence scores, a feed's score modifier and cap, an organisation warninglist, a Perimeter block detection profile with required approval, the review queue
0:55 Share A Palo Alto EDL, Suricata rules and a DNS RPZ zone from the profile, and a live Wazuh manager pulling it as a CDB list with a matching rule
1:20 Close the loop Wazuh's alerts, posted to an alert webhook through its shuffle integration, become sightings
+20 Bonus A retro-hunt notebook (mwlab) and a reactor script that tags campaign infrastructure on arrival

It also includes:

  • pre-session setup (seed-demo, an API key from the SIEM preset), with the lab files inline;
  • must-do and if-you-have-time steps in each lab;
  • facilitator notes and troubleshooting;
  • cleanup steps and links to the docs.

The menu paths follow the navigation from #472.

Checked:

  • every screenshot and docs link resolves;
  • the CDB streaming export with a profile, against dev;
  • Lab 4's alert, run through the Wazuh preset's mapping with the read-only Try it endpoint.

Not run end to end: the labs write to the database, so nobody has clicked through them yet. The Wazuh steps (the CDB list, the rule and the integration) are written from Wazuh 4.x conventions. Both are worth a dry run before the session.

🤖 Generated with Claude Code

tutorial/workshop.md, a hands-on guide in the style of tutorial.md, for one
scenario (ACME Bank's SOC and a phishing campaign against its treasury):

- Ingest: an uploaded (offline) freetext feed, a batch-imported vendor
  report, and what normalisation refangs and flags.
- Curate: confidence scores, a feed's score modifier and cap, an
  organisation warninglist, a "Perimeter block" detection profile with
  required approval, and the review queue.
- Share: a Palo Alto EDL, Suricata rules and a DNS RPZ zone from the
  profile, and a live Wazuh manager pulling it as a CDB list.
- Close the loop: Wazuh's alerts posted back to an alert webhook become
  sightings.
- Bonus: a retro-hunt notebook and a reactor script tagging campaign
  infrastructure on arrival.

With setup, lab files, facilitator notes, troubleshooting and cleanup.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.56%. Comparing base (0e706f9) to head (736cb0b).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #478   +/-   ##
=======================================
  Coverage   88.56%   88.56%           
=======================================
  Files         292      292           
  Lines       34263    34272    +9     
=======================================
+ Hits        30345    30354    +9     
  Misses       3918     3918           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

righel and others added 3 commits October 20, 2026 13:33
Deleting an event only marks it deleted: it stays in the index as a
tombstone. The duplicate-info check on create still matched it, so an event
name could never be used again once deleted ("An event with this info
already exists"). Leave deleted events out of the lookup, as the other event
queries do.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Five false positives (-60) put the walkthrough's C2 at 30, under the 60 a
blocking profile asks for, so the SOC workshop's Perimeter block profile
could never select or approve it. With one (-20) it scores 70, and the
workshop's optional false-positive step then drops it to 50, out of the
profile, as the guide describes.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The workshop reused the feature docs' screenshots, which show stubbed data
unrelated to the scenario. A Playwright script (npm run
workshop:screenshots) now plays the labs as a participant does, with the
lab files in tutorial/files, and captures each screen the guide shows from
the real result: the paste-site feed, the vendor report, the scores, the
ACME warninglist, the Perimeter block profile and its review, the exports
and the retro-hunt notebook. It writes to the instance it points at and
removes a previous run's records by name first.

Two fixes the run turned up in the guide: the Lab 2a query
value:*example-cobalt* matches nothing (value:*cobalt* does), and PAN-OS
EDLs can't take "Subdomains too"; PAN-OS's own list setting covers them.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@righel

righel commented Oct 20, 2026

Copy link
Copy Markdown
Collaborator Author

Follow-ups from playing the workshop end to end (now scripted: npm run workshop:screenshots):

  • Screenshots are now the intended outcome of each lab, captured from a real run, instead of reused feature-doc screenshots.
  • Guide: Lab 2a's query value:*example-cobalt* matched nothing and is now value:*cobalt*. Lab 3a no longer asks for Subdomains too on PAN-OS, where it is disabled, and points to PAN-OS's own Automatically expand to include subdomains instead.
  • Fix: a deleted event no longer blocks creating a new one with the same info. Includes a regression test.
  • Seed: c2.example-cobalt.net keeps 1 false positive instead of 5. With 5 it scored 30, below the Perimeter block profile's 60, so it could never be approved in Lab 2e.

Depends on #484. Without it, Import Data drops the defanged lines of Lab 1b's vendor report (2 of 8 valid).

🤖 Generated with Claude Code

@github-actions

Copy link
Copy Markdown

OpenAPI changes

No changes to the OpenAPI spec.

righel and others added 5 commits October 22, 2026 12:05
Each task now says why it matters (Goal), what to do (Do, with the exact
values), what to check before moving on (Outcome) and where to look when it
doesn't work (Hints); the "if you have time" steps are Extra tasks in the
same shape. Adds how a score is computed and when it changes, especially
after a source's modifier or cap is saved, and an Extra task syncing an
organisation warninglist from a URL (Cloudflare's published ranges).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Ten Marp slides: what it is, how it differs from MISP, Explore, hunts,
ingestion, indicator scores, sharing, alert webhooks, the Tech lab, and a
QR code to the docs with Friday's workshop. talks/README.md shows how to
render a deck to HTML, PDF, PPTX or images.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Login, refresh and logout, the current user, a MISP restSearch, streaming
exports with and without warninglists, a /lookup, a Splunk alert posted
to an alert webhook, and the SIEM alerting profile as a Wazuh CDB list.
The environment holds only the base URL and empty variables: login stores
the access and refresh tokens, and the webhook's token is a variable to
fill in (it is the webhook's only credential).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Login reads its username and password from Postman's vault
({{vault:mw-username}}, {{vault:mw-password}}), so credentials stay out of
exports, and a new request fetches the MCP client config (GET /mcp/config).
The refresh request and the alert webhook URL keep using variables
({{refresh_token}}, saved by login, and {{alert_webhook_token}}) rather
than the pasted values the export brought back.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@righel
righel merged commit 24e6150 into main Oct 23, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant