-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
executable file
·171 lines (138 loc) · 4.34 KB
/
main.go
File metadata and controls
executable file
·171 lines (138 loc) · 4.34 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
// SPDX-License-Identifier: GPL-3.0-or-later
//
//go:generate goversioninfo -arm -64 .goversion.json
package main
import (
"fmt"
"io"
"log"
"os"
"runtime"
"runtime/debug"
"strconv"
"strings"
"time"
_ "github.com/josephspurrier/goversioninfo"
"github.com/alecthomas/kong"
ver "go.foxforensics.dev/fox/v4/internal"
"go.foxforensics.dev/fox/v4/internal/cmd"
"go.foxforensics.dev/fox/v4/internal/cmd/dump"
"go.foxforensics.dev/fox/v4/internal/cmd/hash"
"go.foxforensics.dev/fox/v4/internal/cmd/help"
"go.foxforensics.dev/fox/v4/internal/cmd/hunt"
"go.foxforensics.dev/fox/v4/internal/cmd/info"
"go.foxforensics.dev/fox/v4/internal/cmd/show"
"go.foxforensics.dev/fox/v4/internal/cmd/str"
"go.foxforensics.dev/fox/v4/internal/pkg/text"
)
var Usage = strings.TrimSpace(`
Usage:
fox [COMMAND] [FLAGS...] <PATHS...>
Commands:
s, str Show file contained strings
i, info Show file infos and entropy
h, hash Show file hashes and checksums
d, dump Dump Active Directory secrets
e, hunt Hunt critical system events
File flags:
-i, --in=FILE Read paths from file
-o, --out=FILE Write output to file (receipted)
Limit flags:
-h, --head Limit head of file by...
-t, --tail Limit tail of file by...
-c, --bytes=NUMBER Number of bytes
-l, --lines=NUMBER Number of lines
Unique flags:
-u, --uniq Filter using unique hash
-D, --dist=LENGTH Filter using Levenshtein distance
Filter flags:
-e, --regexp=PATTERN Filter output by pattern
-C, --context=LINES Lines surrounding a match
-B, --before=LINES Lines leading before a match
-A, --after=LINES Lines trailing after a match
Special flags:
-p, --password=TEXT Use archive password (7Z, RAR, ZIP)
-z, --parallel=CORES Use parallel processing
Display flags:
-T, --force-text Force output as text
-X, --force-hex Force output as hex
Disable flags:
-r, --raw Don't process files at all
-q, --quiet Don't print anything
-N, --no-pretty Don't prettify the output
--no-strict Don't stop on parser errors
--no-deflate Don't deflate automatically
--no-extract Don't extract automatically
--no-convert Don't convert automatically
--no-receipt Don't write the receipt
Standard flags:
-v, --verbose[=LEVEL] Print more details (v/vv/vvv)
-d, --dry-run Print only the found files
--version Print the version number
--help Print this help message
Positional arguments:
Globbing paths to open or '-' to read from STDIN
Example: Find occurrences in event logs
$ fox -eWinlogon ./**/*.evtx
Example: List only high entropy files
$ fox info -n6.0 ./**/*
Example: Hunt down critical events
$ fox hunt -u *.dd
Use "fox help <COMMAND>" for sub commands.
`)
type fox struct {
Str str.Str `cmd:"" aliases:"s"`
Hash hash.Hash `cmd:"" aliases:"h"`
Info info.Info `cmd:"" aliases:"i"`
Dump dump.Dump `cmd:"" aliases:"d"`
Hunt hunt.Hunt `cmd:"" aliases:"e"`
Show show.Show `cmd:"" default:"withargs"`
// hidden commands
Help help.Help `cmd:"" hidden:""`
// support flags
Version bool
// global flags
cmd.Globals
}
func main() {
defer trace()
log.SetFlags(0)
log.SetPrefix("fox: ")
cli := new(fox)
ctx := kong.Parse(cli,
kong.NoDefaultHelp(),
kong.Name("fox"),
kong.DefaultEnvars("FOX"),
kong.Vars{
"cores": strconv.Itoa(runtime.NumCPU()),
})
switch {
case len(ctx.Args) == 0, ctx.Error != nil:
fallthrough // show usage
case cli.Globals.Help, ctx.Command() == "help":
_ = text.Usage(Usage)
case cli.Version:
fmt.Printf("fox %s-%s\n", ver.Version, runtime.GOARCH)
default:
if cli.Verbose > 0 {
defer timer(time.Now())
}
// redirect output
if len(cli.File) > 0 {
text.Setup(os.OpenFile(cli.File, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0600))
} else if cli.Quiet {
text.Setup(os.Open(os.DevNull))
log.SetOutput(io.Discard)
}
defer text.Close(cli.File, !cli.NoReceipt)
ctx.FatalIfErrorf(ctx.Run(&cli.Globals))
}
}
func timer(t time.Time) {
log.Printf("time %v\n", time.Since(t))
}
func trace() {
if err := recover(); err != nil {
log.Printf("%+v\n\n%s\n", err, debug.Stack())
}
}