@mitre-attack/attack-data-model
Version:
A TypeScript API for the MITRE ATT&CK data model
1,225 lines (1,195 loc) • 95.1 kB
JavaScript
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/main.ts
var main_exports = {};
__export(main_exports, {
loadDataModel: () => loadDataModel,
registerDataSource: () => registerDataSource
});
module.exports = __toCommonJS(main_exports);
var import_axios = __toESM(require("axios"), 1);
var import_uuid = require("uuid");
var import_zod29 = require("zod");
// src/schemas/sdo/stix-bundle.schema.ts
var import_zod28 = require("zod");
// src/schemas/common/stix-type.ts
var import_zod = require("zod");
var stixTypeToTypeName = {
"attack-pattern": "Technique",
bundle: "StixBundle",
campaign: "Campaign",
"course-of-action": "Mitigation",
identity: "Identity",
"intrusion-set": "Group",
malware: "Malware",
tool: "Tool",
"marking-definition": "MarkingDefinition",
"x-mitre-data-component": "DataComponent",
"x-mitre-data-source": "DataSource",
"x-mitre-tactic": "Tactic",
"x-mitre-asset": "Asset",
"x-mitre-matrix": "Matrix",
"x-mitre-collection": "Collection",
relationship: "Relationship",
file: "",
// not used in ATT&CK but used in sample_refs for Malware
artifact: ""
// not used in ATT&CK but used in sample_refs for Malware
// 'observed-data': 'ObservedData', // not used in ATT&CK
// 'report': 'Report', // not used in ATT&CK
// 'threat-actor': 'ThreatActor', // not used in ATT&CK
// 'vulnerability': 'Vulnerability', // not used in ATT&CK
};
var supportedStixTypes = [
"attack-pattern",
"bundle",
"campaign",
"course-of-action",
"identity",
"intrusion-set",
"malware",
"tool",
"marking-definition",
"x-mitre-data-component",
"x-mitre-data-source",
"x-mitre-tactic",
"x-mitre-asset",
"x-mitre-matrix",
"x-mitre-collection",
"relationship",
"file",
// not used in ATT&CK but used in sample_refs for Malware
"artifact"
// not used in ATT&CK but used in sample_refs for Malware
// "indicator", // not used in ATT&CK
// "observed-data", // not used in ATT&CK
// "report", // not used in ATT&CK
// "threat-actor", // not used in ATT&CK
// "vulnerability", // not used in ATT&CK
];
var stixTypeSchema = import_zod.z.enum(supportedStixTypes, {
errorMap: (issue, ctx) => {
if (issue.code === "invalid_enum_value") {
const received = typeof ctx.data === "string" ? ctx.data : String(ctx.data);
return {
message: `Invalid STIX type '${received}'. Expected one of the supported STIX types.`
};
}
return { message: ctx.defaultError };
}
}).describe(
"The type property identifies the type of STIX Object (SDO, Relationship Object, etc). The value of the type field MUST be one of the types defined by a STIX Object (e.g., indicator)."
);
function createStixTypeValidator(stixType) {
const objectName = stixTypeToTypeName[stixType];
return import_zod.z.string().superRefine((val, ctx) => {
if (val !== stixType) {
ctx.addIssue({
code: import_zod.z.ZodIssueCode.custom,
message: `Invalid 'type' property. Expected '${stixType}' for ${objectName} object, but received '${val}'.`
});
return import_zod.z.NEVER;
}
});
}
function createMultiStixTypeValidator(stixTypes) {
const objectNames = stixTypes.map((type) => stixTypeToTypeName[type]).join(" or ");
const typeList = stixTypes.map((t) => `'${t}'`).join(" or ");
return import_zod.z.string().superRefine((val, ctx) => {
if (!stixTypes.includes(val)) {
ctx.addIssue({
code: import_zod.z.ZodIssueCode.custom,
message: `Invalid 'type' property. Expected ${typeList} for ${objectNames} object, but received '${val}'.`
});
return import_zod.z.NEVER;
}
});
}
// src/schemas/common/stix-identifier.ts
var import_zod2 = require("zod");
var isValidUuid = (uuid) => {
return /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(uuid);
};
var createStixIdError = (id, errorType) => {
const parts = id.split("--");
const stixType = parts.length > 0 ? parts[0] : "";
const typeName = stixType in stixTypeToTypeName ? stixTypeToTypeName[stixType] : "STIX";
let message;
switch (errorType) {
case "format":
message = `Invalid STIX Identifier for ${typeName} object: must comply with format 'type--UUIDv4'`;
break;
case "type":
message = `Invalid STIX Identifier for ${typeName} object: contains invalid STIX type '${stixType}'`;
break;
case "uuid":
message = `Invalid STIX Identifier for ${typeName} object: contains invalid UUIDv4 format`;
break;
}
return {
code: import_zod2.z.ZodIssueCode.custom,
message,
path: ["id"]
};
};
var stixIdentifierSchema = import_zod2.z.string().refine(
(val) => {
if (typeof val !== "string") return false;
if (!val.includes("--")) return false;
const [type, uuid] = val.split("--");
const isValidType = stixTypeSchema.safeParse(type).success;
const isValidUuidValue = isValidUuid(uuid);
return isValidType && isValidUuidValue;
},
(val) => {
if (typeof val !== "string") {
return createStixIdError(String(val), "format");
}
if (!val.includes("--")) {
return createStixIdError(val, "format");
}
const [type, uuid] = val.split("--");
if (!stixTypeSchema.safeParse(type).success) {
return createStixIdError(val, "type");
}
if (!isValidUuid(uuid)) {
return createStixIdError(val, "uuid");
}
return createStixIdError(val, "format");
}
).describe(
"Represents identifiers across the CTI specifications. The format consists of the name of the top-level object being identified, followed by two dashes (--), followed by a UUIDv4."
);
function createStixIdValidator(expectedType) {
const typeName = stixTypeToTypeName[expectedType] || expectedType;
return stixIdentifierSchema.refine(
(val) => val.startsWith(`${expectedType}--`),
{
message: `Invalid STIX Identifier for ${typeName}: must start with '${expectedType}--'`,
path: ["id"]
}
);
}
// src/schemas/sdo/malware.schema.ts
var import_zod27 = require("zod");
// src/schemas/sdo/software.schema.ts
var import_zod11 = require("zod");
// src/schemas/common/attack-base-object.ts
var import_zod9 = require("zod");
// src/schemas/common/stix-core.ts
var import_zod8 = require("zod");
// src/schemas/common/stix-spec-version.ts
var import_zod3 = require("zod");
var specVersionDescription = [
"The version of the STIX specification used to represent this object.",
"The value of this property MUST be 2.1 for STIX Objects defined according to this specification.",
"If objects are found where this property is not present, the implicit value for all STIX Objects other than SCOs is 2.0.",
"Since SCOs are now top-level objects in STIX 2.1, the default value for SCOs is 2.1."
].join(" ");
var stixSpecVersionSchema = import_zod3.z.enum(["2.0", "2.1"]).describe(specVersionDescription);
// src/schemas/common/stix-timestamp.ts
var import_zod4 = require("zod");
var RFC3339_REGEX = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d+)?)Z$/;
var StixTimestampError = {
InvalidFormat: {
code: import_zod4.z.ZodIssueCode.custom,
message: "Invalid STIX timestamp format: must be an RFC3339 timestamp with a timezone specification of 'Z'."
}
};
var isValidRFC3339 = (timestamp) => {
if (!RFC3339_REGEX.test(timestamp)) return false;
const date = new Date(timestamp);
return !isNaN(date.getTime());
};
var stixTimestampSchema = import_zod4.z.custom(
(val) => {
if (val instanceof Date) {
return isValidRFC3339(val.toISOString());
}
if (typeof val === "string") {
return isValidRFC3339(val);
}
return false;
},
{
message: StixTimestampError.InvalidFormat.message
}
).describe(
"Represents timestamps across the CTI specifications. The format is an RFC3339 timestamp, with a required timezone specification of 'Z'."
);
var stixCreatedTimestampSchema = stixTimestampSchema.brand("StixCreatedTimestamp");
var stixModifiedTimestampSchema = stixTimestampSchema.brand("StixModifiedTimestamp");
// src/schemas/common/misc.ts
var import_zod6 = require("zod");
// src/schemas/common/attack-id.ts
var import_zod5 = require("zod");
var stixTypeToAttackIdMapping = {
"x-mitre-tactic": "tactic",
"attack-pattern": "technique",
// Note: subtechniques are also attack-patterns, but need separate handling
"intrusion-set": "group",
malware: "software",
tool: "software",
"course-of-action": "mitigation",
"x-mitre-asset": "asset",
"x-mitre-data-source": "data-source",
campaign: "campaign"
};
var attackIdPatterns = {
tactic: /^TA\d{4}$/,
technique: /^T\d{4}$/,
subtechnique: /^T\d{4}\.\d{3}$/,
group: /^G\d{4}$/,
software: /^S\d{4}$/,
mitigation: /^M\d{4}$/,
asset: /^A\d{4}$/,
"data-source": /^DS\d{4}$/,
campaign: /^C\d{4}$/
};
// src/schemas/common/misc.ts
var externalReferenceSchema = import_zod6.z.object({
source_name: import_zod6.z.string({
required_error: "Source name is required.",
invalid_type_error: "Source name must be a string."
}),
description: import_zod6.z.string({ invalid_type_error: "Description must be a string." }).optional(),
url: import_zod6.z.string({ invalid_type_error: "URL must be a string." }).url({ message: "Invalid URL format. Please provide a valid URL." }).optional(),
external_id: import_zod6.z.string({ invalid_type_error: "External ID must be a string." }).optional()
});
var externalReferencesSchema = import_zod6.z.array(externalReferenceSchema).min(1, "At least one external reference is required when 'external_references' is defined.").describe("A list of external references which refers to non-STIX information.");
var createAttackExternalReferencesSchema = (stixType) => {
return import_zod6.z.array(externalReferenceSchema).min(1, "At least one external reference is required").refine((refs) => !!refs[0]?.external_id, {
message: "ATT&CK ID must be defined in the first external_references entry.",
path: [0, "external_id"]
}).refine(
(refs) => {
if (!refs[0]?.external_id) return true;
const format = stixTypeToAttackIdMapping[stixType];
return attackIdPatterns[format].test(refs[0].external_id);
},
{
message: `The first external_reference must match the ATT&CK ID format ${getFormatExample(stixType)}.`,
path: [0, "external_id"]
}
).describe("A list of external references with the first containing a valid ATT&CK ID");
};
function getFormatExample(stixType) {
switch (stixType) {
case "x-mitre-tactic":
return "TA####";
case "attack-pattern":
return "T#### or T####.###";
case "intrusion-set":
return "G####";
case "malware":
case "tool":
return "S####";
case "course-of-action":
return "M####";
case "x-mitre-data-source":
return "DS####";
case "x-mitre-asset":
return "A####";
case "campaign":
return "C####";
default:
return "";
}
}
var stixCreatedByRefSchema = createStixIdValidator("identity").describe(
"The created_by_ref property specifies the id property of the identity object that describes the entity that created this object. If this attribute is omitted, the source of this information is undefined. This may be used by object creators who wish to remain anonymous."
);
var granularMarkingSchema = import_zod6.z.object({
marking_ref: stixIdentifierSchema,
selectors: import_zod6.z.array(import_zod6.z.string())
});
var extensionSchema = import_zod6.z.object({
extension_type: import_zod6.z.string(),
extension_properties: import_zod6.z.record(import_zod6.z.unknown())
});
var extensionsSchema = import_zod6.z.record(import_zod6.z.union([extensionSchema, import_zod6.z.record(import_zod6.z.unknown())])).describe("Specifies any extensions of the object, as a dictionary.");
// src/schemas/common/common-properties.ts
var import_zod7 = require("zod");
var versionSchema = import_zod7.z.string().regex(/^\d+\.\d+$/, "Version must be in the format 'major.minor'").default("2.1").describe(
"Represents the version of the object in a 'major.minor' format, where both 'major' and 'minor' are integers. This versioning follows semantic versioning principles but excludes the patch number. The version number is incremented by ATT&CK when the content of the object is updated. This property does not apply to relationship objects."
);
var nameSchema = import_zod7.z.string().min(1, "Name must not be empty").describe("The name of the object.");
var descriptionSchema = import_zod7.z.string().describe("A description of the object.");
var aliasesSchema = import_zod7.z.array(import_zod7.z.string(), {
invalid_type_error: "Aliases must be an array of strings."
}).describe(
"Alternative names used to identify this object. The first alias must match the object's name."
);
var majorMinorVersionRegex = /^(\d{1,3})\.(\d{1,3})$/;
var xMitreVersionSchema = import_zod7.z.custom().refine(
(value) => {
if (!majorMinorVersionRegex.test(value)) return false;
const [major, minor] = value.split(".").map(Number);
return Number.isInteger(major) && Number.isInteger(minor) && major >= 0 && major <= 99 && minor >= 0 && minor <= 99;
},
{
message: "The version must be in the format 'M.N' where M and N are integers between 0 and 99"
}
).describe(
"Represents the version of the object in a 'major.minor' format, where both 'major' and 'minor' are integers between 0 and 99. This versioning follows semantic versioning principles but excludes the patch number. The version number is incremented by ATT&CK when the content of the object is updated. This property does not apply to relationship objects."
);
var majorMinorPatchVersionRegex = /^[0-9]\.[0-9]\.[0-9]$/;
var xMitreAttackSpecVersionSchema = import_zod7.z.string().refine(
(value) => {
if (!majorMinorPatchVersionRegex.test(value)) return false;
const [major, minor, patch] = value.split(".").map(Number);
return major >= 0 && major <= 9 && minor >= 0 && minor <= 9 && patch >= 0 && patch <= 9;
},
{
message: "Must be in the format 'M.N.P' where M, N, and P are single-digit integers (0-9)"
}
).describe(
"The version of the ATT&CK spec used by the object. This field helps consuming software determine if the data format is supported. If the field is not present on an object, the spec version will be assumed to be 2.0.0. Refer to the ATT&CK CHANGELOG for all supported versions."
);
var oldAttackIdRegex = /^MOB-(M|S)\d{4}$/;
function createOldMitreAttackIdSchema(stixType) {
const baseSchema = import_zod7.z.string().describe("Old ATT&CK IDs that may have been associated with this object");
switch (stixType) {
case "malware":
case "tool":
return baseSchema.refine(
(value) => {
return /^MOB-S\d{4}$/.test(value);
},
{
message: `x_mitre_old_attack_id for ${stixType} need to be in the format MOB-S####`
}
);
case "course-of-action":
return baseSchema.refine(
(value) => {
return /^MOB-M\d{4}$/.test(value);
},
{
message: `x_mitre_old_attack_id for ${stixType} need to be in the format MOB-M####`
}
);
default:
throw new Error(`Unsupported STIX type: ${stixType}`);
}
}
var xMitreOldAttackIdSchema = import_zod7.z.string().refine(
(value) => {
return oldAttackIdRegex.test(value);
},
{
message: "Must be in the format 'MOB-X0000' where X is either 'M' or 'S', followed by exactly four digits"
}
).describe("Old ATT&CK IDs that may have been associated with this object");
var attackDomainSchema = import_zod7.z.enum(["enterprise-attack", "mobile-attack", "ics-attack"]);
var xMitreDomainsSchema = import_zod7.z.array(attackDomainSchema).min(1, {
message: "At least one MITRE ATT&CK domain must be specified."
}).describe("The technology domains to which the ATT&CK object belongs.");
var xMitreDeprecatedSchema = import_zod7.z.boolean({
invalid_type_error: "x_mitre_deprecated must be a boolean."
}).describe("Indicates whether the object has been deprecated.");
var supportedMitrePlatforms = [
"Field Controller/RTU/PLC/IED",
"Network Devices",
"Data Historian",
"Google Workspace",
"Office Suite",
"ESXi",
"Identity Provider",
"Containers",
"Azure AD",
"Engineering Workstation",
"Control Server",
"Human-Machine Interface",
"Windows",
"Linux",
"IaaS",
"None",
"iOS",
"PRE",
"SaaS",
"Input/Output Server",
"macOS",
"Android",
"Safety Instrumented System/Protection Relay",
"Embedded"
];
var xMitrePlatformsSchema = import_zod7.z.array(import_zod7.z.enum(supportedMitrePlatforms), {
invalid_type_error: "x_mitre_platforms must be an array of strings.",
message: "x_mitre_platforms may only contain values from the following list: " + supportedMitrePlatforms.join(", ")
}).min(1).refine((items) => new Set(items).size === items.length, {
message: "Platforms must be unique (no duplicates allowed)."
}).describe("List of platforms that apply to the object.");
var objectMarkingRefsSchema = import_zod7.z.array(stixIdentifierSchema).superRefine((val, ctx) => {
val.forEach((identifier, index) => {
if (!identifier.startsWith("marking-definition--")) {
ctx.addIssue({
code: import_zod7.z.ZodIssueCode.custom,
message: `All identifiers must start with 'marking-definition--'. Invalid identifier at index ${index}.`,
path: [index]
});
}
});
}).describe("The list of marking-definition objects to be applied to this object.");
var xMitreContributorsSchema = import_zod7.z.array(import_zod7.z.string()).describe(
"People and organizations who have contributed to the object. Not found on relationship objects."
);
var xMitreIdentity = "identity--c78cb6e5-0c4b-4611-8297-d1b8b55e40b5";
var xMitreModifiedByRefSchema = stixIdentifierSchema.refine((val) => val == xMitreIdentity).describe(
"The STIX ID of the MITRE identity object. Used to track the identity of the MITRE organization, which created the current version of the object. Previous versions of the object may have been created by other individuals or organizations."
);
var killChainNameSchema = import_zod7.z.enum([
"mitre-attack",
"mitre-mobile-attack",
"mitre-ics-attack"
]);
var killChainPhaseSchema = import_zod7.z.object({
phase_name: import_zod7.z.string({
required_error: "Phase name is required.",
invalid_type_error: "Phase name must be a string."
}).describe(
"The name of the phase in the kill chain. The value of this property SHOULD be all lowercase and SHOULD use hyphens instead of spaces or underscores as word separators."
).refine(
(value) => {
const isLowercase = value === value.toLowerCase();
const usesHyphens = !value.includes(" ") && !value.includes("_");
return isLowercase && usesHyphens;
},
{
message: "Phase name should be all lowercase and use hyphens instead of spaces or underscores."
}
),
kill_chain_name: killChainNameSchema
}).strict();
// src/schemas/common/stix-core.ts
var stixBaseObjectSchema = import_zod8.z.object({
id: stixIdentifierSchema.describe(
"The id property universally and uniquely identifies this object."
),
type: stixTypeSchema,
spec_version: stixSpecVersionSchema.describe(
"The version of the STIX specification used to represent this object."
),
created: stixCreatedTimestampSchema.describe(
"The created property represents the time at which the first version of this object was created. The timstamp value MUST be precise to the nearest millisecond."
),
modified: stixModifiedTimestampSchema.describe(
"The modified property represents the time that this particular version of the object was modified. The timstamp value MUST be precise to the nearest millisecond."
),
created_by_ref: stixCreatedByRefSchema.optional(),
labels: import_zod8.z.array(import_zod8.z.string()).describe("The labels property specifies a set of terms used to describe this object.").optional(),
revoked: import_zod8.z.boolean().describe("The revoked property indicates whether the object has been revoked.").optional(),
confidence: import_zod8.z.number().describe("Identifies the confidence that the creator has in the correctness of their data.").int().min(1).max(99).optional().refine((val) => val === void 0 || val > 0 && val < 100, {
message: "Confidence must be between 1 and 99 inclusive."
}).optional(),
lang: import_zod8.z.string().describe("Identifies the language of the text content in this object.").optional(),
external_references: externalReferencesSchema.optional(),
object_marking_refs: objectMarkingRefsSchema.optional(),
granular_markings: import_zod8.z.array(granularMarkingSchema).describe("The set of granular markings that apply to this object.").optional(),
extensions: extensionsSchema.optional()
}).required({
id: true,
type: true,
spec_version: true,
created: true,
modified: true
}).strict();
var stixDomainObjectSchema = stixBaseObjectSchema.extend({});
var stixRelationshipObjectSchema = stixBaseObjectSchema.extend({});
// src/schemas/common/attack-base-object.ts
var attackBaseObjectSchema = stixDomainObjectSchema.extend({
name: nameSchema,
/**
* Required on all ATT&CK schemas except:
* - Marking Definition
*/
x_mitre_attack_spec_version: xMitreAttackSpecVersionSchema,
/**
* Required on all ATT&CK schemas except:
* - Marking Definition
* - Identity
* - Relationship
*/
x_mitre_version: xMitreVersionSchema,
x_mitre_old_attack_id: xMitreOldAttackIdSchema.optional(),
x_mitre_deprecated: xMitreDeprecatedSchema.optional()
});
var attackBaseDomainObjectSchema = attackBaseObjectSchema.extend({});
var attackBaseRelationshipObjectSchema = attackBaseObjectSchema.extend({});
var attackBaseMetaObjectSchema = attackBaseObjectSchema.extend({}).omit({ modified: true });
// src/schemas/common/open-vocabulary.ts
var import_zod10 = require("zod");
var MalwareTypeOpenVocabulary = import_zod10.z.enum([
"adware",
"backdoor",
"bot",
"bootkit",
"ddos",
"downloader",
"dropper",
"exploit-kit",
"keylogger",
"ransomware",
"remote-access-trojan",
"resource-exploitation",
"rogue-security-software",
"rootkit",
"screen-capture",
"spyware",
"trojan",
"virus",
"webshell",
"wiper",
"worm",
"unknown"
]);
var ProcessorArchitecturesOpenVocabulary = import_zod10.z.enum([
"alpha",
"arm",
"ia-64",
"mips",
"powerpc",
"sparc",
"x86",
"x86-64"
]);
var ImplementationLanguagesOpenVocabulary = import_zod10.z.enum([
"applescript",
"bash",
"c",
"c++",
"c#",
"go",
"java",
"javascript",
"lua",
"objective-c",
"perl",
"php",
"powershell",
"python",
"ruby",
"scala",
"swift",
"typescript",
"visual-basic",
"x86-32",
"x86-64"
]);
var MalwareCapabilitiesOpenVocabulary = import_zod10.z.enum([
"accesses-remote-machines",
"anti-debugging",
"anti-disassembly",
"anti-emulation",
"anti-memory-forensics",
"anti-sandbox",
"anti-vm",
"captures-input-peripherals",
"captures-output-peripherals",
"captures-system-state-data",
"cleans-traces-of-infection",
"commits-fraud",
"communicates-with-c2",
"compromises-data-integrity",
"compromises-data-availability",
"compromises-system-availability",
"controls-local-machine",
"degrades-security-software",
"degrades-system-updates",
"determines-c2-server",
"emails-spam",
"escalates-privileges",
"evades-av",
"exfiltrates-data",
"fingerprints-host",
"hides-artifacts",
"hides-executing-code",
"infects-files",
"infects-remote-machines",
"installs-other-components",
"persists-after-system-reboot",
"prevents-artifact-access",
"prevents-artifact-deletion",
"probes-network-environment",
"self-modifies",
"steals-authentication-credentials",
"violates-system-operational-integrity"
]);
var ToolTypesOpenVocabulary = import_zod10.z.enum([
"denial-of-service",
"exploitation",
"information-gathering",
"network-capture",
"credential-exploitation",
"remote-access",
"vulnerability-scanning",
"unknown"
]);
var identityClassOpenVocabulary = import_zod10.z.enum([
"individual",
"group",
"system",
"organization",
"class",
"unspecified"
]);
var attackMotivationOpenVocabulary = import_zod10.z.enum([
"accidental",
"coercion",
"dominance",
"ideology",
"notoriety",
"organizational-gain",
"personal-gain",
"personal-satisfaction",
"revenge",
"unpredictable"
]);
var attackResourceLevelOpenVocabulary = import_zod10.z.enum([
"individual",
"club",
"contest",
"team",
"organization",
"government"
]);
var industrySectorOpenVocabulary = import_zod10.z.enum([
"agriculture",
"aerospace",
"automotive",
"chemical",
"commercial",
"communications",
"construction",
"defense",
"education",
"energy",
"entertainment",
"financial-services",
"government",
"government-emergency-services",
"government-local",
"government-national",
"government-public-services",
"government-regional",
"healthcare",
"hospitality-leisure",
"infrastructure",
"infrastructure-dams",
"infrastructure-nuclear",
"infrastructure-water",
"insurance",
"manufacturing",
"mining",
"non-profit",
"pharmaceuticals",
"retail",
"technology",
"telecommunications",
"transportation",
"utilities"
]);
// src/schemas/sdo/software.schema.ts
var extensibleSoftwareSchema = attackBaseDomainObjectSchema.extend({
type: createMultiStixTypeValidator(["malware", "tool"]),
created_by_ref: stixCreatedByRefSchema.describe(
"The ID of the Source object that describes who created this object."
),
description: descriptionSchema,
external_references: externalReferencesSchema,
object_marking_refs: objectMarkingRefsSchema,
// Malware: Required
// Tool: Optional
x_mitre_platforms: xMitrePlatformsSchema.optional(),
x_mitre_contributors: import_zod11.z.array(import_zod11.z.string()).optional(),
x_mitre_aliases: aliasesSchema.describe(
"Alternative names used to identify this software. The first alias must match the object's name."
).optional(),
x_mitre_modified_by_ref: xMitreModifiedByRefSchema,
x_mitre_domains: xMitreDomainsSchema,
// Not used in ATT&CK Malware or Tool but defined in STIX
aliases: aliasesSchema.optional().describe("Alternative names used to identify this software.")
});
var softwareSchema = extensibleSoftwareSchema;
// src/refinements/index.ts
var import_zod26 = require("zod");
// src/schemas/sdo/asset.schema.ts
var import_zod12 = require("zod");
var supportedAssetSectors = [
"Electric",
"Water and Wastewater",
"Manufacturing",
"Rail",
"Maritime",
"General"
];
var xMitreSectorsSchema = import_zod12.z.array(import_zod12.z.enum(supportedAssetSectors), {
invalid_type_error: "related_asset_sectors must be an array."
}).describe("List of industry sector(s) an asset may be commonly observed in.");
var relatedAssetSchema = import_zod12.z.object({
name: import_zod12.z.string({
required_error: "Related asset name is required.",
invalid_type_error: "Related asset name must be a string."
}),
related_asset_sectors: xMitreSectorsSchema.optional(),
description: descriptionSchema.optional()
});
var relatedAssetsSchema = import_zod12.z.array(relatedAssetSchema).describe(
"Related assets describe sector specific device names or alias that may be commonly associated with the primary asset page name or functional description. Related asset objects include a description of how the related asset is associated with the page definition."
);
var extensibleAssetSchema = attackBaseDomainObjectSchema.extend({
id: createStixIdValidator("x-mitre-asset"),
type: createStixTypeValidator("x-mitre-asset"),
description: descriptionSchema.optional(),
// Optional in STIX but required in ATT&CK
external_references: createAttackExternalReferencesSchema("x-mitre-asset"),
// Optional in STIX but required in ATT&CK
object_marking_refs: objectMarkingRefsSchema,
x_mitre_platforms: xMitrePlatformsSchema.optional(),
x_mitre_domains: xMitreDomainsSchema,
x_mitre_contributors: xMitreContributorsSchema.optional(),
x_mitre_sectors: xMitreSectorsSchema.optional(),
x_mitre_related_assets: relatedAssetsSchema.optional(),
x_mitre_modified_by_ref: xMitreModifiedByRefSchema.optional()
}).strict();
var assetSchema = extensibleAssetSchema;
// src/schemas/sdo/campaign.schema.ts
var import_zod13 = require("zod");
var baseCitationSchema = import_zod13.z.custom(
(value) => {
if (typeof value !== "string") return false;
if (!value.startsWith("(") || !value.endsWith(")")) return false;
const content = value.slice(1, -1);
const parts = content.split(":");
if (parts.length !== 2) return false;
if (parts[0].trim() !== "Citation") return false;
if (parts[1].trim() === "") return false;
return true;
},
{
message: "Each citation must conform to the pattern '(Citation: [citation name])'"
}
);
var multipleCitationsSchema = import_zod13.z.custom(
(value) => {
if (typeof value !== "string") return false;
const citations = value.match(/\(Citation:[^)]+\)/g);
if (!citations) return false;
return citations.join("") === value && citations.every((citation) => baseCitationSchema.safeParse(citation).success);
},
{
message: "Must be one or more citations in the form '(Citation: [citation name])' without any separators"
}
);
var xMitreFirstSeenCitationSchema = multipleCitationsSchema.describe(
"One or more citations for when the object was first seen, in the form '(Citation: [citation name])(Citation: [citation name])...', where each [citation name] can be found as one of the source_name values in the external_references."
);
var xMitreLastSeenCitationSchema = multipleCitationsSchema.describe(
"One or more citations for when the object was last seen, in the form '(Citation: [citation name])(Citation: [citation name])...', where each [citation name] can be found as one of the source_name values in the external_references."
);
var extensibleCampaignSchema = attackBaseDomainObjectSchema.extend({
id: createStixIdValidator("campaign"),
type: createStixTypeValidator("campaign"),
description: descriptionSchema,
external_references: createAttackExternalReferencesSchema("campaign"),
x_mitre_domains: xMitreDomainsSchema,
x_mitre_modified_by_ref: xMitreModifiedByRefSchema,
x_mitre_contributors: xMitreContributorsSchema.optional(),
aliases: aliasesSchema,
// Optional in STIX but required in ATT&CK
first_seen: stixTimestampSchema.describe("The time that this Campaign was first seen."),
// Optional in STIX but required in ATT&CK
last_seen: stixTimestampSchema.describe("The time that this Campaign was last seen."),
x_mitre_first_seen_citation: xMitreFirstSeenCitationSchema,
x_mitre_last_seen_citation: xMitreLastSeenCitationSchema
}).required({
created_by_ref: true,
external_references: true,
object_marking_refs: true,
revoked: true
}).strict();
var campaignSchema = extensibleCampaignSchema.superRefine((schema, ctx) => {
createFirstAliasRefinement()(schema, ctx);
createCitationsRefinement()(schema, ctx);
});
// src/schemas/sdo/collection.schema.ts
var import_zod14 = require("zod");
var objectVersionReferenceSchema = import_zod14.z.object({
object_ref: stixIdentifierSchema.describe("The ID of the referenced object."),
object_modified: stixModifiedTimestampSchema.describe(
"The modified time of the referenced object. It MUST be an exact match for the modified time of the STIX object being referenced."
)
});
var xMitreContentsSchema = import_zod14.z.array(objectVersionReferenceSchema).min(1, "At least one STIX object reference is required.").describe("Specifies the objects contained within the collection.");
var extensibleCollectionSchema = attackBaseDomainObjectSchema.extend({
id: createStixIdValidator("x-mitre-collection"),
type: createStixTypeValidator("x-mitre-collection"),
// Optional in STIX but required in ATT&CK
created_by_ref: stixCreatedByRefSchema,
// Optional in STIX but required in ATT&CK
object_marking_refs: objectMarkingRefsSchema,
description: descriptionSchema.describe(
"Details, context, and explanation about the purpose or contents of the collection."
),
x_mitre_contents: xMitreContentsSchema.min(1, "At least one STIX object reference is required")
}).strict();
var collectionSchema = extensibleCollectionSchema;
// src/schemas/sdo/data-component.schema.ts
var import_zod15 = require("zod");
var xMitreDataSourceRefSchema = createStixIdValidator("x-mitre-data-source").describe(
"STIX ID of the data source this component is a part of."
);
var extensibleDataComponentSchema = attackBaseDomainObjectSchema.extend({
id: createStixIdValidator("x-mitre-data-component"),
type: createStixTypeValidator("x-mitre-data-component"),
description: descriptionSchema,
// Optional in STIX but required in ATT&CK
created_by_ref: stixCreatedByRefSchema,
// Optional in STIX but required in ATT&CK
object_marking_refs: objectMarkingRefsSchema,
x_mitre_domains: xMitreDomainsSchema,
x_mitre_modified_by_ref: xMitreModifiedByRefSchema,
x_mitre_data_source_ref: xMitreDataSourceRefSchema
}).strict();
var dataComponentSchema = extensibleDataComponentSchema;
// src/schemas/sdo/data-source.schema.ts
var import_zod16 = require("zod");
var supportedMitreCollectionLayers = [
"Cloud Control Plane",
"Host",
"Report",
"Container",
"Device",
"OSINT",
"Network"
];
var xMitreCollectionLayersSchema = import_zod16.z.array(import_zod16.z.enum(supportedMitreCollectionLayers), {
invalid_type_error: "x_mitre_collection_layers must be an array of supported collection layers."
}).describe("List of places the data can be collected from.");
var dataSourceSchema = attackBaseDomainObjectSchema.extend({
id: createStixIdValidator("x-mitre-data-source"),
type: createStixTypeValidator("x-mitre-data-source"),
// Optional in STIX but required in ATT&CK
created_by_ref: stixCreatedByRefSchema,
description: descriptionSchema,
// Optional in STIX but required in ATT&CK
external_references: createAttackExternalReferencesSchema("x-mitre-data-source"),
// Optional in STIX but required in ATT&CK
object_marking_refs: objectMarkingRefsSchema,
x_mitre_platforms: xMitrePlatformsSchema.optional(),
x_mitre_domains: xMitreDomainsSchema,
x_mitre_modified_by_ref: xMitreModifiedByRefSchema,
x_mitre_contributors: xMitreContributorsSchema.optional(),
x_mitre_collection_layers: xMitreCollectionLayersSchema
}).strict();
// src/schemas/sdo/group.schema.ts
var import_zod17 = require("zod");
var extensibleGroupSchema = attackBaseDomainObjectSchema.extend({
id: createStixIdValidator("intrusion-set"),
type: createStixTypeValidator("intrusion-set"),
// Not used in ATT&CK Group but defined in STIX
description: import_zod17.z.string().optional().describe(
"A description that provides more details and context about the Intrusion Set, potentially including its purpose and its key characteristics."
),
// Optional in STIX but required in ATT&CK
external_references: createAttackExternalReferencesSchema("intrusion-set"),
x_mitre_domains: xMitreDomainsSchema,
x_mitre_contributors: import_zod17.z.array(import_zod17.z.string()).optional(),
x_mitre_modified_by_ref: xMitreModifiedByRefSchema.optional(),
aliases: aliasesSchema.optional().describe(
"Alternative names used to identify this group. The first alias must match the object's name."
),
// Not used in ATT&CK Group but defined in STIX
first_seen: stixTimestampSchema.optional().describe("The time that this Intrusion Set was first seen."),
// Not used in ATT&CK Group but defined in STIX
last_seen: stixTimestampSchema.optional().describe("The time that this Intrusion Set was last seen."),
// Not used in ATT&CK Group but defined in STIX
goals: import_zod17.z.array(import_zod17.z.string()).optional().describe("The high-level goals of this Intrusion Set, namely, what are they trying to do."),
// Not used in ATT&CK Group but defined in STIX
resource_level: attackResourceLevelOpenVocabulary.optional().describe(
"This property specifies the organizational level at which this Intrusion Set typically works, which in turn determines the resources available to this Intrusion Set for use in an attack."
),
primary_motivation: attackMotivationOpenVocabulary.optional().describe("The primary reason, motivation, or purpose behind this Intrusion Set."),
secondary_motivations: import_zod17.z.array(attackMotivationOpenVocabulary).optional().describe("The secondary reasons, motivations, or purposes behind this Intrusion Set.")
}).strict();
var groupSchema = extensibleGroupSchema.superRefine((schema, ctx) => {
createFirstAliasRefinement()(schema, ctx);
});
// src/schemas/sdo/identity.schema.ts
var import_zod18 = require("zod");
var extensibleIdentitySchema = attackBaseDomainObjectSchema.extend({
id: createStixIdValidator("identity"),
type: createStixTypeValidator("identity"),
object_marking_refs: objectMarkingRefsSchema,
identity_class: identityClassOpenVocabulary.describe(
"The type of entity that this Identity describes, e.g., an individual or organization. This is an open vocabulary and the values SHOULD come from the identity-class-ov vocabulary."
),
description: import_zod18.z.string().describe("A description of the object.").optional(),
// Not used in ATT&CK Identity but defined in STIX
roles: import_zod18.z.array(import_zod18.z.string(), {
invalid_type_error: "Roles must be an array of strings."
}).describe("The list of roles that this Identity performs.").optional(),
// Not used in ATT&CK Identity but defined in STIX
sectors: import_zod18.z.array(industrySectorOpenVocabulary).describe(
"The list of industry sectors that this Identity belongs to. This is an open vocabulary and values SHOULD come from the industry-sector-ov vocabulary."
).optional(),
// Not used in ATT&CK Identity but defined in STIX
contact_information: import_zod18.z.string().describe("The contact information (e-mail, phone number, etc.) for this Identity.").optional()
}).omit({
x_mitre_version: true
}).strict();
var identitySchema = extensibleIdentitySchema;
// src/schemas/sdo/matrix.schema.ts
var import_zod19 = require("zod");
var xMitreTacticRefsSchema = import_zod19.z.array(createStixIdValidator("x-mitre-tactic")).describe(
"An ordered list of x-mitre-tactic STIX IDs corresponding to the tactics of the matrix. The order determines the appearance within the matrix."
);
var extensibleMatrixSchema = attackBaseDomainObjectSchema.extend({
id: createStixIdValidator("x-mitre-matrix"),
type: createStixTypeValidator("x-mitre-matrix"),
// Optional in STIX but required in ATT&CK
created_by_ref: stixCreatedByRefSchema,
description: descriptionSchema,
// Optional in STIX but required in ATT&CK
external_references: externalReferencesSchema,
// TODO check that first ext ref is "enterprise-attack" linked to attack website
// Optional in STIX but required in ATT&CK
object_marking_refs: objectMarkingRefsSchema,
x_mitre_domains: xMitreDomainsSchema,
x_mitre_modified_by_ref: xMitreModifiedByRefSchema,
tactic_refs: xMitreTacticRefsSchema
}).strict();
var matrixSchema = extensibleMatrixSchema;
// src/schemas/sdo/mitigation.schema.ts
var import_zod20 = require("zod");
var extensibleMitigationSchema = attackBaseDomainObjectSchema.extend({
id: createStixIdValidator("course-of-action"),
type: createStixTypeValidator("course-of-action"),
// Optional in STIX but required in ATT&CK
created_by_ref: stixCreatedByRefSchema,
description: import_zod20.z.string().describe("A description that provides more details and context about the Mitigation."),
// Optional in STIX but required in ATT&CK
external_references: createAttackExternalReferencesSchema("course-of-action"),
// Optional in STIX but required in ATT&CK
object_marking_refs: objectMarkingRefsSchema,
x_mitre_domains: xMitreDomainsSchema,
x_mitre_modified_by_ref: xMitreModifiedByRefSchema,
x_mitre_contributors: xMitreContributorsSchema.min(1).optional(),
x_mitre_old_attack_id: createOldMitreAttackIdSchema("course-of-action").optional()
}).strict();
var mitigationSchema = extensibleMitigationSchema;
// src/schemas/sdo/tactic.schema.ts
var import_zod21 = require("zod");
var supportedMitreShortNames = [
"credential-access",
"execution",
"impact",
"persistence",
"privilege-escalation",
"lateral-movement",
"defense-evasion",
"exfiltration",
"discovery",
"collection",
"resource-development",
"reconnaissance",
"command-and-control",
"initial-access",
"inhibit-response-function",
"privilege-escalation",
"lateral-movement",
"discovery",
"initial-access",
"impact",
"persistence",
"execution",
"command-and-control",
"collection",
"evasion",
"impair-process-control",
"initial-access",
"exfiltration",
"persistence",
"privilege-escalation",
"command-and-control",
"execution",
"impact",
"credential-access",
"collection",
"lateral-movement",
"defense-evasion",
"network-effects",
"discovery",
"remote-service-effects"
];
var xMitreShortNameSchema = import_zod21.z.enum(supportedMitreShortNames).describe(
"The x_mitre_shortname of the tactic is used for mapping techniques into the tactic. It corresponds to kill_chain_phases.phase_name of the techniques in the tactic."
);
var extensibleTacticSchema = attackBaseDomainObjectSchema.extend({
id: createStixIdValidator("x-mitre-tactic"),
type: createStixTypeValidator("x-mitre-tactic"),
description: descriptionSchema,
// Optional in STIX but required in ATT&CK
created_by_ref: stixCreatedByRefSchema,
// Optional in STIX but required in ATT&CK
external_references: createAttackExternalReferencesSchema("x-mitre-tactic"),
// Optional in STIX but required in ATT&CK
object_marking_refs: objectMarkingRefsSchema,
x_mitre_domains: xMitreDomainsSchema,
x_mitre_shortname: xMitreShortNameSchema,
x_mitre_modified_by_ref: xMitreModifiedByRefSchema,
x_mitre_contributors: xMitreContributorsSchema.optional()
}).strict();
var tacticSchema = extensibleTacticSchema;
// src/schemas/sdo/technique.schema.ts
var import_zod22 = require("zod");
var xMitreNetworkRequirementsSchema = import_zod22.z.boolean().describe("");
var supportedMitreEffectivePermissions = ["Administrator", "SYSTEM", "User", "root"];
var xMitreEffectivePermissionsSchema = import_zod22.z.array(import_zod22.z.enum(supportedMitreEffectivePermissions), {
invalid_type_error: "x_mitre_effective_permissions must be an array of strings.",
message: "x_mitre_effective_permissions may only contain values from the following list: " + supportedMitreEffectivePermissions.join(", ")
}).min(1).refine((items) => new Set(items).size === items.length, {
message: "Effective permissions must be unique (no duplicates allowed)."
}).describe("The level of permissions the adversary will attain by performing the technique.");
var supportedMitreImpactTypes = ["Availability", "Integrity"];
var xMitreImpactTypeSchema = import_zod22.z.array(import_zod22.z.enum(supportedMitreImpactTypes), {
invalid_type_error: "x_mitre_impact_type must be an array of strings."
}).describe("Denotes if the technique can be used for integrity or availability attacks.");
var xMitreSystemRequirementsSchema = import_zod22.z.array(import_zod22.z.string(), {
invalid_type_error: "x_mitre_system_requirements must be an array of strings."
}).describe(
"Additional information on requirements the adversary needs to meet or about the state of the system (software, patch level, etc.) that may be required for the technique to work."
);
var xMitreRemoteSupportSchema = import_zod22.z.boolean().describe("If true, the technique can be used to execute something on a remote system.");
var supportedMitrePermissionsRequired = [
"Remote Desktop Users",
"SYSTEM",
"Administrator",
"root",
"User"
];
var xMitrePermissionsRequiredSchema = import_zod22.z.array(import_zod22.z.enum(supportedMitrePermissionsRequired), {
invalid_type_error: "x_mitre_permissions_required must be an array of strings.",
message: "x_mitre_permissions_required may only contain values from the following list: " + supportedMitrePermissionsRequired.join(", ")
}).min(1).describe(
"The lowest level of permissions the adversary is required to be operating within to perform the technique on a system."
);
var xMitreDataSourceSchema = import_zod22.z.custom(
(value) => {
if (typeof value !== "string") return false;
const parts = value.split(":");
return parts.length === 2 && parts[0].trim() !== "" && parts[1].trim() !== "";
},
{
message: "Each entry must conform to the pattern '<Data Source Name>: <Data Component Name>'"
}
).describe("A single data source in the format 'Data Source Name: Data Component Name'.");
var xMitreDataSourcesSchema = import_zod22.z.array(xMitreDataSourceSchema, {
invalid_type_error: "x_mitre_data_sources must be an array of strings."
}).describe(
"Sources of information that may be used to identify the action or result of the action being performed."
);
var xMitreIsSubtechniqueSchema = import_zod22.z.boolean({
invalid_type_error: "x_mitre_is_subtechnique must be a boolean."
}).describe("If true, this attack-pattern is a sub-technique.");
var supportedMitreTacticTypes = [
"Post-Adversary Device Access",
"Pre-Adversary Device Access",
// TODO only used with PRE-ATT&CK
"Without Adversary Device Access"
];
var xMitreTacticTypeSchema = import_zod22.z.array(import_zod22.z.enum(supportedMitreTacticTypes), {
invalid_type_error: "x_mitre_tactic_type must be an array of strings.",
message: "x_mitre_tactic_type may only contain values from the following list: " + supportedMitreTacticTypes.join(", ")
}).describe(
'"Post-Adversary Device Access", "Pre-Adversary Device Access", or "Without Adversary Device Access".'
);
var supportedMitreDefenseBypasses = [
"Signature-based detection",
"Multi-Factor Authentication",
"Network Intrusion Detection System",
"Application Control",
"Host forensic analysis",
"Exploit Prevention",
"Signature-based Detection",
"Data Execution Prevention",
"Heuristic Detection",
"File system access controls",
"File Monitoring",
"Digital Certificate Validation",
"Logon Credentials",
"Firewall",
"Host Forensic Analysis",
"Static File Analysis",
"Heuristic detection",
"Notarization",
"System access controls",
"Binary Analysis",
"Web Content Filters",
"Network intrusion detection system",
"Host intrusion prevention systems",
"Application control",
"Defensive network service scanning",
"User Mode Signature Validation",
"Encryption",
"Log Analysis",
"Autoruns Analysis",
"Anti Virus",
"Gatekeeper",
"Anti-virus",
"Log analysis",
"Process whitelisting",
"Host Intrusion Prevention Systems",
"Windows User Account Control",
"System Access Controls",
"Application whitelisting",
"Whitelisting by file name or path",
"File monitoring"
];
var xMitreDefenseBypassesSchema = import_zod22.z.array(import_zod22.z.enum(supportedMitreDefenseBypasses)).min(1).refine((items) => new Set(items).size === items.length, {
message: "Mitre defense bypasses must be unique (no duplicates allowed)."
}).describe("List of defensive tools, methodologies, or processes the technique can bypass.");
var xMitreDetectionSchema = import_zod22.z.string({
invalid_type_error: "x_mitre_detection must be a string."
}).describe("Strategies for identifying if a technique has been used by an adversary.");
var extensibleTechniqueSchema = attackBaseDomainObjectSchema.extend({
id: createStixIdValidator("attack-pattern"),
type: createStixTypeValidator("attack-pattern"),
// Optional in STIX but required in ATT&CK
external_references: createAttackExternalReferencesSchema("attack-pattern"),
kill_chain_phases: import_zod22.z.array(killChainPhaseSchema).optional(),
description: descriptionSchema.optional(),
x_mitre_platforms: xMitrePlatformsSchema.optional(),
x_mitre_detection: xMitreDetectionSchema.optional(),
x_mitre_is_subtechnique: xMitreIsSubtechniqueSchema,
x_mitre_data_sources: xMitreDataSourcesSchema.optional(),
x_mitre_defense_bypassed: xMitreDefenseBypassesSchema.optional(),
x_mitre_contributors: xMitreContributorsSchema.optional(),
x_mitre_permissions_required: xMitrePermissionsRequiredSchema.optional(),
x_mitre_remote_supp