diff --git a/extra/shutils/_sqlmap.py b/extra/shutils/_sqlmap.py index 433ca3c24..a5f7625f9 100644 --- a/extra/shutils/_sqlmap.py +++ b/extra/shutils/_sqlmap.py @@ -141,7 +141,6 @@ _arguments -C -s \ '(--hex)'--hex'[Uses DBMS hex function(s) for data retrieval]' \ '(--output-dir)'--output-dir=-'[Custom output directory path]:ODIR' \ '(--parse-errors)'--parse-errors'[Parse and display DBMS error messages from responses]' \ - '(--replicate)'--replicate'[Replicate dumped data into a sqlite3 database]' \ '(--save)'--save'[Save options to a configuration INI file]' \ '(--tor)'--tor'[Use Tor anonymity network]' \ '(--tor-port)'--tor-port=-'[Set Tor proxy port other than default]:TORPORT' \ diff --git a/lib/core/defaults.py b/lib/core/defaults.py index 20ea7a663..039a176e7 100644 --- a/lib/core/defaults.py +++ b/lib/core/defaults.py @@ -20,6 +20,7 @@ _defaults = { "threads": 1, "level": 1, "risk": 1, + "dumpFormat": "CSV", "tech": "BEUST", "torType": "HTTP" } diff --git a/lib/core/dump.py b/lib/core/dump.py index 9cac5784a..ff5f1fdbf 100644 --- a/lib/core/dump.py +++ b/lib/core/dump.py @@ -26,6 +26,7 @@ from lib.core.data import kb from lib.core.data import logger from lib.core.dicts import DUMP_REPLACEMENTS from lib.core.enums import DBMS +from lib.core.enums import DUMP_FORMAT from lib.core.exception import sqlmapGenericException from lib.core.exception import sqlmapValueException from lib.core.replication import Replication @@ -330,7 +331,7 @@ class Dump: db = "All" table = tableValues["__infos__"]["table"] - if conf.replicate: + if conf.dumpFormat == DUMP_FORMAT.SQLITE: replication = Replication("%s%s%s.sqlite3" % (conf.dumpPath, os.sep, unsafeSQLIdentificatorNaming(db))) else: dumpDbPath = "%s%s%s" % (conf.dumpPath, os.sep, unsafeSQLIdentificatorNaming(db)) @@ -357,7 +358,7 @@ class Dump: separator += "+" self._write("Database: %s\nTable: %s" % (db if db else "Current database", table)) - if conf.replicate: + if conf.dumpFormat == DUMP_FORMAT.SQLITE: cols = [] for column in columns: @@ -406,7 +407,7 @@ class Dump: self._write("| %s%s" % (column, blank), newline=False) - if not conf.replicate: + if conf.dumpFormat != DUMP_FORMAT.SQLITE: if field == fields: dataToDumpFile(dumpFP, "%s" % safeCSValue(column)) else: @@ -416,10 +417,10 @@ class Dump: self._write("|\n%s" % separator) - if not conf.replicate: + if conf.dumpFormat != DUMP_FORMAT.SQLITE: dataToDumpFile(dumpFP, "\n") - if conf.replicate: + if conf.dumpFormat == DUMP_FORMAT.SQLITE: rtable.beginTransaction() if count > TRIM_STDOUT_DUMP_SIZE: @@ -451,7 +452,7 @@ class Dump: blank = " " * (maxlength - len(value)) self._write("| %s%s" % (value, blank), newline=False, console=console) - if not conf.replicate: + if conf.dumpFormat != DUMP_FORMAT.SQLITE: if field == fields: dataToDumpFile(dumpFP, "%s" % safeCSValue(value)) else: @@ -459,7 +460,7 @@ class Dump: field += 1 - if conf.replicate: + if conf.dumpFormat == DUMP_FORMAT.SQLITE: try: rtable.insert(values) except sqlmapValueException: @@ -467,12 +468,12 @@ class Dump: self._write("|", console=console) - if not conf.replicate: + if conf.dumpFormat != DUMP_FORMAT.SQLITE: dataToDumpFile(dumpFP, "\n") self._write("%s\n" % separator) - if conf.replicate: + if conf.dumpFormat == DUMP_FORMAT.SQLITE: rtable.endTransaction() logger.info("table '%s.%s' dumped to sqlite3 database '%s'" % (db, table, replication.dbpath)) diff --git a/lib/core/enums.py b/lib/core/enums.py index 2d489493b..d7ae37123 100644 --- a/lib/core/enums.py +++ b/lib/core/enums.py @@ -124,6 +124,11 @@ class PROXYTYPE: SOCKS4 = "SOCKS4" SOCKS5 = "SOCKS5" +class DUMP_FORMAT: + CSV = "CSV" + HTML = "HTML" + SQLITE = "SQLITE" + class HTTPHEADER: ACCEPT = "Accept" ACCEPT_CHARSET = "Accept-Charset" diff --git a/lib/core/option.py b/lib/core/option.py index f0b188960..861dd391c 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -63,6 +63,7 @@ from lib.core.dicts import DBMS_DICT from lib.core.dicts import DUMP_REPLACEMENTS from lib.core.enums import ADJUST_TIME_DELAY from lib.core.enums import CUSTOM_LOGGING +from lib.core.enums import DUMP_FORMAT from lib.core.enums import HTTPHEADER from lib.core.enums import HTTPMETHOD from lib.core.enums import MOBILES @@ -1409,6 +1410,12 @@ def __cleanupOptions(): for _ in DUMP_REPLACEMENTS.keys(): del DUMP_REPLACEMENTS[_] + if conf.dumpFormat: + conf.dumpFormat = conf.dumpFormat.upper() + + if conf.torType: + conf.torType = conf.torType.upper() + threadData = getCurrentThreadData() threadData.reset() @@ -1970,6 +1977,10 @@ def __basicOptionValidation(): errMsg = "option '--tor-type' accepts one of following values: %s" % ", ".join(getPublicTypeMembers(PROXYTYPE, True)) raise sqlmapSyntaxException, errMsg + if conf.dumpFormat not in getPublicTypeMembers(DUMP_FORMAT, True): + errMsg = "option '--dump-format' accepts one of following values: %s" % ", ".join(getPublicTypeMembers(DUMP_FORMAT, True)) + raise sqlmapSyntaxException, errMsg + if conf.skip and conf.testParameter: errMsg = "option '--skip' is incompatible with option '-p'" raise sqlmapSyntaxException, errMsg diff --git a/lib/core/optiondict.py b/lib/core/optiondict.py index 784881688..6e068db90 100644 --- a/lib/core/optiondict.py +++ b/lib/core/optiondict.py @@ -175,6 +175,7 @@ optDict = { "crawlDepth": "integer", "csvDel": "string", "dbmsCred": "string", + "dumpFormat": "string", "eta": "boolean", "flushSession": "boolean", "forms": "boolean", @@ -182,7 +183,6 @@ optDict = { "hexConvert": "boolean", "oDir": "string", "parseErrors": "boolean", - "replicate": "boolean", "updateAll": "boolean", "tor": "boolean", "torPort": "integer", diff --git a/lib/parse/cmdline.py b/lib/parse/cmdline.py index ad08baed9..02253bdfc 100644 --- a/lib/parse/cmdline.py +++ b/lib/parse/cmdline.py @@ -547,6 +547,9 @@ def cmdLineParser(): general.add_option("--dbms-cred", dest="dbmsCred", help="DBMS authentication credentials (user:password)") + general.add_option("--dump-format", dest="dumpFormat", + help="Format of dumped data (CSV (default), HTML or SQLITE)") + general.add_option("--eta", dest="eta", action="store_true", help="Display for each output the " @@ -576,10 +579,6 @@ def cmdLineParser(): action="store_true", help="Parse and display DBMS error messages from responses") - general.add_option("--replicate", dest="replicate", - action="store_true", - help="Replicate dumped data into a sqlite3 database") - general.add_option("--save", dest="saveCmdline", action="store_true", help="Save options to a configuration INI file") @@ -592,7 +591,7 @@ def cmdLineParser(): help="Set Tor proxy port other than default") general.add_option("--tor-type", dest="torType", - help="Set Tor proxy type (HTTP - default, SOCKS4 or SOCKS5)") + help="Set Tor proxy type (HTTP (default), SOCKS4 or SOCKS5)") general.add_option("--update", dest="updateAll", action="store_true", diff --git a/sqlmap.conf b/sqlmap.conf index f560b7d83..b0ade0f5c 100644 --- a/sqlmap.conf +++ b/sqlmap.conf @@ -599,6 +599,10 @@ csvDel = , # Syntax: username:password dbmsCred = +# Format of dumped data +# Valid: CSV, HTML or SQLITE +dumpFormat = CSV + # Retrieve each query output length and calculate the estimated time of # arrival in real time. # Valid: True or False @@ -627,10 +631,6 @@ oDir = # Valid: True or False parseErrors = False -# Replicate dumped data into a sqlite3 database. -# Valid: True or False -replicate = False - # Use Use Tor anonymity network. # Valid: True or False tor = False