-
Notifications
You must be signed in to change notification settings - Fork 11
/
args.py
135 lines (108 loc) · 4.47 KB
/
args.py
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
# Methods for parsing command line arguments
#
# NOTE: you do **not** need to modify this file for this assignment!
#
# This file was originally from https://github.com/kernelmethod/xfuzz/
import argparse, os
# Default list of HTTP response status codes that we should match if the -mc argument
# is not passed in.
DEFAULT_MATCH_CODES = [200, 301, 302, 401, 403]
# Program description printed out when the -h / --help flag is given
DESCRIPTION = "Simple web fuzzer using aiohttp"
# Parser epilogue. This is displayed after the information about the flags when the
# --help flag is passed in to xfuzz.
EPILOGUE = """
-----
EXAMPLES:
Find all pages under https://example.org/ ending with .php or .html that return an
HTTP 200 OK response.
python3 -m xfuzz -w /path/to/wordlist.txt -mc 200 -e php -e html \\
-u 'https://example.org/FUZZ'
Find users with some integer UID by fuzzing the `id` URL parameter of a page:
seq 1 10000 | python3 -m xfuzz -u 'https://example.org/user?id=FUZZ'
Make POST requests with JSON data to fuzz a login API and brute-force the password
of the 'admin' user.
python3 -m xfuzz -w /path/to/password/wordlist.txt -mc 200 -u 'https://example.org/login' \\
-X POST -H 'Content-Type: application/json' -d '{"username":"admin","password":"FUZZ"}'
You can find more information at https://github.com/kernelmethod/xfuzz
"""
def setup_argument_parser() -> argparse.ArgumentParser:
"""Create a new ``ArgumentParser`` instance to parse command-line arguments
passed in to the script."""
# If the COLUMNS environment variable is not set, default to text wrapping at
# 100 columns.
os.environ.setdefault("COLUMNS", "100")
parser = argparse.ArgumentParser(
prog="fuzzer",
description=DESCRIPTION,
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=EPILOGUE,
)
# NOTE: you may *not* change any of the command line arguments that are here by
# default! These are needed to make the tests work correctly.
# Add required arguments
parser.add_argument(
"-u",
"--url",
required=True,
help="The URL to fuzz",
)
# Add optional arguments
parser.add_argument(
"-w",
"--wordlist",
required=True,
help=(
"The wordlist to use (provided as a path to a local file). If '-' is provided, xfuzz will "
"read its wordlist from stdin instead."
),
)
parser.add_argument(
"-e",
"--extension",
dest="extensions",
action="append",
help=("One or more extensions to append (e.g. php, html, etc.). Multiple extensions " "may be provided."),
)
parser.add_argument(
"-X",
"--method",
default="GET",
help="HTTP method to use (GET, POST, PUT, etc.) (default: %(default)s)",
)
parser.add_argument(
"-H",
"--header",
dest="headers",
action="append",
help=(
'One or more HTTP headers to add to requests, in the form "HeaderName: HeaderValue" '
'(e.g. "Content-Type: application/json" or `"Host: FUZZ.example.com"`). May be '
"specified one or more times."
),
)
parser.add_argument("-d", "--data", default=None, help="Data to send in the body of the HTTP request.")
parser.add_argument(
"-mc",
dest="match_codes",
type=int,
action="append",
help=(
"Match HTTP response codes. May be specified multiple times. If let unspecified, "
f"defaults to the following response codes: {DEFAULT_MATCH_CODES}"
),
)
# TODO: add any additional (optional) arguments that you want! However, note that these
# arguments will not be explicitly supplied to the program during testing.
return parser
def parse_args(argv=None) -> argparse.Namespace:
"""Parse command-line arguments and return them in an ``argparse.Namespace`` instance."""
# NOTE: do *not* edit this function! The test harness expects arguments to be passed in to
# the fuzz() function in a certain way.
parser = setup_argument_parser()
args = parser.parse_args(args=argv)
# Set defaults for arguments with action="append"
args.extensions = [] if args.extensions is None else [f".{ext}" for ext in args.extensions]
args.headers = [] if args.headers is None else args.headers
args.match_codes = DEFAULT_MATCH_CODES if args.match_codes is None else args.match_codes
return args