code refactoring regarding charsetType inside inference/bisection

This commit is contained in:
Miroslav Stampar 2012-02-29 14:36:23 +00:00
parent f6f98f1b41
commit 8b9c5c66cc
10 changed files with 47 additions and 31 deletions

View File

@ -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))

View File

@ -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'

View File

@ -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

View File

@ -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)

View File

@ -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"

View File

@ -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)

View File

@ -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

View File

@ -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:

View File

@ -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"

View File

@ -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 "