Skip to content

Commit 94cb6fb

Browse files
authored
Added a documentation site (#27)
Refactored SQLiteHunter: 1. It is now possible to acquire only a single rules based on regex match 2. Notebooks are created lazily to avoid having to calculate many cells at creation time. 3. Notebook cell automatically adds new cells at the top for sources with results.
1 parent 4f5ee50 commit 94cb6fb

61 files changed

Lines changed: 2380 additions & 464 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/gh-pages.yml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
name: github pages
2+
3+
on:
4+
push:
5+
branches:
6+
- main # Set a branch to deploy
7+
pull_request:
8+
9+
jobs:
10+
deploy:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
14+
with:
15+
submodules: true # Fetch Hugo themes (true OR recursive)
16+
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod
17+
18+
- uses: actions/setup-go@93397bea11091df50f3d7e59dc26a7711a8bcfbe
19+
with:
20+
go-version: '^1.23'
21+
22+
- run: go version
23+
24+
- name: Setup Hugo
25+
uses: peaceiris/actions-hugo@v2
26+
with:
27+
hugo-version: 'latest'
28+
extended: true
29+
30+
- name: Prepare
31+
run: |
32+
make build compile
33+
cp output/SQLiteHunter.zip ./docs/static/
34+
35+
- name: Build
36+
run: cd docs/ && hugo --minify
37+
38+
- name: Deploy
39+
uses: peaceiris/actions-gh-pages@v3
40+
if: github.ref == 'refs/heads/master'
41+
with:
42+
github_token: ${{ secrets.GITHUB_TOKEN }}
43+
publish_dir: ./docs/public
44+
force_orphan: true

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
velociraptor*
22
sqlitehunter_compiler*
3-
datastore
3+
datastore
4+
output/*.zip

.pyspelling.yml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
matrix:
2+
- name: Markdown
3+
aspell:
4+
lang: en
5+
d: en_US
6+
dictionary:
7+
wordlists:
8+
- .wordlist.txt
9+
output: .wordlist.dict
10+
sources:
11+
- 'docs/content/**/*.md'
12+
pipeline:
13+
- pyspelling.filters.context:
14+
context_visible_first: true
15+
escapes: '\\[\\`]'
16+
delimiters:
17+
# Ignore multiline content between fences (fences can have 3 or more back ticks)
18+
# ```
19+
# content
20+
# ```
21+
- open: '(?s)^(?P<open> *`{3,})'
22+
close: '^(?P=open)$'
23+
# Insides of URL links
24+
- open: '\]\('
25+
close: '\)'
26+
# Bolded words are usually terms
27+
- open: '[*]+'
28+
close: '[*]+'
29+
# Inside HTML tags
30+
- open: '(?s)(?P<open>[<])'
31+
close: '[>]'
32+
# Ignore text between inline back ticks
33+
- open: '(?P<open>`+)'
34+
close: '(?P=open)'
35+
36+
# Inside yaml headers
37+
- open: '(?s)^(?P<open>---)$'
38+
close: '^(?P=open)$'
39+
40+
- pyspelling.filters.url:

.wordlist.dict

608 Bytes
Binary file not shown.

.wordlist.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# docs/content/_index.md
2+
SQLiteHunter
3+
4+
<url-free> docs/content/docs/sqlite_hunter/_index.md
5+
MacOS
6+
SQLECmd
7+
SQLiteHunter
8+
VQL
9+
Velociraptor
10+
YAML
11+
journaling
12+
SQLite
13+
Velociraptor
14+
de
15+
facto

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ windows:
88
go build -o sqlitehunter_compiler.exe ./bin/*.go
99

1010
compile: FORCE
11-
./sqlitehunter_compiler -config ./config.yaml -definition_directory ./definitions > output/SQLiteHunter.yaml
11+
./sqlitehunter_compiler compile ./definitions/ ./output/SQLiteHunter.yaml --output_zip ./output/SQLiteHunter.zip --index ./docs/content/docs/rules/index.json
1212

1313
golden: compile
1414
./testing/velociraptor.bin --definitions ./output --config ./testing/test.config.yaml golden --env testFiles=`pwd`/test_files ./testing/testcases -v --filter=${GOLDEN}

api/api.go

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,34 @@ type ConfigDefinitions struct {
55
}
66

77
type Definition struct {
8-
Name string `yaml:"Name"`
9-
Author string `yaml:"Author"`
10-
Description string `yaml:"Description"`
11-
Email string `yaml:"Email"`
12-
Reference string `yaml:"Reference"`
13-
Categories []string `yaml:"Categories"`
14-
SQLiteIdentifyQuery string `yaml:"SQLiteIdentifyQuery"`
15-
SQLiteIdentifyValue interface{} `yaml:"SQLiteIdentifyValue"`
16-
Globs []string `yaml:"Globs"`
17-
FilenameRegex string `yaml:"FilenameRegex"`
18-
Sources []Source `yaml:"Sources"`
8+
Name string `yaml:"Name" json:"Name,omitempty"`
9+
Author string `yaml:"Author" json:"Author,omitempty"`
10+
Description string `yaml:"Description" json:"Description,omitempty"`
11+
Email string `yaml:"Email" json:"Email,omitempty"`
12+
Reference string `yaml:"Reference" json:"Reference,omitempty"`
13+
Categories []string `yaml:"Categories" json:"Categories,omitempty"`
14+
SQLiteIdentifyQuery string `yaml:"SQLiteIdentifyQuery" json:"SQLiteIdentifyQuery,omitempty"`
15+
SQLiteIdentifyValue interface{} `yaml:"SQLiteIdentifyValue" json:"SQLiteIdentifyValue,omitempty"`
16+
Globs []string `yaml:"Globs" json:"Globs,omitempty"`
17+
FilenameRegex string `yaml:"FilenameRegex" json:"FilenameRegex,omitempty"`
18+
Sources []Source `yaml:"Sources" json:"Sources,omitempty"`
19+
20+
Filename_ string `yaml:"Filename" json:"Filename,omitempty"`
21+
RawData_ string `yaml:"RawData" json:"RawData,omitempty"`
1922
}
2023

2124
type Source struct {
2225
Name string `yaml:"name"`
26+
27+
// VQL to include prior to the VQL query - for example contains
28+
// custom VQL functions
29+
Preamble string `yaml:"Preamble" json:"Preamble,omitempty"`
30+
2331
// Specialized VQL to post process the rows. Default is a
2432
// passthrough `SELECT * FROM Rows`
25-
VQL string `yaml:"VQL"`
26-
SQL string `yaml:"SQL"`
27-
SQLiteIdentifyQuery string `json:"id_query"`
28-
SQLiteIdentifyValue interface{} `json:"id_value"`
29-
Filename string `json:"filename"`
33+
VQL string `yaml:"VQL" json:"VQL,omitempty"`
34+
SQL string `yaml:"SQL" json:"SQL,omitempty"`
35+
SQLiteIdentifyQuery string `json:"id_query,omitempty"`
36+
SQLiteIdentifyValue interface{} `json:"id_value,omitempty"`
37+
Filename string `json:"filename,omitempty"`
3038
}

api/spec.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@ type GlobSpec struct {
1515
Glob string `json:"glob"`
1616
Tags []string `json:"tags"`
1717
Filename string `json:"name"`
18+
Rule string `json:"rule"`
1819
}

bin/compile.go

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
package main
2+
3+
import (
4+
"os"
5+
6+
"github.com/Velocidex/SQLiteHunter/api"
7+
"github.com/Velocidex/SQLiteHunter/compile"
8+
"github.com/Velocidex/SQLiteHunter/definitions"
9+
"github.com/alecthomas/kingpin"
10+
"gopkg.in/yaml.v3"
11+
12+
_ "embed"
13+
)
14+
15+
//go:embed config.yaml
16+
var config_string string
17+
18+
var (
19+
compile_cmd = app.Command("compile",
20+
"Build an artifact from a set of SQLiteHunter yaml files.")
21+
22+
compile_yaml = compile_cmd.Arg("input",
23+
"Path to the SQLiteHunter yaml directory to compile").
24+
Required().String()
25+
26+
output_artifact = compile_cmd.Arg("output",
27+
"Where to write the final artifact").
28+
Required().String()
29+
30+
output_zip = compile_cmd.Flag("output_zip",
31+
"Produce a ZIP file we can use to hunt").
32+
String()
33+
34+
output_index = compile_cmd.Flag("index", "Where to write the rules index").
35+
String()
36+
)
37+
38+
func loadConfig() (*api.ConfigDefinitions, error) {
39+
config_obj := &api.ConfigDefinitions{}
40+
err := yaml.Unmarshal([]byte(config_string), config_obj)
41+
return config_obj, err
42+
}
43+
44+
func doCompile() error {
45+
config_obj, err := loadConfig()
46+
if err != nil {
47+
return err
48+
}
49+
50+
defs, err := definitions.LoadDefinitions(*compile_yaml)
51+
if err != nil {
52+
return err
53+
}
54+
55+
spec, err := compile.Compile(defs, config_obj)
56+
if err != nil {
57+
return err
58+
}
59+
60+
// Serialize the artifact to YAML
61+
res, err := spec.Yaml()
62+
if err != nil {
63+
return err
64+
}
65+
66+
fd, err := os.OpenFile(*output_artifact,
67+
os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
68+
if err != nil {
69+
return err
70+
}
71+
defer fd.Close()
72+
73+
_, err = fd.Write([]byte(res))
74+
if err != nil {
75+
return err
76+
}
77+
78+
if *output_zip != "" {
79+
err := spec.WriteZip(*output_zip)
80+
if err != nil {
81+
return err
82+
}
83+
}
84+
85+
if *output_index != "" {
86+
fd, err := os.OpenFile(*output_index,
87+
os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
88+
if err != nil {
89+
return err
90+
}
91+
defer fd.Close()
92+
93+
_, err = fd.Write(spec.BuildIndex())
94+
if err != nil {
95+
return err
96+
}
97+
}
98+
99+
return nil
100+
}
101+
102+
func init() {
103+
command_handlers = append(command_handlers, func(command string) bool {
104+
switch command {
105+
case compile_cmd.FullCommand():
106+
err := doCompile()
107+
kingpin.FatalIfError(err, "Compiling artifact")
108+
109+
default:
110+
return false
111+
}
112+
return true
113+
})
114+
}
File renamed without changes.

0 commit comments

Comments
 (0)