[FR] Generate mdx docs (#2718)
This commit is contained in:
@@ -32,7 +32,7 @@ from kibana.connector import Kibana
|
||||
|
||||
from . import attack, rule_loader, utils
|
||||
from .cli_utils import single_collection
|
||||
from .docs import IntegrationSecurityDocs
|
||||
from .docs import IntegrationSecurityDocs, IntegrationSecurityDocsMDX
|
||||
from .endgame import EndgameSchemaManager
|
||||
from .eswrap import CollectEvents, add_range_to_dsl
|
||||
from .ghwrap import GithubClient, update_gist
|
||||
@@ -85,8 +85,9 @@ def dev_group():
|
||||
@click.option('--generate-navigator', is_flag=True, help='Generate ATT&CK navigator files')
|
||||
@click.option('--add-historical', type=str, required=True, default="no",
|
||||
help='Generate historical package-registry files')
|
||||
@click.option('--update-message', type=str, help='Update message for new package')
|
||||
def build_release(config_file, update_version_lock: bool, generate_navigator: bool, add_historical: str,
|
||||
release=None, verbose=True):
|
||||
update_message: str, release=None, verbose=True):
|
||||
"""Assemble all the rules into Kibana-ready release files."""
|
||||
config = load_dump(config_file)['package']
|
||||
add_historical = True if add_historical == "yes" else False
|
||||
@@ -104,7 +105,6 @@ def build_release(config_file, update_version_lock: bool, generate_navigator: bo
|
||||
|
||||
if update_version_lock:
|
||||
default_version_lock.manage_versions(package.rules, save_changes=True, verbose=verbose)
|
||||
|
||||
package.save(verbose=verbose)
|
||||
|
||||
if add_historical:
|
||||
@@ -112,6 +112,11 @@ def build_release(config_file, update_version_lock: bool, generate_navigator: bo
|
||||
sde = SecurityDetectionEngine()
|
||||
historical_rules = sde.load_integration_assets(previous_pkg_version)
|
||||
historical_rules = sde.transform_legacy_assets(historical_rules)
|
||||
|
||||
docs = IntegrationSecurityDocsMDX(config['registry_data']['version'], Path(f'releases/{config["name"]}-docs'),
|
||||
True, historical_rules, package, note=update_message)
|
||||
docs.generate()
|
||||
|
||||
click.echo(f'[+] Adding historical rules from {previous_pkg_version} package')
|
||||
package.add_historical_rules(historical_rules, config['registry_data']['version'])
|
||||
|
||||
|
||||
+459
-2
@@ -10,17 +10,19 @@ import re
|
||||
import shutil
|
||||
import textwrap
|
||||
from collections import defaultdict
|
||||
from dataclasses import asdict, dataclass
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
from typing import Dict, Iterable, Optional, Union
|
||||
from typing import Dict, Iterable, List, Optional, Union
|
||||
|
||||
from semver import Version
|
||||
import xlsxwriter
|
||||
from semver import Version
|
||||
|
||||
from .attack import attack_tm, matrix, tactics, technique_lookup
|
||||
from .packaging import Package
|
||||
from .rule import ThreatMapping, TOMLRule
|
||||
from .rule_loader import DeprecatedCollection, RuleCollection
|
||||
from .utils import load_etc_dump, save_etc_dump
|
||||
|
||||
|
||||
class PackageDocument(xlsxwriter.Workbook):
|
||||
@@ -546,3 +548,458 @@ def name_to_title(name: str) -> str:
|
||||
"""Convert a rule name to tile."""
|
||||
initial = re.sub(r'[^\w]|_', r'-', name.lower().strip())
|
||||
return re.sub(r'-{2,}', '-', initial).strip('-')
|
||||
|
||||
|
||||
@dataclass
|
||||
class UpdateEntry:
|
||||
"""A class schema for downloadable update entries."""
|
||||
update_version: str
|
||||
date: str
|
||||
new_rules: int
|
||||
updated_rules: int
|
||||
note: str
|
||||
url: str
|
||||
|
||||
|
||||
@dataclass
|
||||
class DownloadableUpdates:
|
||||
"""A class for managing downloadable updates."""
|
||||
packages: List[UpdateEntry]
|
||||
|
||||
@classmethod
|
||||
def load_updates(cls):
|
||||
"""Load the package."""
|
||||
prebuilt = load_etc_dump("downloadable_updates.json")
|
||||
packages = [UpdateEntry(**entry) for entry in prebuilt['packages']]
|
||||
return cls(packages)
|
||||
|
||||
def save_updates(self):
|
||||
"""Save the package."""
|
||||
sorted_package = sorted(self.packages, key=lambda entry: Version.parse(entry.update_version), reverse=True)
|
||||
data = {'packages': [asdict(entry) for entry in sorted_package]}
|
||||
save_etc_dump(data, "downloadable_updates.json")
|
||||
|
||||
def add_entry(self, entry: UpdateEntry, overwrite: bool = False):
|
||||
"""Add an entry to the package."""
|
||||
existing_entry_index = -1
|
||||
for index, existing_entry in enumerate(self.packages):
|
||||
if existing_entry.update_version == entry.update_version:
|
||||
if not overwrite:
|
||||
raise ValueError(f"Update version {entry.update_version} already exists.")
|
||||
existing_entry_index = index
|
||||
break
|
||||
|
||||
if existing_entry_index >= 0:
|
||||
self.packages[existing_entry_index] = entry
|
||||
else:
|
||||
self.packages.append(entry)
|
||||
|
||||
|
||||
class MDX:
|
||||
"""A class for generating Markdown content."""
|
||||
|
||||
@classmethod
|
||||
def bold(cls, value: str):
|
||||
"""Return a bold str in Markdown."""
|
||||
return f'**{value}**'
|
||||
|
||||
@classmethod
|
||||
def bold_kv(cls, key: str, value: str):
|
||||
"""Return a bold key-value pair in Markdown."""
|
||||
return f'**{key}**: {value}'
|
||||
|
||||
@classmethod
|
||||
def description_list(cls, value: Dict[str, str], linesep='\n\n'):
|
||||
"""Create a description list in Markdown."""
|
||||
return f'{linesep}'.join(f'**{k}**:\n\n{v}' for k, v in value.items())
|
||||
|
||||
@classmethod
|
||||
def bulleted(cls, value: str, depth=1):
|
||||
"""Create a bulleted list item with a specified depth."""
|
||||
return f'{" " * (depth - 1)}* {value}'
|
||||
|
||||
@classmethod
|
||||
def bulleted_list(cls, values: Iterable):
|
||||
"""Create a bulleted list from an iterable."""
|
||||
return '\n* ' + '\n* '.join(values)
|
||||
|
||||
@classmethod
|
||||
def code(cls, value: str, language='js'):
|
||||
"""Return a code block with the specified language."""
|
||||
return f"```{language}\n{value}```"
|
||||
|
||||
@classmethod
|
||||
def title(cls, depth: int, value: str):
|
||||
"""Create a title with the specified depth."""
|
||||
return f'{"#" * depth} {value}'
|
||||
|
||||
@classmethod
|
||||
def inline_anchor(cls, value: str):
|
||||
"""Create an inline anchor with the specified value."""
|
||||
return f'<a id="{value}" />'
|
||||
|
||||
@classmethod
|
||||
def table(cls, data: dict) -> str:
|
||||
"""Create a table from a dictionary."""
|
||||
entries = [f'| {k} | {v}' for k, v in data.items()]
|
||||
table = ['|---|---|'] + entries
|
||||
return '\n'.join(table)
|
||||
|
||||
|
||||
class IntegrationSecurityDocsMDX:
|
||||
"""Generate docs for prebuilt rules in Elastic documentation using MDX."""
|
||||
|
||||
def __init__(self, release_version: str, directory: Path, overwrite: bool = False,
|
||||
historical_package: Optional[Dict[str, dict]] =
|
||||
None, new_package: Optional[Dict[str, TOMLRule]] = None,
|
||||
note: Optional[str] = "Rule Updates."):
|
||||
self.historical_package = historical_package
|
||||
self.new_package = new_package
|
||||
self.rule_changes = self.get_rule_changes()
|
||||
self.included_rules = list(itertools.chain(self.rule_changes["new"],
|
||||
self.rule_changes["updated"],
|
||||
self.rule_changes["deprecated"]))
|
||||
|
||||
self.release_version_str, self.base_name, self.prebuilt_rule_base = self.parse_release(release_version)
|
||||
self.package_directory = directory / self.base_name
|
||||
self.overwrite = overwrite
|
||||
self.note = note
|
||||
|
||||
if overwrite:
|
||||
shutil.rmtree(self.package_directory, ignore_errors=True)
|
||||
|
||||
self.package_directory.mkdir(parents=True, exist_ok=overwrite)
|
||||
|
||||
@staticmethod
|
||||
def parse_release(release_version: str) -> (str, str, str):
|
||||
"""Parse the release version into a string, base name, and prebuilt rule base."""
|
||||
release_version = Version.parse(release_version)
|
||||
short_release_version = [str(n) for n in release_version[:3]]
|
||||
release_version_str = '.'.join(short_release_version)
|
||||
base_name = "-".join(short_release_version)
|
||||
prebuilt_rule_base = f'prebuilt-rule-{base_name}'
|
||||
|
||||
return release_version_str, base_name, prebuilt_rule_base
|
||||
|
||||
def get_rule_changes(self):
|
||||
"""Compare the rules from the new_package against rules in the historical_package."""
|
||||
|
||||
rule_changes = defaultdict(list)
|
||||
rule_changes["new"], rule_changes["updated"], rule_changes["deprecated"] = [], [], []
|
||||
|
||||
historical_rule_ids = set(self.historical_package.keys())
|
||||
|
||||
# Identify new and updated rules
|
||||
for rule in self.new_package.rules:
|
||||
rule_to_api_format = rule.contents.to_api_format()
|
||||
|
||||
latest_version = rule_to_api_format["version"]
|
||||
rule_id = f'{rule.id}_{latest_version}'
|
||||
|
||||
if rule_id not in historical_rule_ids and latest_version == 1:
|
||||
rule_changes['new'].append(rule)
|
||||
elif rule_id not in historical_rule_ids:
|
||||
rule_changes['updated'].append(rule)
|
||||
|
||||
# Identify deprecated rules
|
||||
# if rule is in the historical but not in the current package, its deprecated
|
||||
deprecated_rule_ids = []
|
||||
for _, content in self.historical_package.items():
|
||||
rule_id = content["attributes"]["rule_id"]
|
||||
if rule_id in self.new_package.deprecated_rules.id_map.keys():
|
||||
deprecated_rule_ids.append(rule_id)
|
||||
|
||||
deprecated_rule_ids = list(set(deprecated_rule_ids))
|
||||
for rule_id in deprecated_rule_ids:
|
||||
rule_changes['deprecated'].append(self.new_package.deprecate_rules.id_map[rule_id])
|
||||
|
||||
return dict(rule_changes)
|
||||
|
||||
def generate_current_rule_summary(self):
|
||||
"""Generate a summary of all available current rules in the latest package."""
|
||||
slug = f'prebuilt-rules-{self.base_name}-all-available-summary.mdx'
|
||||
summary = self.package_directory / slug
|
||||
title = f'Latest rules for Stack Version ^{self.release_version_str}'
|
||||
|
||||
summary_header = textwrap.dedent(f"""
|
||||
---
|
||||
id: {slug}
|
||||
slug: /security-rules/{slug}
|
||||
title: {title}
|
||||
date: {datetime.today().strftime('%Y-%d-%m')}
|
||||
tags: ["rules", "security", "detection-rules"]
|
||||
---
|
||||
|
||||
## {title}
|
||||
This section lists all available rules supporting latest package version {self.release_version_str}
|
||||
and greater of the Fleet integration *Prebuilt Security Detection Rules*.
|
||||
|
||||
| Rule | Description | Tags | Version
|
||||
|---|---|---|---|
|
||||
""").lstrip()
|
||||
|
||||
rule_entries = []
|
||||
for rule in self.new_package.rules:
|
||||
title_name = name_to_title(rule.name)
|
||||
to_api_format = rule.contents.to_api_format()
|
||||
tags = ", ".join(to_api_format["tags"])
|
||||
rule_entries.append(f'| [{title_name}](rules/{self.prebuilt_rule_base}-{name_to_title(rule.name)}.mdx) | '
|
||||
f'{to_api_format["description"]} | {tags} | '
|
||||
f'{to_api_format["version"]}')
|
||||
|
||||
rule_entries = sorted(rule_entries)
|
||||
rule_entries = '\n'.join(rule_entries)
|
||||
|
||||
summary.write_text(summary_header + rule_entries)
|
||||
|
||||
def generate_update_summary(self):
|
||||
"""Generate a summary of all rule updates based on the latest package."""
|
||||
slug = f'prebuilt-rules-{self.base_name}-update-summary.mdx'
|
||||
summary = self.package_directory / slug
|
||||
title = "Current Available Rules"
|
||||
|
||||
summary_header = textwrap.dedent(f"""
|
||||
---
|
||||
id: {slug}
|
||||
slug: /security-rules/{slug}
|
||||
title: {title}
|
||||
date: {datetime.today().strftime('%Y-%d-%m')}
|
||||
tags: ["rules", "security", "detection-rules"]
|
||||
---
|
||||
|
||||
## {title}
|
||||
This section lists all updates associated with version {self.release_version_str}
|
||||
of the Fleet integration *Prebuilt Security Detection Rules*.
|
||||
|
||||
| Rule | Description | Status | Version
|
||||
|---|---|---|---|
|
||||
""").lstrip()
|
||||
|
||||
rule_entries = []
|
||||
new_rule_id_list = [rule.id for rule in self.rule_changes["new"]]
|
||||
updated_rule_id_list = [rule.id for rule in self.rule_changes["updated"]]
|
||||
for rule in self.included_rules:
|
||||
title_name = name_to_title(rule.name)
|
||||
status = 'new' if rule.id in new_rule_id_list else 'update' if rule.id in updated_rule_id_list \
|
||||
else 'deprecated'
|
||||
to_api_format = rule.contents.to_api_format()
|
||||
rule_entries.append(f'| [{title_name}](rules/{self.prebuilt_rule_base}-{name_to_title(rule.name)}.mdx) | '
|
||||
f'{to_api_format["description"]} | {status} | '
|
||||
f'{to_api_format["version"]}')
|
||||
|
||||
rule_entries = sorted(rule_entries)
|
||||
rule_entries = '\n'.join(rule_entries)
|
||||
|
||||
summary.write_text(summary_header + rule_entries)
|
||||
|
||||
def generate_rule_details(self):
|
||||
"""Generate a markdown file for each rule."""
|
||||
rules_dir = self.package_directory / "rules"
|
||||
rules_dir.mkdir(exist_ok=True)
|
||||
for rule in self.new_package.rules:
|
||||
slug = f'{self.prebuilt_rule_base}-{name_to_title(rule.name)}.mdx'
|
||||
rule_detail = IntegrationRuleDetailMDX(rule.id, rule.contents.to_api_format(), {}, self.base_name)
|
||||
rule_path = rules_dir / slug
|
||||
tags = ', '.join(f"\"{tag}\"" for tag in rule.contents.data.tags)
|
||||
frontmatter = textwrap.dedent(f"""
|
||||
---
|
||||
id: {slug}
|
||||
slug: /security-rules/{slug}
|
||||
title: {rule.name}
|
||||
date: {datetime.today().strftime('%Y-%d-%m')}
|
||||
tags: [{tags}]
|
||||
---
|
||||
|
||||
""").lstrip()
|
||||
rule_path.write_text(frontmatter + rule_detail.generate())
|
||||
|
||||
def generate_downloadable_updates_summary(self):
|
||||
"""Generate a summary of all the downloadable updates."""
|
||||
|
||||
docs_url = 'https://www.elastic.co/guide/en/security/current/rules-ui-management.html#download-prebuilt-rules'
|
||||
slug = 'prebuilt-rules-downloadable-packages-summary.mdx'
|
||||
title = "Downloadable rule updates"
|
||||
summary = self.package_directory / slug
|
||||
today = datetime.today().strftime('%d %b %Y')
|
||||
package_list = DownloadableUpdates.load_updates()
|
||||
ref = f"./prebuilt-rules-{self.base_name}-update-summary.mdx"
|
||||
|
||||
# Add a new entry
|
||||
new_entry = UpdateEntry(
|
||||
update_version=self.release_version_str,
|
||||
date=today,
|
||||
new_rules=len(self.rule_changes["new"]),
|
||||
updated_rules=len(self.rule_changes["updated"]),
|
||||
note=self.note,
|
||||
url=ref
|
||||
)
|
||||
package_list.add_entry(new_entry, self.overwrite)
|
||||
|
||||
# Write the updated Package object back to the JSON file
|
||||
package_list.save_updates()
|
||||
|
||||
# generate the summary
|
||||
summary_header = textwrap.dedent(f"""
|
||||
---
|
||||
id: {slug}
|
||||
slug: /security-rules/{slug}
|
||||
title: {title}
|
||||
date: {datetime.today().strftime('%Y-%d-%m')}
|
||||
tags: ["rules", "security", "detection-rules"]
|
||||
---
|
||||
|
||||
## {title}
|
||||
|
||||
This section lists all updates to prebuilt detection rules, made available
|
||||
with the Prebuilt Security Detection Rules integration in Fleet.
|
||||
|
||||
To download the latest updates, follow the instructions in [download-prebuilt-rules]({docs_url})
|
||||
|
||||
|
||||
|Update version |Date | New rules | Updated rules | Notes
|
||||
|---|---|---|---|---|
|
||||
""").lstrip()
|
||||
|
||||
entries = []
|
||||
for entry in sorted(package_list.packages, key=lambda entry: Version.parse(entry.update_version), reverse=True):
|
||||
entries.append(f'| [{entry.update_version}]({entry.url}) | {today} |'
|
||||
f' {entry.new_rules} | {entry.updated_rules} | {entry.note}| ')
|
||||
|
||||
entries = '\n'.join(entries)
|
||||
summary.write_text(summary_header + entries)
|
||||
|
||||
def generate(self) -> Path:
|
||||
"""Generate the updates."""
|
||||
|
||||
# generate all the rules as markdown files
|
||||
self.generate_rule_details()
|
||||
|
||||
# generate the rule summary of changes within a package
|
||||
self.generate_update_summary()
|
||||
|
||||
# generate the package summary that lists all downloadable packages
|
||||
self.generate_downloadable_updates_summary()
|
||||
|
||||
# generate the overview that lists all current available rules
|
||||
self.generate_current_rule_summary()
|
||||
|
||||
return self.package_directory
|
||||
|
||||
|
||||
class IntegrationRuleDetailMDX:
|
||||
"""Generates a rule detail page in Markdown."""
|
||||
|
||||
def __init__(self, rule_id: str, rule: dict, changelog: Dict[str, dict], package_str: str):
|
||||
"""Initialize with rule ID, rule details, changelog, and package string.
|
||||
|
||||
>>> rule_file = "/path/to/rule.toml"
|
||||
>>> rule = RuleCollection().load_file(Path(rule_file))
|
||||
>>> rule_detail = IntegrationRuleDetailMDX(rule.id, rule.contents.to_api_format(), {}, "test")
|
||||
>>> rule_detail.generate()
|
||||
|
||||
"""
|
||||
self.rule_id = rule_id
|
||||
self.rule = rule
|
||||
self.changelog = changelog
|
||||
self.package = package_str
|
||||
self.rule_title = f'prebuilt-rule-{self.package}-{name_to_title(self.rule["name"])}'
|
||||
|
||||
# set some defaults
|
||||
self.rule.setdefault('max_signals', 100)
|
||||
self.rule.setdefault('interval', '5m')
|
||||
|
||||
def generate(self) -> str:
|
||||
"""Generate the rule detail page in Markdown."""
|
||||
page = [
|
||||
MDX.title(1, self.rule["name"]),
|
||||
'',
|
||||
self.rule['description'],
|
||||
'',
|
||||
self.metadata_str(),
|
||||
''
|
||||
]
|
||||
if 'note' in self.rule:
|
||||
page.extend([self.guide_str(), ''])
|
||||
if 'query' in self.rule:
|
||||
page.extend([self.query_str(), ''])
|
||||
if 'threat' in self.rule:
|
||||
page.extend([self.threat_mapping_str(), ''])
|
||||
|
||||
return '\n'.join(page)
|
||||
|
||||
def metadata_str(self) -> str:
|
||||
"""Generate the metadata section for the rule detail page."""
|
||||
|
||||
date_math_doc = "https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#date-math"
|
||||
loopback_doc = "https://www.elastic.co/guide/en/security/current/rules-ui-create.html#rule-schedule"
|
||||
fields = {
|
||||
'type': 'Rule type',
|
||||
'index': 'Rule indices',
|
||||
'severity': 'Severity',
|
||||
'risk_score': 'Risk score',
|
||||
'interval': 'Runs every',
|
||||
'from': 'Searches indices from',
|
||||
'max_signals': 'Maximum alerts per execution',
|
||||
'references': 'References',
|
||||
'tags': 'Tags',
|
||||
'version': 'Version',
|
||||
'author': 'Rule authors',
|
||||
'license': 'Rule license'
|
||||
}
|
||||
values = []
|
||||
|
||||
for field, friendly_name in fields.items():
|
||||
value = self.rule.get(field) or self.changelog.get(field)
|
||||
if isinstance(value, list):
|
||||
str_value = MDX.bulleted_list(value)
|
||||
else:
|
||||
str_value = str(value)
|
||||
|
||||
if field == 'from':
|
||||
str_value += f' ([Date Math format]({date_math_doc}), [Additional look-back time]({loopback_doc}))'
|
||||
|
||||
values.append(MDX.bold_kv(friendly_name, str_value))
|
||||
|
||||
return '\n\n'.join(values)
|
||||
|
||||
def guide_str(self) -> str:
|
||||
"""Generate the investigation guide section for the rule detail page."""
|
||||
return f'{MDX.title(2, "Investigation guide")}\n\n{MDX.code(self.rule["note"], "markdown")}'
|
||||
|
||||
def query_str(self) -> str:
|
||||
"""Generate the rule query section for the rule detail page."""
|
||||
return f'{MDX.title(2, "Rule query")}\n\n{MDX.code(self.rule["query"], "sql")}'
|
||||
|
||||
def threat_mapping_str(self) -> str:
|
||||
"""Generate the threat mapping section for the rule detail page."""
|
||||
values = [MDX.bold_kv('Framework', 'MITRE ATT&CK^TM^')]
|
||||
|
||||
for entry in self.rule['threat']:
|
||||
tactic = entry['tactic']
|
||||
entry_values = [
|
||||
MDX.bulleted(MDX.bold('Tactic:')),
|
||||
MDX.bulleted(f'Name: {tactic["name"]}', depth=2),
|
||||
MDX.bulleted(f'ID: {tactic["id"]}', depth=2),
|
||||
MDX.bulleted(f'Reference URL: {tactic["reference"]}', depth=2)
|
||||
]
|
||||
techniques = entry.get('technique', [])
|
||||
for technique in techniques:
|
||||
entry_values.extend([
|
||||
MDX.bulleted('Technique:'),
|
||||
MDX.bulleted(f'Name: {technique["name"]}', depth=3),
|
||||
MDX.bulleted(f'ID: {technique["id"]}', depth=3),
|
||||
MDX.bulleted(f'Reference URL: {technique["reference"]}', depth=3)
|
||||
])
|
||||
|
||||
subtechniques = technique.get('subtechnique', [])
|
||||
for subtechnique in subtechniques:
|
||||
entry_values.extend([
|
||||
MDX.bulleted('Sub-technique:'),
|
||||
MDX.bulleted(f'Name: {subtechnique["name"]}', depth=3),
|
||||
MDX.bulleted(f'ID: {subtechnique["id"]}', depth=3),
|
||||
MDX.bulleted(f'Reference URL: {subtechnique["reference"]}', depth=4)
|
||||
])
|
||||
|
||||
values.extend(entry_values)
|
||||
|
||||
return '\n'.join(values)
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
{
|
||||
"packages": [
|
||||
{
|
||||
"date": "15 Feb 2023",
|
||||
"new_rules": 29,
|
||||
"note": "This release includes new rules for Windows and Linux endpoints. Additionally, significant rule tuning for Windows and Linux rules has been added for better rule efficacy. A Google Workspace promotional rule was added to promote security alerts from the Alert Center. Machine learning rules related to failed logins have been adjusted for better scoring results. Additional investigation guides have been added for Windows and Linux rules. A New Terms rule has been created to identify loaded Windows drivers not seen in the last 30 days. A guided onboarding rule has been created to assist new SIEM users with getting started.",
|
||||
"update_version": "8.7.1",
|
||||
"updated_rules": 110,
|
||||
"url": "https://www.elastic.co/guide/en/security/current/prebuilt-rule-8-7-1-prebuilt-rules-8-7-1-summary.html"
|
||||
},
|
||||
{
|
||||
"date": "15 Feb 2023",
|
||||
"new_rules": 28,
|
||||
"note": "This release includes new rules for Windows and Linux endpoints. Additionally, significant rule tuning for Windows and Linux rules has been added for better rule efficacy. A Google Workspace promotional rule was added to promote security alerts from the Alert Center. Machine learning rules related to failed logins have been adjusted for better scoring results. Additional investigation guides have been added for Windows and Linux rules. A New Terms rule has been created to identify loaded Windows drivers not seen in the last 30 days.",
|
||||
"update_version": "8.6.1",
|
||||
"updated_rules": 110,
|
||||
"url": "https://www.elastic.co/guide/en/security/current/prebuilt-rule-8-6-1-prebuilt-rules-8-6-1-summary.html"
|
||||
},
|
||||
{
|
||||
"date": "14 Feb 2023",
|
||||
"new_rules": 27,
|
||||
"note": "This release includes new rules for Windows and Linux endpoints. Additionally, significant rule tuning for Windows and Linux rules has been added for better rule efficacy. A Google Workspace promotional rule was added to promote security alerts from the Alert Center. Machine learning rules related to failed logins have been adjusted for better scoring results. Additional investigation guides have been added for Windows and Linux rules.",
|
||||
"update_version": "8.5.1",
|
||||
"updated_rules": 110,
|
||||
"url": "https://www.elastic.co/guide/en/security/current/prebuilt-rule-8-5-1-prebuilt-rules-8-5-1-summary.html"
|
||||
},
|
||||
{
|
||||
"date": "14 Feb 2023",
|
||||
"new_rules": 27,
|
||||
"note": "This release includes new rules for Windows and Linux endpoints. Additionally, significant rule tuning for Windows and Linux rules has been added for better rule efficacy. A Google Workspace promotional rule was added to promote security alerts from the Alert Center. Machine learning rules related to failed logins have been adjusted for better scoring results. Additional investigation guides have been added for Windows and Linux rules.",
|
||||
"update_version": "8.4.3",
|
||||
"updated_rules": 110,
|
||||
"url": "https://www.elastic.co/guide/en/security/current/prebuilt-rule-8-4-3-prebuilt-rules-8-4-3-summary.html"
|
||||
},
|
||||
{
|
||||
"date": "24 Jan 2023",
|
||||
"new_rules": 5,
|
||||
"note": "This release includes new rules for Windows regarding Microsoft Exchange interaction via Powershell. Additionally, significant rule tuning for Windows rules has been added for better rule efficacy. A new rule for multiple alerts with different ATT&CK tactics on a single host has also been included. A new rule for multiple alerts involving a single user has been added. Related integration tags and recommended versions have been added to endpoint rules. Bug fixes for OSQuery execution in rule investigation guides has been added.",
|
||||
"update_version": "8.4.2",
|
||||
"updated_rules": 494,
|
||||
"url": "https://www.elastic.co/guide/en/security/current/prebuilt-rule-8-4-2-prebuilt-rules-8-4-2-summary.html"
|
||||
},
|
||||
{
|
||||
"date": "05 Dec 2022",
|
||||
"new_rules": 20,
|
||||
"note": "This release includes new rules for Linux regarding reverse shells. Additionally, new windows rules have been added to supply coverage for credential access and access token manipulation. Specific Windows and Linux rules have been tuned to reduce false-positive signals.",
|
||||
"update_version": "8.4.1",
|
||||
"updated_rules": 298,
|
||||
"url": "https://www.elastic.co/guide/en/security/current/prebuilt-rule-8-4-1-prebuilt-rules-8-4-1-summary.html"
|
||||
},
|
||||
{
|
||||
"date": "24 Jan 2023",
|
||||
"new_rules": 1,
|
||||
"note": "This release includes new rules for Windows regarding Microsoft Exchange interaction via PowerShell. A new rule for multiple alerts with different ATT&CK tactics on a single host has also been included. Additionally, a new rule for multiple alerts involving a single user has been added. This release also includes rule tuning for suspicious Windows Error Reporting child processes.",
|
||||
"update_version": "8.3.4",
|
||||
"updated_rules": 4,
|
||||
"url": "https://www.elastic.co/guide/en/security/current/prebuilt-rule-8-3-4-prebuilt-rules-8-3-4-summary.html"
|
||||
},
|
||||
{
|
||||
"date": "19 Jan 2023",
|
||||
"new_rules": 17,
|
||||
"note": "This release includes new rules for Windows regarding Microsoft Exchange interaction via PowerShell. Additionally, significant rule tuning for Windows rules has been added for better rule efficacy. Related integration tags and recommended versions have been added to endpoint rules. Bug fixes for OSQuery execution in rule investigation guides has been added.",
|
||||
"update_version": "8.3.3",
|
||||
"updated_rules": 500,
|
||||
"url": "https://www.elastic.co/guide/en/security/current/prebuilt-rule-8-3-3-prebuilt-rules-8-3-3-summary.html"
|
||||
},
|
||||
{
|
||||
"date": "06 Oct 2022",
|
||||
"new_rules": 25,
|
||||
"note": "This release includes new rules for Linux, Windows, Google Workspace and Kubernetes. Also included are expanded investigation guides for Linux, Windows and macOS rules.",
|
||||
"update_version": "8.3.2",
|
||||
"updated_rules": 232,
|
||||
"url": "https://www.elastic.co/guide/en/security/current/prebuilt-rule-8-3-2-prebuilt-rules-8-3-2-summary.html"
|
||||
},
|
||||
{
|
||||
"date": "26 Aug 2022",
|
||||
"new_rules": 0,
|
||||
"note": "This release includes new rules for Linux, Windows, Google Workspace and Kubernetes. Also included are expanded investigation and setup guides for Linux, Windows and macOS rules. Rule compatibility for required event fields and related Fleet integrations has also been included.",
|
||||
"update_version": "8.3.1",
|
||||
"updated_rules": 113,
|
||||
"url": "https://www.elastic.co/guide/en/security/current/prebuilt-rule-8-3-1-prebuilt-rules-8-3-1-summary.html"
|
||||
},
|
||||
{
|
||||
"date": "24 Aug 2022",
|
||||
"new_rules": 442,
|
||||
"note": "This release includes new rules for Windows, MacOS, Linux, Kubernetes, and considerable tuning efforts. Also included are expanded investigation guides for Windows, Azure and AWS rules.",
|
||||
"update_version": "8.2.1",
|
||||
"updated_rules": 96,
|
||||
"url": "https://www.elastic.co/guide/en/security/current/prebuilt-rule-8-2-1-prebuilt-rules-8-2-1-summary.html"
|
||||
},
|
||||
{
|
||||
"date": "24 Jun 2022",
|
||||
"new_rules": 14,
|
||||
"note": "This release includes new rules for Windows, MacOS, Linux and Kubernetes. Also included are expanded investigation guides for Windows rules. Additionally, this update includes new rules to help detect emerging threat BPFDoor. Updates to existing Windows rules were made to help detect exploitation attempts against CVE-2022-30190.",
|
||||
"update_version": "8.1.1",
|
||||
"updated_rules": 159,
|
||||
"url": "https://www.elastic.co/guide/en/security/current/prebuilt-rule-8-1-1-prebuilt-rules-8-1-1-summary.html"
|
||||
},
|
||||
{
|
||||
"date": "03 May 2022",
|
||||
"new_rules": 42,
|
||||
"note": "This release includes new rules for MacOS regarding initial access and persistence coverage. New rules to detect shell evasion in Linux have also been added. Also included are expanded investigation guides for Windows rules as well as new rules for credential theft and Active Directory (AD). Additionally, this update includes new rules to help detect the emerging threat CVE-2022-0847 (Dirty Pipe).",
|
||||
"update_version": "1.0.2",
|
||||
"updated_rules": 341,
|
||||
"url": "https://www.elastic.co/guide/en/security/current/prebuilt-rule-1-0-2-prebuilt-rules-1-0-2-summary.html"
|
||||
},
|
||||
{
|
||||
"date": "13 Dec 2021",
|
||||
"new_rules": 35,
|
||||
"note": "This release includes an update to an existing rule and adds a new rule to help detect CVE-2021-44228 (log4j2). Also included are updates and new rules for cloud integrations, windows, PowerShell, and others.",
|
||||
"update_version": "0.14.3",
|
||||
"updated_rules": 45,
|
||||
"url": "https://www.elastic.co/guide/en/security/current/prebuilt-rule-0-14-3-prebuilt-rules-0-14-3-summary.html"
|
||||
},
|
||||
{
|
||||
"date": "15 Oct 2021",
|
||||
"new_rules": 18,
|
||||
"note": "This release includes rules covering Windows endpoints, as well as several third-party integrations \u2014 including rules contributed by the community.",
|
||||
"update_version": "0.14.2",
|
||||
"updated_rules": 89,
|
||||
"url": "https://www.elastic.co/guide/en/security/current/prebuilt-rule-0-14-2-prebuilt-rules-0-14-2-summary.html"
|
||||
},
|
||||
{
|
||||
"date": "08 Sep 2021",
|
||||
"new_rules": 3,
|
||||
"note": "Included in this release is a rule to detect web shells, including ProxyShell activity.",
|
||||
"update_version": "0.14.1",
|
||||
"updated_rules": 71,
|
||||
"url": "https://www.elastic.co/guide/en/security/current/prebuilt-rule-0-14-1-prebuilt-rules-0-14-1-summary.html"
|
||||
},
|
||||
{
|
||||
"date": "22 Jul 2021",
|
||||
"new_rules": 4,
|
||||
"note": "Included in this release is a rule for Windows Defender Exclusions, which has been used in recent campaigns, as well as a rule to resiliently detect parent PID spoofing.",
|
||||
"update_version": "0.13.3",
|
||||
"updated_rules": 36,
|
||||
"url": "https://www.elastic.co/guide/en/security/current/prebuilt-rule-0-13-3-prebuilt-rules-0-13-3-summary.html"
|
||||
},
|
||||
{
|
||||
"date": "07 Jul 2021",
|
||||
"new_rules": 15,
|
||||
"note": "Included in this release are 3 new rules for the recently observed REvil activity as well as 4 new rules covering the recent PrintNightmare vulnerability.",
|
||||
"update_version": "0.13.2",
|
||||
"updated_rules": 6,
|
||||
"url": "https://www.elastic.co/guide/en/security/current/prebuilt-rule-0-13-2-prebuilt-rules-0-13-2-summary.html"
|
||||
},
|
||||
{
|
||||
"date": "21 Jun 2021",
|
||||
"new_rules": 4,
|
||||
"note": "",
|
||||
"update_version": "0.13.1",
|
||||
"updated_rules": 41,
|
||||
"url": "https://www.elastic.co/guide/en/security/current/prebuilt-rule-0-13-1-prebuilt-rules-0-13-1-summary.html"
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user