Skip to content
This repository was archived by the owner on Jul 17, 2025. It is now read-only.

Commit 1d55780

Browse files
committed
cli
1 parent 2cab562 commit 1d55780

315 files changed

Lines changed: 348216 additions & 45 deletions

File tree

Some content is hidden

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

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ go.work.sum
4444
# Fern Python
4545
generated/python/**
4646

47-
# Webscan binary
47+
# MethodWebTest binary
4848
/methodwebtest
4949

5050
# .DS_Store

Dockerfile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,13 @@ RUN \
1212
mkdir -p /opt/method/${CLI_NAME}/var/data && \
1313
mkdir -p /opt/method/${CLI_NAME}/var/data/tmp && \
1414
mkdir -p /opt/method/${CLI_NAME}/var/conf && \
15+
mkdir -p /opt/method/${CLI_NAME}/var/conf/paths && \
1516
mkdir -p /opt/method/${CLI_NAME}/var/log && \
1617
mkdir -p /opt/method/${CLI_NAME}/service/bin && \
1718
mkdir -p /mnt/output
1819

20+
COPY configs/paths/* /opt/method/${CLI_NAME}/var/conf/paths/
21+
1922
COPY ${CLI_NAME} /opt/method/${CLI_NAME}/service/bin/${CLI_NAME}
2023

2124
RUN \

cmd/apache.go

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
package cmd
2+
3+
import (
4+
"errors"
5+
6+
methodwebtest "github.com/Method-Security/methodwebtest/generated/go"
7+
path "github.com/Method-Security/methodwebtest/internal/apache/path"
8+
"github.com/spf13/cobra"
9+
)
10+
11+
// InitApacheCommand initializes the apache command for the methodwebtest CLI.
12+
func (a *MethodWebTest) InitApacheCommand() {
13+
a.ApacheCmd = &cobra.Command{
14+
Use: "apache",
15+
Short: "Perform apache specific injection tests against a target",
16+
Long: `Perform apache specific injection tests against a target`,
17+
}
18+
19+
a.ApacheCmd.PersistentFlags().StringSlice("targets", []string{}, "The URL of target")
20+
a.ApacheCmd.PersistentFlags().Int("timeout", 30, "Timeout per request (seconds)")
21+
a.ApacheCmd.PersistentFlags().Int("sleep", 0, "Sleep time between requests (seconds)")
22+
a.ApacheCmd.PersistentFlags().Int("retries", 0, "Number of attempts per credential pair")
23+
24+
// pathCmd holds the subcommands for path injection tests
25+
pathCmd := &cobra.Command{
26+
Use: "path",
27+
Short: "Perform path injection tests against a target",
28+
Long: `Perform path injection tests against a target`,
29+
}
30+
31+
modfileCmd := &cobra.Command{
32+
Use: "modfile",
33+
Short: "Perform modfile injection tests in the path of a target",
34+
Long: `Perform modfile injection tests in the path of a target`,
35+
Run: func(cmd *cobra.Command, args []string) {
36+
defer a.OutputSignal.PanicHandler(cmd.Context())
37+
38+
// Target flags
39+
targets, err := cmd.Flags().GetStringSlice("targets")
40+
if err != nil {
41+
a.OutputSignal.AddError(err)
42+
return
43+
}
44+
if len(targets) == 0 {
45+
a.OutputSignal.AddError(errors.New("no targets provided"))
46+
return
47+
}
48+
49+
// Configuration flags
50+
timeout, err := cmd.Flags().GetInt("timeout")
51+
if err != nil {
52+
a.OutputSignal.AddError(err)
53+
return
54+
}
55+
sleep, err := cmd.Flags().GetInt("sleep")
56+
if err != nil {
57+
a.OutputSignal.AddError(err)
58+
return
59+
}
60+
retries, err := cmd.Flags().GetInt("retries")
61+
if err != nil {
62+
a.OutputSignal.AddError(err)
63+
return
64+
}
65+
66+
// Load configuration
67+
config := LoadPathModFileConfig(targets, timeout, sleep, retries)
68+
69+
// Generate report
70+
report := path.PerformApachePathModFileInjection(cmd.Context(), config)
71+
if len(report.Errors) > 0 {
72+
a.OutputSignal.Status = 1
73+
}
74+
a.OutputSignal.Content = report
75+
},
76+
}
77+
78+
pathCmd.AddCommand(modfileCmd)
79+
80+
traversalCmd := &cobra.Command{
81+
Use: "traversal",
82+
Short: "Perform a Apache specific path traversal for common file locations",
83+
Long: `Perform a Apache specific path traversal for common file locations`,
84+
Run: func(cmd *cobra.Command, args []string) {
85+
defer a.OutputSignal.PanicHandler(cmd.Context())
86+
87+
// Target flags
88+
targets, err := cmd.Flags().GetStringSlice("targets")
89+
if err != nil {
90+
a.OutputSignal.AddError(err)
91+
return
92+
}
93+
if len(targets) == 0 {
94+
a.OutputSignal.AddError(errors.New("no targets provided"))
95+
return
96+
}
97+
98+
// Configuration flags
99+
responseCodes, err := cmd.Flags().GetString("responsecodes")
100+
if err != nil {
101+
a.OutputSignal.AddError(err)
102+
return
103+
}
104+
ignoreBase, err := cmd.Flags().GetBool("ignore-base-content-match")
105+
if err != nil {
106+
a.OutputSignal.AddError(err)
107+
return
108+
}
109+
timeout, err := cmd.Flags().GetInt("timeout")
110+
if err != nil {
111+
a.OutputSignal.AddError(err)
112+
return
113+
}
114+
sleep, err := cmd.Flags().GetInt("sleep")
115+
if err != nil {
116+
a.OutputSignal.AddError(err)
117+
return
118+
}
119+
retries, err := cmd.Flags().GetInt("retries")
120+
if err != nil {
121+
a.OutputSignal.AddError(err)
122+
return
123+
}
124+
successfulOnly, err := cmd.Flags().GetBool("successfulonly")
125+
if err != nil {
126+
a.OutputSignal.AddError(err)
127+
return
128+
}
129+
130+
// Load configuration
131+
config := LoadPathTraversalConfig(targets, []string{}, []string{}, "", responseCodes, ignoreBase, timeout, sleep, retries, successfulOnly)
132+
133+
// Generate report
134+
report := path.PerformApachePathTraversal(cmd.Context(), config)
135+
if len(report.Errors) > 0 {
136+
a.OutputSignal.Status = 1
137+
}
138+
a.OutputSignal.Content = report
139+
},
140+
}
141+
142+
traversalCmd.Flags().String("responsecodes", "200-299", "Response codes to consider as valid responses")
143+
traversalCmd.Flags().Bool("ignorebasecontentmatch", true, "Ignores valid responses with identical size and word length to the base path, typically signifying a web backend redirect")
144+
traversalCmd.Flags().Bool("successfulonly", false, "Only show successful attempts")
145+
146+
pathCmd.AddCommand(traversalCmd)
147+
148+
a.ApacheCmd.AddCommand(pathCmd)
149+
150+
a.RootCmd.AddCommand(a.ApacheCmd)
151+
}
152+
153+
func LoadPathModFileConfig(targets []string, timeout int, sleep int, retries int) *methodwebtest.PathModFileConfig {
154+
config := &methodwebtest.PathModFileConfig{
155+
Targets: targets,
156+
Timeout: timeout,
157+
Sleep: sleep,
158+
Retries: retries,
159+
}
160+
161+
if config.Timeout < 1 {
162+
config.Timeout = 0
163+
}
164+
165+
return config
166+
}

0 commit comments

Comments
 (0)