Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
maurosoria
GitHub Repository: maurosoria/dirsearch
Path: blob/master/lib/parse/cmdline.py
896 views
1
# -*- coding: utf-8 -*-
2
# This program is free software; you can redistribute it and/or modify
3
# it under the terms of the GNU General Public License as published by
4
# the Free Software Foundation; either version 2 of the License, or
5
# (at your option) any later version.
6
#
7
# This program is distributed in the hope that it will be useful,
8
# but WITHOUT ANY WARRANTY; without even the implied warranty of
9
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
# GNU General Public License for more details.
11
#
12
# You should have received a copy of the GNU General Public License
13
# along with this program; if not, write to the Free Software
14
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
15
# MA 02110-1301, USA.
16
#
17
# Author: Mauro Soria
18
19
from optparse import OptionParser, OptionGroup, Values
20
21
22
from lib.core.settings import (
23
AUTHENTICATION_TYPES,
24
FILE_BASED_OUTPUT_FORMATS,
25
VERSION,
26
)
27
from lib.utils.common import get_config_file
28
29
30
def parse_arguments() -> Values:
31
usage = "Usage: %prog [-u|--url] target [-e|--extensions] extensions [options]"
32
epilog = "See 'config.ini' for the example configuration file"
33
parser = OptionParser(usage=usage, epilog=epilog, version=f"dirsearch v{VERSION}")
34
35
# Mandatory arguments
36
mandatory = OptionGroup(parser, "Mandatory")
37
mandatory.add_option(
38
"-u",
39
"--url",
40
action="append",
41
dest="urls",
42
metavar="URL",
43
help="Target URL(s), can use multiple flags",
44
)
45
mandatory.add_option(
46
"-l",
47
"--urls-file",
48
action="store",
49
dest="urls_file",
50
metavar="PATH",
51
help="URL list file",
52
)
53
mandatory.add_option(
54
"--stdin", action="store_true", dest="stdin_urls", help="Read URL(s) from STDIN"
55
)
56
mandatory.add_option("--cidr", action="store", dest="cidr", help="Target CIDR")
57
mandatory.add_option(
58
"--raw",
59
action="store",
60
dest="raw_file",
61
metavar="PATH",
62
help="Load raw HTTP request from file (use '--scheme' flag to set the scheme)",
63
)
64
mandatory.add_option(
65
"--nmap-report",
66
action="store",
67
dest="nmap_report",
68
metavar="PATH",
69
help="Load targets from nmap report (Ensure the inclusion of the -sV flag during nmap scan for comprehensive results)",
70
)
71
mandatory.add_option(
72
"-s", "--session", action="store", dest="session_file", help="Session file"
73
)
74
mandatory.add_option(
75
"--session-id",
76
action="store",
77
dest="session_id",
78
metavar="ID",
79
help="Load session by numeric id (use --list-sessions to see ids)",
80
)
81
mandatory.add_option(
82
"--config",
83
action="store",
84
dest="config",
85
metavar="PATH",
86
help="Path to configuration file (Default: 'DIRSEARCH_CONFIG' environment variable, otherwise 'config.ini')",
87
default=get_config_file(),
88
)
89
90
# Dictionary Settings
91
dictionary = OptionGroup(parser, "Dictionary Settings")
92
dictionary.add_option(
93
"-w",
94
"--wordlists",
95
action="store",
96
dest="wordlists",
97
help="Wordlist files or directories contain wordlists (separated by commas)",
98
)
99
dictionary.add_option(
100
"--wordlist-categories",
101
action="store",
102
dest="wordlist_categories",
103
help=(
104
"Comma-separated wordlist category names (e.g. common,conf,web). "
105
"Use 'all' to include all bundled categories"
106
),
107
)
108
dictionary.add_option(
109
"-e",
110
"--extensions",
111
action="store",
112
dest="extensions",
113
help="Extension list, separated by commas (e.g. php,asp)",
114
)
115
dictionary.add_option(
116
"-f",
117
"--force-extensions",
118
action="store_true",
119
dest="force_extensions",
120
help="Add extensions to the end of every wordlist entry. By default dirsearch only replaces the %EXT% keyword with extensions",
121
)
122
dictionary.add_option(
123
"--overwrite-extensions",
124
action="store_true",
125
dest="overwrite_extensions",
126
help="Overwrite other extensions in the wordlist with your extensions (selected via `-e`)",
127
)
128
dictionary.add_option(
129
"--exclude-extensions",
130
action="store",
131
dest="exclude_extensions",
132
metavar="EXTENSIONS",
133
help="Exclude extension list, separated by commas (e.g. asp,jsp)",
134
)
135
dictionary.add_option(
136
"--prefixes",
137
action="store",
138
dest="prefixes",
139
help="Add custom prefixes to all wordlist entries (separated by commas)",
140
)
141
dictionary.add_option(
142
"--suffixes",
143
action="store",
144
dest="suffixes",
145
help="Add custom suffixes to all wordlist entries, ignore directories (separated by commas)",
146
)
147
dictionary.add_option(
148
"-U",
149
"--uppercase",
150
action="store_true",
151
dest="uppercase",
152
help="Uppercase wordlist",
153
)
154
dictionary.add_option(
155
"-L",
156
"--lowercase",
157
action="store_true",
158
dest="lowercase",
159
help="Lowercase wordlist",
160
)
161
dictionary.add_option(
162
"-C",
163
"--capital",
164
action="store_true",
165
dest="capital",
166
help="Capital wordlist",
167
)
168
169
# Optional Settings
170
general = OptionGroup(parser, "General Settings")
171
general.add_option(
172
"-t",
173
"--threads",
174
action="store",
175
type="int",
176
dest="thread_count",
177
metavar="THREADS",
178
help="Number of threads",
179
)
180
general.add_option(
181
"--list-sessions",
182
action="store_true",
183
dest="list_sessions",
184
help="List resumable sessions and exit",
185
)
186
general.add_option(
187
"--sessions-dir",
188
action="store",
189
dest="sessions_dir",
190
metavar="PATH",
191
help=(
192
"Directory to search for resumable sessions (default: dirsearch path "
193
"/sessions, or $HOME/.dirsearch/sessions when bundled)"
194
),
195
)
196
general.add_option(
197
"-a",
198
"--async",
199
action="store_true",
200
dest="async_mode",
201
help="Enable asynchronous mode",
202
)
203
general.add_option(
204
"-r",
205
"--recursive",
206
action="store_true",
207
dest="recursive",
208
help="Brute-force recursively",
209
)
210
general.add_option(
211
"--deep-recursive",
212
action="store_true",
213
dest="deep_recursive",
214
help="Perform recursive scan on every directory depth (e.g. api/users -> api/)",
215
)
216
general.add_option(
217
"--force-recursive",
218
action="store_true",
219
dest="force_recursive",
220
help="Do recursive brute-force for every found path, not only directories",
221
)
222
general.add_option(
223
"-R",
224
"--max-recursion-depth",
225
action="store",
226
type="int",
227
dest="recursion_depth",
228
metavar="DEPTH",
229
help="Maximum recursion depth",
230
)
231
general.add_option(
232
"--recursion-status",
233
action="store",
234
dest="recursion_status_codes",
235
metavar="CODES",
236
help="Valid status codes to perform recursive scan, support ranges (separated by commas)",
237
)
238
general.add_option(
239
"--filter-threshold",
240
action="store",
241
type="int",
242
dest="filter_threshold",
243
metavar="THRESHOLD",
244
help="Maximum number of results with duplicate responses before getting filtered out",
245
)
246
general.add_option(
247
"--subdirs",
248
action="store",
249
dest="subdirs",
250
metavar="SUBDIRS",
251
help="Scan sub-directories of the given URL[s] (separated by commas)",
252
)
253
general.add_option(
254
"--exclude-subdirs",
255
action="store",
256
dest="exclude_subdirs",
257
metavar="SUBDIRS",
258
help="Exclude the following subdirectories during recursive scan (separated by commas)",
259
)
260
general.add_option(
261
"-i",
262
"--include-status",
263
action="store",
264
dest="include_status_codes",
265
metavar="CODES",
266
help="Include status codes, separated by commas, support ranges (e.g. 200,300-399)",
267
)
268
general.add_option(
269
"-x",
270
"--exclude-status",
271
action="store",
272
dest="exclude_status_codes",
273
metavar="CODES",
274
help="Exclude status codes, separated by commas, support ranges (e.g. 301,500-599)",
275
)
276
general.add_option(
277
"--exclude-sizes",
278
action="store",
279
dest="exclude_sizes",
280
metavar="SIZES",
281
help="Exclude responses by sizes, separated by commas (e.g. 0B,4KB)",
282
)
283
general.add_option(
284
"--exclude-text",
285
action="append",
286
dest="exclude_texts",
287
metavar="TEXTS",
288
help="Exclude responses by text, can use multiple flags",
289
)
290
general.add_option(
291
"--exclude-regex",
292
action="store",
293
dest="exclude_regex",
294
metavar="REGEX",
295
help="Exclude responses by regular expression",
296
)
297
general.add_option(
298
"--exclude-redirect",
299
action="store",
300
dest="exclude_redirect",
301
metavar="STRING",
302
help="Exclude responses if this regex (or text) matches redirect URL (e.g. '/index.html')",
303
)
304
general.add_option(
305
"--exclude-response",
306
action="store",
307
dest="exclude_response",
308
metavar="PATH",
309
help="Exclude responses similar to response of this page, path as input (e.g. 404.html)",
310
)
311
general.add_option(
312
"--skip-on-status",
313
action="store",
314
dest="skip_on_status",
315
metavar="CODES",
316
help="Skip target whenever hit one of these status codes, separated by commas, support ranges",
317
)
318
general.add_option(
319
"--min-response-size",
320
action="store",
321
type="int",
322
dest="minimum_response_size",
323
help="Minimum response length",
324
metavar="LENGTH",
325
default=0,
326
)
327
general.add_option(
328
"--max-response-size",
329
action="store",
330
type="int",
331
dest="maximum_response_size",
332
help="Maximum response length",
333
metavar="LENGTH",
334
default=0,
335
)
336
general.add_option(
337
"--max-time",
338
action="store",
339
type="int",
340
dest="max_time",
341
metavar="SECONDS",
342
help="Maximum runtime for the scan",
343
)
344
general.add_option(
345
"--target-max-time",
346
action="store",
347
type="int",
348
dest="target_max_time",
349
metavar="SECONDS",
350
help="Maximum runtime for a target",
351
)
352
general.add_option(
353
"--exit-on-error",
354
action="store_true",
355
dest="exit_on_error",
356
help="Exit whenever an error occurs",
357
)
358
359
# Request Settings
360
request = OptionGroup(parser, "Request Settings")
361
request.add_option(
362
"-m",
363
"--http-method",
364
action="store",
365
dest="http_method",
366
metavar="METHOD",
367
help="HTTP method (default: GET)",
368
)
369
request.add_option(
370
"-d", "--data", action="store", dest="data", help="HTTP request data"
371
)
372
request.add_option(
373
"--data-file",
374
action="store",
375
dest="data_file",
376
metavar="PATH",
377
help="File contains HTTP request data"
378
)
379
request.add_option(
380
"-H",
381
"--header",
382
action="append",
383
dest="headers",
384
help="HTTP request header, can use multiple flags",
385
)
386
request.add_option(
387
"--headers-file",
388
dest="headers_file",
389
metavar="PATH",
390
help="File contains HTTP request headers",
391
)
392
request.add_option(
393
"-F",
394
"--follow-redirects",
395
action="store_true",
396
dest="follow_redirects",
397
help="Follow HTTP redirects",
398
)
399
request.add_option(
400
"--random-agent",
401
action="store_true",
402
dest="random_agents",
403
help="Choose a random User-Agent for each request",
404
)
405
request.add_option(
406
"--auth",
407
action="store",
408
dest="auth",
409
metavar="CREDENTIAL",
410
help="Authentication credential (e.g. user:password or bearer token)",
411
)
412
request.add_option(
413
"--auth-type",
414
action="store",
415
dest="auth_type",
416
metavar="TYPE",
417
help=f"Authentication type ({', '.join(AUTHENTICATION_TYPES)})",
418
)
419
request.add_option(
420
"--cert-file",
421
action="store",
422
dest="cert_file",
423
metavar="PATH",
424
help="File contains client-side certificate",
425
)
426
request.add_option(
427
"--key-file",
428
action="store",
429
dest="key_file",
430
metavar="PATH",
431
help="File contains client-side certificate private key (unencrypted)",
432
)
433
request.add_option("--user-agent", action="store", dest="user_agent")
434
request.add_option("--cookie", action="store", dest="cookie")
435
436
# Connection Settings
437
connection = OptionGroup(parser, "Connection Settings")
438
connection.add_option(
439
"--timeout",
440
action="store",
441
type="float",
442
dest="timeout",
443
help="Connection timeout",
444
)
445
connection.add_option(
446
"--delay",
447
action="store",
448
type="float",
449
dest="delay",
450
help="Delay between requests",
451
)
452
connection.add_option(
453
"-p",
454
"--proxy",
455
action="append",
456
dest="proxies",
457
metavar="PROXY",
458
help="Proxy URL (HTTP/SOCKS), can use multiple flags",
459
)
460
connection.add_option(
461
"--proxies-file",
462
action="store",
463
dest="proxies_file",
464
metavar="PATH",
465
help="File contains proxy servers",
466
)
467
connection.add_option(
468
"--proxy-auth",
469
action="store",
470
dest="proxy_auth",
471
metavar="CREDENTIAL",
472
help="Proxy authentication credential",
473
)
474
connection.add_option(
475
"--replay-proxy",
476
action="store",
477
dest="replay_proxy",
478
metavar="PROXY",
479
help="Proxy to replay with found paths",
480
)
481
connection.add_option(
482
"--tor", action="store_true", dest="tor", help="Use Tor network as proxy"
483
)
484
connection.add_option(
485
"--scheme",
486
action="store",
487
dest="scheme",
488
metavar="SCHEME",
489
help="Scheme for raw request or if there is no scheme in the URL (Default: auto-detect)",
490
)
491
connection.add_option(
492
"--max-rate",
493
action="store",
494
type="int",
495
dest="max_rate",
496
metavar="RATE",
497
help="Max requests per second",
498
)
499
connection.add_option(
500
"--retries",
501
action="store",
502
type="int",
503
dest="max_retries",
504
metavar="RETRIES",
505
help="Number of retries for failed requests",
506
)
507
connection.add_option("--ip", action="store", dest="ip", help="Server IP address")
508
connection.add_option("--interface", action="store", dest="network_interface", help="Network interface to use")
509
510
# Advanced Settings
511
advanced = OptionGroup(parser, "Advanced Settings")
512
advanced.add_option(
513
"--crawl",
514
action="store_true",
515
dest="crawl",
516
help="Crawl for new paths in responses"
517
)
518
519
# View Settings
520
view = OptionGroup(parser, "View Settings")
521
view.add_option(
522
"--full-url",
523
action="store_true",
524
dest="full_url",
525
help="Full URLs in the output (enabled automatically in quiet mode)",
526
)
527
view.add_option(
528
"--redirects-history",
529
action="store_true",
530
dest="redirects_history",
531
help="Show redirects history",
532
)
533
view.add_option(
534
"--no-color", action="store_false", dest="color", help="No colored output"
535
)
536
view.add_option(
537
"-q", "--quiet-mode", action="store_true", dest="quiet", help="Quiet mode"
538
)
539
view.add_option(
540
"--disable-cli", action="store_true", dest="disable_cli", help="Turn off command-line output"
541
)
542
543
# Output Settings
544
output = OptionGroup(parser, "Output Settings")
545
output.add_option(
546
"-O",
547
"--output-formats",
548
action="store",
549
dest="output_formats",
550
metavar="FORMAT",
551
help=f"Report formats, separated by commas (Available: {', '.join(FILE_BASED_OUTPUT_FORMATS)})",
552
)
553
output.add_option(
554
"-o",
555
"--output-file",
556
action="store",
557
dest="output_file",
558
metavar="PATH",
559
help="Output file location",
560
)
561
output.add_option(
562
"--mysql-url",
563
action="store",
564
dest="mysql_url",
565
metavar="URL",
566
help="Database URL for MySQL output (Format: mysql://[username:password@]host[:port]/database-name)",
567
)
568
output.add_option(
569
"--postgres-url",
570
action="store",
571
dest="postgres_url",
572
metavar="URL",
573
help="Database URL for PostgreSQL output (Format: postgres://[username:password@]host[:port]/database-name)",
574
)
575
output.add_option(
576
"--log", action="store", dest="log_file", metavar="PATH", help="Log file"
577
)
578
579
parser.add_option_group(mandatory)
580
parser.add_option_group(dictionary)
581
parser.add_option_group(general)
582
parser.add_option_group(request)
583
parser.add_option_group(connection)
584
parser.add_option_group(advanced)
585
parser.add_option_group(view)
586
parser.add_option_group(output)
587
options, _ = parser.parse_args()
588
589
return options
590
591