Hayabusa is a Windows event log fast forensics timeline generator and threat hunting tool.
This artifact runs Hayabusa on the endpoint against the specified Windows event log directory, and generates and uploads a single CSV/JSONL file for further analysis with excel, timeline explorer, elastic stack, jq, etc.
name: Windows.EventLogs.Hayabusa
description: |
[Hayabusa](https://github.com/Yamato-Security/hayabusa) is a
Windows event log fast forensics timeline generator and threat
hunting tool.
This artifact runs Hayabusa on the endpoint against the specified
Windows event log directory, and generates and uploads a single CSV/JSONL
file for further analysis with excel, timeline explorer, elastic
stack, jq, etc.
author: Eric Capuano - @eric_capuano, Whitney Champion - @shortxstack, Zach Mathis - @yamatosecurity, Fukusuke Takahashi - @fukusuket
tools:
- name: Hayabusa-2.18.0
url: https://github.com/Yamato-Security/hayabusa/releases/download/v2.18.0/hayabusa-2.18.0-win-x64-live-response.zip
expected_hash: f52d51f62bb3b4cb4a6e9f66716d024e022f22a3c9b0c44386ee25d67853668a
version: 2.18.0
precondition: SELECT OS From info() where OS = 'windows'
parameters:
- name: EvtxDirectory
description: "Directory of .evtx files"
default: C:/Windows/System32/winevt/Logs
- name: MinimalLevel
description: "Minimum level for rules"
default: medium
type: choices
choices:
- informational
- low
- medium
- high
- critical
- name: OutputFormat
description: "Choose the format of the result file"
default: csv
type: choices
choices:
- csv
- jsonl
- name: OutputProfile
description: "Decide how much data you want back"
default: standard
type: choices
choices:
- minimal
- standard
- verbose
- all-field-info
- all-field-info-verbose
- super-verbose
- timesketch-minimal
- timesketch-verbose
- name: OutputTimeFormat
description: "Choose the format of timestamp"
default: ISO-8601
type: choices
choices:
- European-time
- ISO-8601
- RFC-2822
- RFC-3339
- US-military-time
- US-time
- UTC
- name: Threads
description: "Number of threads"
type: int
default: 4
- name: UpdateRules
description: "Update rules before scanning"
type: bool
default: Y
- name: SortEvents
description: "Sort events before saving the file"
type: bool
default: N
- name: NoisyRules
description: "Enable rules marked as noisy"
type: bool
default: N
- name: EIDFilter
description: "Scan only common Event IDs for quicker scans"
type: bool
default: N
- name: TimelineOffset
description: "Scan recent events based on an offset (ex: 1y, 3M, 30d, 24h, 30m)"
- name: TimelineStart
description: "Start time of the event logs to load (ex: '2020-02-22 00:00:00 +09:00')"
- name: TimelineEnd
description: "End time of the event logs to load (ex: '2022-02-22 23:59:59 +09:00')"
- name: ExcludeCategory
description: "Do not load rules with specified logsource categories (ex: process_creation,pipe_created)"
- name: ExcludeEID
description: "Do not scan specific EIDs for faster speed (ex: 1) (ex: 1,4688)"
- name: ExcludeStatus
description: "Do not load rules according to status (ex: experimental) (ex: stable,test)"
- name: ExcludeTag
description: "Do not load rules with specific tags (ex: sysmon)"
- name: IncludeCategory
description: "Only load rules with specified logsource categories (ex: process_creation,pipe_created)"
- name: IncludeEID
description: "Scan only specified EIDs for faster speed (ex: 1) (ex: 1,4688)"
- name: IncludeTag
description: "Only load rules with specific tags (ex: attack.execution,attack.discovery)"
sources:
- name: Upload
query: |
-- Fetch the binary
LET Toolzip <= SELECT FullPath
FROM Artifact.Generic.Utils.FetchBinary(ToolName="Hayabusa-2.18.0", IsExecutable=FALSE)
LET TmpDir <= tempdir()
-- Unzip the binary
LET _ <= SELECT *
FROM unzip(filename=Toolzip.FullPath, output_directory=TmpDir)
LET HayabusaExe <= TmpDir + '\\hayabusa-2.18.0-win-x64.exe'
-- Optionally update the rules
LET _ <= if(condition=UpdateRules, then={
SELECT * FROM execve(argv=[HayabusaExe, 'update-rules'], cwd=TmpDir) })
LET HayabusaCmd <= if(condition=OutputFormat = "csv", then="csv-timeline", else="json-timeline")
LET ResultFile <= TmpDir + '\\hayabusa_results.' + OutputFormat
-- Build the command line considering all options
-- If it does not match if(condition...), it returns Null, so remove Null with filter(....regex=".+")
LET cmdline <= filter(list=(
HayabusaExe, HayabusaCmd,
"--no-wizard",
"--quiet", "--no-summary",
"--directory", EvtxDirectory,
"--output", ResultFile,
"--min-level", MinimalLevel,
"--profile", OutputProfile,
"--" + OutputTimeFormat,
"--threads", str(str=Threads),
if(condition=OutputFormat = "jsonl", then="-L"),
if(condition=SortEvents, then="--sort-events"),
if(condition=NoisyRules, then="--enable-noisy-rules"),
if(condition=EIDFilter, then="--eid-filter"),
if(condition=TimelineOffset, then="--timeline-offset"), if(condition=TimelineOffset, then=TimelineOffset),
if(condition=TimelineStart, then="--timeline-start"), if(condition=TimelineStart, then=TimelineStart),
if(condition=TimelineEnd, then="--timeline-end"), if(condition=TimelineEnd, then=TimelineEnd),
if(condition=ExcludeCategory, then="--exclude-category"), if(condition=ExcludeCategory, then=ExcludeCategory),
if(condition=ExcludeEID, then="--exclude-eid"), if(condition=ExcludeEID, then=ExcludeEID),
if(condition=ExcludeStatus, then="--exclude-status"), if(condition=ExcludeStatus, then=ExcludeStatus),
if(condition=ExcludeTag, then="--exclude-tag"), if(condition=ExcludeTag, then=ExcludeTag),
if(condition=IncludeCategory, then="--include-category"), if(condition=IncludeCategory, then=IncludeCategory),
if(condition=IncludeEID, then="--include-eid"), if(condition=IncludeEID, then=IncludeEID),
if(condition=IncludeTag, then="--include-tag"), if(condition=IncludeTag, then=IncludeTag),
), regex=".+")
-- Run the tool and divert messages to logs.
LET ExecHB <= SELECT *
FROM execve(argv=cmdline, cwd=TmpDir, sep="\n", length=9999999)
WHERE log(message=Stdout)
-- Upload the raw file.
SELECT upload(file=ResultFile) AS Uploads FROM scope()
- name: Results
query: |
LET CSV_RESULT = SELECT * FROM parse_csv(filename=ResultFile)
LET JSONL_RESULT = SELECT * FROM parse_jsonl(filename=ResultFile)
LET s = scope()
SELECT *, timestamp(string=s.Timestamp || s.datetime) AS EventTime
FROM if(condition= OutputFormat = "csv", then=CSV_RESULT, else=JSONL_RESULT)