Write a Sigma rule and run it
Sigma is the shared YAML format detection engineers use to describe an attack once and run it on any SIEM. TB's detect library reads a practical subset of it. You'll load a rule, write your own, and run a whole folder of rules over Linux, web and Windows logs, all in your browser.
1.Read a Sigma rule
TB comes with a few sample rules in apps/data/sigma. Here is the SSH brute-force one.
import fs
say(fs.read("apps/data/sigma/ssh_brute_force.yml"))
The detection part says what to match (selection) and when to fire (condition): more than ten matches from one IP within five minutes.
2.Run it over a log
detect.sigma loads a rule from a file (or from text). detect.run runs a list of rules over records.
import logs
import detect
let rule = detect.sigma("apps/data/sigma/ssh_brute_force.yml")
say(rule.name, "/", rule.level)
let records = logs.read("apps/data/auth.log", "auth")
for alert in detect.run([rule], records) {
say(f"{alert.level}: {alert.rule} from {alert.by}, {alert.count} times")
}
3.Write your own rule
Field modifiers like |contains, |startswith and |endswith match part of a value. This rule catches path traversal in web requests.
import logs
import detect
let yaml = [
"title: Path traversal in a web request",
"level: high",
"detection:",
" selection:",
" path|contains: '../'",
" condition: selection",
].join("\n")
let records = logs.read("apps/data/access.log", "apache")
for alert in detect.run([detect.sigma(yaml)], records) {
for r in alert.records {
say(r.when, r.ip, r.status, r.path)
}
}
4.Windows events
The same rules work on Windows Security events exported as JSON or CSV. This one looks for PowerShell started with a hidden, base64-encoded command, and encode.unbase64 shows what it really said.
import logs
import detect
import encode
import re
let rule = detect.sigma("apps/data/sigma/win_encoded_powershell.yml")
let records = logs.read("apps/data/windows_security.json", "windows")
for alert in detect.run([rule], records) {
let cmd = alert.records[0].command_line
say(alert.level, alert.rule)
let blob = re.match("-[eE]nc\\w* (?P<b64>\\S+)", cmd)
if blob != nil {
say("Decoded:", encode.unbase64(blob.b64, "utf-16le"))
}
}
5.Run a whole folder
Real detection is many rules at once. detect.sigma_folder loads every .yml in a folder.
import logs
import detect
import report
let rules = detect.sigma_folder("apps/data/sigma")
let records = logs.read("apps/data/windows_security.json", "windows")
let alerts = detect.run(rules, records)
say(report.table(alerts, ["level", "rule", "count", "first_when"]))
Where next
The Sigma runner app runs a folder of rules over any log files from the command line. The detect reference lists the supported Sigma features and TB's own rule maps, which can do everything shown here without YAML.