IIM – The Grammar of Adversary Infrastructure (3/7)

by Robin Dost

Part 3 of 7 of building the Malwarebox Ecosystem
Official Website: https://iim.malwarebox.eu
GitHub: https://github.com/MalwareboxEU/IIM

Threat intelligence has a small problem.

We have more data than ever. Blocklists with millions of entries. Feeds that refresh every thirty seconds. Vendors that will happily sell you a TAXII endpoint streaming 200 indicators per minute, all guaranteed to be expired by the time your SIEM finishes ingesting them.

And somehow, with all this data, we still don’t really know what we’re looking at.

That’s not a tooling problem. It’s a structure problem. After enough time staring at infrastructure rotations from groups like Gamaredon and concluding that “shift everything daily” is in fact a coherent strategy when nobody has the language to describe what’s actually shifting, I decided to try and fix it.

This is part 3 of 7 on the Malwarebox ecosystem. We’re starting today with IIM, the Infrastructure Intelligence Model. Part 4 will cover IIMQL, the query language built on top of it. Part 5 will tie the whole thing together. ACDP already has its own write-up, so I’m leaving it out here.

Two pillars and a hole

Classical threat intelligence rests on two pillars.

On one side: IOCs. Domains, IPs, hashes. Concrete, actionable and useful for roughly the time it takes an attacker to spin up a new Cloudflare Worker. The half-life of a C2 domain in 2026 is somewhere between “a coffee” and “a long lunch.”
Blocklists describe what existed and not what will exist tomorrow.

On the other side: MITRE ATT&CK®. A genuinely good behavioral framework.
Stable, well-maintained, internationally adopted.
Tells you what adversaries do on endpoints, process injection, credential dumping, lateral movement.

What ATT&CK very deliberately does not tell you is anything about infrastructure.
Hosting, routing, resolution, gating, none of it lives in the model. That’s by design.
ATT&CK was never meant to describe how a phishing redirect chain is composed.

So here’s the picture:

On one side, you have millions of indicators that go stale before lunch.
On the other side, you have a few hundred techniques describing adversary behavior, mostly from the endpoint perspective.
And in between sits the operational reality of how a campaign is actually delivered, routed, staged, resolved, gated and defended.
That layer is still mostly captured in analyst writeups, vendor reports and free-form descriptions.

  • There are standards for exchanging threat intelligence
  • There are frameworks for describing adversary behavior
  • There are platforms for storing indicators

But there is no widely adopted, infrastructure-focused model for describing the logic of a delivery chain itself.

  • There are standards for exchanging threat intelligence.
  • There are frameworks for describing adversary behavior.
  • There are platforms for storing indicators.

But

  • No shared vocabulary for saying what role a host plays
  • No consistent way to distinguish an entry point from a redirector, a staging host, a payload location or a C2 endpoint
  • No clean structure for expressing how those pieces relate to each other over time

So the same patterns keep reappearing in analyst notes, vendor whitepapers and PDF reports, just described with slightly different words.

Adversaries operate as systems.

We have been treating those systems as events too much imo.

What “infrastructure” actually means

Quick definition. Because everyone in TI uses “infrastructure” to mean something slightly different and that’s part of the problem.

When I say infrastructure, I mean everything between the adversary and the click:

  • Where things are hosted
  • How DNS resolves
  • How traffic is routed
  • Who is allowed to reach which node
  • How the chain is composed and ordered

This is the layer that survives a sample being detonated, a hash being burned, an IOC list being published. The specific URL changes weekly.
The fact that there is a Cloudflare Worker in front of an HTA-dropping nginx behind a domain that resolves through RegRU, that pattern often survives.

That pattern is what IIM tries to describe.

Six concepts, one chain

IIM is small on purpose.
Six concepts, four primitives, two abstractions.
If a model needs three pages to explain itself, nobody is going to use it easily and I have personally read enough threat intel framework PDFs to consider this a moral position

Entities are the facts. A URL, an IP, a domain, a file hash, a TLS cert.
Pure observation, no interpretation.
An entity exists, has identity and has timestamps. That’s it.

{
  "id": "e3",
  "type": "url",
  "value": "https://worker.example.dev/r",
  "first_seen": "2026-04-10T12:00:00Z"
}

Roles give an entity meaning in context.
The same Cloudflare Worker can be an entry point in one campaign and a redirector in another.
Roles live on the chain position, not the entity itself.
That means: The role isn’t a property of the artifact. The role is what the artifact is doing in this particular operation.

The role catalog is small: entry, redirector, staging, payload, c2.
Five positions, because when I tried to add more I couldn’t honestly justify any of them.

Relations are the actual interactions.
download, redirect, drops, execute, connect, resolves-to, references, communicates-with

Critically: relations carry evidence.
They are observed, not assumed.
If you can’t tell me when and how you saw the redirect, the relation doesn’t go in the chain. We have enough threat intel that’s “well, probably” already.

Techniques are the reusable infrastructure patterns. CDN Abuse, Fast-Flux DNS, Geofenced Delivery, Multi-Hop Redirect, Dead-Drop Resolver.
Twenty-six of them in v1.1.
The catalog will grow, but only when something new actually shows up in the wild.

The thing to internalize: IIM techniques describe infrastructure, not behavior. They are deliberately complementary to ATT&CK, not competitive. If your technique describes what happens on the endpoint, it belongs in ATT&CK. If it describes how traffic flows, where things are hosted or who is allowed to reach what, it belongs here. The two catalogs sit on different axes by design.

Chains are concrete observations. A specific campaigns specific infrastructure at a specific time, modeled as an ordered sequence of role positions, each carrying entities and techniques. (it isn’t as complex as it sounds ^^)
Chains describe what was actually seen.

Patterns are chains with the entities stripped out.
Just the structural fingerprint: role sequence, techniques, match semantics.
Patterns are what you share when you want to publish “this is what these guys infrastructure looks like” without having to ship a list of IOCs that will be dead soon.

That’s the whole model.
Six concepts, deliberately small.

A real example

Let’s run Gamaredon through it.

Scale: an active operation against Ukrainian government and military targets, abusing CVE-2025-6218 to place an HTA loader into the Startup folder without user interaction.

In IIM terms, the chain is not interesting because of one specific domain, one Telegram channel or one IP address.

It is interesting because of the operational shape.

The observed chain looks like this:

entry       > UA government / military-themed spearphishing lure
staging     > RAR archive abusing CVE-2025-6218
staging     > HTA file placed in the Startup folder
redirector  > masqueraded URL using president.gov.ua-style userinfo
payload     > Pteranodon Stage-2 loader
redirector  > Telegram dead-drop channel: oberfarir
redirector  > Telegram dead-drop channel: natural_blood
redirector  > dynamic DNS host: document-downloads.ddns.net
c2          > resolved Telegram-provided endpoint: 194.67.71.75
c2          > resolved Telegram-provided endpoint: 45.33.16.183

The chain contains ten role positions:

entry         > UA gov/military-themed spearphishing sender
staging       > RAR archive triggering CVE-2025-6218
staging       > HTA dropped into Startup
redirector    > URL abusing trusted-looking Ukrainian government branding
payload       > Pteranodon Stage-2 loader
redirector    > Telegram channel used as dead-drop resolver
redirector    > second Telegram channel used as dead-drop resolver
redirector    > dynamic DNS redirector / resolver
c2            > C2 endpoint
c2            > additional resolved C2 endpoint

Techniques attached:

entry          IIM-T019, IIM-T008
staging-1      IIM-T023
staging-2      -
redirector-1   IIM-T006, IIM-T008, IIM-T020
payload        -
redirector-2   IIM-T006, IIM-T013
redirector-3   IIM-T006, IIM-T013, IIM-T023
redirector-4   IIM-T006, IIM-T008, IIM-T020
c2-1           -
c2-2           -

What matters here is the split between volatile infrastructure and reusable structure.

The Telegram channels can rotate. The Dynamic DNS host can disappear. The bulletproof hosting endpoint can be replaced. The loader can be recompiled. The lure, archive name, HTA filename, Telegram channels, DynDNS domain and final IPs are all replaceable pieces.

But the backbone remains visible:

spearphishing entry
-> archive-based staging
-> Startup-folder HTA persistence / loader execution
-> trusted-looking redirector
-> Pteranodon loader
-> Telegram dead-drop resolution
-> dynamic DNS / hosted C2 infrastructure

That is the point of modelling this as infrastructure behavior instead of just collecting indicators.

If you only track the IOCs, every rotation looks like a new campaign. A new Telegram channel, a new DynDNS hostname, a new IP address, a new loader hash.

If you track the pattern, it looks different.

It becomes the same operational design with swapped components.

And that is exactly the layer IIM is meant to describe: not just what was observed, but how the infrastructure was composed, how the pieces related to each other and which parts of the chain are actor tradecraft rather than disposable infrastructure.

Here’s a visual representation of the chain as SVG.

If you want to try yourself, here’s the chain, you can visualize it yourself within the IIM Workbench.

Click to view chain
{
  "iim_version": "1.1",
  "chain_id": "gamaredon-2025-zero-click-rar",
  "entities": [
    {
      "id": "e1",
      "type": "file",
      "value": "<UA gov/military-themed spearphishing sender>"
    },
    {
      "id": "e2",
      "type": "file",
      "value": "*.rar (CVE-2025-6218 trigger archive)"
    },
    {
      "id": "e3",
      "type": "file",
      "value": "<docname>.HTA in Startup folder"
    },
    {
      "id": "e4",
      "type": "url",
      "value": "http://president.gov.ua@readers.serveirc.com?/gss_11.11.2025/kidneyfih/broadlyrQZ.pdf"
    },
    {
      "id": "e5",
      "type": "file",
      "value": "Pteranodon (Stage-2 loader)"
    },
    {
      "id": "e6",
      "type": "url",
      "value": "https://www.telegram.me/s/oberfarir"
    },
    {
      "id": "e7",
      "type": "url",
      "value": "https://www.telegram.me/s/natural_blood"
    },
    {
      "id": "e8",
      "type": "url",
      "value": "document-downloads.ddns.net"
    },
    {
      "id": "e9",
      "type": "url",
      "value": "194.67.71.75"
    },
    {
      "id": "e10",
      "type": "ip",
      "value": "45.33.16.183"
    }
  ],
  "chain": [
    {
      "entity_id": "e1",
      "role": "entry",
      "techniques": [
        "IIM-T019",
        "IIM-T008"
      ]
    },
    {
      "entity_id": "e2",
      "role": "staging",
      "techniques": [
        "IIM-T023"
      ]
    },
    {
      "entity_id": "e3",
      "role": "staging",
      "techniques": []
    },
    {
      "entity_id": "e4",
      "role": "redirector",
      "techniques": [
        "IIM-T006",
        "IIM-T008",
        "IIM-T008",
        "IIM-T020"
      ]
    },
    {
      "entity_id": "e5",
      "role": "payload",
      "techniques": []
    },
    {
      "entity_id": "e6",
      "role": "redirector",
      "techniques": [
        "IIM-T006",
        "IIM-T013"
      ]
    },
    {
      "entity_id": "e7",
      "role": "redirector",
      "techniques": [
        "IIM-T006",
        "IIM-T013",
        "IIM-T023"
      ]
    },
    {
      "entity_id": "e8",
      "role": "redirector",
      "techniques": [
        "IIM-T006",
        "IIM-T008",
        "IIM-T020"
      ]
    },
    {
      "entity_id": "e9",
      "role": "c2",
      "techniques": []
    },
    {
      "entity_id": "e10",
      "role": "c2",
      "techniques": []
    }
  ],
  "relations": [
    {
      "from": "e1",
      "to": "e2",
      "type": "references",
      "sequence_order": 1
    },
    {
      "from": "e2",
      "to": "e3",
      "type": "drops",
      "sequence_order": 2
    },
    {
      "from": "e3",
      "to": "e4",
      "type": "resolves-to",
      "sequence_order": 3
    },
    {
      "from": "e4",
      "to": "e5",
      "type": "drops",
      "sequence_order": 4
    },
    {
      "from": "e5",
      "to": "e6",
      "type": "connect",
      "sequence_order": 5
    },
    {
      "from": "e5",
      "to": "e7",
      "type": "connect",
      "sequence_order": 6
    },
    {
      "from": "e5",
      "to": "e9",
      "type": "connect",
      "sequence_order": 7
    },
    {
      "from": "e8",
      "to": "e9",
      "type": "resolves-to",
      "sequence_order": 8
    },
    {
      "from": "e6",
      "to": "e10",
      "type": "resolves-to",
      "sequence_order": 9
    }
  ],
  "confidence": "confirmed",
  "observed_at": "2025-11-22T00:00:00Z"
}

“But isn’t this just STIX?”

No. And this is the section where I save you the GitHub issue.

STIX 2.1 is an exchange format. It defines objects (indicators, infrastructure, attack-patterns, relationships) and lets you serialize them into bundles you can ship between tools. STIX is excellent at what it does. It’s also explicitly not a model of how an operation is structured.

The STIX Infrastructure SDO has a name, a description, an infrastructure_types tag and some first/last seen timestamps.
That’s it.
No notion of a position in a chain. No notion of “this redirector comes after that entry point.” No notion of techniques attached to a specific role. STIX relationships connect any two objects with a flat verb uses, consists-of, related-to and any ordering or semantic position has to be expressed in free text or vendor-specific extensions, which means in practice it isn’t expressed at all.

IIM exports to STIX losslessly. A chain becomes a bundle of Infrastructure objects with x_iim_* custom properties, plus relationships, plus attack-patterns for the techniques.
The reverse direction, STIX to IIM, is an enrichment workflow, not a conversion, because STIX doesn’t carry the information IIM needs and we shouldn’t pretend it does.
Anything inferred on import gets marked tentative and needs_review: true. No silent upgrades.

Diamond Model has four vertices: adversary, capability, infrastructure, victim. “Infrastructure” is one vertex. One. The whole thing collapses into a single bucket.
Diamond is a fine high-level analytical model, but if you try to express how the infrastructure was actually composed in a Diamond representation, you end up writing a paragraph in a notes field. IIM is what happens when you zoom into the infrastructure vertex and give it real structure.

MISP and OpenCTI taxonomies let you tag an IP as c2 or a domain as redirector.
That’s helpful and IIMs role catalog is partially aligned with those tags on purpose. But tagging is flat. You can tag a thousand IPs as C2 and never express that twelve of them rotate through the same dead-drop resolver while the rest don’t.
Tags describe artifacts.
IIM describes operations.

ATT&CK I already covered. Different axis. Same campaign, different facets. Use both.

The principle I stuck to throughout: don’t replace mature standards, fill the gap they don’t cover.
Composability over reinvention.
There’s enough threat intel work to do without forcing everyone to migrate off STIX again.

Why this matters

Here’s the operational case for caring about any of this.

If you’re a defender and you treat every rotation as a new event, you will spend the rest of your career re-blocking the same operation. You will write the same incident report seven times. Your detection coverage will look like a list of last weeks domains, because that’s exactly what it will be.

If you have a structural model, you can ask different questions. Have we seen this shape before? Does the new infrastructure cluster with the previous campaign at the pattern level? Are the same operators behind it, even though every artifact is new? These are the questions that actually matter when the artifacts are gone within hours.

IIM is not the only way to ask those questions. But it’s a way to ask them in a vocabulary that’s the same on Tuesday as it was on Monday and that lets you compare your observations to mine without us having to first agree on what the words mean.

Federation or: why this actually scales

Here’s the part nobody talks about until it’s been built: the actually interesting property of a structural model is what happens when more than one person uses it.

Threat intel sharing today is broken in a very specific way. We share IOCs through MISP, ISACs, vendor feeds and mailing lists. The IOCs are stale by the time they arrive. When we try to share something more durable, TTPs, actor profiles, narrative reports, the format is a PDF.
PDFs do not match against telemetry. Your SOC analyst opens the PDF, ctrl-Fs for “domain,” and copies the obviously-already-burned indicators into a watchlist. We are still doing this in 2026.

What an IIM federation enables, in one sentence: share patterns instead of indicators and the patterns are still good after the rotation.

Concretely. Org A observes a campaign, builds an IIM chain, abstracts it to a pattern (entities stripped, structure preserved) and publishes it. Org B receives the pattern and matches it against their own observations. Org B might be sitting on completely different domains, different IPs, different hashes and still get a hit, because the shape of the operation matches. The same operators with new clothes.
Pattern-level matching survives rotation by definition.

A few things follow from this:

Sharing scales because patterns don’t expire. A pattern published in March is still useful in November, because the structural fingerprint is what the actors are bad at changing. Their hosting provider rotates daily. Their composition logic rotates roughly never. Once you have ten or twenty good patterns for a group, you can attribute new infrastructure to them within minutes of seeing it, regardless of whether any of the indicators have ever been seen before.

Privacy gets easier, not harder. Patterns have no entities. There are no victim domains, no internal IPs, no attributable hostnames. This bypasses an enormous fraction of the “we can’t share because legal” friction that kills useful TI exchange today. Particularly relevant under GDPR, where IOC sharing involving any kind of victim-identifying data is a pain.
At the end it’s your decision if you share your full chain or just a pattern, both have their worth.
Patterns are PII-free by construction.

Attribution becomes contestable. Right now actor attribution is a process that still requires a lot of manual aggregation and verification. With pattern-level federation, you can publish the patterns you used to cluster and someone else can argue with the clustering. This is how science works.

The network effect actually kicks in. Every additional participant in an IIM federation increases the match rate for everyone else, because the same actor groups hit multiple targets. With IOC sharing, the network effect is muted because IOCs burn fast. With pattern sharing, the network effect compounds.

No central authority required. A federation is not hub-and-spoke. There’s no need for a central database, no single point of failure. Every participant publishes their own patterns from their own infrastructure, signed and timestamped. You consume the patterns from the participants you trust. This is structurally different from how most TI sharing currently works and structurally important if you take sovereignty seriously.

The federation layer is what makes the model worth more than the sum of its installations.
A single org running IIM in isolation gets some structural benefits.
A hundred orgs running IIM with shared patterns gets the actual prize: a defensive intelligence ecosystem that doesn’t rot every Tuesday.

Joining a federation is roughly as hard as validating a JSON file: no central registry to negotiate with, no shared infrastructure to maintain, no legal review of victim data because patterns have none and no vendor sitting between you and the people you actually want to share with.

What’s actually built

IIM v1.1 is published as a draft. Spec, JSON schema, technique catalog, reference chains and bidirectional STIX 2.1 tooling are all on GitHub. Composes with the standards you already use; doesn’t try to replace them.

There’s also a Workbench: a local and web tool for building, validating and exporting IIM chains. Runs on your machine, doesn’t phone home, ships with the technique catalog baked in. Use it to model a campaign you’re working on, sketch a pattern for sharing or just play with the model to see if it makes sense.

If a technique you need isn’t in the catalog, open an issue. If a role definition is wrong, even better, open an issue with a specific case it doesn’t handle.
The model is a draft for a reason. I’d rather get it right than get it done fast.

Open core, closed lab

IIM is one piece of Malwarebox, an independent CTI research initiative I’m building in Europe, publishing open frameworks and methodologies for a corner of threat intelligence that doesn’t really have an open ecosystem yet.

The model is roughly open core, with one important inversion.
The frameworks IIM, ACDP, the schemas, the catalogs, the reference implementations are open. They have to be.
You can’t ask the community to standardize around something they can’t review.

The closed part is Kraken, the working environment behind the research, the platform where adversary infrastructure is actually tracked as a living graph. Kraken stays closed for now and access goes through vetting. Not because closed tooling is the goal, but because some research needs to mature somewhere private before it shapes the public frameworks. Open frameworks need a place where mistakes are cheap.
Kraken is that place.

Why bother with any of this?
Two reasons.

First: civilian threat intelligence research in Europe is structurally underfunded compared to the US, where commercial vendors and government programs subsidize a lot of public work.
We’ve been importing that work for a decade. It worked, mostly.
It has also shaped what European defenders can see and what they can’t and it has made independent research a hobby rather than a profession on this side of the Atlantic.
Open frameworks are one small lever for changing that, they give independent researchers a vocabulary and a publication target that doesn’t require a vendors marketing approval.

Second: a real European CTI federation doesn’t exist yet.
There are bilateral exchanges, sectoral ISACs, vendor-mediated feeds, EU-level initiatives.
None of them constitute a federation in the sense the previous section described.
Building one isn’t a tooling problem.
It’s a structural problem, a trust problem, a vocabulary problem and a sovereignty problem.
IIM is the vocabulary piece. ACDP is the methodology piece. Kraken is the working environment that puts them through their paces.
Together they’re an attempt to be a foundation 🙂

Next

Part four will cover IIMQL the query language that sits on top of IIM.
Once you have a structural model, the next obvious question is “okay, but how do I actually search through thousands of these chains for the patterns I care about.”
That’s what IIMQL is for and it’s where things get more interesting.

Part five will be the partial Malwarebox ecosystem write-up Kraken, IIM/IIMQL, ACDP and how the loop between them is supposed to work in practice.
With a slightly heavier emphasis on the “why this is built in Europe and stays in Europe” argument, because that one deserves its own piece.
All these components are just part of what I’ve actually built and a fraction of what’s planned :3

For now: read the spec, try the workbench, break the model, tell me what’s wrong with it.
You’ll find more real-world examples in the IIM repository soon.

If you want to contact me for feedback or anything else, you can reach me via contact@robin-dost.de

License

IIM is published under the Apache License 2.0.

The reason is simple: IIM is meant to be used.

It should be possible for researchers, vendors, public-sector teams, open-source projects, internal SOC platforms, detection pipelines and threat intelligence tools to adopt the model without asking for permission first.

Apache 2.0 allows free use, modification, distribution and integration, including in commercial products, while still preserving attribution and providing a clear patent grant. That makes it a practical license for an infrastructure intelligence model that is supposed to become interoperable, not decorative.

In short:

You can use it.
You can build on it.
You can integrate it into your own tooling.
You can ship products with it.

Just keep the license notice and attribution intact.

That is the point.


Resources

Malwareboxhttps://malwarebox.eu
IIMhttps://iim.malwarebox.eu
IIM Specification v1.1GitHub
Technique CatalogGitHub
IIM Workbenchhttps://workbench.iim.malwarebox.eu / https://github.com/MalwareboxEU/IIM-Workbench

Upload Response

Your data will be stored in the mainframe. Required fields are marked *