diff --git a/lib/core/common.py b/lib/core/common.py index f569d92e4..c65830bc0 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -57,6 +57,7 @@ from lib.core.convert import htmlunescape from lib.core.convert import unicodeencode from lib.core.convert import urldecode from lib.core.convert import urlencode +from lib.core.enums import CHARSET_TYPE from lib.core.enums import DBMS from lib.core.enums import EXPECTED from lib.core.enums import HTTPHEADER @@ -1312,30 +1313,30 @@ def getCharset(charsetType=None): asciiTbl.extend(xrange(0, 128)) # 0 or 1 - elif charsetType == 1: + elif charsetType == CHARSET_TYPE.BINARY: asciiTbl.extend([0, 1]) asciiTbl.extend(xrange(47, 50)) # Digits - elif charsetType == 2: + elif charsetType == CHARSET_TYPE.DIGITS: asciiTbl.extend([0, 1]) asciiTbl.extend(xrange(47, 58)) # Hexadecimal - elif charsetType == 3: + elif charsetType == CHARSET_TYPE.HEXADECIMAL: asciiTbl.extend([0, 1]) asciiTbl.extend(xrange(47, 58)) asciiTbl.extend(xrange(64, 71)) asciiTbl.extend(xrange(96, 103)) # Characters - elif charsetType == 4: + elif charsetType == CHARSET_TYPE.ALPHA: asciiTbl.extend([0, 1]) asciiTbl.extend(xrange(64, 91)) asciiTbl.extend(xrange(96, 123)) # Characters and digits - elif charsetType == 5: + elif charsetType == CHARSET_TYPE.ALPHANUM: asciiTbl.extend([0, 1]) asciiTbl.extend(xrange(47, 58)) asciiTbl.extend(xrange(64, 91)) diff --git a/lib/core/enums.py b/lib/core/enums.py index e803fddb3..6ebabe198 100644 --- a/lib/core/enums.py +++ b/lib/core/enums.py @@ -80,6 +80,13 @@ class REFLECTIVE_COUNTER: MISS = "MISS" HIT = "HIT" +class CHARSET_TYPE: + BINARY = 1, + DIGITS = 2, + HEXADECIMAL = 3, + ALPHA = 4, + ALPHANUM = 5 + class HASH: MYSQL = r'(?i)\A\*[0-9a-f]{40}\Z' MYSQL_OLD = r'(?i)\A(?![0-9]+\Z)[0-9a-f]{16}\Z' diff --git a/lib/takeover/udf.py b/lib/takeover/udf.py index 0594d414a..22b22cd7e 100644 --- a/lib/takeover/udf.py +++ b/lib/takeover/udf.py @@ -18,6 +18,7 @@ from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger from lib.core.data import queries +from lib.core.enums import CHARSET_TYPE from lib.core.enums import DBMS from lib.core.enums import OS from lib.core.enums import PAYLOAD @@ -53,7 +54,7 @@ class UDF: logger.info("checking if UDF '%s' already exist" % udf) query = agent.forgeCaseStatement(queries[Backend.getIdentifiedDbms()].check_udf.query % (udf, udf)) - exists = inject.getValue(query, resumeValue=False, charsetType=2) + exists = inject.getValue(query, resumeValue=False, charsetType=CHARSET_TYPE.DIGITS) if exists == "1": return True diff --git a/lib/utils/resume.py b/lib/utils/resume.py index 5632f9217..f781bcf04 100644 --- a/lib/utils/resume.py +++ b/lib/utils/resume.py @@ -23,6 +23,7 @@ from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger from lib.core.data import queries +from lib.core.enums import CHARSET_TYPE from lib.core.enums import DBMS from lib.core.unescaper import unescaper from lib.techniques.blind.inference import bisection @@ -70,7 +71,7 @@ def queryOutputLength(expression, payload): start = time.time() lengthExprUnescaped = unescaper.unescape(lengthExpr) - count, length = bisection(payload, lengthExprUnescaped, charsetType=2) + count, length = bisection(payload, lengthExprUnescaped, charsetType=CHARSET_TYPE.DIGITS) debugMsg = "performed %d queries in %d seconds" % (count, calculateDeltaSeconds(start)) logger.debug(debugMsg) diff --git a/plugins/dbms/mssqlserver/enumeration.py b/plugins/dbms/mssqlserver/enumeration.py index 31f8f69aa..285ddeed5 100644 --- a/plugins/dbms/mssqlserver/enumeration.py +++ b/plugins/dbms/mssqlserver/enumeration.py @@ -21,6 +21,7 @@ from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger from lib.core.data import queries +from lib.core.enums import CHARSET_TYPE from lib.core.enums import EXPECTED from lib.core.enums import PAYLOAD from lib.core.exception import sqlmapNoneDataException @@ -120,7 +121,7 @@ class Enumeration(GenericEnumeration): for query in (rootQuery.blind.count, rootQuery.blind.count2, rootQuery.blind.count3): _ = query.replace("%s", db) - count = inject.getValue(_, inband=False, error=False, charsetType=2) + count = inject.getValue(_, inband=False, error=False, charsetType=CHARSET_TYPE.DIGITS) if not isNoneValue(count): break @@ -221,7 +222,7 @@ class Enumeration(GenericEnumeration): query = rootQuery.blind.count query = query.replace("%s", db) query += " AND %s" % tblQuery - count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2) + count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) if not isNumPosStrValue(count): warnMsg = "no table" @@ -338,7 +339,7 @@ class Enumeration(GenericEnumeration): query = rootQuery.blind.count query = query % (db, db, db, db, db, db) query += " AND %s" % colQuery.replace("[DB]", db) - count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2) + count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) if not isNumPosStrValue(count): warnMsg = "no tables contain column" diff --git a/plugins/dbms/mssqlserver/filesystem.py b/plugins/dbms/mssqlserver/filesystem.py index df9311a14..9afd80ed1 100644 --- a/plugins/dbms/mssqlserver/filesystem.py +++ b/plugins/dbms/mssqlserver/filesystem.py @@ -18,6 +18,7 @@ from lib.core.common import posixToNtSlashes from lib.core.common import randomStr from lib.core.data import conf from lib.core.data import logger +from lib.core.enums import CHARSET_TYPE from lib.core.enums import PAYLOAD from lib.core.exception import sqlmapNoneDataException from lib.core.exception import sqlmapUnsupportedFeatureException @@ -96,7 +97,7 @@ class Filesystem(GenericFilesystem): if not result: result = [] - count = inject.getValue("SELECT COUNT(*) FROM %s" % (hexTbl), resumeValue=False, charsetType=2) + count = inject.getValue("SELECT COUNT(*) FROM %s" % (hexTbl), resumeValue=False, charsetType=CHARSET_TYPE.DIGITS) if not isNumPosStrValue(count): errMsg = "unable to retrieve the content of the " @@ -106,7 +107,7 @@ class Filesystem(GenericFilesystem): indexRange = getLimitRange(count) for index in indexRange: - chunk = inject.getValue("SELECT TOP 1 %s FROM %s WHERE %s NOT IN (SELECT TOP %d %s FROM %s ORDER BY id ASC) ORDER BY id ASC" % (self.tblField, hexTbl, self.tblField, index, self.tblField, hexTbl), unpack=False, resumeValue=False, unique=False, charsetType=3) + chunk = inject.getValue("SELECT TOP 1 %s FROM %s WHERE %s NOT IN (SELECT TOP %d %s FROM %s ORDER BY id ASC) ORDER BY id ASC" % (self.tblField, hexTbl, self.tblField, index, self.tblField, hexTbl), unpack=False, resumeValue=False, unique=False, charsetType=CHARSET_TYPE.HEXADECIMAL) result.append(chunk) inject.goStacked("DROP TABLE %s" % hexTbl) diff --git a/plugins/dbms/mysql/filesystem.py b/plugins/dbms/mysql/filesystem.py index 4ffcf3843..80d2dd177 100644 --- a/plugins/dbms/mysql/filesystem.py +++ b/plugins/dbms/mysql/filesystem.py @@ -14,6 +14,7 @@ from lib.core.common import unArrayizeValue from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger +from lib.core.enums import CHARSET_TYPE from lib.core.enums import PLACE from lib.core.exception import sqlmapNoneDataException from lib.request import inject @@ -51,7 +52,7 @@ class Filesystem(GenericFilesystem): logger.debug(debugMsg) inject.goStacked("LOAD DATA INFILE '%s' INTO TABLE %s FIELDS TERMINATED BY '%s' (%s)" % (tmpFile, self.fileTblName, randomStr(10), self.tblField)) - length = unArrayizeValue(inject.getValue("SELECT LENGTH(%s) FROM %s" % (self.tblField, self.fileTblName), unique=False, resumeValue=False, charsetType=2)) + length = unArrayizeValue(inject.getValue("SELECT LENGTH(%s) FROM %s" % (self.tblField, self.fileTblName), unique=False, resumeValue=False, charsetType=CHARSET_TYPE.DIGITS)) if not isNumPosStrValue(length): errMsg = "unable to retrieve the content of the " @@ -65,11 +66,11 @@ class Filesystem(GenericFilesystem): result = [] for i in xrange(1, length, sustrLen): - chunk = inject.getValue("SELECT MID(%s, %d, %d) FROM %s" % (self.tblField, i, sustrLen, self.fileTblName), unpack=False, unique=False, resumeValue=False, charsetType=3) + chunk = inject.getValue("SELECT MID(%s, %d, %d) FROM %s" % (self.tblField, i, sustrLen, self.fileTblName), unpack=False, unique=False, resumeValue=False, charsetType=CHARSET_TYPE.HEXADECIMAL) result.append(chunk) else: - result = inject.getValue("SELECT %s FROM %s" % (self.tblField, self.fileTblName), unique=False, resumeValue=False, charsetType=3) + result = inject.getValue("SELECT %s FROM %s" % (self.tblField, self.fileTblName), unique=False, resumeValue=False, charsetType=CHARSET_TYPE.HEXADECIMAL) return result diff --git a/plugins/dbms/oracle/enumeration.py b/plugins/dbms/oracle/enumeration.py index 58bbc629c..fefc44bc3 100644 --- a/plugins/dbms/oracle/enumeration.py +++ b/plugins/dbms/oracle/enumeration.py @@ -17,6 +17,7 @@ from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger from lib.core.data import queries +from lib.core.enums import CHARSET_TYPE from lib.core.enums import EXPECTED from lib.core.enums import PAYLOAD from lib.core.exception import sqlmapNoneDataException @@ -119,7 +120,7 @@ class Enumeration(GenericEnumeration): query = rootQuery.blind.count2 % queryUser else: query = rootQuery.blind.count % queryUser - count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2) + count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) if not isNumPosStrValue(count): if not count.isdigit() and not query2: diff --git a/plugins/generic/enumeration.py b/plugins/generic/enumeration.py index 6be2697a2..db46fd569 100644 --- a/plugins/generic/enumeration.py +++ b/plugins/generic/enumeration.py @@ -45,6 +45,7 @@ from lib.core.dicts import mysqlPrivs from lib.core.dicts import pgsqlPrivs from lib.core.dicts import firebirdPrivs from lib.core.dicts import db2Privs +from lib.core.enums import CHARSET_TYPE from lib.core.enums import DBMS from lib.core.enums import EXPECTED from lib.core.enums import PAYLOAD @@ -158,7 +159,7 @@ class Enumeration: query = queries[Backend.getIdentifiedDbms()].is_dba.query query = agent.forgeCaseStatement(query) - kb.data.isDba = unArrayizeValue(inject.getValue(query, charsetType=1)) + kb.data.isDba = unArrayizeValue(inject.getValue(query, charsetType=CHARSET_TYPE.BINARY)) return kb.data.isDba == "1" @@ -189,7 +190,7 @@ class Enumeration: query = rootQuery.blind.count2 else: query = rootQuery.blind.count - count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2) + count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) if not isNumPosStrValue(count): errMsg = "unable to retrieve the number of database users" @@ -329,7 +330,7 @@ class Enumeration: query = rootQuery.blind.count2 % user else: query = rootQuery.blind.count % user - count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2) + count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) if not isNumPosStrValue(count): warnMsg = "unable to retrieve the number of password " @@ -563,7 +564,7 @@ class Enumeration: query = rootQuery.blind.count2 % user else: query = rootQuery.blind.count % user - count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2) + count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) if not isNumPosStrValue(count): if Backend.isDbms(DBMS.ORACLE) and not query2: @@ -740,7 +741,7 @@ class Enumeration: query = rootQuery.blind.count2 else: query = rootQuery.blind.count - count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2) + count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) if not isNumPosStrValue(count): errMsg = "unable to retrieve the number of databases" @@ -903,7 +904,7 @@ class Enumeration: query = rootQuery.blind.count else: query = rootQuery.blind.count % unsafeSQLIdentificatorNaming(db) - count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2) + count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) if not isNumPosStrValue(count): warnMsg = "unable to retrieve the number of " @@ -1194,7 +1195,7 @@ class Enumeration: parseSqliteTableSchema(value) return kb.data.cachedColumns - count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2) + count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) if not isNumPosStrValue(count): errMsg = "unable to retrieve the number of columns " @@ -1313,7 +1314,7 @@ class Enumeration: else: query = "SELECT %s FROM %s.%s" % (queries[Backend.getIdentifiedDbms()].count.query % '*', safeSQLIdentificatorNaming(db), safeSQLIdentificatorNaming(table, True)) - count = inject.getValue(query, expected=EXPECTED.INT, charsetType=2) + count = inject.getValue(query, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) if isNumPosStrValue(count): if safeSQLIdentificatorNaming(db) not in kb.data.cachedCounts: @@ -1662,7 +1663,7 @@ class Enumeration: query = rootQuery.blind.count % tbl else: query = rootQuery.blind.count % (conf.db, tbl) - count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2) + count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) lengths = {} entries = {} @@ -1934,7 +1935,7 @@ class Enumeration: query = rootQuery.blind.count query += dbQuery query += exclDbsQuery - count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2) + count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) if not isNumPosStrValue(count): warnMsg = "no database" @@ -2052,7 +2053,7 @@ class Enumeration: query = rootQuery.blind.count query += tblQuery query += whereDbsQuery - count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2) + count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) if not isNumPosStrValue(count): warnMsg = "no databases have table" @@ -2096,7 +2097,7 @@ class Enumeration: query = rootQuery.blind.count2 query = query % unsafeSQLIdentificatorNaming(db) query += " AND %s" % tblQuery - count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2) + count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) if not isNumPosStrValue(count): warnMsg = "no table" @@ -2244,7 +2245,7 @@ class Enumeration: query = rootQuery.blind.count query += colQuery query += whereDbsQuery - count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2) + count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) if not isNumPosStrValue(count): warnMsg = "no databases have tables containing column" @@ -2294,7 +2295,7 @@ class Enumeration: query = rootQuery.blind.count2 query = query % db query += " AND %s" % colQuery - count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=2) + count = inject.getValue(query, inband=False, error=False, expected=EXPECTED.INT, charsetType=CHARSET_TYPE.DIGITS) if not isNumPosStrValue(count): warnMsg = "no tables contain column" diff --git a/plugins/generic/filesystem.py b/plugins/generic/filesystem.py index 3c9cb6214..ef33fa9ea 100644 --- a/plugins/generic/filesystem.py +++ b/plugins/generic/filesystem.py @@ -19,6 +19,7 @@ from lib.core.common import randomStr from lib.core.common import readInput from lib.core.data import conf from lib.core.data import logger +from lib.core.enums import CHARSET_TYPE from lib.core.enums import DBMS from lib.core.enums import PAYLOAD from lib.core.exception import sqlmapUndefinedMethod @@ -109,7 +110,7 @@ class Filesystem: wFileSize = os.path.getsize(wFile) logger.debug("checking if the %s file has been written" % fileType) - dFileSize = inject.getValue(lengthQuery, resumeValue=False, charsetType=2) + dFileSize = inject.getValue(lengthQuery, resumeValue=False, charsetType=CHARSET_TYPE.DIGITS) if dFileSize and dFileSize.isdigit(): infoMsg = "the file has been successfully written and "