in src/Elastic.Markdown/Extensions/DetectionRules/DetectionRuleFile.cs [136:222]
private string GetMarkdown()
{
if (Rule is null)
return $"# {Title}";
// language=markdown
var markdown =
$"""
# {Rule.Name}
{Rule.Description}
**Rule type**: {Rule.Type}<br>
**Rule indices**: {RenderArray(Rule.Indices)}
**Rule Severity**: {Rule.Severity}<br>
**Risk Score**: {Rule.RiskScore}<br>
**Runs every**: {Rule.RunsEvery}<br>
**Searches indices from**: `{Rule.IndicesFromDateMath}`<br>
**Maximum alerts per execution**: {Rule.MaximumAlertsPerExecution}<br>
**References**: {RenderArray((Rule.References ?? []).Select(r => $"[{r}]({r})").ToArray())}
**Tags**: {RenderArray(Rule.Tags)}
**Version**: {Rule.Version}<br>
**Rule authors**: {RenderArray(Rule.Authors)}
**Rule license**: {Rule.License}<br>
""";
// language=markdown
if (!string.IsNullOrWhiteSpace(Rule.Setup))
{
markdown +=
$"""
{Rule.Setup}
""";
}
// language=markdown
if (!string.IsNullOrWhiteSpace(Rule.Note))
{
markdown +=
$"""
## Investigation guide
{Rule.Note}
""";
}
// language=markdown
if (!string.IsNullOrWhiteSpace(Rule.Query))
{
markdown +=
$"""
## Rule Query
```{Rule.Language ?? Rule.Type}
{Rule.Query}
```
""";
}
foreach (var threat in Rule.Threats)
{
// language=markdown
markdown +=
$"""
**Framework:** {threat.Framework}
* Tactic:
* Name: {threat.Tactic.Name}
* Id: {threat.Tactic.Id}
* Reference URL: [{threat.Tactic.Reference}]({threat.Tactic.Reference})
""";
foreach (var technique in threat.Techniques)
{
// language=markdown
markdown += TechniqueMarkdown(technique, "Technique");
foreach (var subTechnique in technique.SubTechniques)
markdown += TechniqueMarkdown(subTechnique, "Sub Technique");
}
}
return markdown;
}