Sign in

Roadmap

A 704,528-byte Mach-O in the malware corpus contains exactly one URL:

$ strings -a sample | grep -oiE 'https?://[^ ]+' | sort -u
http://upx.sf.net

That is the packer's own banner. Statically unpacking the file produces 2,036,784 bytes of original Go 1.17.8 executable, and one URL again:

$ strings -a unpacked | grep -oiE 'https?://[^ ]+' | sort -u
http://46.137.201.254:8001initSpan:

An IPv4 literal on port 8001, running straight into the next entry in the Go runtime's read-only string blob because those strings carry no terminator. It occurs once in the unpacked bytes and zero times in the 704,528 that were submitted. Twenty-one files in the corpus carry the UPX magic; the twelve Mach-O are the measured set and the nine Windows PE have never been run through it. Three more of the twelve:

SamplePackedUnpackedWhat the payload carries
Mabouia53,872125,472http://creativecode.com.br/mabouia — the only URL in the payload
Pymafka1,458,5203,759,708no URL at all; the only absolute paths are a statically linked OpenSSL config tree (/usr/local/ssl/private, /usr/local/lib/engines-1.1)
ColdRoot983,0403,292,828/Library/LaunchDaemons, in a sample delivered as com.apple.audio.driver, plus http://www.indyproject.org/ — a networking library's homepage

None of those strings exist in the corresponding packed file. An endpoint carries the verdict in neither direction: Pymafka's payload has no URL at all and scores Malicious 709 on behavior alone, against Suspicious 18 for the stub that was uploaded; ColdRoot's is a library homepage sitting in the same string table as a beacon, which is why raw endpoint presence cannot raise a verdict on its own. Eight of the twelve payloads carried evidence strong enough to change the verdict on the file that was actually uploaded, one parent scoring Benign on its stub and LikelyMalicious on its 41,516-byte payload. Unpacking has the promotion rules that keep a benign compressed installer from being caught by the same mechanism.

Mabouia's payload scores lower than its stub — Suspicious 15 against 18 — because the one genuine command-and-control address in the table fires nothing. Command-and-control recognition is a curated set of twenty-one patterns (.onion and Tor gateways, dynamic-DNS providers, pastebin.com/raw/ and raw.githubusercontent.com, the Telegram bot API, Discord webhooks, ngrok tunnels, Cloudflare Workers, DNS-over-HTTPS, bare IPv4-with-port), and an arbitrary vendor hostname matches none of them. Treating any hardcoded endpoint as command-and-control is the wrong repair — on the Go payloads in this same set the unclassified endpoints are module-path fragments and ip6.int, not beacons — so the open work is family-aware config extraction.

Milestones and commercial tests

Every milestone is gated on one commercial test, not on shipped features — a bar whose clearing triggers a raise or a doubling down, and whose miss is data. Machinery at the depth above already runs under all five; what none of it has yet is proof that anyone pays for it.

MilestoneStatusTest it must passBar that clears it
1. CloudliveDo they come, and do they pay?First paying Pro at $149/mo — 100 the bar, 1,000 the dream
2. FirmwarepartialDoes someone pay for a firmware or package report?First firmware design partner, or first paid report
3. AuditpartialAre the findings clean enough to bill?First paid audit engagement
4. AgentpartialDoes an agentic workflow actually use it?First LLM-native partner or integration live
5. FleetpartialWill an org deploy it and pay?First enterprise contract at the $25,000 floor — one named org indexed across hundreds of hosts

What those bars are worth:

PlanPrice100 subscribers
Pro, monthly$149 per user per month$178,800 a year
Pro, annual$1,490 a year — $124 a month, two months free$149,000 a year
Enterprisefrom $25,000 a year, about fourteen Pro seats

1. Cloud — free and Pro analysis (live)

Objective — turn adoption into first revenue and the leads that become enterprise.

Scope — open any Mach-O, ELF or PE without running it: behavior, capabilities, network surface, functions, libraries, memory segments. Pro adds a private workspace and retained history.

Shipped — Stripe checkout, the customer portal and the entitlement webhook are live. The Pro floor gates eight capabilities in the feature resolver, cleared by Pro and by anything ranked above it:

Four firmware routes carry their own Pro-or-above check on top of that: package detail, whole-firmware SARIF, SBOM export, and package re-processing.

Tier is also what the rate limiter reads:

CallerReads per minuteUploads per hour
Anonymous60, keyed by client IP5, keyed by client IP
Free, signed in300, keyed by user100, keyed by user
Pro and above3,000, keyed by userunmetered per user

A Pro read ceiling exists at all so that a stolen token cannot mine the corpus unthrottled. Independently of caller tier, each deployment node is capped at 500 uploads and 8 GiB per hour.

An upload with no visibility set defaults to public, so a free upload joins the public corpus — which makes privacy the first thing Pro sells rather than a feature bundled behind it.

Limits — three measured costs scale with the corpus rather than with the request.

CostMeasured
Landing-page aggregate — an O(corpus) walk5.6 s at 1M rows. Its 30-second cache applies only to anonymous, default-scope requests, so every signed-in load, Free or Pro, recomputes the full walk
Per-hash sightings rollup — scans the whole append-only upload ledger, not that hash's own rows14.6 ms at 100,000 ledger rows, 96.7 ms at 650,000
Opening the store at boot228 ms at 100K binaries, 1,434 ms at 1M

Platform has the full measurement.

2. Firmware — unpacking, inventory, diff (partial)

Objective — own the question "what is inside this firmware, OS release or vendor package, and what changed."

Scope — unpack the container, inventory every binary inside it, attribute known CVEs, track which file belongs to which version, then batch-diff releases down to function code.

Shipped — recursive unpacking across filesystems, archives, compression, firmware carriers, disk images, Docker and OCI images, RAR, UPX, and the Apple update chain (pbzx, AppleArchive, Img4, BuildManifest, APFS, the dyld shared cache). A Zyxel NAS326 image of 59,389,563 bytes unpacks to 6,789 files and yields CVE-2020-9054 before a single binary is opened; the per-component version-to-CVE table is in CVEs & SBOM. Package-versus-package diff and a whole-firmware SARIF rollup sit on top. The full extractor catalog is in Architectures.

Limits — a container that is identified is not necessarily a container that opens, the header-level CVE hit is a hardcoded table rather than a mechanism, and the vulnerability the showcase image is named after is not the one the engine finds.

ContainerStateConsequence
ext2, journal-clean ext3, ext4extracted — extent trees, 64-bit block numbers, flexible block groups, 3-level htree directories
ext4 with an unreplayed journal, relocated descriptor tables, inline data, or encryptionrejected at validationthe reader replays no journal and holds no keys; a dirty image must be cleanly unmounted first. Block size is also capped at 4 KiB
btrfs, logfs, Seama, eCos, Wind River kernel imagesidentified, not extracted — no extractor has been writtendifferent from a container that defeats extraction

CVE-2020-9054 comes out of the container header because a version substring matched a hardcoded table of eight rules and six path patterns, every one of them Zyxel:

Version pattern matchedCVE attributed
three AAZF.* firmware revisionsCVE-2020-9054
one build numberCVE-2024-40891, CVE-2025-0890
four V4.6* / V4.7* revisionsCVE-2023-28771

Nothing generalises to a vendor not in that table.

The showcase image does not yield the injection flaw it is named for. The NAS326's weblogin.cgi produces ten findings and no CWE-78: the tainted username is handed to a linked shared object and the system() call sits inside that separate file. Taint composes across functions within one binary, not across binaries in an unpacked tree — whole-firmware call graphs and per-library summaries are unbuilt. The CVE above is a version-string match, not a reading of the vulnerable code.

The OSV, EPSS and KEV vulnerability data is fetched by the operator rather than shipped in the binary, so a deployment that never fetches it reports component versions with no CVE attribution at all.

3. Audit — malware verdicts and CWE findings (partial)

Objective — make the findings trustworthy enough to sell as paid audits.

Scope — a malware verdict plus CWE findings on a binary or a whole firmware image; grow the rule set; triage away false positives.

Shipped — the verdict engine runs on Mach-O, ELF and PE, measured against a 1,729-sample malware corpus. Seventy-two CWE ids appear across the binary detectors and 71 have a detector that can emit them. A UPX-packed sample's verdict folds in what its unpacked payload does — child evidence crosses to the parent through a closed curated table and can only raise the parent's tier — and SARIF 2.1.0 export carries findings into GitHub code scanning. The pinned capa rule snapshot is accounted for row by row:

DispositionRules
Reproduced as native detectors828
Routed to fingerprinting — they identify what a binary is rather than what it does157
Kept as structural Rust detectors11
Not ported — 7 are capa's own file-type limitation markers rather than behaviors; the other 28 each record why, most often an unmapped mnemonic or a required instruction co-location35
Total in the pinned snapshot1,031

Limits — CWE findings cannot be bought at any plan tier, the measured corpus skews macOS, static stripped ELF collapses to a handful of finding types, config extraction is narrow, and false-positive triage is unbuilt.

The same program, curl, built two ways:

BuildFindingsDistinct CWE idsComposition
static, stripped, aarch64 ELF2,629 — 42 critical, 1,783 high, 766 medium61,519 are CWE-787; by detector, 1,240 symbolic execution, 1,311 heuristics, 78 name-keyed static rules
dynamically linked macOS15321includes the format-string, strcpy-family overflow and path-traversal classes the static build reports zero of

Per-CWE detector behavior, including what each one misses, is in Findings.

4. Agent — MCP tools and query surface (partial)

Objective — be the binary-intelligence layer LLMs and agents reason over.

Scope — MCP server plus chat: ask a binary what it does, drive deeper queries, talk to the reconstructed program.

Shipped — 48 MCP tools over the corpus:

The internal evidence-chain analyst is the first agentic consumer.

Limits — the chat surface and talking to the reconstructed program are unbuilt. The query language's own gaps — including a reverse endpoint lookup that returns zero for every binary because the indexer and the extractor disagree on a key name — are in Answers.

5. Fleet — org-wide binary index (partial)

Objective — turn Pro users and design partners into org-wide deployments, the enterprise revenue.

Scope — index every binary across all hosts; what is installed where; CVE-versus-SBOM to show what is vulnerable and where; where a hash or a near neighbour has shown up; malicious indicators.

Shipped — the plumbing. A fleet CVE rollup with per-host tracking, and a patching simulator that takes a component name and a hypothetical version and answers:

A WebSocket-dispatched compute farm absorbs scan bursts. The endpoint side sits outside this system: hosts are scanned and their inventories uploaded by macwarden, a separate agent that talks to the API, so a deployment that installs only this server has no host attribution at all.

Limits — no organization is deployed fleet-wide, and two independent gates stand between a Pro account and the host-aware surface: the deployment must be configured as a Fleet deployment with host capture enabled, and the caller must clear an Enterprise floor. Pro clears neither. The fleet CVE rollup also refuses oversized answers rather than truncating them — a query whose estimated response exceeds the cap comes back with an instruction to narrow it by minimum severity or to KEV-listed entries only.


Library and function recognition

Quad-hash, FLIRT, kernel body-hash and prologue tiers name bundled components inside stripped binaries, and every component named is another row SBOM and CVE attribution can join against. Recognition is not a milestone — it runs under all five, always.

Naming is ahead of joining. Of the 1,835,557 bundled quad-hash signatures, 93.8% carry a version string, but only 69.6% carry one with enough segments to be ordered against a range like "before 3.0.14" — a bare 3 mined from libcrypto.so.3 identifies the library and settles no CVE. Fingerprinting has the per-tier coverage.