Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
sqlmapproject
GitHub Repository: sqlmapproject/sqlmap
Path: blob/master/lib/parse/cmdline.py
3556 views
1
#!/usr/bin/env python
2
3
"""
4
Copyright (c) 2006-2026 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("--skip-xmlencode", dest="skipXmlEncode", action="store_true",
280
help="Skip safe encoding of payload data for SOAP/XML")
281
282
request.add_argument("--csrf-token", dest="csrfToken",
283
help="Parameter used to hold anti-CSRF token")
284
285
request.add_argument("--csrf-url", dest="csrfUrl",
286
help="URL address to visit for extraction of anti-CSRF token")
287
288
request.add_argument("--csrf-method", dest="csrfMethod",
289
help="HTTP method to use during anti-CSRF token page visit")
290
291
request.add_argument("--csrf-data", dest="csrfData",
292
help="POST data to send during anti-CSRF token page visit")
293
294
request.add_argument("--csrf-retries", dest="csrfRetries", type=int,
295
help="Retries for anti-CSRF token retrieval (default %d)" % defaults.csrfRetries)
296
297
request.add_argument("--force-ssl", dest="forceSSL", action="store_true",
298
help="Force usage of SSL/HTTPS")
299
300
request.add_argument("--chunked", dest="chunked", action="store_true",
301
help="Use HTTP chunked transfer encoded (POST) requests")
302
303
request.add_argument("--hpp", dest="hpp", action="store_true",
304
help="Use HTTP parameter pollution method")
305
306
request.add_argument("--eval", dest="evalCode",
307
help="Evaluate provided Python code before the request (e.g. \"import hashlib;id2=hashlib.md5(id).hexdigest()\")")
308
309
# Optimization options
310
optimization = parser.add_argument_group("Optimization", "These options can be used to optimize the performance of sqlmap")
311
312
optimization.add_argument("-o", dest="optimize", action="store_true",
313
help="Turn on all optimization switches")
314
315
optimization.add_argument("--predict-output", dest="predictOutput", action="store_true",
316
help="Predict common queries output")
317
318
optimization.add_argument("--keep-alive", dest="keepAlive", action="store_true",
319
help="Use persistent HTTP(s) connections")
320
321
optimization.add_argument("--null-connection", dest="nullConnection", action="store_true",
322
help="Retrieve page length without actual HTTP response body")
323
324
optimization.add_argument("--threads", dest="threads", type=int,
325
help="Max number of concurrent HTTP(s) requests (default %d)" % defaults.threads)
326
327
# Injection options
328
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")
329
330
injection.add_argument("-p", dest="testParameter",
331
help="Testable parameter(s)")
332
333
injection.add_argument("--skip", dest="skip",
334
help="Skip testing for given parameter(s)")
335
336
injection.add_argument("--skip-static", dest="skipStatic", action="store_true",
337
help="Skip testing parameters that not appear to be dynamic")
338
339
injection.add_argument("--param-exclude", dest="paramExclude",
340
help="Regexp to exclude parameters from testing (e.g. \"ses\")")
341
342
injection.add_argument("--param-filter", dest="paramFilter",
343
help="Select testable parameter(s) by place (e.g. \"POST\")")
344
345
injection.add_argument("--dbms", dest="dbms",
346
help="Force back-end DBMS to provided value")
347
348
injection.add_argument("--dbms-cred", dest="dbmsCred",
349
help="DBMS authentication credentials (user:password)")
350
351
injection.add_argument("--os", dest="os",
352
help="Force back-end DBMS operating system to provided value")
353
354
injection.add_argument("--invalid-bignum", dest="invalidBignum", action="store_true",
355
help="Use big numbers for invalidating values")
356
357
injection.add_argument("--invalid-logical", dest="invalidLogical", action="store_true",
358
help="Use logical operations for invalidating values")
359
360
injection.add_argument("--invalid-string", dest="invalidString", action="store_true",
361
help="Use random strings for invalidating values")
362
363
injection.add_argument("--no-cast", dest="noCast", action="store_true",
364
help="Turn off payload casting mechanism")
365
366
injection.add_argument("--no-escape", dest="noEscape", action="store_true",
367
help="Turn off string escaping mechanism")
368
369
injection.add_argument("--prefix", dest="prefix",
370
help="Injection payload prefix string")
371
372
injection.add_argument("--suffix", dest="suffix",
373
help="Injection payload suffix string")
374
375
injection.add_argument("--tamper", dest="tamper",
376
help="Use given script(s) for tampering injection data")
377
378
# Detection options
379
detection = parser.add_argument_group("Detection", "These options can be used to customize the detection phase")
380
381
detection.add_argument("--level", dest="level", type=int,
382
help="Level of tests to perform (1-5, default %d)" % defaults.level)
383
384
detection.add_argument("--risk", dest="risk", type=int,
385
help="Risk of tests to perform (1-3, default %d)" % defaults.risk)
386
387
detection.add_argument("--string", dest="string",
388
help="String to match when query is evaluated to True")
389
390
detection.add_argument("--not-string", dest="notString",
391
help="String to match when query is evaluated to False")
392
393
detection.add_argument("--regexp", dest="regexp",
394
help="Regexp to match when query is evaluated to True")
395
396
detection.add_argument("--code", dest="code", type=int,
397
help="HTTP code to match when query is evaluated to True")
398
399
detection.add_argument("--smart", dest="smart", action="store_true",
400
help="Perform thorough tests only if positive heuristic(s)")
401
402
detection.add_argument("--text-only", dest="textOnly", action="store_true",
403
help="Compare pages based only on the textual content")
404
405
detection.add_argument("--titles", dest="titles", action="store_true",
406
help="Compare pages based only on their titles")
407
408
# Techniques options
409
techniques = parser.add_argument_group("Techniques", "These options can be used to tweak testing of specific SQL injection techniques")
410
411
techniques.add_argument("--technique", dest="technique",
412
help="SQL injection techniques to use (default \"%s\")" % defaults.technique)
413
414
techniques.add_argument("--time-sec", dest="timeSec", type=int,
415
help="Seconds to delay the DBMS response (default %d)" % defaults.timeSec)
416
417
techniques.add_argument("--disable-stats", dest="disableStats", action="store_true",
418
help="Disable the statistical model for detecting the delay")
419
420
techniques.add_argument("--union-cols", dest="uCols",
421
help="Range of columns to test for UNION query SQL injection")
422
423
techniques.add_argument("--union-char", dest="uChar",
424
help="Character to use for bruteforcing number of columns")
425
426
techniques.add_argument("--union-from", dest="uFrom",
427
help="Table to use in FROM part of UNION query SQL injection")
428
429
techniques.add_argument("--union-values", dest="uValues",
430
help="Column values to use for UNION query SQL injection")
431
432
techniques.add_argument("--dns-domain", dest="dnsDomain",
433
help="Domain name used for DNS exfiltration attack")
434
435
techniques.add_argument("--second-url", dest="secondUrl",
436
help="Resulting page URL searched for second-order response")
437
438
techniques.add_argument("--second-req", dest="secondReq",
439
help="Load second-order HTTP request from file")
440
441
# Fingerprint options
442
fingerprint = parser.add_argument_group("Fingerprint")
443
444
fingerprint.add_argument("-f", "--fingerprint", dest="extensiveFp", action="store_true",
445
help="Perform an extensive DBMS version fingerprint")
446
447
# Enumeration options
448
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")
449
450
enumeration.add_argument("-a", "--all", dest="getAll", action="store_true",
451
help="Retrieve everything")
452
453
enumeration.add_argument("-b", "--banner", dest="getBanner", action="store_true",
454
help="Retrieve DBMS banner")
455
456
enumeration.add_argument("--current-user", dest="getCurrentUser", action="store_true",
457
help="Retrieve DBMS current user")
458
459
enumeration.add_argument("--current-db", dest="getCurrentDb", action="store_true",
460
help="Retrieve DBMS current database")
461
462
enumeration.add_argument("--hostname", dest="getHostname", action="store_true",
463
help="Retrieve DBMS server hostname")
464
465
enumeration.add_argument("--is-dba", dest="isDba", action="store_true",
466
help="Detect if the DBMS current user is DBA")
467
468
enumeration.add_argument("--users", dest="getUsers", action="store_true",
469
help="Enumerate DBMS users")
470
471
enumeration.add_argument("--passwords", dest="getPasswordHashes", action="store_true",
472
help="Enumerate DBMS users password hashes")
473
474
enumeration.add_argument("--privileges", dest="getPrivileges", action="store_true",
475
help="Enumerate DBMS users privileges")
476
477
enumeration.add_argument("--roles", dest="getRoles", action="store_true",
478
help="Enumerate DBMS users roles")
479
480
enumeration.add_argument("--dbs", dest="getDbs", action="store_true",
481
help="Enumerate DBMS databases")
482
483
enumeration.add_argument("--tables", dest="getTables", action="store_true",
484
help="Enumerate DBMS database tables")
485
486
enumeration.add_argument("--columns", dest="getColumns", action="store_true",
487
help="Enumerate DBMS database table columns")
488
489
enumeration.add_argument("--schema", dest="getSchema", action="store_true",
490
help="Enumerate DBMS schema")
491
492
enumeration.add_argument("--count", dest="getCount", action="store_true",
493
help="Retrieve number of entries for table(s)")
494
495
enumeration.add_argument("--dump", dest="dumpTable", action="store_true",
496
help="Dump DBMS database table entries")
497
498
enumeration.add_argument("--dump-all", dest="dumpAll", action="store_true",
499
help="Dump all DBMS databases tables entries")
500
501
enumeration.add_argument("--search", dest="search", action="store_true",
502
help="Search column(s), table(s) and/or database name(s)")
503
504
enumeration.add_argument("--comments", dest="getComments", action="store_true",
505
help="Check for DBMS comments during enumeration")
506
507
enumeration.add_argument("--statements", dest="getStatements", action="store_true",
508
help="Retrieve SQL statements being run on DBMS")
509
510
enumeration.add_argument("-D", dest="db",
511
help="DBMS database to enumerate")
512
513
enumeration.add_argument("-T", dest="tbl",
514
help="DBMS database table(s) to enumerate")
515
516
enumeration.add_argument("-C", dest="col",
517
help="DBMS database table column(s) to enumerate")
518
519
enumeration.add_argument("-X", dest="exclude",
520
help="DBMS database identifier(s) to not enumerate")
521
522
enumeration.add_argument("-U", dest="user",
523
help="DBMS user to enumerate")
524
525
enumeration.add_argument("--exclude-sysdbs", dest="excludeSysDbs", action="store_true",
526
help="Exclude DBMS system databases when enumerating tables")
527
528
enumeration.add_argument("--pivot-column", dest="pivotColumn",
529
help="Pivot column name")
530
531
enumeration.add_argument("--where", dest="dumpWhere",
532
help="Use WHERE condition while table dumping")
533
534
enumeration.add_argument("--start", dest="limitStart", type=int,
535
help="First dump table entry to retrieve")
536
537
enumeration.add_argument("--stop", dest="limitStop", type=int,
538
help="Last dump table entry to retrieve")
539
540
enumeration.add_argument("--first", dest="firstChar", type=int,
541
help="First query output word character to retrieve")
542
543
enumeration.add_argument("--last", dest="lastChar", type=int,
544
help="Last query output word character to retrieve")
545
546
enumeration.add_argument("--sql-query", dest="sqlQuery",
547
help="SQL statement to be executed")
548
549
enumeration.add_argument("--sql-shell", dest="sqlShell", action="store_true",
550
help="Prompt for an interactive SQL shell")
551
552
enumeration.add_argument("--sql-file", dest="sqlFile",
553
help="Execute SQL statements from given file(s)")
554
555
# Brute force options
556
brute = parser.add_argument_group("Brute force", "These options can be used to run brute force checks")
557
558
brute.add_argument("--common-tables", dest="commonTables", action="store_true",
559
help="Check existence of common tables")
560
561
brute.add_argument("--common-columns", dest="commonColumns", action="store_true",
562
help="Check existence of common columns")
563
564
brute.add_argument("--common-files", dest="commonFiles", action="store_true",
565
help="Check existence of common files")
566
567
# User-defined function options
568
udf = parser.add_argument_group("User-defined function injection", "These options can be used to create custom user-defined functions")
569
570
udf.add_argument("--udf-inject", dest="udfInject", action="store_true",
571
help="Inject custom user-defined functions")
572
573
udf.add_argument("--shared-lib", dest="shLib",
574
help="Local path of the shared library")
575
576
# File system options
577
filesystem = parser.add_argument_group("File system access", "These options can be used to access the back-end database management system underlying file system")
578
579
filesystem.add_argument("--file-read", dest="fileRead",
580
help="Read a file from the back-end DBMS file system")
581
582
filesystem.add_argument("--file-write", dest="fileWrite",
583
help="Write a local file on the back-end DBMS file system")
584
585
filesystem.add_argument("--file-dest", dest="fileDest",
586
help="Back-end DBMS absolute filepath to write to")
587
588
# Takeover options
589
takeover = parser.add_argument_group("Operating system access", "These options can be used to access the back-end database management system underlying operating system")
590
591
takeover.add_argument("--os-cmd", dest="osCmd",
592
help="Execute an operating system command")
593
594
takeover.add_argument("--os-shell", dest="osShell", action="store_true",
595
help="Prompt for an interactive operating system shell")
596
597
takeover.add_argument("--os-pwn", dest="osPwn", action="store_true",
598
help="Prompt for an OOB shell, Meterpreter or VNC")
599
600
takeover.add_argument("--os-smbrelay", dest="osSmb", action="store_true",
601
help="One click prompt for an OOB shell, Meterpreter or VNC")
602
603
takeover.add_argument("--os-bof", dest="osBof", action="store_true",
604
help="Stored procedure buffer overflow "
605
"exploitation")
606
607
takeover.add_argument("--priv-esc", dest="privEsc", action="store_true",
608
help="Database process user privilege escalation")
609
610
takeover.add_argument("--msf-path", dest="msfPath",
611
help="Local path where Metasploit Framework is installed")
612
613
takeover.add_argument("--tmp-path", dest="tmpPath",
614
help="Remote absolute path of temporary files directory")
615
616
# Windows registry options
617
windows = parser.add_argument_group("Windows registry access", "These options can be used to access the back-end database management system Windows registry")
618
619
windows.add_argument("--reg-read", dest="regRead", action="store_true",
620
help="Read a Windows registry key value")
621
622
windows.add_argument("--reg-add", dest="regAdd", action="store_true",
623
help="Write a Windows registry key value data")
624
625
windows.add_argument("--reg-del", dest="regDel", action="store_true",
626
help="Delete a Windows registry key value")
627
628
windows.add_argument("--reg-key", dest="regKey",
629
help="Windows registry key")
630
631
windows.add_argument("--reg-value", dest="regVal",
632
help="Windows registry key value")
633
634
windows.add_argument("--reg-data", dest="regData",
635
help="Windows registry key value data")
636
637
windows.add_argument("--reg-type", dest="regType",
638
help="Windows registry key value type")
639
640
# General options
641
general = parser.add_argument_group("General", "These options can be used to set some general working parameters")
642
643
general.add_argument("-s", dest="sessionFile",
644
help="Load session from a stored (.sqlite) file")
645
646
general.add_argument("-t", dest="trafficFile",
647
help="Log all HTTP traffic into a textual file")
648
649
general.add_argument("--abort-on-empty", dest="abortOnEmpty", action="store_true",
650
help="Abort data retrieval on empty results")
651
652
general.add_argument("--answers", dest="answers",
653
help="Set predefined answers (e.g. \"quit=N,follow=N\")")
654
655
general.add_argument("--base64", dest="base64Parameter",
656
help="Parameter(s) containing Base64 encoded data")
657
658
general.add_argument("--base64-safe", dest="base64Safe", action="store_true",
659
help="Use URL and filename safe Base64 alphabet (RFC 4648)")
660
661
general.add_argument("--batch", dest="batch", action="store_true",
662
help="Never ask for user input, use the default behavior")
663
664
general.add_argument("--binary-fields", dest="binaryFields",
665
help="Result fields having binary values (e.g. \"digest\")")
666
667
general.add_argument("--check-internet", dest="checkInternet", action="store_true",
668
help="Check Internet connection before assessing the target")
669
670
general.add_argument("--cleanup", dest="cleanup", action="store_true",
671
help="Clean up the DBMS from sqlmap specific UDF and tables")
672
673
general.add_argument("--crawl", dest="crawlDepth", type=int,
674
help="Crawl the website starting from the target URL")
675
676
general.add_argument("--crawl-exclude", dest="crawlExclude",
677
help="Regexp to exclude pages from crawling (e.g. \"logout\")")
678
679
general.add_argument("--csv-del", dest="csvDel",
680
help="Delimiting character used in CSV output (default \"%s\")" % defaults.csvDel)
681
682
general.add_argument("--charset", dest="charset",
683
help="Blind SQL injection charset (e.g. \"0123456789abcdef\")")
684
685
general.add_argument("--dump-file", dest="dumpFile",
686
help="Store dumped data to a custom file")
687
688
general.add_argument("--dump-format", dest="dumpFormat",
689
help="Format of dumped data (CSV (default), HTML or SQLITE)")
690
691
general.add_argument("--encoding", dest="encoding",
692
help="Character encoding used for data retrieval (e.g. GBK)")
693
694
general.add_argument("--eta", dest="eta", action="store_true",
695
help="Display for each output the estimated time of arrival")
696
697
general.add_argument("--flush-session", dest="flushSession", action="store_true",
698
help="Flush session files for current target")
699
700
general.add_argument("--forms", dest="forms", action="store_true",
701
help="Parse and test forms on target URL")
702
703
general.add_argument("--fresh-queries", dest="freshQueries", action="store_true",
704
help="Ignore query results stored in session file")
705
706
general.add_argument("--gpage", dest="googlePage", type=int,
707
help="Use Google dork results from specified page number")
708
709
general.add_argument("--har", dest="harFile",
710
help="Log all HTTP traffic into a HAR file")
711
712
general.add_argument("--hex", dest="hexConvert", action="store_true",
713
help="Use hex conversion during data retrieval")
714
715
general.add_argument("--output-dir", dest="outputDir", action="store",
716
help="Custom output directory path")
717
718
general.add_argument("--parse-errors", dest="parseErrors", action="store_true",
719
help="Parse and display DBMS error messages from responses")
720
721
general.add_argument("--preprocess", dest="preprocess",
722
help="Use given script(s) for preprocessing (request)")
723
724
general.add_argument("--postprocess", dest="postprocess",
725
help="Use given script(s) for postprocessing (response)")
726
727
general.add_argument("--repair", dest="repair", action="store_true",
728
help="Redump entries having unknown character marker (%s)" % INFERENCE_UNKNOWN_CHAR)
729
730
general.add_argument("--save", dest="saveConfig",
731
help="Save options to a configuration INI file")
732
733
general.add_argument("--scope", dest="scope",
734
help="Regexp for filtering targets")
735
736
general.add_argument("--skip-heuristics", dest="skipHeuristics", action="store_true",
737
help="Skip heuristic detection of vulnerabilities")
738
739
general.add_argument("--skip-waf", dest="skipWaf", action="store_true",
740
help="Skip heuristic detection of WAF/IPS protection")
741
742
general.add_argument("--table-prefix", dest="tablePrefix",
743
help="Prefix used for temporary tables (default: \"%s\")" % defaults.tablePrefix)
744
745
general.add_argument("--test-filter", dest="testFilter",
746
help="Select tests by payloads and/or titles (e.g. ROW)")
747
748
general.add_argument("--test-skip", dest="testSkip",
749
help="Skip tests by payloads and/or titles (e.g. BENCHMARK)")
750
751
general.add_argument("--time-limit", dest="timeLimit", type=float,
752
help="Run with a time limit in seconds (e.g. 3600)")
753
754
general.add_argument("--unsafe-naming", dest="unsafeNaming", action="store_true",
755
help="Disable escaping of DBMS identifiers (e.g. \"user\")")
756
757
general.add_argument("--web-root", dest="webRoot",
758
help="Web server document root directory (e.g. \"/var/www\")")
759
760
# Miscellaneous options
761
miscellaneous = parser.add_argument_group("Miscellaneous", "These options do not fit into any other category")
762
763
miscellaneous.add_argument("-z", dest="mnemonics",
764
help="Use short mnemonics (e.g. \"flu,bat,ban,tec=EU\")")
765
766
miscellaneous.add_argument("--alert", dest="alert",
767
help="Run host OS command(s) when SQL injection is found")
768
769
miscellaneous.add_argument("--beep", dest="beep", action="store_true",
770
help="Beep on question and/or when vulnerability is found")
771
772
miscellaneous.add_argument("--dependencies", dest="dependencies", action="store_true",
773
help="Check for missing (optional) sqlmap dependencies")
774
775
miscellaneous.add_argument("--disable-coloring", dest="disableColoring", action="store_true",
776
help="Disable console output coloring")
777
778
miscellaneous.add_argument("--disable-hashing", dest="disableHashing", action="store_true",
779
help="Disable hash analysis on table dumps")
780
781
miscellaneous.add_argument("--gui", dest="gui", action="store_true",
782
help="Experimental Tkinter GUI")
783
784
miscellaneous.add_argument("--list-tampers", dest="listTampers", action="store_true",
785
help="Display list of available tamper scripts")
786
787
miscellaneous.add_argument("--no-logging", dest="noLogging", action="store_true",
788
help="Disable logging to a file")
789
790
miscellaneous.add_argument("--no-truncate", dest="noTruncate", action="store_true",
791
help="Disable console output truncation (e.g. long entr...)")
792
793
miscellaneous.add_argument("--offline", dest="offline", action="store_true",
794
help="Work in offline mode (only use session data)")
795
796
miscellaneous.add_argument("--purge", dest="purge", action="store_true",
797
help="Safely remove all content from sqlmap data directory")
798
799
miscellaneous.add_argument("--results-file", dest="resultsFile",
800
help="Location of CSV results file in multiple targets mode")
801
802
miscellaneous.add_argument("--shell", dest="shell", action="store_true",
803
help="Prompt for an interactive sqlmap shell")
804
805
miscellaneous.add_argument("--tmp-dir", dest="tmpDir",
806
help="Local directory for storing temporary files")
807
808
miscellaneous.add_argument("--tui", dest="tui", action="store_true",
809
help="Experimental ncurses TUI")
810
811
miscellaneous.add_argument("--unstable", dest="unstable", action="store_true",
812
help="Adjust options for unstable connections")
813
814
miscellaneous.add_argument("--update", dest="updateAll", action="store_true",
815
help="Update sqlmap")
816
817
miscellaneous.add_argument("--wizard", dest="wizard", action="store_true",
818
help="Simple wizard interface for beginner users")
819
820
# Hidden and/or experimental options
821
parser.add_argument("--crack", dest="hashFile",
822
help=SUPPRESS) # "Load and crack hashes from a file (standalone)"
823
824
parser.add_argument("--dummy", dest="dummy", action="store_true",
825
help=SUPPRESS)
826
827
parser.add_argument("--yuge", dest="yuge", action="store_true",
828
help=SUPPRESS)
829
830
parser.add_argument("--murphy-rate", dest="murphyRate", type=int,
831
help=SUPPRESS)
832
833
parser.add_argument("--debug", dest="debug", action="store_true",
834
help=SUPPRESS)
835
836
parser.add_argument("--deprecations", dest="deprecations", action="store_true",
837
help=SUPPRESS)
838
839
parser.add_argument("--disable-multi", dest="disableMulti", action="store_true",
840
help=SUPPRESS)
841
842
parser.add_argument("--disable-precon", dest="disablePrecon", action="store_true",
843
help=SUPPRESS)
844
845
parser.add_argument("--profile", dest="profile", action="store_true",
846
help=SUPPRESS)
847
848
parser.add_argument("--localhost", dest="localhost", action="store_true",
849
help=SUPPRESS)
850
851
parser.add_argument("--force-dbms", dest="forceDbms",
852
help=SUPPRESS)
853
854
parser.add_argument("--force-dns", dest="forceDns", action="store_true",
855
help=SUPPRESS)
856
857
parser.add_argument("--force-partial", dest="forcePartial", action="store_true",
858
help=SUPPRESS)
859
860
parser.add_argument("--force-pivoting", dest="forcePivoting", action="store_true",
861
help=SUPPRESS)
862
863
parser.add_argument("--ignore-stdin", dest="ignoreStdin", action="store_true",
864
help=SUPPRESS)
865
866
parser.add_argument("--non-interactive", dest="nonInteractive", action="store_true",
867
help=SUPPRESS)
868
869
parser.add_argument("--smoke-test", dest="smokeTest", action="store_true",
870
help=SUPPRESS)
871
872
parser.add_argument("--vuln-test", dest="vulnTest", action="store_true",
873
help=SUPPRESS)
874
875
parser.add_argument("--disable-json", dest="disableJson", action="store_true",
876
help=SUPPRESS)
877
878
# API options
879
parser.add_argument("--api", dest="api", action="store_true",
880
help=SUPPRESS)
881
882
parser.add_argument("--taskid", dest="taskid",
883
help=SUPPRESS)
884
885
parser.add_argument("--database", dest="database",
886
help=SUPPRESS)
887
888
# Dirty hack to display longer options without breaking into two lines
889
if hasattr(parser, "formatter"):
890
def _(self, *args):
891
retVal = parser.formatter._format_option_strings(*args)
892
if len(retVal) > MAX_HELP_OPTION_LENGTH:
893
retVal = ("%%.%ds.." % (MAX_HELP_OPTION_LENGTH - parser.formatter.indent_increment)) % retVal
894
return retVal
895
896
parser.formatter._format_option_strings = parser.formatter.format_option_strings
897
parser.formatter.format_option_strings = type(parser.formatter.format_option_strings)(_, parser)
898
else:
899
def _format_action_invocation(self, action):
900
retVal = self.__format_action_invocation(action)
901
if len(retVal) > MAX_HELP_OPTION_LENGTH:
902
retVal = ("%%.%ds.." % (MAX_HELP_OPTION_LENGTH - self._indent_increment)) % retVal
903
return retVal
904
905
parser.formatter_class.__format_action_invocation = parser.formatter_class._format_action_invocation
906
parser.formatter_class._format_action_invocation = _format_action_invocation
907
908
# Dirty hack for making a short option '-hh'
909
if hasattr(parser, "get_option"):
910
option = parser.get_option("--hh")
911
option._short_opts = ["-hh"]
912
option._long_opts = []
913
else:
914
for action in get_actions(parser):
915
if action.option_strings == ["--hh"]:
916
action.option_strings = ["-hh"]
917
break
918
919
# Dirty hack for inherent help message of switch '-h'
920
if hasattr(parser, "get_option"):
921
option = parser.get_option("-h")
922
option.help = option.help.capitalize().replace("this help", "basic help")
923
else:
924
for action in get_actions(parser):
925
if action.option_strings == ["-h", "--help"]:
926
action.help = action.help.capitalize().replace("this help", "basic help")
927
break
928
929
_ = []
930
advancedHelp = True
931
extraHeaders = []
932
auxIndexes = {}
933
934
# Reference: https://stackoverflow.com/a/4012683 (Note: previously used "...sys.getfilesystemencoding() or UNICODE_ENCODING")
935
for arg in argv:
936
_.append(getUnicode(arg, encoding=sys.stdin.encoding))
937
938
argv = _
939
checkOldOptions(argv)
940
941
if "--gui" in argv:
942
from lib.utils.gui import runGui
943
944
runGui(parser)
945
946
raise SqlmapSilentQuitException
947
948
elif "--tui" in argv:
949
from lib.utils.tui import runTui
950
951
runTui(parser)
952
953
raise SqlmapSilentQuitException
954
955
elif "--shell" in argv:
956
_createHomeDirectories()
957
958
parser.usage = ""
959
cmdLineOptions.sqlmapShell = True
960
961
commands = set(("x", "q", "exit", "quit", "clear"))
962
commands.update(get_all_options(parser))
963
964
autoCompletion(AUTOCOMPLETE_TYPE.SQLMAP, commands=commands)
965
966
while True:
967
command = None
968
prompt = "sqlmap > "
969
970
try:
971
# Note: in Python2 command should not be converted to Unicode before passing to shlex (Reference: https://bugs.python.org/issue1170)
972
command = _input(prompt).strip()
973
except (KeyboardInterrupt, EOFError):
974
print()
975
raise SqlmapShellQuitException
976
977
command = re.sub(r"(?i)\Anew\s+", "", command or "")
978
979
if not command:
980
continue
981
elif command.lower() == "clear":
982
clearHistory()
983
dataToStdout("[i] history cleared\n")
984
saveHistory(AUTOCOMPLETE_TYPE.SQLMAP)
985
elif command.lower() in ("x", "q", "exit", "quit"):
986
raise SqlmapShellQuitException
987
elif command[0] != '-':
988
if not re.search(r"(?i)\A(\?|help)\Z", command):
989
dataToStdout("[!] invalid option(s) provided\n")
990
dataToStdout("[i] valid example: '-u http://www.site.com/vuln.php?id=1 --banner'\n")
991
else:
992
saveHistory(AUTOCOMPLETE_TYPE.SQLMAP)
993
loadHistory(AUTOCOMPLETE_TYPE.SQLMAP)
994
break
995
996
try:
997
for arg in shlex.split(command):
998
argv.append(getUnicode(arg, encoding=sys.stdin.encoding))
999
except ValueError as ex:
1000
raise SqlmapSyntaxException("something went wrong during command line parsing ('%s')" % getSafeExString(ex))
1001
1002
longOptions = set(re.findall(r"\-\-([^= ]+?)=", parser.format_help()))
1003
longSwitches = set(re.findall(r"\-\-([^= ]+?)\s", parser.format_help()))
1004
1005
for i in xrange(len(argv)):
1006
# Reference: https://en.wiktionary.org/wiki/-
1007
argv[i] = re.sub(u"\\A(\u2010|\u2013|\u2212|\u2014|\u4e00|\u1680|\uFE63|\uFF0D)+", lambda match: '-' * len(match.group(0)), argv[i])
1008
1009
# Reference: https://unicode-table.com/en/sets/quotation-marks/
1010
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")
1011
1012
if argv[i] == "-hh":
1013
argv[i] = "-h"
1014
elif i == 1 and re.search(r"\A(http|www\.|\w[\w.-]+\.\w{2,})", argv[i]) is not None:
1015
argv[i] = "--url=%s" % argv[i]
1016
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])):
1017
dataToStdout("[!] copy-pasting illegal (non-console) quote characters from Internet is illegal (%s)\n" % argv[i])
1018
raise SystemExit
1019
elif len(argv[i]) > 1 and u"\uff0c" in argv[i].split('=', 1)[-1]:
1020
dataToStdout("[!] copy-pasting illegal (non-console) comma characters from Internet is illegal (%s)\n" % argv[i])
1021
raise SystemExit
1022
elif re.search(r"\A-\w=.+", argv[i]):
1023
dataToStdout("[!] potentially miswritten (illegal '=') short option detected ('%s')\n" % argv[i])
1024
raise SystemExit
1025
elif re.search(r"\A-\w{3,}", argv[i]):
1026
if argv[i].strip('-').split('=')[0] in (longOptions | longSwitches):
1027
argv[i] = "-%s" % argv[i]
1028
elif argv[i] in IGNORED_OPTIONS:
1029
argv[i] = ""
1030
elif argv[i] in DEPRECATED_OPTIONS:
1031
argv[i] = ""
1032
elif argv[i] in ("-s", "--silent"):
1033
if i + 1 < len(argv) and argv[i + 1].startswith('-') or i + 1 == len(argv):
1034
argv[i] = ""
1035
conf.verbose = 0
1036
elif argv[i].startswith("--data-raw"):
1037
argv[i] = argv[i].replace("--data-raw", "--data", 1)
1038
elif argv[i].startswith("--auth-creds"):
1039
argv[i] = argv[i].replace("--auth-creds", "--auth-cred", 1)
1040
elif argv[i].startswith("--drop-cookie"):
1041
argv[i] = argv[i].replace("--drop-cookie", "--drop-set-cookie", 1)
1042
elif re.search(r"\A--tamper[^=\s]", argv[i]):
1043
argv[i] = ""
1044
elif re.search(r"\A(--(tamper|ignore-code|skip))(?!-)", argv[i]):
1045
key = re.search(r"\-?\-(\w+)\b", argv[i]).group(1)
1046
index = auxIndexes.get(key, None)
1047
if index is None:
1048
index = i if '=' in argv[i] else (i + 1 if i + 1 < len(argv) and not argv[i + 1].startswith('-') else None)
1049
auxIndexes[key] = index
1050
else:
1051
delimiter = ','
1052
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 ""))
1053
argv[i] = ""
1054
elif argv[i] in ("-H", "--header") or any(argv[i].startswith("%s=" % _) for _ in ("-H", "--header")):
1055
if '=' in argv[i]:
1056
extraHeaders.append(argv[i].split('=', 1)[1])
1057
elif i + 1 < len(argv):
1058
extraHeaders.append(argv[i + 1])
1059
elif argv[i] == "--deps":
1060
argv[i] = "--dependencies"
1061
elif argv[i] == "--disable-colouring":
1062
argv[i] = "--disable-coloring"
1063
elif argv[i] == "-r":
1064
for j in xrange(i + 2, len(argv)):
1065
value = argv[j]
1066
if os.path.isfile(value):
1067
argv[i + 1] += ",%s" % value
1068
argv[j] = ''
1069
else:
1070
break
1071
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]):
1072
argv[i] = argv[i][:-1]
1073
conf.skipThreadCheck = True
1074
elif argv[i] == "--version":
1075
print(VERSION_STRING.split('/')[-1])
1076
raise SystemExit
1077
elif argv[i] in ("-h", "--help"):
1078
advancedHelp = False
1079
for group in get_groups(parser)[:]:
1080
found = False
1081
for option in get_actions(group):
1082
if option.dest not in BASIC_HELP_ITEMS:
1083
option.help = SUPPRESS
1084
else:
1085
found = True
1086
if not found:
1087
get_groups(parser).remove(group)
1088
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:
1089
dataToStdout("[!] detected usage of long-option without a starting hyphen ('%s')\n" % argv[i])
1090
raise SystemExit
1091
1092
for verbosity in (_ for _ in argv if re.search(r"\A\-v+\Z", _)):
1093
try:
1094
if argv.index(verbosity) == len(argv) - 1 or not argv[argv.index(verbosity) + 1].isdigit():
1095
conf.verbose = verbosity.count('v')
1096
del argv[argv.index(verbosity)]
1097
except (IndexError, ValueError):
1098
pass
1099
1100
try:
1101
(args, _) = parser.parse_known_args(argv) if hasattr(parser, "parse_known_args") else parser.parse_args(argv)
1102
except UnicodeEncodeError as ex:
1103
dataToStdout("\n[!] %s\n" % getUnicode(ex.object.encode("unicode-escape")))
1104
raise SystemExit
1105
except SystemExit:
1106
if "-h" in argv and not advancedHelp:
1107
dataToStdout("\n[!] to see full list of options run with '-hh'\n")
1108
raise
1109
1110
if extraHeaders:
1111
if not args.headers:
1112
args.headers = ""
1113
delimiter = "\\n" if "\\n" in args.headers else "\n"
1114
args.headers += delimiter + delimiter.join(extraHeaders)
1115
1116
# Expand given mnemonic options (e.g. -z "ign,flu,bat")
1117
for i in xrange(len(argv) - 1):
1118
if argv[i] == "-z":
1119
expandMnemonics(argv[i + 1], parser, args)
1120
1121
if args.dummy:
1122
args.url = args.url or DUMMY_URL
1123
1124
if hasattr(sys.stdin, "fileno") and not any((os.isatty(sys.stdin.fileno()), args.api, args.ignoreStdin, "GITHUB_ACTIONS" in os.environ)):
1125
args.stdinPipe = iter(sys.stdin.readline, None)
1126
else:
1127
args.stdinPipe = None
1128
1129
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)):
1130
errMsg = "missing a mandatory option (-d, -u, -l, -m, -r, -g, -c, --wizard, --shell, --update, --purge, --list-tampers or --dependencies). "
1131
errMsg += "Use -h for basic and -hh for advanced help\n"
1132
parser.error(errMsg)
1133
1134
return args
1135
1136
except (ArgumentError, TypeError) as ex:
1137
parser.error(ex)
1138
1139
except SystemExit:
1140
# Protection against Windows dummy double clicking
1141
if IS_WIN and "--non-interactive" not in sys.argv:
1142
dataToStdout("\nPress Enter to continue...")
1143
_input()
1144
raise
1145
1146
debugMsg = "parsing command line"
1147
logger.debug(debugMsg)
1148
1149