-
Notifications
You must be signed in to change notification settings - Fork 0
/
help.go
151 lines (135 loc) · 5.09 KB
/
help.go
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
package main
import (
"flag"
"fmt"
"os"
"github.com/ffuf/ffuf/v2/pkg/ffuf"
)
type UsageSection struct {
Name string
Description string
Flags []UsageFlag
Hidden bool
ExpectedFlags []string
}
// PrintSection prints out the section name, description and each of the flags
func (u *UsageSection) PrintSection(max_length int, extended bool) {
// Do not print if extended usage not requested and section marked as hidden
if !extended && u.Hidden {
return
}
fmt.Printf("%s:\n", u.Name)
for _, f := range u.Flags {
f.PrintFlag(max_length)
}
fmt.Printf("\n")
}
type UsageFlag struct {
Name string
Description string
Default string
}
// PrintFlag prints out the flag name, usage string and default value
func (f *UsageFlag) PrintFlag(max_length int) {
// Create format string, used for padding
format := fmt.Sprintf(" -%%-%ds %%s", max_length)
if f.Default != "" {
format = format + " (default: %s)\n"
fmt.Printf(format, f.Name, f.Description, f.Default)
} else {
format = format + "\n"
fmt.Printf(format, f.Name, f.Description)
}
}
func Usage() {
u_http := UsageSection{
Name: "HTTP OPTIONS",
Description: "Options controlling the HTTP request and its parts.",
Flags: make([]UsageFlag, 0),
Hidden: false,
ExpectedFlags: []string{"H", "X", "b", "d", "r", "u", "recursion", "recursion-depth", "recursion-strategy", "replay-proxy", "timeout", "ignore-body", "x", "sni", "http2"},
}
u_general := UsageSection{
Name: "GENERAL OPTIONS",
Description: "",
Flags: make([]UsageFlag, 0),
Hidden: false,
ExpectedFlags: []string{"ac", "acc", "ack", "ach", "acs", "c", "config", "json", "maxtime", "maxtime-job", "noninteractive", "p", "rate", "scraperfile", "scrapers", "search", "s", "sa", "se", "sf", "t", "v", "V"},
}
u_compat := UsageSection{
Name: "COMPATIBILITY OPTIONS",
Description: "Options to ensure compatibility with other pieces of software.",
Flags: make([]UsageFlag, 0),
Hidden: true,
ExpectedFlags: []string{"compressed", "cookie", "data", "data-ascii", "data-binary", "i", "k"},
}
u_matcher := UsageSection{
Name: "MATCHER OPTIONS",
Description: "Matchers for the response filtering.",
Flags: make([]UsageFlag, 0),
Hidden: false,
ExpectedFlags: []string{"mmode", "mc", "ml", "mr", "ms", "mt", "mw"},
}
u_filter := UsageSection{
Name: "FILTER OPTIONS",
Description: "Filters for the response filtering.",
Flags: make([]UsageFlag, 0),
Hidden: false,
ExpectedFlags: []string{"fmode", "fc", "fl", "fr", "fs", "ft", "fw"},
}
u_input := UsageSection{
Name: "INPUT OPTIONS",
Description: "Options for input data for fuzzing. Wordlists and input generators.",
Flags: make([]UsageFlag, 0),
Hidden: false,
ExpectedFlags: []string{"D", "ic", "input-cmd", "input-num", "input-shell", "mode", "request", "request-proto", "e", "w"},
}
u_output := UsageSection{
Name: "OUTPUT OPTIONS",
Description: "Options for output. Output file formats, file names and debug file locations.",
Flags: make([]UsageFlag, 0),
Hidden: false,
ExpectedFlags: []string{"debug-log", "o", "of", "od", "or"},
}
sections := []UsageSection{u_http, u_general, u_compat, u_matcher, u_filter, u_input, u_output}
// Populate the flag sections
max_length := 0
flag.VisitAll(func(f *flag.Flag) {
found := false
for i, section := range sections {
if ffuf.StrInSlice(f.Name, section.ExpectedFlags) {
sections[i].Flags = append(sections[i].Flags, UsageFlag{
Name: f.Name,
Description: f.Usage,
Default: f.DefValue,
})
found = true
}
}
if !found {
fmt.Printf("DEBUG: Flag %s was found but not defined in help.go.\n", f.Name)
os.Exit(1)
}
if len(f.Name) > max_length {
max_length = len(f.Name)
}
})
fmt.Printf("Fuzz Faster U Fool - v%s\n\n", ffuf.Version())
// Print out the sections
for _, section := range sections {
section.PrintSection(max_length, false)
}
// Usage examples.
fmt.Printf("EXAMPLE USAGE:\n")
fmt.Printf(" Fuzz file paths from wordlist.txt, match all responses but filter out those with content-size 42.\n")
fmt.Printf(" Colored, verbose output.\n")
fmt.Printf(" ffuf -w wordlist.txt -u https://example.org/FUZZ -mc all -fs 42 -c -v\n\n")
fmt.Printf(" Fuzz Host-header, match HTTP 200 responses.\n")
fmt.Printf(" ffuf -w hosts.txt -u https://example.org/ -H \"Host: FUZZ\" -mc 200\n\n")
fmt.Printf(" Fuzz POST JSON data. Match all responses not containing text \"error\".\n")
fmt.Printf(" ffuf -w entries.txt -u https://example.org/ -X POST -H \"Content-Type: application/json\" \\\n")
fmt.Printf(" -d '{\"name\": \"FUZZ\", \"anotherkey\": \"anothervalue\"}' -fr \"error\"\n\n")
fmt.Printf(" Fuzz multiple locations. Match only responses reflecting the value of \"VAL\" keyword. Colored.\n")
fmt.Printf(" ffuf -w params.txt:PARAM -w values.txt:VAL -u https://example.org/?PARAM=VAL -mr \"VAL\" -c\n\n")
fmt.Printf(" More information and examples: https://github.com/ffuf/ffuf\n\n")
}