mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-12-20 22:49:01 +00:00
Patching silent per-thread issue with technique switching (fixes #3784)
This commit is contained in:
@@ -12,6 +12,7 @@ from lib.core.common import Backend
|
||||
from lib.core.common import extractRegexResult
|
||||
from lib.core.common import filterNone
|
||||
from lib.core.common import getSQLSnippet
|
||||
from lib.core.common import getTechnique
|
||||
from lib.core.common import isDBMSVersionAtLeast
|
||||
from lib.core.common import isNumber
|
||||
from lib.core.common import isTechniqueAvailable
|
||||
@@ -89,8 +90,8 @@ class Agent(object):
|
||||
|
||||
if kb.forceWhere:
|
||||
where = kb.forceWhere
|
||||
elif where is None and isTechniqueAvailable(kb.technique):
|
||||
where = kb.injection.data[kb.technique].where
|
||||
elif where is None and isTechniqueAvailable(getTechnique()):
|
||||
where = kb.injection.data[getTechnique()].where
|
||||
|
||||
if kb.injection.place is not None:
|
||||
place = kb.injection.place
|
||||
@@ -234,8 +235,8 @@ class Agent(object):
|
||||
expression = unescaper.escape(expression)
|
||||
query = None
|
||||
|
||||
if where is None and kb.technique and kb.technique in kb.injection.data:
|
||||
where = kb.injection.data[kb.technique].where
|
||||
if where is None and getTechnique() is not None and getTechnique() in kb.injection.data:
|
||||
where = kb.injection.data[getTechnique()].where
|
||||
|
||||
# If we are replacing (<where>) the parameter original value with
|
||||
# our payload do not prepend with the prefix
|
||||
@@ -244,7 +245,7 @@ class Agent(object):
|
||||
|
||||
# If the technique is stacked queries (<stype>) do not put a space
|
||||
# after the prefix or it is in GROUP BY / ORDER BY (<clause>)
|
||||
elif kb.technique == PAYLOAD.TECHNIQUE.STACKED:
|
||||
elif getTechnique() == PAYLOAD.TECHNIQUE.STACKED:
|
||||
query = kb.injection.prefix
|
||||
elif kb.injection.clause == [2, 3] or kb.injection.clause == [2] or kb.injection.clause == [3]:
|
||||
query = kb.injection.prefix
|
||||
@@ -282,9 +283,9 @@ class Agent(object):
|
||||
# Take default values if None
|
||||
suffix = kb.injection.suffix if kb.injection and suffix is None else suffix
|
||||
|
||||
if kb.technique and kb.technique in kb.injection.data:
|
||||
where = kb.injection.data[kb.technique].where if where is None else where
|
||||
comment = kb.injection.data[kb.technique].comment if comment is None else comment
|
||||
if getTechnique() is not None and getTechnique() in kb.injection.data:
|
||||
where = kb.injection.data[getTechnique()].where if where is None else where
|
||||
comment = kb.injection.data[getTechnique()].comment if comment is None else comment
|
||||
|
||||
if Backend.getIdentifiedDbms() == DBMS.ACCESS and any((comment or "").startswith(_) for _ in ("--", "[GENERIC_SQL_COMMENT]")):
|
||||
comment = queries[DBMS.ACCESS].comment.query
|
||||
|
||||
@@ -1125,6 +1125,20 @@ def readInput(message, default=None, checkBatch=True, boolean=False):
|
||||
|
||||
return retVal or ""
|
||||
|
||||
def setTechnique(technique):
|
||||
"""
|
||||
Thread-safe setting of currently used technique (Note: dealing with cases of per-thread technique switching)
|
||||
"""
|
||||
|
||||
getCurrentThreadData().technique = technique
|
||||
|
||||
def getTechnique():
|
||||
"""
|
||||
Thread-safe getting of currently used technique
|
||||
"""
|
||||
|
||||
return getCurrentThreadData().technique or kb.technique
|
||||
|
||||
def randomRange(start=0, stop=1000, seed=None):
|
||||
"""
|
||||
Returns random integer value in given range
|
||||
@@ -3231,18 +3245,16 @@ def isHeavyQueryBased(technique=None):
|
||||
Returns True whether current (kb.)technique is heavy-query based
|
||||
|
||||
>>> pushValue(kb.injection.data)
|
||||
>>> pushValue(kb.technique)
|
||||
>>> kb.technique = PAYLOAD.TECHNIQUE.STACKED
|
||||
>>> kb.injection.data[kb.technique] = [test for test in getSortedInjectionTests() if "heavy" in test["title"].lower()][0]
|
||||
>>> setTechnique(PAYLOAD.TECHNIQUE.STACKED)
|
||||
>>> kb.injection.data[getTechnique()] = [test for test in getSortedInjectionTests() if "heavy" in test["title"].lower()][0]
|
||||
>>> isHeavyQueryBased()
|
||||
True
|
||||
>>> kb.technique = popValue()
|
||||
>>> kb.injection.data = popValue()
|
||||
"""
|
||||
|
||||
retVal = False
|
||||
|
||||
technique = technique or kb.technique
|
||||
technique = technique or getTechnique()
|
||||
|
||||
if isTechniqueAvailable(technique):
|
||||
data = getTechniqueData(technique)
|
||||
@@ -3630,7 +3642,7 @@ def unhandledExceptionMessage():
|
||||
errMsg += "Python version: %s\n" % PYVERSION
|
||||
errMsg += "Operating system: %s\n" % platform.platform()
|
||||
errMsg += "Command line: %s\n" % re.sub(r".+?\bsqlmap\.py\b", "sqlmap.py", getUnicode(" ".join(sys.argv), encoding=sys.stdin.encoding))
|
||||
errMsg += "Technique: %s\n" % (enumValueToNameLookup(PAYLOAD.TECHNIQUE, kb.technique) if kb.get("technique") else ("DIRECT" if conf.get("direct") else None))
|
||||
errMsg += "Technique: %s\n" % (enumValueToNameLookup(PAYLOAD.TECHNIQUE, getTechnique()) if getTechnique() is not None else ("DIRECT" if conf.get("direct") else None))
|
||||
errMsg += "Back-end DBMS:"
|
||||
|
||||
if Backend.getDbms() is not None:
|
||||
|
||||
@@ -18,7 +18,7 @@ from lib.core.enums import OS
|
||||
from thirdparty.six import unichr as _unichr
|
||||
|
||||
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
||||
VERSION = "1.3.6.58"
|
||||
VERSION = "1.3.7.0"
|
||||
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)
|
||||
|
||||
@@ -63,6 +63,7 @@ class _ThreadData(threading.local):
|
||||
self.retriesCount = 0
|
||||
self.seqMatcher = difflib.SequenceMatcher(None)
|
||||
self.shared = shared
|
||||
self.technique = None
|
||||
self.validationRun = 0
|
||||
self.valueStack = []
|
||||
|
||||
@@ -113,6 +114,7 @@ def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardExceptio
|
||||
|
||||
kb.threadContinue = True
|
||||
kb.threadException = False
|
||||
kb.technique = ThreadData.technique
|
||||
|
||||
if threadChoice and numThreads == 1 and not (kb.injection.data and not any(_ not in (PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED) for _ in kb.injection.data)):
|
||||
while True:
|
||||
@@ -206,6 +208,7 @@ def runThreads(numThreads, threadFunction, cleanupFunction=None, forwardExceptio
|
||||
finally:
|
||||
kb.threadContinue = True
|
||||
kb.threadException = False
|
||||
kb.technique = None
|
||||
|
||||
for lock in kb.locks.values():
|
||||
if lock.locked():
|
||||
|
||||
Reference in New Issue
Block a user