npx skills add mukul975/Anthropic-Cybersecurity-SkillsMITRE ATT&CK
When to Use
- When the organization needs a real risk assessment — an analysis of specific threats, likelihoods, and impacts — rather than a maturity score against a framework. (Maturity tells you how mature your practices are; a risk assessment tells you what could hurt you and how badly.)
- When another framework requires a documented risk analysis as a mandatory input: NIST CSF (ID.RA), ISO 27001 (Clause 6.1.2), NIST RMF / 800-37 (the Prepare and Select steps), SOC 2 (CC3), PCI DSS, or HIPAA (§164.308(a)(1)(ii)(A)).
- When standing up or significantly changing a system and you must understand its risk before authorization or go-live.
- When leadership asks for the organization's top risks, ranked, with a rationale they can defend to a board or regulator.
- When building or refreshing an enterprise risk register.
Prerequisites
- An inventory of in-scope assets, systems, and the information types they handle (system boundary defined).
- Access to threat intelligence (internal incident history, sector ISAC feeds, MITRE ATT&CK) to ground threat-event likelihood in observed behavior.
- Vulnerability data (scan results, pen-test findings, configuration/architecture review) for the in-scope systems.
- Business context: which missions/processes the systems support, and what impact to confidentiality, integrity, or availability would mean in business terms.
- Agreement on the risk model and scales before scoring, so results are comparable and repeatable (see
references/standards.md). - Familiarity with the three-tier risk-management context from NIST SP 800-39 (organization, mission/business process, information system).
Workflow
NIST SP 800-30 Rev 1 defines four steps. Steps 1 and 4 bookend the assessment; Step 2 is the analytic core.
1. Prepare for the assessment
Define and document:
- Purpose (e.g., support an authorization decision, inform control selection, satisfy ISO 6.1.2).
- Scope — organizational tier (Tier 1/2/3), systems, and time horizon.
- Assumptions and constraints (e.g., assume an external adversarial threat with moderate capability).
- Information sources — threat, vulnerability, and impact inputs.
- Risk model and analytic approach — the factors (threat source, threat event, vulnerability, likelihood, impact) and the scales (qualitative Very Low–Very High, or semi-quantitative 0–10). Lock these now.
2. Conduct the assessment
Work through the analytic tasks in order. The 800-30 appendices provide the reference taxonomies (D–I).
2a. Identify threat sources (Appendix D). Classify by type: Adversarial (individuals, groups, nation-states — characterize capability, intent, targeting), Accidental (user error), Structural (equipment/software failure), Environmental (natural disasters, infrastructure outages).
2b. Identify threat events (Appendix E). The specific actions a source could take (e.g., "adversary exfiltrates credentials via phishing then moves laterally"). Map adversarial events to MITRE ATT&CK techniques for traceability.
2c. Identify vulnerabilities and predisposing conditions (Appendix F). Weaknesses (missing MFA, unpatched service) and conditions that make exploitation more or less likely (internet exposure, flat network, lack of segmentation).
2d. Determine likelihood (Appendix G). Assess the likelihood that a threat event is initiated (adversarial) or occurs (non-adversarial), and the likelihood it results in adverse impact given the vulnerabilities. Combine into an overall likelihood on the agreed scale.
2e. Determine impact (Appendix H). Magnitude of harm if the event succeeds — to operations, assets, individuals, other organizations, or the nation. Express against the agreed scale and in business terms.
2f. Determine risk (Appendix I). Risk is a function of likelihood and impact. Plot each threat event on the risk matrix (e.g., likelihood × impact → Very Low … Very High). Record the risk level, the contributing factors, and uncertainty/assumptions.
3. Communicate and share results
Produce the risk register and an executive briefing. For each risk: the threat event, affected assets, likelihood, impact, risk level, key contributing vulnerabilities, and a recommended treatment. Rank by risk level so decision-makers see the top risks first.
4. Maintain the assessment
Risk is not static. Define a refresh cadence and the triggers that force re-assessment (new system, major architecture change, significant incident, new threat intel). Track risk-acceptance decisions and treatment progress over time.
5. Drive treatment decisions
Hand the ranked register to risk owners. For each risk choose a treatment — mitigate (add/strengthen controls), transfer (insurance, contractual), avoid (stop the activity), or accept (document residual risk with an authorizing signature). Re-score residual risk after planned controls to show the post-treatment position.
Key Concepts
| Concept | Definition |
|---|---|
| Threat source | The cause of a threat event: adversarial, accidental, structural, or environmental. |
| Threat event | A specific action or occurrence that could cause harm (mapped to ATT&CK for adversarial cases). |
| Vulnerability | A weakness that a threat event can exploit. |
| Predisposing condition | A condition that increases or decreases the likelihood of adverse impact (e.g., internet exposure). |
| Likelihood | The chance a threat event initiates/occurs and results in adverse impact. |
| Impact | The magnitude of harm if the event succeeds. |
| Risk | A function of likelihood and impact; the expected harm to the organization. |
| Inherent vs residual risk | Risk before vs after planned/implemented controls. |
| Risk tolerance / appetite | The level of risk leadership is willing to accept. |
| Risk register | The prioritized record of risks, scores, owners, and treatments. |
Tools & Systems
- NIST SP 800-30 Rev 1 — the methodology and Appendices D–I taxonomies (threat sources, events, vulnerabilities, likelihood, impact, risk).
- NIST SP 800-39 — enterprise risk-management context (three tiers).
- MITRE ATT&CK — to enumerate and ground adversarial threat events in observed TTPs.
- Vulnerability scanners / pen-test reports — empirical vulnerability input.
- Threat intel sources — sector ISACs, vendor feeds, internal incident history for likelihood grounding.
- GRC / risk-register tooling — spreadsheet, or platforms such as ServiceNow GRC, Archer, OneTrust, to store and track the register.
- FAIR (optional) — a quantitative model if leadership wants risk expressed in dollar ranges rather than qualitative bands.
Common Scenarios
- CSF/ISO/SOC 2 needs a risk analysis. Run 800-30 to produce the documented assessment those frameworks require as input, then map results to their control sets.
- New system before go-live. Assess threat events against the system's architecture and feed the result into the authorization (RMF Select/Authorize) decision.
- Board wants the top risks. Deliver a ranked register with impacts in business terms and clear treatment recommendations.
- Post-incident. Re-assess the affected systems; the incident updates likelihood evidence and may surface new threat events.
- Annual refresh. Re-score against current threat intel and control changes; show movement in residual risk year over year.
Output Format
Produce a Risk Assessment Report using assets/template.md, containing:
- Purpose, scope, and tier — what was assessed and why.
- Assumptions, constraints, and risk model — the factors and scales used (so results are reproducible).
- Threat sources — by type, with adversarial characterization.
- Threat events — each with affected assets and ATT&CK mapping where adversarial.
- Vulnerabilities and predisposing conditions — tied to threat events.
- Risk register — table: ID, threat event, asset, likelihood, impact, risk level, contributing vulnerabilities, recommended treatment, owner, residual risk.
- Top risks summary — ranked, in business terms, for leadership.
- Maintenance plan — refresh cadence and re-assessment triggers.
Use scripts/process.py to score the register from a risk-input JSON (likelihood × impact → risk level on a configurable matrix), rank risks, and emit the register table.
References and resources
Everything below is rendered for inspection. Script files are read-only and never run.
References 1
standards.md3.7 KB
NIST SP 800-30 — Standards & Reference
Primary standard
NIST SP 800-30 Revision 1 — Guide for Conducting Risk Assessments
- Publisher: NIST
- Published: September 2012
- Scope: The risk-assessment component of the broader risk-management process.
- URL: https://csrc.nist.gov/pubs/sp/800/30/r1/final
Companion standards
| Document | Role |
|---|---|
| NIST SP 800-39 | Managing Information Security Risk — three-tier context (Tier 1 organization, Tier 2 mission/business process, Tier 3 information system). |
| NIST SP 800-37 Rev 2 | Risk Management Framework — risk assessment feeds the Prepare, Select, and Authorize steps. |
| NIST SP 800-53 Rev 5 | Control catalog — source of mitigating controls chosen in risk treatment. |
| FIPS 199 / FIPS 200 | Security categorization (L/M/H per C/I/A) and minimum requirements. |
| MITRE ATT&CK | Adversarial threat-event enumeration and traceability. |
| FAIR (Open Group) | Optional quantitative risk model (dollar-range loss exposure). |
The four-step process (800-30 Rev 1)
- Prepare — purpose, scope, assumptions/constraints, sources, risk model and scales.
- Conduct — tasks 2a–2f below.
- Communicate — risk register + briefing.
- Maintain — monitoring and refresh.
Conduct tasks and their reference appendices
| Task | Appendix | Output |
|---|---|---|
| Identify threat sources | D | Adversarial / Accidental / Structural / Environmental sources |
| Identify threat events | E | Specific events (map adversarial to ATT&CK) |
| Identify vulnerabilities & predisposing conditions | F | Weaknesses + conditions affecting impact likelihood |
| Determine likelihood | G | Likelihood of initiation/occurrence and of adverse impact |
| Determine impact | H | Magnitude of harm |
| Determine risk | I | Risk level = f(likelihood, impact) |
Threat source types (Appendix D)
- Adversarial — individuals, groups, organizations, nation-states. Characterize by capability, intent, and targeting.
- Accidental — erroneous actions by authorized users.
- Structural — failures of equipment, software, or environmental controls.
- Environmental — natural or man-made disasters, infrastructure outages.
Assessment scales (qualitative / semi-quantitative)
800-30 uses five-level scales. A common qualitative mapping:
| Level | Semi-quantitative (0–10) |
|---|---|
| Very Low | 0–4 |
| Low | 5–20 |
| Moderate | 21–79 |
| High | 80–95 |
| Very High | 96–100 |
Reference 5×5 risk matrix (likelihood × impact → risk)
| Likelihood ↓ / Impact → | Very Low | Low | Moderate | High | Very High |
|---|---|---|---|---|---|
| Very High | Very Low | Low | Moderate | High | Very High |
| High | Very Low | Low | Moderate | High | Very High |
| Moderate | Very Low | Low | Moderate | Moderate | High |
| Low | Very Low | Low | Low | Low | Moderate |
| Very Low | Very Low | Very Low | Very Low | Low | Low |
Document whichever matrix the organization adopts during Prepare; the engine in
scripts/process.pydefaults to the table above and is configurable.
NIST CSF 2.0 alignment
| CSF 2.0 ID | Relevance |
|---|---|
| GV.RM-01 | Risk management objectives established |
| ID.RA-01 | Vulnerabilities in assets identified |
| ID.RA-03 | Internal and external threats identified |
| ID.RA-04 | Potential impacts and likelihoods identified |
| ID.RA-05 | Threats, vulnerabilities, likelihoods, and impacts used to understand inherent risk and prioritize response |
Risk treatment options
- Mitigate — implement/strengthen controls (re-score residual risk).
- Transfer — insurance or contractual shift.
- Avoid — discontinue the risk-generating activity.
- Accept — document residual risk with an authorizing signature within risk tolerance.
Scripts 1
process.py7.8 KB
#!/usr/bin/env python3
"""
NIST SP 800-30 Rev 1 risk-register scoring engine.
Reads a risk-input JSON file describing threat events with their assessed
likelihood and impact, computes a risk level for each using the 800-30 5x5
reference matrix (configurable), ranks the register highest-risk-first, and
emits a Markdown risk register plus a top-risks summary.
Input JSON shape:
{
"assessment": {
"name": "Q2 FY26 Enterprise Risk Assessment",
"scope": "Internet-facing application tier",
"tier": 3
},
"matrix": { # OPTIONAL - overrides the default 800-30 matrix
"High": {"Very High": "Very High", ...}
},
"risks": [
{
"id": "R-01",
"threat_event": "Adversary phishes credentials and moves laterally",
"threat_source": "Adversarial",
"asset": "Customer portal / identity provider",
"attack_techniques": ["T1566", "T1021"],
"likelihood": "High",
"impact": "Very High",
"vulnerabilities": ["No phishing-resistant MFA", "Flat internal network"],
"treatment": "Mitigate",
"owner": "IAM Lead",
"residual_risk": "Moderate"
}
]
}
Likelihood / impact values must be one of:
Very Low | Low | Moderate | High | Very High
Usage:
python process.py --input risks.json [--output register.md] [--fail-on High]
python process.py --print-matrix
"""
import argparse
import json
import sys
LEVELS = ["Very Low", "Low", "Moderate", "High", "Very High"]
RANK = {lvl: i for i, lvl in enumerate(LEVELS)}
# 800-30 Rev 1 reference 5x5 matrix: MATRIX[likelihood][impact] -> risk level
MATRIX = {
"Very High": {"Very Low": "Very Low", "Low": "Low", "Moderate": "Moderate", "High": "High", "Very High": "Very High"},
"High": {"Very Low": "Very Low", "Low": "Low", "Moderate": "Moderate", "High": "High", "Very High": "Very High"},
"Moderate": {"Very Low": "Very Low", "Low": "Low", "Moderate": "Moderate", "High": "Moderate", "Very High": "High"},
"Low": {"Very Low": "Very Low", "Low": "Low", "Moderate": "Low", "High": "Low", "Very High": "Moderate"},
"Very Low": {"Very Low": "Very Low", "Low": "Very Low", "Moderate": "Very Low", "High": "Low", "Very High": "Low"},
}
def validate_level(value, field, rid):
if value not in LEVELS:
raise ValueError(
f"risk {rid}: {field} '{value}' is not a valid 800-30 level "
f"(expected one of {LEVELS})"
)
return value
def score_risk(risk, matrix):
rid = risk.get("id", "?")
likelihood = validate_level(risk.get("likelihood"), "likelihood", rid)
impact = validate_level(risk.get("impact"), "impact", rid)
level = matrix[likelihood][impact]
return level
def render_markdown(data, matrix):
meta = data.get("assessment", {})
risks = data.get("risks", [])
scored = []
for r in risks:
level = score_risk(r, matrix)
scored.append((r, level))
# rank highest risk first; tie-break by impact then likelihood
scored.sort(
key=lambda rl: (
RANK[rl[1]],
RANK[rl[0].get("impact", "Very Low")],
RANK[rl[0].get("likelihood", "Very Low")],
),
reverse=True,
)
lines = []
title = meta.get("name", "Risk Assessment")
lines.append(f"# Risk Register - {title}")
lines.append("")
if meta.get("scope"):
lines.append(f"- **Scope:** {meta['scope']}")
if meta.get("tier"):
lines.append(f"- **Risk-management tier (SP 800-39):** Tier {meta['tier']}")
lines.append(f"- **Risks assessed:** {len(scored)}")
lines.append("")
lines.append("Risk level computed from likelihood x impact on the NIST SP 800-30 Rev 1 5x5 matrix.")
lines.append("")
# main register
header = (
"| ID | Threat event | Source | Asset | ATT&CK | Likelihood | Impact "
"| Risk | Key vulnerabilities | Treatment | Residual | Owner |"
)
sep = "|" + "---|" * 12
lines.append(header)
lines.append(sep)
for r, level in scored:
attck = ", ".join(r.get("attack_techniques", [])) or "-"
vulns = "; ".join(r.get("vulnerabilities", [])) or "-"
lines.append(
"| {id} | {event} | {src} | {asset} | {attck} | {like} | {imp} "
"| **{risk}** | {vulns} | {treat} | {res} | {owner} |".format(
id=r.get("id", "-"),
event=r.get("threat_event", "-"),
src=r.get("threat_source", "-"),
asset=r.get("asset", "-"),
attck=attck,
like=r.get("likelihood", "-"),
imp=r.get("impact", "-"),
risk=level,
vulns=vulns,
treat=r.get("treatment", "-"),
res=r.get("residual_risk", "-"),
owner=r.get("owner", "-"),
)
)
# top risks summary
top = [rl for rl in scored if RANK[rl[1]] >= RANK["High"]]
lines.append("")
lines.append("## Top risks (High and above)")
lines.append("")
if not top:
lines.append("_No risks scored High or above._")
else:
for r, level in top:
lines.append(f"- **{level}** - {r.get('id','-')}: {r.get('threat_event','-')} "
f"(impact {r.get('impact','-')}, likelihood {r.get('likelihood','-')})")
# distribution
dist = {lvl: 0 for lvl in LEVELS}
for _, level in scored:
dist[level] += 1
lines.append("")
lines.append("## Risk distribution")
lines.append("")
lines.append("| Risk level | Count |")
lines.append("|---|---|")
for lvl in reversed(LEVELS):
lines.append(f"| {lvl} | {dist[lvl]} |")
return "\n".join(lines), scored, dist
def main():
ap = argparse.ArgumentParser(description="NIST SP 800-30 risk-register scoring engine")
ap.add_argument("--input", "-i", help="Path to risk-input JSON")
ap.add_argument("--output", "-o", help="Write Markdown register to this path")
ap.add_argument("--fail-on", choices=LEVELS,
help="Exit non-zero if any risk scores at or above this level (for pipelines)")
ap.add_argument("--print-matrix", action="store_true", help="Print the active risk matrix and exit")
args = ap.parse_args()
if args.print_matrix:
print("NIST SP 800-30 Rev 1 reference 5x5 matrix (likelihood x impact -> risk):\n")
hdr = "Likelihood \\ Impact | " + " | ".join(LEVELS)
print(hdr)
print("-" * len(hdr))
for like in reversed(LEVELS):
row = " | ".join(MATRIX[like][imp] for imp in LEVELS)
print(f"{like} | {row}")
return 0
if not args.input:
ap.error("--input is required unless --print-matrix is used")
try:
with open(args.input) as f:
data = json.load(f)
except (OSError, json.JSONDecodeError) as e:
print(f"ERROR: could not read input JSON: {e}", file=sys.stderr)
return 2
matrix = data.get("matrix", MATRIX)
try:
md, scored, dist = render_markdown(data, matrix)
except ValueError as e:
print(f"ERROR: {e}", file=sys.stderr)
return 2
if args.output:
with open(args.output, "w") as f:
f.write(md + "\n")
print(f"Risk register written to {args.output}", file=sys.stderr)
else:
print(md)
# summary to stderr
summary = ", ".join(f"{lvl}:{dist[lvl]}" for lvl in reversed(LEVELS) if dist[lvl])
print(f"Scored {len(scored)} risks ({summary}).", file=sys.stderr)
if args.fail_on:
threshold = RANK[args.fail_on]
breaches = [(r.get("id", "?"), lvl) for r, lvl in scored if RANK[lvl] >= threshold]
if breaches:
ids = ", ".join(f"{rid}={lvl}" for rid, lvl in breaches)
print(f"FAIL: {len(breaches)} risk(s) at or above {args.fail_on}: {ids}", file=sys.stderr)
return 1
return 0
if __name__ == "__main__":
sys.exit(main())