Introducing Censys CLI Skills: AI-Assisted Investigations at Scale

A practitioner's guide to AI-assisted threat hunting, exposure measurement, and brand protection with Censys.
Product News

At 2 a.m., a workstation makes an outbound TLS connection to a VPS on port 7443. The EDR flags it. A Tier 1 analyst on her third night shift (and her third cup of coffee) pulls up the IP: DigitalOcean, Linux, a self-signed certificate, nothing in the usual reputation feeds. She writes “no further action” and closes the ticket.

Negligence? No. It’s what one query at a time produces at 2 a.m.

The difference between that ticket and an investigation is about nine questions and somewhere to put the answers. Bookkeeping. Count the population before you believe a pivot. Write down the pivot that returned nothing. Keep the raw output next to the conclusion so somebody can check your work on Friday.

Bookkeeping is the first thing to go when the queue is deep. It’s also the one thing an agent does every time without getting bored.

So we wrote the job down: nine markdown files that teach an AI coding assistant how to drive cencli, the Censys open source CLI. 

Maybe you’re strapped for time or staff. Maybe you just have an intolerance for repetitive drudgery. Below you’ll learn about the nine new Censys skills, available as Claude Code plugins, and how they help SOC analysts, CTI analysts, vuln managers, brand protection teams, and others scale investigations to alert-queue speed.

Pro-tip: plenty of advice in here is stealable whether or not you use AI.

What a “Skill” Actually Is

A skill is a markdown file with instructions in it.

Each file carries a short description, and the assistant loads the ones matching what you asked for. If you’ve ever written a runbook, you’ve written a skill.

Two properties worth knowing before you install any of this:

  • Designed not to over-fire. The heavyweight investigation skill triggers on explicit requests — “investigate this,” “hunt for related infrastructure.” Ask “what’s running on this IP” and you get the lookup skill: one call, done. 
  • It quotes you the bill first. Before an investigation starts, it confirms the target and the estimated API call count and offers a lighter pass. Standard run: 20–50 calls. Deep pivoting can pass 100.

It ships as a Claude Code plugin because that handles loading automatically, but the files are plain markdown and work with Cursor, Windsurf, Cline, Codex, or anything else that takes custom instructions.

What Censys Hands the Agent

Skip this if you’ve used Censys. If you haven’t: Censys continuously and exhaustively scans the Internet and actively resolves DNS, then applies finished vuln and threat labels on top. The resulting map is searchable as four kinds of object:

  • Hosts — an IP and everything on it: ports, services, software versions, OS, TLS, certificates it presents, known vulnerabilities, ASN, geography.
  • Web properties — a hostname and port serving HTTP: titles, response bodies and their hashes, headers, favicons, redirect chains, detected web software.
  • Certificates — the certificate as its own object: subject, issuer, every name in it, validation level, CT records.
  • Names — a fully qualified domain name as its own object, re-resolved roughly daily: its A, AAAA, CNAME, MX, NS, SOA, and TXT records, each stamped with when Censys first and last saw it.

Three things you do with them: 

  • Pivot: Turn one observable into the rest of the infrastructure it belongs to.
  • Rescan: Confirm it’s still true before you write a rule around it
  • Monitor: Watch a pattern over time via a Censys Collection instead of re-running queries by hand

Nine New Skills

Before reading this section, recall that these skills teach an AI coding assistant how to drive cencli, the Censys open source CLI. 

The new skills can be categorized into three layers:

  • Command wrappers — Six new command wrappers: search · view · aggregate · enrich · censeye · timeline. One per CLI subcommand: turns a request into the right command, flags, and output handling. They’re self-contained, and therefore useful for one-off lookups on their own.
  • Reference — One new reference skill: censys-cenql. Query syntax, field paths, operators, and a catalogue of known noise that may confound results and lead to wasted investigations. 
  • Methodology — Two new methodology skills. censys-investigate runs a fixed baseline and then branches through decision trees. Because Censys returns deeply nested JSON, and a single host record can run to hundreds of lines before you reach the one field you wanted, censys-analyze leverages jq and SQLite to pull out and cross-reference important values.

The frontmatter is what keeps this cheap. Only a skill’s description sits in context until a trigger phrase matches, and every description ends by naming the skills it isn’t — a safeguard from kicking off a fifty-call investigation.

Four Hypothetical Use Cases

Each of these use cases have roughly the same shape: the alert → the naive mistake one could make without having enough time → what you ask the AI instead → what it returns → what you keep.

1. SOC/IR: the same 2 a.m. alert, run comprehensively

Back to 2 a.m., this time with the methodology loaded.

The naive mistake was one lookup and a verdict. Not wrong — just incomplete. 

What she asks instead: “Enrich this IP, then tell me whether the services look like a known framework and how many other hosts on the Internet look the same.”

The enrichment API call runs first, and it comes back with the services and the certificate. The certificate subject organization reads O=Mythic.

Mythic is an open-source, plugin-based command-and-control framework with a web operator UI. Red teams use it on authorized engagements and threat actors use it on unauthorized ones, which is what makes it interesting rather than conclusive.

Censys ARC profiled 115 hosts carrying O=Mythic or O=Mythic C2 as the certificate subject organization. That’s the installer default, and most operators never change it. 

host.services.cert.parsed.subject_dn: "O=Mythic"

What she keeps: an enrichment block in the ticket, a collection watching the certificate subject so the next host to stand up gets noticed, and a quick query against egress logs for anything else in the estate that talked to the tracked set.

The ticket still closes by 2:20 a.m. But this time, it actually says something.

2. CTI: the report with twelve IOCs, seven of them dead

A report lands with twelve indicators in an appendix. Most are sinkholed, parked, or reassigned already. That’s the normal condition of published intelligence, through no fault of the publisher — IPs and domains are the cheapest things an operator owns.

The naive mistake is to paste all twelve into a blocklist and close the ticket. You have now defended against last month.

What you ask instead: “Which of these are still live? For the live ones, find the thing about them that isn’t an IP, and tell me how many hosts share it.”

One is still up: 85[.]137[.]243[.]49. Four services — SSH on 22, HTTP on 80, nginx on 887 and 888 both returning 403. Hosting provider in Hong Kong. One DNS name.

Censys scores it 0.66 and calls it suspicious.

Read the thing before you fingerprint it

The response body on port 80 is 689 bytes and the title is “Test Page.”

It builds an iframe, sets it to one pixel square at one percent opacity, positions it absolutely at left: -9999px, points it at frame.html with a random query string to defeat caching, and appends it to the document. Whoever wrote it left a developer comment in the source, in Russian.

That’s a hidden injector wearing a default server page as a costume. A visitor sees nothing. A scanner sees a test page. The iframe loads.

The IP is disposable. A hand-written 689-byte injector with a comment still in it is a build, and builds get reused. That’s the pivot!

Pivot one: how common is this page

web.endpoints.http.body_hash_sha256 = "50582f8d52e49f549615ec7cd68629b9f939a0cfc5c5408f324b2f1cff070e99"

231 results. Not a lot, not a little. That’s the shape of a shared build: one kit, deployed by whoever is renting or running it, across infrastructure that doesn’t all belong to the same person.

Pivot two: carve an operator out of the kit

A kit-wide population needs a second constraint. Candidates: hosting ASN, country, the 22/80/887/888 port scheme, or something stapled to the machine itself.

The strongest is the SSH host key — generated once at install, unique per machine. Searching it returns two hosts, and only one of them serves the injector.

Two machines sharing host key material means a cloned disk image or a shared template. That’s the pivot earning its keep: it didn’t confirm what you already had, it produced a host that was nowhere in the report.

What you keep: a watchlist in tiers, each with a stated confidence and an honest false-positive rate:

  • Tight — the SSH host key; the body hash narrowed by ASN or port scheme. Operator-sized.
  • Medium — the body hash and its corresponding fuzzy hash (TLSH). Kit-sized.
  • Loose — the original twelve indicators, kept for log correlation, no longer treated as detections.

Then hand it to detection engineering and let them put it where it fires.

3. Vulnerability management: the one leadership saw on Hacker News

Your CISO forwards a news article about CVE-2026-85706, a path traversal flaw in the repository commits API of self-managed GitLab. CVSS 10.0, unauthenticated arbitrary file read. GitLab shipped fixes on 10 September; Internet-wide probing started the next morning; CISA added it to the Known Exploited Vulnerabilities catalog the same day with a federal remediation deadline of 14 September, which has already passed.

The question in the email: are we exposed?

The naive mistake is to run a Censys query for all GitLab webservers. It’s the right place to start with 208,000 web properties — but it’s not the final answer.

The vulnerable population is a fraction of it

Affected branches are 18.7 through 19.1.7, 19.2.0 through 19.2.5, and 19.3.0 through 19.3.1. Fixed in 19.1.8, 19.2.6, and 19.3.2.

Break the population down by version. Narrow to the affected ranges and you get about 32,800 web properties.

That’s a more useful pair of sentences than “200,000 GitLab servers are on the Internet,” and a better story than the panic version.

Then the turn that makes it an incident

What you ask next: “Of the affected ones, which do we own [per our ASN / netblocks / DNS names, etc.]? Were any of them Internet-reachable before the patch date?”

What you keep: You have the number your CISO actually asked for. Two artifacts, not a dashboard: a number you can defend in a meeting, and a rotation decision with a scope attached.

4. Brand and fraud: one phishing URL from a customer

A customer forwards a link. It’s a login page wearing your logo. You have one domain and a screenshot.

The naive mistake is a takedown request for that domain. It works, it takes a week, and the kit reappears on a new domain the next day.

What you ask instead: “Find the other instances of this page. Start with the favicon, then the response body, then the certificate. Exclude our own properties.”

Order matters. A favicon is a file the operator copied from you and rarely bothers to change. A body hash is tighter but breaks on any edit. The certificate tells you who issued it and what else it covers. Each one narrows the next.

The queries run under the hood amount to:

web.endpoints.http.favicons.hash_sha256 = "<favicon hash from the reported page>"
and web.labels.value = "LOGIN_PAGE"
and not web.labels.value = "DEFAULT_LANDING_PAGE"
and not web.hostname = "yourbrand.com"
and not web.hostname =~ "\\.yourbrand\\.com$"

That’s the general shape for any brand: the artifact, a label confirming it’s a real login form rather than a parked page, and your own estate carved out. Substitute your assets and it’s a standing query.

What you keep: a takedown package covering every instance rather than the one your customer happened to click, and a collection on the durable artifact so the next variant surfaces without anyone reporting it.

How do we combat common agent mistakes?

Part of the development here was identifying common pitfalls, and directing agents to avoid them.

For example: left alone, the agent trusts automated enumeration: it once put AnyDesk on port 7070 into an operator profile when the seed host never ran AnyDesk. It treats platform defaults as tradecraft — a certificate CN shared by 3,475 hosts got called operationally significant when it was a hosting-provider image artifact. And it reaches for hashes before it reads. Fifteen-plus queries went into banner and body hash pivots in one session while the response body carried a globally unique meta description, one hit in all of Censys, that nobody searched until the end. The injector in Hypothetical 2 is 689 bytes; reading it took ten seconds and it was the only reason anyone knew what to pivot on.

Those became checks in the skill. The one that matters most is the population count: before any pivot, count the hosts that match. Zero to five, treat it as unique; twenty-five or more, treat it as broad. It’s a script rather than a suggestion, because the obvious ways to count are wrong — asking for one page of one result returns a record and no total, and summing a breakdown’s buckets undercounts whatever fell off the capped list.

The confidence call — high, moderate, low, unrelated — stays with the analyst, along with whether a signal is tradecraft or provider noise, and what gets published.

Roughly half of our example investigations went into proving signals were not operator-specific. Document negative findings with the same rigor as positive ones: they are the foundation the positive conclusions rest on. One caveat on reading them, though:. Ssome fields only index services that are currently listening, so zero hits can mean “not currently visible” rather than “unique to this host.” Check the field is populated at all before you call anything unique.

Set It Up Yourself

The skills ship as a Claude Code plugin and work with any agent harness that supports the skills spec. They need cencli 1.0 or later, which installs from Homebrew or as a release binary from the releases page. 

Note: pip install censys gets you the legacy Python wrapper and is the incorrect command.

# 1. install cencli - Homebrew (macOS/Linux)
brew install --cask censys/tap/cencli

# ...or grab the release binary directly
# github.com/censys/cencli/releases/latest

censys version                    # should print JSON with a 1.x version

# 2. authenticate
censys auth login                 # OAuth, interactive
censys config auth add            # or a PAT, non-interactive
censys config org-id              # needed for enrich

# 3. install the skills
claude plugin marketplace add censys/censys-ai-skills
claude plugin install censys

Two capabilities need Adversary Investigation module access: CensEye pivots and certificate history. Worth confirming against your licence before you plan around them. Everything else runs on any account with API privileges. 

Clone, Hunt, and Tell Us 

The nine skills, the shell helpers, and the evals are all in the repo. Fork it, use it, tell us what breaks.

Detection Engineering in the Modern SOC

Learn how to adjust for the AI-driven attack landscape by shifting left of your EDR and writing detections that stay ahead of AI-driven threats.

AUTHOR
Alex Gartner

Alex Gartner has led teams to uncover novel threats and build scalable data platforms for SecOps. Previously tackling sensitive missions for the U.S. Air Force, and serving as Sr. Engineering Manager of Security Research, he brings industry-leading data practices into detection engineering. SQL everything.