Skip to content
Security
Skill

/offsec-intel-graph

Neo4j graph database for offensive security intel. Model writes Cypher directly via MCP tools — no scripts, no wrappers.

From plugin
pownie
244 skills

Claude Code

$ npx -y skills add d0gesec/pownie --skill offsec-intel-graph --agent claude-code

SKILL.md

offsec-intel-graph.SKILL.md
name: offsec-intel-graph
description: Neo4j graph database for offensive security intel. Model writes Cypher directly via MCP tools — no scripts, no wrappers.
user-invocable: false

Intel Graph — Neo4j Attack Knowledge Graph

The model writes Cypher directly to Neo4j using the `mcp__neo4j__write_cypher` and `mcp__neo4j__read_cypher` MCP tools. The model determines what entities and relationships exist in the data — this is LLM judgment, not scripted extraction.

When to Activate

  • Any offensive security engagement (CTF, pentest, lab, red team)
  • At the start of every attack session
  • After context compaction (recovery read)

Before Any Attack Action (MANDATORY)

Before calling ANY kali MCP tool that targets a service, endpoint, or vulnerability:

1. **Query disproven attack classes** — entire categories ruled out:

MATCH (ac:attack_class)-[:ON_TARGET]->(tgt:target {name: $targetName})
WHERE ac.status = 'disproven'
RETURN ac.key, ac.reason, ac.blocked_techniques

If your planned technique falls within a disproven class, STOP. Choose a different class entirely.

2. **Query prior attempts** on the target:

MATCH (a:attempt)-[:TRIED_ON]->(target)
WHERE target.addr = $targetIp OR target.key CONTAINS $targetIp
RETURN a.technique, a.tool, a.outcome, a.output_summary, a.error_signature
ORDER BY a.created_at DESC

3. **Query untested edges** — credentials or services not yet tried:

MATCH (c:credential)-[r:AUTHENTICATES_TO {status: 'untested'}]->(s:service)
WHERE s.key STARTS WITH $targetIp
RETURN c.key, s.service

4. **Decide**: If the attack class is disproven, do NOT try any variant — the entire class is dead. If the same technique already failed and nothing has materially changed, do NOT retry. Choose a different technique or gather new intel first.

4. **After execution, immediately RECORD**:

MERGE (a:attempt {key: 'att:<technique>:<tool>@<target_component>'})
SET a.technique = '<technique>', a.tool = '<tool>',
    a.outcome = '<failed|succeeded|partial>',
    a.output_summary = '<1-2 sentence summary>',
    a.error_signature = '<access_denied|timeout|waf_blocked|...>',
    a.created_at = datetime()

A PreToolUse hook (`trace.sh`) queries Neo4j and surfaces prior attempts, credentials, and strategies as context BEFORE execution. This is a safety net — your own CHECK query above is the primary defense.

A PostToolUse hook (`trace.sh`) **auto-extracts credentials and services** from commands and writes them directly to Neo4j:

  • **Credentials**: extracted from `sshpass`, `nxc`/`crackmapexec`, `evil-winrm`, impacket tools
  • **Auth status**: determined from result (`[+]`=confirmed, `[-]`/`Permission denied`=failed)
  • **Services**: extracted from nmap output (port/service/version)

Auto-extracted intel appears as `additionalContext` ("Auto-recorded to graph: ..."). You still need to manually write: target nodes (box name), vulnerabilities, shells, strategies, attempts, and flags.

Phase Classification (MANDATORY)

After every kali MCP tool call, the PostToolUse hook prompts you to classify the command's phase. **Always include the phase SET in your next `write_cypher` call** — piggyback it on whatever intel you're already writing:

MATCH (cl:command_log {sha256: '<sha256_from_prompt>'}) SET cl.phase = '<phase>'

Use dot-notation: `recon.port-scan`, `enum.dir-brute`, `enum.web`, `exploit.sqli`, `exploit.lfi`, `privesc.sudo`, `lateral.cred-reuse`, `access.login`. Create deeper keys freely: `exploit.deserialization.java`, `privesc.service.race`.

The PreToolUse vet surfaces phase breakdown — commands grouped by phase with productive counts. This lets you see at a glance which phases are stale (many commands, zero productive) and which are yielding results.

Post-Compaction Recovery (MANDATORY)

After every compaction, before doing ANYTHING else:

1. Run the full graph recovery:

MATCH (t:target)-[r*1..3]-(n)
UNWIND r AS rel
RETURN DISTINCT labels(n)[0] AS type, n.key AS key, properties(n) AS props
ORDER BY type, key

2. Check what has already been tried and FAILED:

MATCH (a:attempt {outcome: 'failed'})
RETURN a.technique, a.tool, a.error_signature, a.output_summary
ORDER BY a.created_at DESC LIMIT 15

Do NOT proceed with any attack until you have reviewed both results.

How It Works

1. Model discovers a finding via Kali MCP 2. Model determines what entities and relationships exist 3. Model calls `write_cypher` with MERGE statements using ONLY the schema defined below 4. Model reads graph context with `read_cypher` when planning next steps

MCP Tools

| Tool | Use | | ---- | --- | | `mcp__neo4j__write_cypher` | Create/update nodes and relationships | | `mcp__neo4j__read_cypher` | Query the graph — returns structured results | | `mcp__neo4j__get_schema` | Inspect current labels, relationship types, property keys |

Recording Findings

When you discover something, write Cypher immediately. Every finding is a MERGE — never skip, never batch "for later." Unrecorded findings are permanently lost on compaction.

Schema

Use ONLY the node labels and relationship types defined below. Do NOT invent new labels or relationship types. If a finding doesn't fit the schema, store it as properties on existing nodes rather than creating new types.

Node Labels

| Label | Key Property | Key Format | Other Properties | | ----- | ------------ | ---------- | ---------------- | | target | name | `BoxName` | platform, notes, domain | | ip | addr | `10.0.0.1` | | | port | key | `10.0.0.1:22/tcp` | port, proto | | service | key | `10.0.0.1:22:ssh` | service, version | | credential | key | `admin:P@ssw0rd` | username, secret, secret_type | | user | name | `admin` | domain, groups | | vulnerability | key | `CVE-2024-1234` or `vuln:sqli@/login` | name, cve, endpoint, param, tool, exploitation_method, prerequisites, payload_format, confidence, wrong_approaches | | shell | key | `BoxName:www-

Read more
@d0gesec
Ships withpownie

I vibe-hacked my way to Top #87 Global on Hack The Box. Hall of Fame. Built entirely on Claude Code.

Stars on GitHub

Momentum

stars in total
24
Star history of d0gesec/pownie on GitHub, a chart by star-history.com

Other skills on pownie.

offsec-debrief

offsec-debrief

Post-challenge debrief — generates writeup with structured failure analysis. Outputs to writeup/ directory and updates MEMORY.md…

@d0gesec@d0gesecInstall Skill
offsec-lead

offsec-lead

Orchestrator agent for iterative-deepening multi-agent coordination. Manages task trees, spawns focused teammates, evaluates…

@d0gesec@d0gesecInstall Skill
strategy-compact

strategy-compact

Suggests manual context compaction at logical intervals to preserve context through task phases rather than arbitrary…

@d0gesec@d0gesecInstall Skill

More skills from other plugins.

api-security

api-security

Use for authorized security assessment of REST, GraphQL, WebSocket, or SOAP APIs, including discovery, authentication,…

@zhaoxuya520@zhaoxuya520Install Skill
nemoclaw-user-guide

nemoclaw-user-guide

Find official NemoClaw documentation for installation, configuration, operation, or troubleshooting. Also handles requested docs…

@nvidia@nvidiaInstall Skill

Questions about offsec-intel-graph.

Which coding agents can use offsec-intel-graph?
offsec-intel-graph installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.