Skip to content

Commit

Permalink
Added capability to use KAPE targets
Browse files Browse the repository at this point in the history
  • Loading branch information
sprungknoedl committed Dec 13, 2024
1 parent f6c7a2f commit d43798a
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 1 deletion.
2 changes: 2 additions & 0 deletions collection.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ func LoadMatchers(cfg Configuration) ([]Matcher, []string, error) {
}

return ParseQuack(fh)
} else if cfg.KapeTargets != "" {
return ParseKapeTargets(cfg.KapeTargets, cfg.KapeFiles)
} else {
r := bytes.NewReader(defaultQuack)
return ParseQuack(r)
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ require (
github.com/hashicorp/golang-lru v0.5.3 // indirect
github.com/kr/fs v0.1.0 // indirect
golang.org/x/sys v0.10.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,7 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
www.velocidex.com/golang/go-ntfs v0.1.1 h1:///bh0pjoKMHC8x/Q1yaIm2Wa2UNOYwmVti9PsR3i9A=
www.velocidex.com/golang/go-ntfs v0.1.1/go.mod h1:1sqoU8u2Jchwiqsbz4yMSq061wEAOcyXhTCfm6Gz3Lk=
107 changes: 107 additions & 0 deletions kape.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package main

import (
"fmt"
"io/fs"
"os"
"path/filepath"
"strings"

"gopkg.in/yaml.v3"
)

type TKape struct {
ID string `yaml:"Id"`
Description string `yaml:"Description"`
Author string `yaml:"Author"`
Version string `yaml:"Version"`
RecreateDirectories bool `yaml:"RecreateDirectories"`
Targets []struct {
Name string `yaml:"Name"`
Category string `yaml:"Category"`
Path string `yaml:"Path"`
Recursive bool `yaml:"Recursive"`
FileMask string `yaml:"FileMask"`
Comment string `yaml:"Comment"`
} `yaml:"Targets"`
}

type MKape struct {
ID string `yaml:"Id"`
Description string `yaml:"Description"`
Category string `yaml:"Category"`
Author string `yaml:"Author"`
Version string `yaml:"Version"`
BinaryUrl string `yaml:"BinaryUrl"`
ExportFormat string `yaml:"ExportFormat"`
WaitTimeout int `yaml:"WaitTimeout"`
FileMask string `yaml:"FileMask"`

Processors []struct {
Executable string `yaml:"Executable"`
CommandLine string `yaml:"CommandLine"`
ExportFormat string `yaml:"ExportFormat"`
} `yaml:"Processors"`
}

func ParseKapeTargets(target string, dir string) ([]Matcher, []string, error) {
targets := map[string]string{}
filepath.WalkDir(dir, func(path string, d fs.DirEntry, err error) error {
if d.IsDir() {
return nil
}

targets[strings.ToLower(filepath.Base(path))] = path
return nil
})

return convert(targets, target)
}

func convert(targets map[string]string, name string) ([]Matcher, []string, error) {
fh, err := os.Open(targets[strings.ToLower(name)])
if err != nil {
return nil, nil, err
}

tkape := TKape{}
d := yaml.NewDecoder(fh)
err = d.Decode(&tkape)
if err != nil {
return nil, nil, err
}

var matchers []Matcher
var paths []string
for _, t := range tkape.Targets {
switch {
case strings.HasSuffix(t.Path, ".tkape"):
m, p, err := convert(targets, t.Path)
if err != nil {
return nil, nil, err
}
matchers = append(matchers, m...)
paths = append(paths, p...)

case t.FileMask == "" && t.Recursive:
pattern := fmt.Sprintf("%s\\**", strings.TrimSuffix(t.Path, "\\"))
pattern = strings.ReplaceAll(pattern, "%user%", "*")
matchers = append(matchers, NewGlobMatcher(pattern))

case t.FileMask == "" && !t.Recursive:
pattern := fmt.Sprintf("%s\\*", strings.TrimSuffix(t.Path, "\\"))
pattern = strings.ReplaceAll(pattern, "%user%", "*")
matchers = append(matchers, NewGlobMatcher(pattern))

case t.FileMask != "":
pattern := fmt.Sprintf("%s\\%s", strings.TrimSuffix(t.Path, "\\"), t.FileMask)
pattern = strings.ReplaceAll(pattern, "%user%", "*")
matchers = append(matchers, NewGlobMatcher(pattern))

default:
return nil, nil, fmt.Errorf("unsupported kape target: %+v", t)
}
}

return matchers, paths, nil
}
6 changes: 5 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ type Configuration struct {

CollectionRoots []string // Search root paths
QuackTargets string // Quack collection paths file
KapeTargets string // Kape target file (soon)
KapeTargets string // Kape target name
KapeFiles string // Directory with Kape target and module files

RawAccess bool // Use raw NTFS access (Windows only)

Expand Down Expand Up @@ -265,6 +266,9 @@ func ParseConfig() (Configuration, error) {
})
flag.StringVar(&cfg.QuackTargets, "c", "", "Add custom collection paths (one entry per line). NOTE: Please see example.quack for the syntax.")

flag.StringVar(&cfg.KapeTargets, "kt", "", "The KAPE target configuration to collect, without the extension. ")
flag.StringVar(&cfg.KapeFiles, "kf", "KapeFiles", "Directory containing targets intended for use with KAPE.")

flag.BoolVar(&cfg.RawAccess, "raw", true, "Use raw NTFS access. Only supported on Windows.")

flag.BoolVar(&cfg.SkipTraversal, "skip-traversal", false, "Skip step #1: traversal / enumaration.")
Expand Down

0 comments on commit d43798a

Please sign in to comment.