Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sqlmapproject
GitHub Repository: sqlmapproject/sqlmap
Path: blob/master/lib/parse/cmdline.py
2989 views
1
#!/usr/bin/env python
2
3
"""
4
Copyright (c) 2006-2025 sqlmap developers (https://sqlmap.org)
5
See the file 'LICENSE' for copying permission
6
"""
7
8
from __future__ import print_function
9
10
import os
11
import re
12
import shlex
13
import sys
14
15
try:
16
from optparse import OptionError as ArgumentError
17
from optparse import OptionGroup
18
from optparse import OptionParser as ArgumentParser
19
from optparse import SUPPRESS_HELP as SUPPRESS
20
21
ArgumentParser.add_argument = ArgumentParser.add_option
22
23
def _add_argument_group(self, *args, **kwargs):
24
return self.add_option_group(OptionGroup(self, *args, **kwargs))
25
26
ArgumentParser.add_argument_group = _add_argument_group
27
28
def _add_argument(self, *args, **kwargs):
29
return self.add_option(*args, **kwargs)
30
31
OptionGroup.add_argument = _add_argument
32
33
except ImportError:
34
from argparse import ArgumentParser
35
from argparse import ArgumentError
36
from argparse import SUPPRESS
37
38
finally:
39
def get_actions(instance):
40
for attr in ("option_list", "_group_actions", "_actions"):
41
if hasattr(instance, attr):
42
return getattr(instance, attr)
43
44
def get_groups(parser):
45
return getattr(parser, "option_groups", None) or getattr(parser, "_action_groups")
46
47
def get_all_options(parser):
48
retVal = set()
49
50
for option in get_actions(parser):
51
if hasattr(option, "option_strings"):
52
retVal.update(option.option_strings)
53
else:
54
retVal.update(option._long_opts)
55
retVal.update(option._short_opts)
56
57
for group in get_groups(parser):
58
for option in get_actions(group):
59
if hasattr(option, "option_strings"):
60
retVal.update(option.option_strings)
61
else:
62
retVal.update(option._long_opts)
63
retVal.update(option._short_opts)
64
65
return retVal
66
67
from lib.core.common import checkOldOptions
68
from lib.core.common import checkSystemEncoding
69
from lib.core.common import dataToStdout
70
from lib.core.common import expandMnemonics
71
from lib.core.common import getSafeExString
72
from lib.core.compat import xrange
73
from lib.core.convert import getUnicode
74
from lib.core.data import cmdLineOptions
75
from lib.core.data import conf
76
from lib.core.data import logger
77
from lib.core.defaults import defaults
78
from lib.core.dicts import DEPRECATED_OPTIONS
79
from lib.core.enums import AUTOCOMPLETE_TYPE
80
from lib.core.exception import SqlmapShellQuitException
81
from lib.core.exception import SqlmapSilentQuitException
82
from lib.core.exception import SqlmapSyntaxException
83
from lib.core.option import _createHomeDirectories
84
from lib.core.settings import BASIC_HELP_ITEMS
85
from lib.core.settings import DUMMY_URL
86
from lib.core.settings import IGNORED_OPTIONS
87
from lib.core.settings import INFERENCE_UNKNOWN_CHAR
88
from lib.core.settings import IS_WIN
89
from lib.core.settings import MAX_HELP_OPTION_LENGTH
90
from lib.core.settings import VERSION_STRING
91
from lib.core.shell import autoCompletion
92
from lib.core.shell import clearHistory
93
from lib.core.shell import loadHistory
94
from lib.core.shell import saveHistory
95
from thirdparty.six.moves import input as _input
96
97
def cmdLineParser(argv=None):
98
"""
99
This function parses the command line parameters and arguments
100
"""
101
102
if not argv:
103
argv = sys.argv
104
105
checkSystemEncoding()
106
107
# Reference: https://stackoverflow.com/a/4012683 (Note: previously used "...sys.getfilesystemencoding() or UNICODE_ENCODING")
108
_ = getUnicode(os.path.basename(argv[0]), encoding=sys.stdin.encoding)
109
110
usage = "%s%s [options]" % ("%s " % os.path.basename(sys.executable) if not IS_WIN else "", "\"%s\"" % _ if " " in _ else _)
111
parser = ArgumentParser(usage=usage)
112
113
try:
114
parser.add_argument("--hh", dest="advancedHelp", action="store_true",
115
help="Show advanced help message and exit")
116
117
parser.add_argument("--version", dest="showVersion", action="store_true",
118
help="Show program's version number and exit")
119
120
parser.add_argument("-v", dest="verbose", type=int,
121
help="Verbosity level: 0-6 (default %d)" % defaults.verbose)
122
123
# Target options
124
target = parser.add_argument_group("Target", "At least one of these options has to be provided to define the target(s)")
125
126
target.add_argument("-u", "--url", dest="url",
127
help="Target URL (e.g. \"http://www.site.com/vuln.php?id=1\")")
128
129
target.add_argument("-d", dest="direct",
130
help="Connection string for direct database connection")
131
132
target.add_argument("-l", dest="logFile",
133
help="Parse target(s) from Burp or WebScarab proxy log file")
134
135
target.add_argument("-m", dest="bulkFile",
136
help="Scan multiple targets given in a textual file ")
137
138
target.add_argument("-r", dest="requestFile",
139
help="Load HTTP request from a file")
140
141
target.add_argument("-g", dest="googleDork",
142
help="Process Google dork results as target URLs")
143
144
target.add_argument("-c", dest="configFile",
145
help="Load options from a configuration INI file")
146
147
# Request options
148
request = parser.add_argument_group("Request", "These options can be used to specify how to connect to the target URL")
149
150
request.add_argument("-A", "--user-agent", dest="agent",
151
help="HTTP User-Agent header value")
152
153
request.add_argument("-H", "--header", dest="header",
154
help="Extra header (e.g. \"X-Forwarded-For: 127.0.0.1\")")
155
156
request.add_argument("--method", dest="method",
157
help="Force usage of given HTTP method (e.g. PUT)")
158
159
request.add_argument("--data", dest="data",
160
help="Data string to be sent through POST (e.g. \"id=1\")")
161
162
request.add_argument("--param-del", dest="paramDel",
163
help="Character used for splitting parameter values (e.g. &)")
164
165
request.add_argument("--cookie", dest="cookie",
166
help="HTTP Cookie header value (e.g. \"PHPSESSID=a8d127e..\")")
167
168
request.add_argument("--cookie-del", dest="cookieDel",
169
help="Character used for splitting cookie values (e.g. ;)")
170
171
request.add_argument("--live-cookies", dest="liveCookies",
172
help="Live cookies file used for loading up-to-date values")
173
174
request.add_argument("--load-cookies", dest="loadCookies",
175
help="File containing cookies in Netscape/wget format")
176
177
request.add_argument("--drop-set-cookie", dest="dropSetCookie", action="store_true",
178
help="Ignore Set-Cookie header from response")
179
180
request.add_argument("--http1.0", dest="http10", action="store_true",
181
help="Use HTTP version 1.0 (old)")
182
183
request.add_argument("--http2", dest="http2", action="store_true",
184
help="Use HTTP version 2 (experimental)")
185
186
request.add_argument("--mobile", dest="mobile", action="store_true",
187
help="Imitate smartphone through HTTP User-Agent header")
188
189
request.add_argument("--random-agent", dest="randomAgent", action="store_true",
190
help="Use randomly selected HTTP User-Agent header value")
191
192
request.add_argument("--host", dest="host",
193
help="HTTP Host header value")
194
195
request.add_argument("--referer", dest="referer",
196
help="HTTP Referer header value")
197
198
request.add_argument("--headers", dest="headers",
199
help="Extra headers (e.g. \"Accept-Language: fr\\nETag: 123\")")
200
201
request.add_argument("--auth-type", dest="authType",
202
help="HTTP authentication type (Basic, Digest, Bearer, ...)")
203
204
request.add_argument("--auth-cred", dest="authCred",
205
help="HTTP authentication credentials (name:password)")
206
207
request.add_argument("--auth-file", dest="authFile",
208
help="HTTP authentication PEM cert/private key file")
209
210
request.add_argument("--abort-code", dest="abortCode",
211
help="Abort on (problematic) HTTP error code(s) (e.g. 401)")
212
213
request.add_argument("--ignore-code", dest="ignoreCode",
214
help="Ignore (problematic) HTTP error code(s) (e.g. 401)")
215
216
request.add_argument("--ignore-proxy", dest="ignoreProxy", action="store_true",
217
help="Ignore system default proxy settings")
218
219
request.add_argument("--ignore-redirects", dest="ignoreRedirects", action="store_true",
220
help="Ignore redirection attempts")
221
222
request.add_argument("--ignore-timeouts", dest="ignoreTimeouts", action="store_true",
223
help="Ignore connection timeouts")
224
225
request.add_argument("--proxy", dest="proxy",
226
help="Use a proxy to connect to the target URL")
227
228
request.add_argument("--proxy-cred", dest="proxyCred",
229
help="Proxy authentication credentials (name:password)")
230
231
request.add_argument("--proxy-file", dest="proxyFile",
232
help="Load proxy list from a file")
233
234
request.add_argument("--proxy-freq", dest="proxyFreq", type=int,
235
help="Requests between change of proxy from a given list")
236
237
request.add_argument("--tor", dest="tor", action="store_true",
238
help="Use Tor anonymity network")
239
240
request.add_argument("--tor-port", dest="torPort",
241
help="Set Tor proxy port other than default")
242
243
request.add_argument("--tor-type", dest="torType",
244
help="Set Tor proxy type (HTTP, SOCKS4 or SOCKS5 (default))")
245
246
request.add_argument("--check-tor", dest="checkTor", action="store_true",
247
help="Check to see if Tor is used properly")
248
249
request.add_argument("--delay", dest="delay", type=float,
250
help="Delay in seconds between each HTTP request")
251
252
request.add_argument("--timeout", dest="timeout", type=float,
253
help="Seconds to wait before timeout connection (default %d)" % defaults.timeout)
254
255
request.add_argument("--retries", dest="retries", type=int,
256
help="Retries when the connection timeouts (default %d)" % defaults.retries)
257
258
request.add_argument("--retry-on", dest="retryOn",
259
help="Retry request on regexp matching content (e.g. \"drop\")")
260
261
request.add_argument("--randomize", dest="rParam",
262
help="Randomly change value for given parameter(s)")
263
264
request.add_argument("--safe-url", dest="safeUrl",
265
help="URL address to visit frequently during testing")
266
267
request.add_argument("--safe-post", dest="safePost",
268
help="POST data to send to a safe URL")
269
270
request.add_argument("--safe-req", dest="safeReqFile",
271
help="Load safe HTTP request from a file")
272
273
request.add_argument("--safe-freq", dest="safeFreq", type=int,
274
help="Regular requests between visits to a safe URL")
275
276
request.add_argument("--skip-urlencode", dest="skipUrlEncode", action="store_true",
277
help="Skip URL encoding of payload data")
278
279
request.add_argument("--csrf-token", dest="csrfToken",
280
help="Parameter used to hold anti-CSRF token")
281
282
request.add_argument("--csrf-url", dest="csrfUrl",
283
help="URL address to visit for extraction of anti-CSRF token")
284
285
request.add_argument("--csrf-method", dest="csrfMethod",
286
help="HTTP method to use during anti-CSRF token page visit")
287
288
request.add_argument("--csrf-data", dest="csrfData",
289
help="POST data to send during anti-CSRF token page visit")
290
291
request.add_argument("--csrf-retries", dest="csrfRetries", type=int,
292
help="Retries for anti-CSRF token retrieval (default %d)" % defaults.csrfRetries)
293
294
request.add_argument("--force-ssl", dest="forceSSL", action="store_true",
295
help="Force usage of SSL/HTTPS")
296
297
request.add_argument("--chunked", dest="chunked", action="store_true",
298
help="Use HTTP chunked transfer encoded (POST) requests")
299
300
request.add_argument("--hpp", dest="hpp", action="store_true",
301
help="Use HTTP parameter pollution method")
302
303
request.add_argument("--eval", dest="evalCode",
304
help="Evaluate provided Python code before the request (e.g. \"import hashlib;id2=hashlib.md5(id).hexdigest()\")")
305
306
# Optimization options
307
optimization = parser.add_argument_group("Optimization", "These options can be used to optimize the performance of sqlmap")
308
309
optimization.add_argument("-o", dest="optimize", action="store_true",
310
help="Turn on all optimization switches")
311
312
optimization.add_argument("--predict-output", dest="predictOutput", action="store_true",
313
help="Predict common queries output")
314
315
optimization.add_argument("--keep-alive", dest="keepAlive", action="store_true",
316
help="Use persistent HTTP(s) connections")
317
318
optimization.add_argument("--null-connection", dest="nullConnection", action="store_true",
319
help="Retrieve page length without actual HTTP response body")
320
321
optimization.add_argument("--threads", dest="threads", type=int,
322
help="Max number of concurrent HTTP(s) requests (default %d)" % defaults.threads)
323
324
# Injection options
325
injection = parser.add_argument_group("Injection", "These options can be used to specify which parameters to test for, provide custom injection payloads and optional tampering scripts")
326
327
injection.add_argument("-p", dest="testParameter",
328
help="Testable parameter(s)")
329
330
injection.add_argument("--skip", dest="skip",
331
help="Skip testing for given parameter(s)")
332
333
injection.add_argument("--skip-static", dest="skipStatic", action="store_true",
334
help="Skip testing parameters that not appear to be dynamic")
335
336
injection.add_argument("--param-exclude", dest="paramExclude",
337
help="Regexp to exclude parameters from testing (e.g. \"ses\")")
338
339
injection.add_argument("--param-filter", dest="paramFilter",
340
help="Select testable parameter(s) by place (e.g. \"POST\")")
341
342
injection.add_argument("--dbms", dest="dbms",
343
help="Force back-end DBMS to provided value")
344
345
injection.add_argument("--dbms-cred", dest="dbmsCred",
346
help="DBMS authentication credentials (user:password)")
347
348
injection.add_argument("--os", dest="os",
349
help="Force back-end DBMS operating system to provided value")
350
351
injection.add_argument("--invalid-bignum", dest="invalidBignum", action="store_true",
352
help="Use big numbers for invalidating values")
353
354
injection.add_argument("--invalid-logical", dest="invalidLogical", action="store_true",
355
help="Use logical operations for invalidating values")
356
357
injection.add_argument("--invalid-string", dest="invalidString", action="store_true",
358
help="Use random strings for invalidating values")
359
360
injection.add_argument("--no-cast", dest="noCast", action="store_true",
361
help="Turn off payload casting mechanism")
362
363
injection.add_argument("--no-escape", dest="noEscape", action="store_true",
364
help="Turn off string escaping mechanism")
365
366
injection.add_argument("--prefix", dest="prefix",
367
help="Injection payload prefix string")
368
369
injection.add_argument("--suffix", dest="suffix",
370
help="Injection payload suffix string")
371
372
injection.add_argument("--tamper", dest="tamper",
373
help="Use given script(s) for tampering injection data")
374
375
# Detection options
376
detection = parser.add_argument_group("Detection", "These options can be used to customize the detection phase")
377
378
detection.add_argument("--level", dest="level", type=int,
379
help="Level of tests to perform (1-5, default %d)" % defaults.level)
380
381
detection.add_argument("--risk", dest="risk", type=int,
382
help="Risk of tests to perform (1-3, default %d)" % defaults.risk)
383
384
detection.add_argument("--string", dest="string",
385
help="String to match when query is evaluated to True")
386
387
detection.add_argument("--not-string", dest="notString",
388
help="String to match when query is evaluated to False")
389
390
detection.add_argument("--regexp", dest="regexp",
391
help="Regexp to match when query is evaluated to True")
392
393
detection.add_argument("--code", dest="code", type=int,
394
help="HTTP code to match when query is evaluated to True")
395
396
detection.add_argument("--smart", dest="smart", action="store_true",
397
help="Perform thorough tests only if positive heuristic(s)")
398
399
detection.add_argument("--text-only", dest="textOnly", action="store_true",
400
help="Compare pages based only on the textual content")
401
402
detection.add_argument("--titles", dest="titles", action="store_true",
403
help="Compare pages based only on their titles")
404
405
# Techniques options
406
techniques = parser.add_argument_group("Techniques", "These options can be used to tweak testing of specific SQL injection techniques")
407
408
techniques.add_argument("--technique", dest="technique",
409
help="SQL injection techniques to use (default \"%s\")" % defaults.technique)
410
411
techniques.add_argument("--time-sec", dest="timeSec", type=int,
412
help="Seconds to delay the DBMS response (default %d)" % defaults.timeSec)
413
414
techniques.add_argument("--disable-stats", dest="disableStats", action="store_true",
415
help="Disable the statistical model for detecting the delay")
416
417
techniques.add_argument("--union-cols", dest="uCols",
418
help="Range of columns to test for UNION query SQL injection")
419
420
techniques.add_argument("--union-char", dest="uChar",
421
help="Character to use for bruteforcing number of columns")
422
423
techniques.add_argument("--union-from", dest="uFrom",
424
help="Table to use in FROM part of UNION query SQL injection")
425
426
techniques.add_argument("--union-values", dest="uValues",
427
help="Column values to use for UNION query SQL injection")
428
429
techniques.add_argument("--dns-domain", dest="dnsDomain",
430
help="Domain name used for DNS exfiltration attack")
431
432
techniques.add_argument("--second-url", dest="secondUrl",
433
help="Resulting page URL searched for second-order response")
434
435
techniques.add_argument("--second-req", dest="secondReq",
436
help="Load second-order HTTP request from file")
437
438
# Fingerprint options
439
fingerprint = parser.add_argument_group("Fingerprint")
440
441
fingerprint.add_argument("-f", "--fingerprint", dest="extensiveFp", action="store_true",
442
help="Perform an extensive DBMS version fingerprint")
443
444
# Enumeration options
445
enumeration = parser.add_argument_group("Enumeration", "These options can be used to enumerate the back-end database management system information, structure and data contained in the tables")
446
447
enumeration.add_argument("-a", "--all", dest="getAll", action="store_true",
448
help="Retrieve everything")
449
450
enumeration.add_argument("-b", "--banner", dest="getBanner", action="store_true",
451
help="Retrieve DBMS banner")
452
453
enumeration.add_argument("--current-user", dest="getCurrentUser", action="store_true",
454
help="Retrieve DBMS current user")
455
456
enumeration.add_argument("--current-db", dest="getCurrentDb", action="store_true",
457
help="Retrieve DBMS current database")
458
459
enumeration.add_argument("--hostname", dest="getHostname", action="store_true",
460
help="Retrieve DBMS server hostname")
461
462
enumeration.add_argument("--is-dba", dest="isDba", action="store_true",
463
help="Detect if the DBMS current user is DBA")
464
465
enumeration.add_argument("--users", dest="getUsers", action="store_true",
466
help="Enumerate DBMS users")
467
468
enumeration.add_argument("--passwords", dest="getPasswordHashes", action="store_true",
469
help="Enumerate DBMS users password hashes")
470
471
enumeration.add_argument("--privileges", dest="getPrivileges", action="store_true",
472
help="Enumerate DBMS users privileges")
473
474
enumeration.add_argument("--roles", dest="getRoles", action="store_true",
475
help="Enumerate DBMS users roles")
476
477
enumeration.add_argument("--dbs", dest="getDbs", action="store_true",
478
help="Enumerate DBMS databases")
479
480
enumeration.add_argument("--tables", dest="getTables", action="store_true",
481
help="Enumerate DBMS database tables")
482
483
enumeration.add_argument("--columns", dest="getColumns", action="store_true",
484
help="Enumerate DBMS database table columns")
485
486
enumeration.add_argument("--schema", dest="getSchema", action="store_true",
487
help="Enumerate DBMS schema")
488
489
enumeration.add_argument("--count", dest="getCount", action="store_true",
490
help="Retrieve number of entries for table(s)")
491
492
enumeration.add_argument("--dump", dest="dumpTable", action="store_true",
493
help="Dump DBMS database table entries")
494
495
enumeration.add_argument("--dump-all", dest="dumpAll", action="store_true",
496
help="Dump all DBMS databases tables entries")
497
498
enumeration.add_argument("--search", dest="search", action="store_true",
499
help="Search column(s), table(s) and/or database name(s)")
500
501
enumeration.add_argument("--comments", dest="getComments", action="store_true",
502
help="Check for DBMS comments during enumeration")
503
504
enumeration.add_argument("--statements", dest="getStatements", action="store_true",
505
help="Retrieve SQL statements being run on DBMS")
506
507
enumeration.add_argument("-D", dest="db",
508
help="DBMS database to enumerate")
509
510
enumeration.add_argument("-T", dest="tbl",
511
help="DBMS database table(s) to enumerate")
512
513
enumeration.add_argument("-C", dest="col",
514
help="DBMS database table column(s) to enumerate")
515
516
enumeration.add_argument("-X", dest="exclude",
517
help="DBMS database identifier(s) to not enumerate")
518
519
enumeration.add_argument("-U", dest="user",
520
help="DBMS user to enumerate")
521
522
enumeration.add_argument("--exclude-sysdbs", dest="excludeSysDbs", action="store_true",
523
help="Exclude DBMS system databases when enumerating tables")
524
525
enumeration.add_argument("--pivot-column", dest="pivotColumn",
526
help="Pivot column name")
527
528
enumeration.add_argument("--where", dest="dumpWhere",
529
help="Use WHERE condition while table dumping")
530
531
enumeration.add_argument("--start", dest="limitStart", type=int,
532
help="First dump table entry to retrieve")
533
534
enumeration.add_argument("--stop", dest="limitStop", type=int,
535
help="Last dump table entry to retrieve")
536
537
enumeration.add_argument("--first", dest="firstChar", type=int,
538
help="First query output word character to retrieve")
539
540
enumeration.add_argument("--last", dest="lastChar", type=int,
541
help="Last query output word character to retrieve")
542
543
enumeration.add_argument("--sql-query", dest="sqlQuery",
544
help="SQL statement to be executed")
545
546
enumeration.add_argument("--sql-shell", dest="sqlShell", action="store_true",
547
help="Prompt for an interactive SQL shell")
548
549
enumeration.add_argument("--sql-file", dest="sqlFile",
550
help="Execute SQL statements from given file(s)")
551
552
# Brute force options
553
brute = parser.add_argument_group("Brute force", "These options can be used to run brute force checks")
554
555
brute.add_argument("--common-tables", dest="commonTables", action="store_true",
556
help="Check existence of common tables")
557
558
brute.add_argument("--common-columns", dest="commonColumns", action="store_true",
559
help="Check existence of common columns")
560
561
brute.add_argument("--common-files", dest="commonFiles", action="store_true",
562
help="Check existence of common files")
563
564
# User-defined function options
565
udf = parser.add_argument_group("User-defined function injection", "These options can be used to create custom user-defined functions")
566
567
udf.add_argument("--udf-inject", dest="udfInject", action="store_true",
568
help="Inject custom user-defined functions")
569
570
udf.add_argument("--shared-lib", dest="shLib",
571
help="Local path of the shared library")
572
573
# File system options
574
filesystem = parser.add_argument_group("File system access", "These options can be used to access the back-end database management system underlying file system")
575
576
filesystem.add_argument("--file-read", dest="fileRead",
577
help="Read a file from the back-end DBMS file system")
578
579
filesystem.add_argument("--file-write", dest="fileWrite",
580
help="Write a local file on the back-end DBMS file system")
581
582
filesystem.add_argument("--file-dest", dest="fileDest",
583
help="Back-end DBMS absolute filepath to write to")
584
585
# Takeover options
586
takeover = parser.add_argument_group("Operating system access", "These options can be used to access the back-end database management system underlying operating system")
587
588
takeover.add_argument("--os-cmd", dest="osCmd",
589
help="Execute an operating system command")
590
591
takeover.add_argument("--os-shell", dest="osShell", action="store_true",
592
help="Prompt for an interactive operating system shell")
593
594
takeover.add_argument("--os-pwn", dest="osPwn", action="store_true",
595
help="Prompt for an OOB shell, Meterpreter or VNC")
596
597
takeover.add_argument("--os-smbrelay", dest="osSmb", action="store_true",
598
help="One click prompt for an OOB shell, Meterpreter or VNC")
599
600
takeover.add_argument("--os-bof", dest="osBof", action="store_true",
601
help="Stored procedure buffer overflow "
602
"exploitation")
603
604
takeover.add_argument("--priv-esc", dest="privEsc", action="store_true",
605
help="Database process user privilege escalation")
606
607
takeover.add_argument("--msf-path", dest="msfPath",
608
help="Local path where Metasploit Framework is installed")
609
610
takeover.add_argument("--tmp-path", dest="tmpPath",
611
help="Remote absolute path of temporary files directory")
612
613
# Windows registry options
614
windows = parser.add_argument_group("Windows registry access", "These options can be used to access the back-end database management system Windows registry")
615
616
windows.add_argument("--reg-read", dest="regRead", action="store_true",
617
help="Read a Windows registry key value")
618
619
windows.add_argument("--reg-add", dest="regAdd", action="store_true",
620
help="Write a Windows registry key value data")
621
622
windows.add_argument("--reg-del", dest="regDel", action="store_true",
623
help="Delete a Windows registry key value")
624
625
windows.add_argument("--reg-key", dest="regKey",
626
help="Windows registry key")
627
628
windows.add_argument("--reg-value", dest="regVal",
629
help="Windows registry key value")
630
631
windows.add_argument("--reg-data", dest="regData",
632
help="Windows registry key value data")
633
634
windows.add_argument("--reg-type", dest="regType",
635
help="Windows registry key value type")
636
637
# General options
638
general = parser.add_argument_group("General", "These options can be used to set some general working parameters")
639
640
general.add_argument("-s", dest="sessionFile",
641
help="Load session from a stored (.sqlite) file")
642
643
general.add_argument("-t", dest="trafficFile",
644
help="Log all HTTP traffic into a textual file")
645
646
general.add_argument("--abort-on-empty", dest="abortOnEmpty", action="store_true",
647
help="Abort data retrieval on empty results")
648
649
general.add_argument("--answers", dest="answers",
650
help="Set predefined answers (e.g. \"quit=N,follow=N\")")
651
652
general.add_argument("--base64", dest="base64Parameter",
653
help="Parameter(s) containing Base64 encoded data")
654
655
general.add_argument("--base64-safe", dest="base64Safe", action="store_true",
656
help="Use URL and filename safe Base64 alphabet (RFC 4648)")
657
658
general.add_argument("--batch", dest="batch", action="store_true",
659
help="Never ask for user input, use the default behavior")
660
661
general.add_argument("--binary-fields", dest="binaryFields",
662
help="Result fields having binary values (e.g. \"digest\")")
663
664
general.add_argument("--check-internet", dest="checkInternet", action="store_true",
665
help="Check Internet connection before assessing the target")
666
667
general.add_argument("--cleanup", dest="cleanup", action="store_true",
668
help="Clean up the DBMS from sqlmap specific UDF and tables")
669
670
general.add_argument("--crawl", dest="crawlDepth", type=int,
671
help="Crawl the website starting from the target URL")
672
673
general.add_argument("--crawl-exclude", dest="crawlExclude",
674
help="Regexp to exclude pages from crawling (e.g. \"logout\")")
675
676
general.add_argument("--csv-del", dest="csvDel",
677
help="Delimiting character used in CSV output (default \"%s\")" % defaults.csvDel)
678
679
general.add_argument("--charset", dest="charset",
680
help="Blind SQL injection charset (e.g. \"0123456789abcdef\")")
681
682
general.add_argument("--dump-file", dest="dumpFile",
683
help="Store dumped data to a custom file")
684
685
general.add_argument("--dump-format", dest="dumpFormat",
686
help="Format of dumped data (CSV (default), HTML or SQLITE)")
687
688
general.add_argument("--encoding", dest="encoding",
689
help="Character encoding used for data retrieval (e.g. GBK)")
690
691
general.add_argument("--eta", dest="eta", action="store_true",
692
help="Display for each output the estimated time of arrival")
693
694
general.add_argument("--flush-session", dest="flushSession", action="store_true",
695
help="Flush session files for current target")
696
697
general.add_argument("--forms", dest="forms", action="store_true",
698
help="Parse and test forms on target URL")
699
700
general.add_argument("--fresh-queries", dest="freshQueries", action="store_true",
701
help="Ignore query results stored in session file")
702
703
general.add_argument("--gpage", dest="googlePage", type=int,
704
help="Use Google dork results from specified page number")
705
706
general.add_argument("--har", dest="harFile",
707
help="Log all HTTP traffic into a HAR file")
708
709
general.add_argument("--hex", dest="hexConvert", action="store_true",
710
help="Use hex conversion during data retrieval")
711
712
general.add_argument("--output-dir", dest="outputDir", action="store",
713
help="Custom output directory path")
714
715
general.add_argument("--parse-errors", dest="parseErrors", action="store_true",
716
help="Parse and display DBMS error messages from responses")
717
718
general.add_argument("--preprocess", dest="preprocess",
719
help="Use given script(s) for preprocessing (request)")
720
721
general.add_argument("--postprocess", dest="postprocess",
722
help="Use given script(s) for postprocessing (response)")
723
724
general.add_argument("--repair", dest="repair", action="store_true",
725
help="Redump entries having unknown character marker (%s)" % INFERENCE_UNKNOWN_CHAR)
726
727
general.add_argument("--save", dest="saveConfig",
728
help="Save options to a configuration INI file")
729
730
general.add_argument("--scope", dest="scope",
731
help="Regexp for filtering targets")
732
733
general.add_argument("--skip-heuristics", dest="skipHeuristics", action="store_true",
734
help="Skip heuristic detection of vulnerabilities")
735
736
general.add_argument("--skip-waf", dest="skipWaf", action="store_true",
737
help="Skip heuristic detection of WAF/IPS protection")
738
739
general.add_argument("--table-prefix", dest="tablePrefix",
740
help="Prefix used for temporary tables (default: \"%s\")" % defaults.tablePrefix)
741
742
general.add_argument("--test-filter", dest="testFilter",
743
help="Select tests by payloads and/or titles (e.g. ROW)")
744
745
general.add_argument("--test-skip", dest="testSkip",
746
help="Skip tests by payloads and/or titles (e.g. BENCHMARK)")
747
748
general.add_argument("--time-limit", dest="timeLimit", type=float,
749
help="Run with a time limit in seconds (e.g. 3600)")
750
751
general.add_argument("--unsafe-naming", dest="unsafeNaming", action="store_true",
752
help="Disable escaping of DBMS identifiers (e.g. \"user\")")
753
754
general.add_argument("--web-root", dest="webRoot",
755
help="Web server document root directory (e.g. \"/var/www\")")
756
757
# Miscellaneous options
758
miscellaneous = parser.add_argument_group("Miscellaneous", "These options do not fit into any other category")
759
760
miscellaneous.add_argument("-z", dest="mnemonics",
761
help="Use short mnemonics (e.g. \"flu,bat,ban,tec=EU\")")
762
763
miscellaneous.add_argument("--alert", dest="alert",
764
help="Run host OS command(s) when SQL injection is found")
765
766
miscellaneous.add_argument("--beep", dest="beep", action="store_true",
767
help="Beep on question and/or when vulnerability is found")
768
769
miscellaneous.add_argument("--dependencies", dest="dependencies", action="store_true",
770
help="Check for missing (optional) sqlmap dependencies")
771
772
miscellaneous.add_argument("--disable-coloring", dest="disableColoring", action="store_true",
773
help="Disable console output coloring")
774
775
miscellaneous.add_argument("--disable-hashing", dest="disableHashing", action="store_true",
776
help="Disable hash analysis on table dumps")
777
778
miscellaneous.add_argument("--list-tampers", dest="listTampers", action="store_true",
779
help="Display list of available tamper scripts")
780
781
miscellaneous.add_argument("--no-logging", dest="noLogging", action="store_true",
782
help="Disable logging to a file")
783
784
miscellaneous.add_argument("--no-truncate", dest="noTruncate", action="store_true",
785
help="Disable console output truncation (e.g. long entr...)")
786
787
miscellaneous.add_argument("--offline", dest="offline", action="store_true",
788
help="Work in offline mode (only use session data)")
789
790
miscellaneous.add_argument("--purge", dest="purge", action="store_true",
791
help="Safely remove all content from sqlmap data directory")
792
793
miscellaneous.add_argument("--results-file", dest="resultsFile",
794
help="Location of CSV results file in multiple targets mode")
795
796
miscellaneous.add_argument("--shell", dest="shell", action="store_true",
797
help="Prompt for an interactive sqlmap shell")
798
799
miscellaneous.add_argument("--tmp-dir", dest="tmpDir",
800
help="Local directory for storing temporary files")
801
802
miscellaneous.add_argument("--unstable", dest="unstable", action="store_true",
803
help="Adjust options for unstable connections")
804
805
miscellaneous.add_argument("--update", dest="updateAll", action="store_true",
806
help="Update sqlmap")
807
808
miscellaneous.add_argument("--wizard", dest="wizard", action="store_true",
809
help="Simple wizard interface for beginner users")
810
811
# Hidden and/or experimental options
812
parser.add_argument("--crack", dest="hashFile",
813
help=SUPPRESS) # "Load and crack hashes from a file (standalone)"
814
815
parser.add_argument("--dummy", dest="dummy", action="store_true",
816
help=SUPPRESS)
817
818
parser.add_argument("--yuge", dest="yuge", action="store_true",
819
help=SUPPRESS)
820
821
parser.add_argument("--murphy-rate", dest="murphyRate", type=int,
822
help=SUPPRESS)
823
824
parser.add_argument("--debug", dest="debug", action="store_true",
825
help=SUPPRESS)
826
827
parser.add_argument("--deprecations", dest="deprecations", action="store_true",
828
help=SUPPRESS)
829
830
parser.add_argument("--disable-multi", dest="disableMulti", action="store_true",
831
help=SUPPRESS)
832
833
parser.add_argument("--disable-precon", dest="disablePrecon", action="store_true",
834
help=SUPPRESS)
835
836
parser.add_argument("--profile", dest="profile", action="store_true",
837
help=SUPPRESS)
838
839
parser.add_argument("--localhost", dest="localhost", action="store_true",
840
help=SUPPRESS)
841
842
parser.add_argument("--force-dbms", dest="forceDbms",
843
help=SUPPRESS)
844
845
parser.add_argument("--force-dns", dest="forceDns", action="store_true",
846
help=SUPPRESS)
847
848
parser.add_argument("--force-partial", dest="forcePartial", action="store_true",
849
help=SUPPRESS)
850
851
parser.add_argument("--force-pivoting", dest="forcePivoting", action="store_true",
852
help=SUPPRESS)
853
854
parser.add_argument("--ignore-stdin", dest="ignoreStdin", action="store_true",
855
help=SUPPRESS)
856
857
parser.add_argument("--non-interactive", dest="nonInteractive", action="store_true",
858
help=SUPPRESS)
859
860
parser.add_argument("--gui", dest="gui", action="store_true",
861
help=SUPPRESS)
862
863
parser.add_argument("--smoke-test", dest="smokeTest", action="store_true",
864
help=SUPPRESS)
865
866
parser.add_argument("--vuln-test", dest="vulnTest", action="store_true",
867
help=SUPPRESS)
868
869
parser.add_argument("--disable-json", dest="disableJson", action="store_true",
870
help=SUPPRESS)
871
872
# API options
873
parser.add_argument("--api", dest="api", action="store_true",
874
help=SUPPRESS)
875
876
parser.add_argument("--taskid", dest="taskid",
877
help=SUPPRESS)
878
879
parser.add_argument("--database", dest="database",
880
help=SUPPRESS)
881
882
# Dirty hack to display longer options without breaking into two lines
883
if hasattr(parser, "formatter"):
884
def _(self, *args):
885
retVal = parser.formatter._format_option_strings(*args)
886
if len(retVal) > MAX_HELP_OPTION_LENGTH:
887
retVal = ("%%.%ds.." % (MAX_HELP_OPTION_LENGTH - parser.formatter.indent_increment)) % retVal
888
return retVal
889
890
parser.formatter._format_option_strings = parser.formatter.format_option_strings
891
parser.formatter.format_option_strings = type(parser.formatter.format_option_strings)(_, parser)
892
else:
893
def _format_action_invocation(self, action):
894
retVal = self.__format_action_invocation(action)
895
if len(retVal) > MAX_HELP_OPTION_LENGTH:
896
retVal = ("%%.%ds.." % (MAX_HELP_OPTION_LENGTH - self._indent_increment)) % retVal
897
return retVal
898
899
parser.formatter_class.__format_action_invocation = parser.formatter_class._format_action_invocation
900
parser.formatter_class._format_action_invocation = _format_action_invocation
901
902
# Dirty hack for making a short option '-hh'
903
if hasattr(parser, "get_option"):
904
option = parser.get_option("--hh")
905
option._short_opts = ["-hh"]
906
option._long_opts = []
907
else:
908
for action in get_actions(parser):
909
if action.option_strings == ["--hh"]:
910
action.option_strings = ["-hh"]
911
break
912
913
# Dirty hack for inherent help message of switch '-h'
914
if hasattr(parser, "get_option"):
915
option = parser.get_option("-h")
916
option.help = option.help.capitalize().replace("this help", "basic help")
917
else:
918
for action in get_actions(parser):
919
if action.option_strings == ["-h", "--help"]:
920
action.help = action.help.capitalize().replace("this help", "basic help")
921
break
922
923
_ = []
924
advancedHelp = True
925
extraHeaders = []
926
auxIndexes = {}
927
928
# Reference: https://stackoverflow.com/a/4012683 (Note: previously used "...sys.getfilesystemencoding() or UNICODE_ENCODING")
929
for arg in argv:
930
_.append(getUnicode(arg, encoding=sys.stdin.encoding))
931
932
argv = _
933
checkOldOptions(argv)
934
935
if "--gui" in argv:
936
from lib.core.gui import runGui
937
938
runGui(parser)
939
940
raise SqlmapSilentQuitException
941
942
elif "--shell" in argv:
943
_createHomeDirectories()
944
945
parser.usage = ""
946
cmdLineOptions.sqlmapShell = True
947
948
commands = set(("x", "q", "exit", "quit", "clear"))
949
commands.update(get_all_options(parser))
950
951
autoCompletion(AUTOCOMPLETE_TYPE.SQLMAP, commands=commands)
952
953
while True:
954
command = None
955
prompt = "sqlmap > "
956
957
try:
958
# Note: in Python2 command should not be converted to Unicode before passing to shlex (Reference: https://bugs.python.org/issue1170)
959
command = _input(prompt).strip()
960
except (KeyboardInterrupt, EOFError):
961
print()
962
raise SqlmapShellQuitException
963
964
command = re.sub(r"(?i)\Anew\s+", "", command or "")
965
966
if not command:
967
continue
968
elif command.lower() == "clear":
969
clearHistory()
970
dataToStdout("[i] history cleared\n")
971
saveHistory(AUTOCOMPLETE_TYPE.SQLMAP)
972
elif command.lower() in ("x", "q", "exit", "quit"):
973
raise SqlmapShellQuitException
974
elif command[0] != '-':
975
if not re.search(r"(?i)\A(\?|help)\Z", command):
976
dataToStdout("[!] invalid option(s) provided\n")
977
dataToStdout("[i] valid example: '-u http://www.site.com/vuln.php?id=1 --banner'\n")
978
else:
979
saveHistory(AUTOCOMPLETE_TYPE.SQLMAP)
980
loadHistory(AUTOCOMPLETE_TYPE.SQLMAP)
981
break
982
983
try:
984
for arg in shlex.split(command):
985
argv.append(getUnicode(arg, encoding=sys.stdin.encoding))
986
except ValueError as ex:
987
raise SqlmapSyntaxException("something went wrong during command line parsing ('%s')" % getSafeExString(ex))
988
989
longOptions = set(re.findall(r"\-\-([^= ]+?)=", parser.format_help()))
990
longSwitches = set(re.findall(r"\-\-([^= ]+?)\s", parser.format_help()))
991
992
for i in xrange(len(argv)):
993
# Reference: https://en.wiktionary.org/wiki/-
994
argv[i] = re.sub(u"\\A(\u2010|\u2013|\u2212|\u2014|\u4e00|\u1680|\uFE63|\uFF0D)+", lambda match: '-' * len(match.group(0)), argv[i])
995
996
# Reference: https://unicode-table.com/en/sets/quotation-marks/
997
argv[i] = argv[i].strip(u"\u00AB\u2039\u00BB\u203A\u201E\u201C\u201F\u201D\u2019\u275D\u275E\u276E\u276F\u2E42\u301D\u301E\u301F\uFF02\u201A\u2018\u201B\u275B\u275C")
998
999
if argv[i] == "-hh":
1000
argv[i] = "-h"
1001
elif i == 1 and re.search(r"\A(http|www\.|\w[\w.-]+\.\w{2,})", argv[i]) is not None:
1002
argv[i] = "--url=%s" % argv[i]
1003
elif len(argv[i]) > 1 and all(ord(_) in xrange(0x2018, 0x2020) for _ in ((argv[i].split('=', 1)[-1].strip() or ' ')[0], argv[i][-1])):
1004
dataToStdout("[!] copy-pasting illegal (non-console) quote characters from Internet is illegal (%s)\n" % argv[i])
1005
raise SystemExit
1006
elif len(argv[i]) > 1 and u"\uff0c" in argv[i].split('=', 1)[-1]:
1007
dataToStdout("[!] copy-pasting illegal (non-console) comma characters from Internet is illegal (%s)\n" % argv[i])
1008
raise SystemExit
1009
elif re.search(r"\A-\w=.+", argv[i]):
1010
dataToStdout("[!] potentially miswritten (illegal '=') short option detected ('%s')\n" % argv[i])
1011
raise SystemExit
1012
elif re.search(r"\A-\w{3,}", argv[i]):
1013
if argv[i].strip('-').split('=')[0] in (longOptions | longSwitches):
1014
argv[i] = "-%s" % argv[i]
1015
elif argv[i] in IGNORED_OPTIONS:
1016
argv[i] = ""
1017
elif argv[i] in DEPRECATED_OPTIONS:
1018
argv[i] = ""
1019
elif argv[i] in ("-s", "--silent"):
1020
if i + 1 < len(argv) and argv[i + 1].startswith('-') or i + 1 == len(argv):
1021
argv[i] = ""
1022
conf.verbose = 0
1023
elif argv[i].startswith("--data-raw"):
1024
argv[i] = argv[i].replace("--data-raw", "--data", 1)
1025
elif argv[i].startswith("--auth-creds"):
1026
argv[i] = argv[i].replace("--auth-creds", "--auth-cred", 1)
1027
elif argv[i].startswith("--drop-cookie"):
1028
argv[i] = argv[i].replace("--drop-cookie", "--drop-set-cookie", 1)
1029
elif re.search(r"\A--tamper[^=\s]", argv[i]):
1030
argv[i] = ""
1031
elif re.search(r"\A(--(tamper|ignore-code|skip))(?!-)", argv[i]):
1032
key = re.search(r"\-?\-(\w+)\b", argv[i]).group(1)
1033
index = auxIndexes.get(key, None)
1034
if index is None:
1035
index = i if '=' in argv[i] else (i + 1 if i + 1 < len(argv) and not argv[i + 1].startswith('-') else None)
1036
auxIndexes[key] = index
1037
else:
1038
delimiter = ','
1039
argv[index] = "%s%s%s" % (argv[index], delimiter, argv[i].split('=')[1] if '=' in argv[i] else (argv[i + 1] if i + 1 < len(argv) and not argv[i + 1].startswith('-') else ""))
1040
argv[i] = ""
1041
elif argv[i] in ("-H", "--header") or any(argv[i].startswith("%s=" % _) for _ in ("-H", "--header")):
1042
if '=' in argv[i]:
1043
extraHeaders.append(argv[i].split('=', 1)[1])
1044
elif i + 1 < len(argv):
1045
extraHeaders.append(argv[i + 1])
1046
elif argv[i] == "--deps":
1047
argv[i] = "--dependencies"
1048
elif argv[i] == "--disable-colouring":
1049
argv[i] = "--disable-coloring"
1050
elif argv[i] == "-r":
1051
for j in xrange(i + 2, len(argv)):
1052
value = argv[j]
1053
if os.path.isfile(value):
1054
argv[i + 1] += ",%s" % value
1055
argv[j] = ''
1056
else:
1057
break
1058
elif re.match(r"\A\d+!\Z", argv[i]) and argv[max(0, i - 1)] == "--threads" or re.match(r"\A--threads.+\d+!\Z", argv[i]):
1059
argv[i] = argv[i][:-1]
1060
conf.skipThreadCheck = True
1061
elif argv[i] == "--version":
1062
print(VERSION_STRING.split('/')[-1])
1063
raise SystemExit
1064
elif argv[i] in ("-h", "--help"):
1065
advancedHelp = False
1066
for group in get_groups(parser)[:]:
1067
found = False
1068
for option in get_actions(group):
1069
if option.dest not in BASIC_HELP_ITEMS:
1070
option.help = SUPPRESS
1071
else:
1072
found = True
1073
if not found:
1074
get_groups(parser).remove(group)
1075
elif '=' in argv[i] and not argv[i].startswith('-') and argv[i].split('=')[0] in longOptions and re.search(r"\A-{1,2}\w", argv[i - 1]) is None:
1076
dataToStdout("[!] detected usage of long-option without a starting hyphen ('%s')\n" % argv[i])
1077
raise SystemExit
1078
1079
for verbosity in (_ for _ in argv if re.search(r"\A\-v+\Z", _)):
1080
try:
1081
if argv.index(verbosity) == len(argv) - 1 or not argv[argv.index(verbosity) + 1].isdigit():
1082
conf.verbose = verbosity.count('v')
1083
del argv[argv.index(verbosity)]
1084
except (IndexError, ValueError):
1085
pass
1086
1087
try:
1088
(args, _) = parser.parse_known_args(argv) if hasattr(parser, "parse_known_args") else parser.parse_args(argv)
1089
except UnicodeEncodeError as ex:
1090
dataToStdout("\n[!] %s\n" % getUnicode(ex.object.encode("unicode-escape")))
1091
raise SystemExit
1092
except SystemExit:
1093
if "-h" in argv and not advancedHelp:
1094
dataToStdout("\n[!] to see full list of options run with '-hh'\n")
1095
raise
1096
1097
if extraHeaders:
1098
if not args.headers:
1099
args.headers = ""
1100
delimiter = "\\n" if "\\n" in args.headers else "\n"
1101
args.headers += delimiter + delimiter.join(extraHeaders)
1102
1103
# Expand given mnemonic options (e.g. -z "ign,flu,bat")
1104
for i in xrange(len(argv) - 1):
1105
if argv[i] == "-z":
1106
expandMnemonics(argv[i + 1], parser, args)
1107
1108
if args.dummy:
1109
args.url = args.url or DUMMY_URL
1110
1111
if hasattr(sys.stdin, "fileno") and not any((os.isatty(sys.stdin.fileno()), args.api, args.ignoreStdin, "GITHUB_ACTIONS" in os.environ)):
1112
args.stdinPipe = iter(sys.stdin.readline, None)
1113
else:
1114
args.stdinPipe = None
1115
1116
if not any((args.direct, args.url, args.logFile, args.bulkFile, args.googleDork, args.configFile, args.requestFile, args.updateAll, args.smokeTest, args.vulnTest, args.wizard, args.dependencies, args.purge, args.listTampers, args.hashFile, args.stdinPipe)):
1117
errMsg = "missing a mandatory option (-d, -u, -l, -m, -r, -g, -c, --wizard, --shell, --update, --purge, --list-tampers or --dependencies). "
1118
errMsg += "Use -h for basic and -hh for advanced help\n"
1119
parser.error(errMsg)
1120
1121
return args
1122
1123
except (ArgumentError, TypeError) as ex:
1124
parser.error(ex)
1125
1126
except SystemExit:
1127
# Protection against Windows dummy double clicking
1128
if IS_WIN and "--non-interactive" not in sys.argv:
1129
dataToStdout("\nPress Enter to continue...")
1130
_input()
1131
raise
1132
1133
debugMsg = "parsing command line"
1134
logger.debug(debugMsg)
1135
1136