mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2026-08-04 14:55:40 +00:00
Minor patches
This commit is contained in:
parent
39d22d26c3
commit
3a680be4eb
11 changed files with 42 additions and 28 deletions
|
|
@ -1967,19 +1967,21 @@ def getLimitRange(count, plusOne=False):
|
|||
|
||||
if kb.dumpTable:
|
||||
if conf.limitStart and conf.limitStop and conf.limitStart > conf.limitStop:
|
||||
limitStop = conf.limitStart
|
||||
limitStop = min(conf.limitStart, count) # a '--start' beyond the table must not request out-of-range offsets (phantom rows)
|
||||
limitStart = conf.limitStop
|
||||
reverse = True
|
||||
else:
|
||||
if isinstance(conf.limitStop, int) and conf.limitStop > 0 and conf.limitStop < limitStop:
|
||||
limitStop = conf.limitStop
|
||||
|
||||
if isinstance(conf.limitStart, int) and conf.limitStart > 0 and conf.limitStart <= limitStop:
|
||||
# NOTE: no '<= limitStop' gate - a '--start' past the row count must yield an EMPTY range
|
||||
# (correctly skipping past every row), not silently fall back to dumping the whole table
|
||||
if isinstance(conf.limitStart, int) and conf.limitStart > 0:
|
||||
limitStart = conf.limitStart
|
||||
|
||||
retVal = xrange(limitStart, limitStop + 1) if plusOne else xrange(limitStart - 1, limitStop)
|
||||
|
||||
if reverse:
|
||||
if reverse and len(retVal): # len() guard: a clamped out-of-range '--start' can leave the range empty
|
||||
retVal = xrange(retVal[-1], retVal[0] - 1, -1)
|
||||
|
||||
return retVal
|
||||
|
|
|
|||
|
|
@ -577,7 +577,7 @@ def getUnicode(value, encoding=None, noneToNull=False):
|
|||
|
||||
try:
|
||||
return six.text_type(value, encoding or (kb.get("pageEncoding") if kb.get("originalPage") else None) or UNICODE_ENCODING)
|
||||
except UnicodeDecodeError:
|
||||
except (UnicodeDecodeError, LookupError): # LookupError: an unknown/invalid encoding name must fall back, not crash
|
||||
return six.text_type(value, UNICODE_ENCODING, errors="reversible")
|
||||
elif isListLike(value):
|
||||
value = list(getUnicode(_, encoding, noneToNull) for _ in value)
|
||||
|
|
|
|||
|
|
@ -520,7 +520,8 @@ def _setOpenApiTargets():
|
|||
checkFile(conf.openApiFile)
|
||||
infoMsg = "parsing OpenAPI/Swagger specification from '%s'" % conf.openApiFile
|
||||
logger.info(infoMsg)
|
||||
content = openFile(conf.openApiFile).read()
|
||||
with openFile(conf.openApiFile) as f:
|
||||
content = f.read()
|
||||
|
||||
tags = [_.strip() for _ in re.split(PARAMETER_SPLITTING_REGEX, conf.openApiTags) if _.strip()] if conf.openApiTags else None
|
||||
if tags:
|
||||
|
|
@ -835,7 +836,8 @@ def _listTamperingFunctions():
|
|||
logger.info(infoMsg)
|
||||
|
||||
for script in sorted(glob.glob(os.path.join(paths.SQLMAP_TAMPER_PATH, "*.py"))):
|
||||
content = openFile(script, 'r').read()
|
||||
with openFile(script, 'r') as f:
|
||||
content = f.read()
|
||||
match = re.search(r'(?s)__priority__.+"""(.+)"""', content)
|
||||
if match:
|
||||
comment = match.group(1).strip()
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ from lib.core.enums import OS
|
|||
from thirdparty import six
|
||||
|
||||
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
||||
VERSION = "1.10.7.242"
|
||||
VERSION = "1.10.7.243"
|
||||
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
|
||||
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
|
||||
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
|
||||
|
|
@ -533,8 +533,11 @@ ERROR_PARSING_REGEXES = (
|
|||
r'"(?:errmsg|errorMessage|reason|msg)"\s*:\s*"(?P<result>[^"]+)"' # generic JSON error-message field (NoSQL document/REST back-ends)
|
||||
)
|
||||
|
||||
# Regular expression used for parsing charset info from meta html headers
|
||||
META_CHARSET_REGEX = r"""(?si)<head\b[^>]*>.*<meta[^>]+charset\s*=\s*["']?(?P<result>[^"'> ]+).*</head>"""
|
||||
# Regular expression used for parsing charset info from meta html headers (Note: the tempered token
|
||||
# '(?:(?!</head>).)*?' keeps the meta strictly INSIDE <head> - as the old trailing '.*</head>' did -
|
||||
# while the bounded meta-attr scan '{0,300}?' keeps it LINEAR; the old greedy form went quadratic and
|
||||
# hung for many minutes on an attacker-controlled body full of '<meta' tokens lacking '>'/'</head>')
|
||||
META_CHARSET_REGEX = r"""(?si)<head\b[^>]*>(?:(?!</head>).)*?<meta[^>]{0,300}?charset\s*=\s*["']?(?P<result>[^"'> ]+)"""
|
||||
|
||||
# Regular expression used for parsing refresh info from meta html headers
|
||||
META_REFRESH_REGEX = r'(?i)<meta http-equiv="?refresh"?[^>]+content="?[^">]+;\s*(url=)?["\']?(?P<result>[^\'">]+)'
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ def comparison(page, headers, code=None, getRatioValue=False, pageLength=None):
|
|||
return _
|
||||
|
||||
def _adjust(condition, getRatioValue):
|
||||
if not any((conf.string, conf.notString, conf.regexp, conf.code)):
|
||||
if not any((conf.string, conf.notString, conf.regexp, conf.code, conf.lengths)):
|
||||
# Negative logic approach is used in raw page comparison scheme as that what is "different" than original
|
||||
# PAYLOAD.WHERE.NEGATIVE response is considered as True; in switch based approach negative logic is not
|
||||
# applied as that what is by user considered as True is that what is returned by the comparison mechanism
|
||||
|
|
|
|||
|
|
@ -406,7 +406,8 @@ class Connect(object):
|
|||
errMsg = "problem occurred while loading cookies from file '%s'" % conf.liveCookies
|
||||
raise SqlmapValueException(errMsg)
|
||||
|
||||
cookie = openFile(conf.liveCookies).read().strip()
|
||||
with openFile(conf.liveCookies) as f:
|
||||
cookie = f.read().strip()
|
||||
cookie = re.sub(r"(?i)\ACookie:\s*", "", cookie)
|
||||
|
||||
if multipart:
|
||||
|
|
@ -545,7 +546,8 @@ class Connect(object):
|
|||
headers = forgeHeaders(auxHeaders, headers)
|
||||
|
||||
if kb.headersFile:
|
||||
content = openFile(kb.headersFile, 'r').read()
|
||||
with openFile(kb.headersFile, 'r') as f:
|
||||
content = f.read()
|
||||
for line in content.split("\n"):
|
||||
line = getText(line.strip())
|
||||
if ':' in line:
|
||||
|
|
|
|||
|
|
@ -875,7 +875,8 @@ def download(taskid, target, filename):
|
|||
|
||||
if os.path.isfile(path):
|
||||
logger.debug("(%s) Retrieved content of file %s" % (taskid, target))
|
||||
content = openFile(path, "rb").read()
|
||||
with openFile(path, "rb") as f:
|
||||
content = f.read()
|
||||
return jsonize({"success": True, "file": encodeBase64(content, binary=False)})
|
||||
else:
|
||||
logger.warning("[%s] File does not exist %s" % (taskid, target))
|
||||
|
|
|
|||
|
|
@ -1117,7 +1117,7 @@ def _bruteProcessVariantA(attack_info, hash_regex, suffix, retVal, proc_id, proc
|
|||
word = word + suffix
|
||||
|
||||
try:
|
||||
current = __functions__[hash_regex](password=word, uppercase=False)
|
||||
current = __functions__[hash_regex](password=getBytes(word, unsafe=False), uppercase=False)
|
||||
|
||||
if current in hashes:
|
||||
for item in attack_info[:]:
|
||||
|
|
@ -1195,7 +1195,7 @@ def _bruteProcessVariantB(user, hash_, kwargs, hash_regex, suffix, retVal, found
|
|||
word = word + suffix
|
||||
|
||||
try:
|
||||
current = __functions__[hash_regex](password=word, uppercase=False, **kwargs)
|
||||
current = __functions__[hash_regex](password=getBytes(word, unsafe=False), uppercase=False, **kwargs)
|
||||
|
||||
if hash_ == current:
|
||||
if hash_regex == HASH.ORACLE_OLD: # only for cosmetic purposes
|
||||
|
|
@ -1285,7 +1285,7 @@ def _bruteProcessVariantSalted(attack_info, hash_regex, suffix, retVal, proc_id,
|
|||
((user, hash_), kwargs) = item
|
||||
|
||||
try:
|
||||
current = __functions__[hash_regex](password=word, uppercase=False, **kwargs)
|
||||
current = __functions__[hash_regex](password=getBytes(word, unsafe=False), uppercase=False, **kwargs)
|
||||
|
||||
if hash_ == current:
|
||||
retVal.put((user, hash_, word))
|
||||
|
|
|
|||
|
|
@ -333,7 +333,9 @@ class Entries(object):
|
|||
kb.data.dumpedTable[column] = {"length": len(column), "values": BigArray()}
|
||||
|
||||
for entry in entries:
|
||||
if entry is None or len(entry) == 0:
|
||||
# skip a missing/empty ROW container, but NOT an empty-string CELL value
|
||||
# (single-column dumps yield bare strings; len("")==0 must not drop the row)
|
||||
if entry is None or (isListLike(entry) and len(entry) == 0):
|
||||
continue
|
||||
|
||||
if isinstance(entry, six.string_types):
|
||||
|
|
|
|||
|
|
@ -135,8 +135,9 @@ class Search(object):
|
|||
query = agent.limitQuery(index, query, dbCond)
|
||||
|
||||
value = unArrayizeValue(inject.getValue(query, union=False, error=False))
|
||||
value = safeSQLIdentificatorNaming(value)
|
||||
foundDbs.append(value)
|
||||
if not isNoneValue(value): # guard (mirrors searchTable) so a failed retrieval can't push a None/garbage name
|
||||
value = safeSQLIdentificatorNaming(value)
|
||||
foundDbs.append(value)
|
||||
|
||||
conf.dumper.lister("found databases", foundDbs)
|
||||
|
||||
|
|
|
|||
|
|
@ -627,17 +627,18 @@ class Users(object):
|
|||
elif Backend.isDbms(DBMS.DB2):
|
||||
privs = privilege.split(',')
|
||||
privilege = privs[0]
|
||||
privs = privs[1]
|
||||
privs = list(privs.strip())
|
||||
i = 1
|
||||
if len(privs) > 1: # guard a comma-less privilege value (mirrors the inband path)
|
||||
privs = privs[1]
|
||||
privs = list(privs.strip())
|
||||
i = 1
|
||||
|
||||
for priv in privs:
|
||||
if priv.upper() in ('Y', 'G'):
|
||||
for position, db2Priv in DB2_PRIVS.items():
|
||||
if position == i:
|
||||
privilege += ", " + db2Priv
|
||||
for priv in privs:
|
||||
if priv.upper() in ('Y', 'G'):
|
||||
for position, db2Priv in DB2_PRIVS.items():
|
||||
if position == i:
|
||||
privilege += ", " + db2Priv
|
||||
|
||||
i += 1
|
||||
i += 1
|
||||
|
||||
privileges.add(privilege)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue