Skip to content

Triage walkthrough

pak edited this page Aug 30, 2026 · 3 revisions

A triage, start to finish

One phishing case, from a pasted block of indicators to a downloaded bundle. Every gesture below is the real one, with the label the button actually carries. It assumes you have never opened the tool.

The case is fictional. The IP address comes from a reserved documentation range and the AS number from the private-use range, so you can type the whole thing in as it stands without pointing at anybody real.

What STIX objects mean, and why consists-of is not related-to, is not explained here. That is the in-app guide: https://app.drawmeastix.io/guide

Before you start: read a finished one

If you would rather see the shape of a finished investigation before drawing your own, that is a legitimate starting point and it takes one click. On the investigation list, the Load the example button (or Load the example investigation on the welcome card, when you have no investigations yet) builds Operation Aviary: a fictional case with around thirty linked objects, the analyst's notes, and two screenshots pinned on the canvas.

It is a real investigation once loaded, not a demo mode. You can edit it, break it, export it, and delete it from the list when you are done. The click fetches the example bundle from the same server that served the page, and nothing else: no third party is contacted, and the two screenshots are drawn in the browser at load time rather than downloaded.

Reading it first makes the rest of this page faster, because you will recognise what you are building towards.

The case

An HR department forwards a phishing email. Payroll notice, a link to a fake single sign-on page, a lookalike domain registered nine days ago. You have pulled the useful lines out of the headers and the body:

hr-payroll@aerodyne-hr[.]top
hxxps://aerodyne-hr[.]top/sso/login
aerodyne-hr[.]top
203.0.113.24
AS64500
mx1.aerodyne.tech

Six lines, five of which matter. The sixth (mx1.aerodyne.tech) is the victim's own mail gateway: it came along for the ride, as things always do, and getting rid of it is exactly what the triage tray is for.

1. Create the investigation

On the investigation list, type a name in the field and press Create. You land on the canvas.

One investigation is one silo and one bundle. There is nothing to configure, and nothing you do from here on leaves the browser. Where the data actually lives, and what a cleared cache costs you, is spelled out at https://app.drawmeastix.io/about

2. Paste the indicators

Three doors, all opening the same box:

  • the Import menu in the toolbar, entry Paste IOCs…;
  • the command palette (Ctrl/Cmd + K), entry Paste IOCs…;
  • the Paste IOCs… chip at the bottom of the Objects panel on the left.

Paste the block into the textarea. The typing is analysed as you go, and a preview list appears under it with one row per indicator: a colour dot, the type, the value.

What you pasted What it becomes Why
hr-payroll@aerodyne-hr[.]top Email [.] is refanged to . before anything else looks at the token
hxxps://aerodyne-hr[.]top/sso/login URL hxxp/hxxps becomes http/https, same pass
aerodyne-hr[.]top Domain
203.0.113.24 IPv4 each octet is checked against 255, so a version number is not an address
AS64500 AS the number is stored as a number, not as text
mx1.aerodyne.tech Domain

The button now reads Add (6). Press it.

The defanged forms understood are [.], (.), {.}, [dot], (dot), {dot}, [@], (@), {@}, [at], (at), {at}, [:], [://], hxxp, fxp and meow://, in either case. Hashes are typed by length: 32, 40 or 64 hexadecimal characters give MD5, SHA-1 or SHA-256 on a file object.

Anything the detector cannot type is listed under the preview as Not recognised (ignored), first five then a count. Nothing is guessed, and nothing is created from a line it did not understand. There is no language model here and there never will be: an indicator either matches a rule or it is left out.

What the paste box will not do for you

It splits on whitespace, commas and semicolons, and then strips only a trailing comma or semicolon. Everything else stays part of the value. So (198.51.100.7) comes back as unrecognised, and <hr-payroll@evil.example> is accepted with the angle brackets inside the value, which is worse, because it looks like it worked. Strip surrounding brackets before pasting.

Pasting raw prose is the wrong tool. For a real report, use Import ▸ A document… instead: .txt, .md, .csv, .log, .html, .htm, .docx, .pdf, up to 25 MB. That path is built for prose and trims punctuation properly, matches the embedded ATT&CK dictionary on whole words of four characters or more, and attaches to each candidate a note recording the file name, the page number when there is one, and the sentence the indicator sat in. It also applies a guardrail the paste box does not: a domain is only kept if its top-level domain is plausible, otherwise every setup.exe and report.docx in the text would become a domain. The price of that guardrail is that an exotic TLD gets dropped, and the paste box is the way round it.

The file is read in the page. It is not uploaded and it is not kept.

The one rule that surprises people

A single indicator goes straight to the canvas. Two or more go to the triage tray.

That is not an inconsistency. Pasting one value is a deliberate gesture: you know what it is and you want it on the graph. Pasting a block is a semi-automatic source, and no semi-automatic source is allowed to write on the canvas without you.

3. Triage

The tray appears at the bottom of the canvas, headed Triage tray with the count, and the reminder j k y n on the right. It does not exist when there is nothing to decide. The tray button on the left rail carries the same count as a badge, and reopens the tray when you have folded it.

Your six candidates are grouped by type, in order of first appearance: Email 1, URL 1, Domain 2, IPv4 1, AS 1. Groups fold with the chevron.

Hovering a row shows its type, its value, and where it came from (paste here, the enricher's name for enrichment, doc for a document import, with the detection excerpt underneath when there is one). That is why the source is on the row at all: a decision made without knowing where a value came from is a coin toss.

Gesture What it does
The check on a row Accepts that one object onto the canvas
The cross on a row Rejects it: the candidate is deleted
The check or cross on a group header Same, for the whole group
Accept all (N) at the bottom Everything in the tray, in one pass
j / k, y / n Same four actions from the keyboard

The keyboard is the fast path, and it has one condition: the tray must have focus, which one click on it gives. The keys are bound to the panel rather than to the window on purpose, so that an n typed while you work on the canvas cannot reject anything. Holding y down works: the cursor stays where it is and the next row slides into its place.

For this case: accept the email, the URL, the domain aerodyne-hr.top, the IP and the AS. Reject mx1.aerodyne.tech.

Three things worth knowing before you press anything:

Rejecting deletes. The candidate and its notes are gone. Ctrl+Z brings them back, the same undo that covers deletions on the canvas, and it is the reason there is no confirmation dialog. See Canvas-reference for what the undo stack does and does not cover.

Accepting a duplicate merges. If the object you accept is already on the canvas (same type, same value), it is absorbed into the one that is there rather than creating a twin, and you are told: "…" was already on the canvas: its relationships joined it. That convergence is usually the interesting part, for instance when two domains resolve to the same address.

Accepted objects land in the middle of your current view, in the first free slot, not where the tray is. If the canvas is scrolled somewhere odd they will appear somewhere odd. The Arrange button, top right of the canvas, draws the whole graph around what it is about afterwards: the most connected object in the middle, what it touches on a ring around it. My layout appears next to it and puts everything back where you had it.

Nothing left in the tray is exported. The status bar keeps a N awaiting triage counter for that reason, and the export lint says it again on the way out.

4. Add what the paste could not know

You now have five observables and no story. The email, the URL and the IP are facts; who is behind them and who they were aimed at is analysis, and analysis is typed by hand.

Open the Objects panel from the left rail (Ctrl+B toggles it) and add:

Type Name Field to fill
Infrastructure Phishing kit - aerodyne-hr.top Description, and the First seen date if you know it
Identity Aerodyne Industries Class: organization
Threat Actor Passerine Kind: group (it changes the identifier that gets generated)

For the technique, use the Frameworks panel on the rail instead of typing it, ATT&CK being the one it opens on: search spearphishing, and pick the row that reads Spearphishing Link with T1566.002 beside it. Two techniques carry that exact name, and the identifier on the row is the only thing that separates them: the other one, T1598.003, is reconnaissance rather than initial access. The object arrives with that identifier already filled in. It is what a receiving platform deduplicates on, so a technique typed by hand deduplicates on its name alone and does it badly.

Every creation selects the new object, so the Inspector on the right is already showing the record you just made.

The shortcut you may prefer

The Scenarios panel carries sixteen ready-made subgraphs, one of which is Phishing - credential harvesting: it asks for the actor, the kit, the sender, the harvesting URL, the domain, the hosting IP and the targeted organisation, then creates all of them plus the nine relationships between them, with Spearphishing Link included.

It is the same API as manual entry, with the same matrix validation and the same identifiers. It is a typing shortcut, never a way round the rules. This walkthrough does it by hand because the manual path is what you will use on a case that does not fit a template, and templates are easy once the manual gesture is familiar.

5. Relate

Drag from a grip on any side of one object onto another - they appear when the pointer comes near a card, and every card that can receive the link shows its own while you drag. A dialog opens offering only the verbs STIX 2.1 allows between those two types, each with a sentence saying what it means, and you pick one.

For this case:

Drag from onto Verb you pick
Threat Actor Passerine Infrastructure Phishing kit uses
Threat Actor Passerine Technique Spearphishing Link uses
Threat Actor Passerine Identity Aerodyne Industries targets
Technique Spearphishing Link Identity Aerodyne Industries targets
Domain aerodyne-hr.top IPv4 203.0.113.24 resolves-to
IPv4 203.0.113.24 AS AS64500 belongs-to
Email, URL, Domain, IPv4 Infrastructure Phishing kit consists-of

That last row is where the tool does something you should expect. Drag the sender email onto the kit and the dialog comes back reading Phishing kit → hr-payroll@aerodyne-hr.top, with consists-of: the opposite of the direction you dragged.

That is deliberate, and it is the whole point of the guided canvas. An observable is never the source of a relationship towards an object, so the correct reading is infrastructure consists-of email-addr. Your direction is tried first, the reverse is tried second, and the matrix decides. You get to think "these four things belong to this kit" without having read the specification.

Linking four things at once

Select the email, the URL, the domain and the IP with Shift+click, then Ctrl+K and Relate the 4 selected objects to…, then pick the kit. One dialog, four relationships.

One caveat that is not obvious. When the dialog opens in the direction you asked for, it offers only the verbs legal for every object in the selection, and it says so under the dropdown. When it flips the direction, as it does here, that guarantee narrows: the verbs come from one object of the batch, and which one is not something you choose. So communicates-with can be offered, legal for the URL, the domain and the IP but not for the email address, and the run stops on the email address partway through. When the batch is mixed, pick the verb that makes sense for all of them, or link the odd one out separately.

When there is no legal link

Drag Passerine onto the URL and nothing legal exists in either direction. Instead of refusing, the tool opens No direct STIX relationship and offers the canonical detour, tickable, one or both:

  • Its infrastructure (C2, hosting…), which creates an infrastructure and both legs: uses then communicates-with;
  • A detection indicator, which creates an indicator with the pattern generated from the observable, plus indicates and based-on.

Here you would press Cancel, because the kit already exists and a second infrastructure object would say the same thing twice. The dialog is there for the case where the intermediate genuinely does not exist yet. What it never does is offer you a meaningless related-to towards an observable: the matrix stays strict, and the clean path costs one click.

Fixing a relationship afterwards

Click the edge. The Inspector shows the relationship as a card, with the verb as a dropdown when the matrix allows more than one, so you can correct it without deleting and redrawing. Underneath it, Active from and Until record when the relationship held true, which is not when you drew it. Those two travel in the bundle as start_time and stop_time.

6. Pin what you are thinking

Two objects are facts, the sentence explaining why you believe they belong together is not, and it is usually the part that gets lost.

Select the Infrastructure node. At the bottom of the Inspector, Notes on this entity: type into the box, leave the kind on note, press Add.

Switch the kind to opinion and a second dropdown appears, from strongly-disagree to strongly-agree. That is where an attribution doubt goes: "attribution to Passerine rests on the kit alone", disagree. It is a first-class STIX object, not a comment.

Notes and opinions are exported. The panel says so under the form.

To put a note on the graph rather than in a panel, use the button on the note card whose tooltip reads Pin on the canvas. It becomes a card on the canvas, tied to its object by a dashed line with no arrowhead and no verb, so it can never be mistaken for a relationship. The minus button on that card takes it off the canvas again without deleting it.

A screenshot

Copy an image to the clipboard (a whois output, a proxy log, the rendered phishing page) and press Ctrl+V with the canvas focused and the caret outside any text field. It becomes a capture node, and a message tells you it has been added.

Link it by dragging from the handle on the capture's left edge onto an object. Double-click it to open it full screen.

Captures are stored in the browser, compressed, and never exported in the bundle. They cannot be: STIX has nowhere to put them. If you need to move an investigation with its screenshots to another machine, that is the Back up everything button on the investigation list, not the bundle.

The scratchpad

The Working notes strip at the very bottom of the window is per investigation, saves itself a moment after you stop typing, and is marked never exported. Drafts, hypotheses, the timeline you are reconstructing, the thing you must not forget to check. It never reaches the bundle and editing it never changes the version fingerprint, which is exactly what makes it usable for thinking out loud.

7. Export

The status bar along the bottom is the summary: objects, relationships, notes, anything still awaiting triage, a lint count when there is one, and how stale your last export is. That lint count is warnings only, so it can be absent while the export dialog still has a list for you. A fresh investigation reads never exported, because until the file exists nothing on disk holds your work.

Press Export STIX, top right.

The dialog opens with the lint at the top, headed what would make the bundle cleaner. It reads the state you are about to export and says what a consumer will find thin: an object nothing links to, an observable no detection covers, a technique with no MITRE identifier. None of those three blocks anything. Two findings in that list do block, and they say so in their own wording: a location with neither country, region nor coordinates, and an indicator with no pattern. The builder refuses both, and the dialog comes back with Export impossible.

This is the moment to notice that the case has no detection in it. Select the URL and press Generate an indicator in the Inspector: you get an indicator carrying the STIX pattern for that observable, already linked based-on. That link is the provenance chain a receiving platform reads, which is why the lint mentions it when it is missing.

Then: pick the container, the TLP, the confidence and the author, press Generate the bundle, then Download the .json. Only the download counts: generating and closing changes nothing, because no file exists.

What each option changes, what the lint findings mean, what blocks an export and what the version fingerprint is for: Exporting. What the receiving platform does with your confidence and your TLP: Importing-into-OpenCTI.

The status bar flips to exported just now, and stays that way until you change something.

What you ended up with

Ten objects on the canvas: five observables from the paste, an infrastructure, an identity, a threat actor, a technique, and the indicator you generated. Ten relationships from the table above, plus the indicator's based-on, all of them legal by construction. A note and an opinion that travel in the bundle. A screenshot and a scratchpad that stay here.

One rejected domain that never got the chance to become somebody else's intelligence, which is the part of this that has no equivalent in an automatic extractor.

Two habits worth forming

Put things back in the tray instead of deleting them. The Inspector's Send back to triage takes an object off the canvas without destroying anything: its relationships are kept and come back with it when you accept it again. It is the right move for something you are no longer sure of.

Export before you close the tab. Not as a ritual, as the actual save. The status bar is the only thing that will tell you, and it will tell you every time.

Related

Clone this wiki locally