Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit db90ff9

Browse files
committed
Fixing mess with --common-files --threads>1 (threads in threads - '.shared.' hell)
1 parent b62680b commit db90ff9

5 files changed

Lines changed: 48 additions & 28 deletions

File tree

lib/core/decorators.py

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@
1414
from lib.core.settings import UNICODE_ENCODING
1515
from lib.core.threads import getCurrentThreadData
1616

17-
_lock = threading.Lock()
17+
_cache_lock = threading.Lock()
18+
_method_locks = {}
1819

1920
def cachedmethod(f, cache=LRUDict(capacity=MAX_CACHE_ITEMS)):
2021
"""
@@ -38,12 +39,12 @@ def _(*args, **kwargs):
3839
key = int(hashlib.md5("|".join(str(_) for _ in (f, args, kwargs)).encode(UNICODE_ENCODING)).hexdigest(), 16) & 0x7fffffffffffffff
3940

4041
try:
41-
with _lock:
42+
with _cache_lock:
4243
result = cache[key]
4344
except KeyError:
4445
result = f(*args, **kwargs)
4546

46-
with _lock:
47+
with _cache_lock:
4748
cache[key] = result
4849

4950
return result
@@ -76,3 +77,16 @@ def _(*args, **kwargs):
7677
return result
7778

7879
return _
80+
81+
def lockedmethod(f):
82+
@functools.wraps(f)
83+
def _(*args, **kwargs):
84+
if f not in _method_locks:
85+
_method_locks[f] = threading.Lock()
86+
87+
with _method_locks[f]:
88+
result = f(*args, **kwargs)
89+
90+
return result
91+
92+
return _

lib/core/settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
from thirdparty.six import unichr as _unichr
1919

2020
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
21-
VERSION = "1.3.7.34"
21+
VERSION = "1.3.7.35"
2222
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
2323
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
2424
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)

lib/request/inject.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
from lib.core.data import kb
4040
from lib.core.data import logger
4141
from lib.core.data import queries
42+
from lib.core.decorators import lockedmethod
4243
from lib.core.decorators import stackedmethod
4344
from lib.core.dicts import FROM_DUMMY_TABLE
4445
from lib.core.enums import CHARSET_TYPE
@@ -351,6 +352,7 @@ def _goUnion(expression, unpack=True, dump=False):
351352

352353
return output
353354

355+
@lockedmethod
354356
@stackedmethod
355357
def getValue(expression, blind=True, union=True, error=True, time=True, fromUser=False, expected=None, batch=False, unpack=True, resumeValue=True, charsetType=None, firstChar=None, lastChar=None, dump=False, suppressOutput=None, expectingNone=False, safeCharEncode=True):
356358
"""

lib/techniques/blind/inference.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,11 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
162162
length = None
163163

164164
showEta = conf.eta and isinstance(length, int)
165-
numThreads = min(conf.threads or 0, length or 0) or 1
165+
166+
if kb.bruteMode:
167+
numThreads = 1
168+
else:
169+
numThreads = min(conf.threads or 0, length or 0) or 1
166170

167171
if showEta:
168172
progress = ProgressBar(maxValue=length)
@@ -174,13 +178,13 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
174178
else:
175179
numThreads = 1
176180

177-
if conf.threads == 1 and not timeBasedCompare and not conf.predictOutput:
181+
if numThreads == 1 and not timeBasedCompare and not conf.predictOutput:
178182
warnMsg = "running in a single-thread mode. Please consider "
179183
warnMsg += "usage of option '--threads' for faster data retrieval"
180184
singleTimeWarnMessage(warnMsg)
181185

182-
if conf.verbose in (1, 2) and not showEta and not conf.api:
183-
if isinstance(length, int) and conf.threads > 1:
186+
if conf.verbose in (1, 2) and not any((showEta, conf.api, kb.bruteMode)):
187+
if isinstance(length, int) and numThreads > 1:
184188
dataToStdout("[%s] [INFO] retrieved: %s" % (time.strftime("%X"), "_" * min(length, conf.progressWidth)))
185189
dataToStdout("\r[%s] [INFO] retrieved: " % time.strftime("%X"))
186190
else:
@@ -459,7 +463,7 @@ def getChar(idx, charTbl=None, continuousOrder=True, expand=charsetType is None,
459463
return decodeIntToUnicode(candidates[0])
460464

461465
# Go multi-threading (--threads > 1)
462-
if conf.threads > 1 and isinstance(length, int) and length > 1:
466+
if numThreads > 1 and isinstance(length, int) and length > 1:
463467
threadData.shared.value = [None] * length
464468
threadData.shared.index = [firstChar] # As list for python nested function scoping
465469
threadData.shared.start = firstChar
@@ -517,7 +521,7 @@ def blindThread():
517521
if (endCharIndex - startCharIndex == conf.progressWidth) and (endCharIndex < length - 1):
518522
output = output[:-2] + ".."
519523

520-
if conf.verbose in (1, 2) and not showEta and not conf.api:
524+
if conf.verbose in (1, 2) and not any((showEta, conf.api, kb.bruteMode)):
521525
_ = count - firstChar
522526
output += '_' * (min(length, conf.progressWidth) - len(output))
523527
status = ' %d/%d (%d%%)' % (_, length, int(100.0 * _ / length))
@@ -547,7 +551,7 @@ def blindThread():
547551
finalValue = "".join(value)
548552
infoMsg = "\r[%s] [INFO] retrieved: %s" % (time.strftime("%X"), filterControlChars(finalValue))
549553

550-
if conf.verbose in (1, 2) and not showEta and infoMsg and not conf.api:
554+
if conf.verbose in (1, 2) and infoMsg and not any((showEta, conf.api, kb.bruteMode)):
551555
dataToStdout(infoMsg)
552556

553557
# No multi-threading (--threads = 1)
@@ -632,7 +636,7 @@ def blindThread():
632636

633637
if showEta:
634638
progress.progress(index)
635-
elif conf.verbose in (1, 2) or conf.api:
639+
elif (conf.verbose in (1, 2) and not kb.bruteMode) or conf.api:
636640
dataToStdout(filterControlChars(val))
637641

638642
# some DBMSes (e.g. Firebird, DB2, etc.) have issues with trailing spaces
@@ -661,11 +665,11 @@ def blindThread():
661665
elif partialValue:
662666
hashDBWrite(expression, "%s%s" % (PARTIAL_VALUE_MARKER if not conf.hexConvert else PARTIAL_HEX_VALUE_MARKER, partialValue))
663667

664-
if conf.hexConvert and not abortedFlag and not conf.api:
668+
if conf.hexConvert and not any((abortedFlag, conf.api, kb.bruteMode)):
665669
infoMsg = "\r[%s] [INFO] retrieved: %s %s\n" % (time.strftime("%X"), filterControlChars(finalValue), " " * retrievedLength)
666670
dataToStdout(infoMsg)
667671
else:
668-
if conf.verbose in (1, 2) and not showEta and not conf.api:
672+
if conf.verbose in (1, 2) and not any((showEta, conf.api, kb.bruteMode)):
669673
dataToStdout("\n")
670674

671675
if (conf.verbose in (1, 2) and showEta) or conf.verbose >= 3:

lib/utils/brute.py

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ def tableExists(tableFile, regex=None):
102102
threadData = getCurrentThreadData()
103103
threadData.shared.count = 0
104104
threadData.shared.limit = len(tables)
105-
threadData.shared.value = []
105+
threadData.shared.files = []
106106
threadData.shared.unique = set()
107107

108108
def tableExistsThread():
@@ -128,7 +128,7 @@ def tableExistsThread():
128128
kb.locks.io.acquire()
129129

130130
if result and table.lower() not in threadData.shared.unique:
131-
threadData.shared.value.append(table)
131+
threadData.shared.files.append(table)
132132
threadData.shared.unique.add(table.lower())
133133

134134
if conf.verbose in (1, 2) and not conf.api:
@@ -152,17 +152,17 @@ def tableExistsThread():
152152
clearConsoleLine(True)
153153
dataToStdout("\n")
154154

155-
if not threadData.shared.value:
155+
if not threadData.shared.files:
156156
warnMsg = "no table(s) found"
157157
logger.warn(warnMsg)
158158
else:
159-
for item in threadData.shared.value:
159+
for item in threadData.shared.files:
160160
if conf.db not in kb.data.cachedTables:
161161
kb.data.cachedTables[conf.db] = [item]
162162
else:
163163
kb.data.cachedTables[conf.db].append(item)
164164

165-
for _ in ((conf.db, item) for item in threadData.shared.value):
165+
for _ in ((conf.db, item) for item in threadData.shared.files):
166166
if _ not in kb.brute.tables:
167167
kb.brute.tables.append(_)
168168

@@ -224,7 +224,7 @@ def columnExists(columnFile, regex=None):
224224
threadData = getCurrentThreadData()
225225
threadData.shared.count = 0
226226
threadData.shared.limit = len(columns)
227-
threadData.shared.value = []
227+
threadData.shared.files = []
228228

229229
def columnExistsThread():
230230
threadData = getCurrentThreadData()
@@ -244,7 +244,7 @@ def columnExistsThread():
244244
kb.locks.io.acquire()
245245

246246
if result:
247-
threadData.shared.value.append(column)
247+
threadData.shared.files.append(column)
248248

249249
if conf.verbose in (1, 2) and not conf.api:
250250
clearConsoleLine(True)
@@ -269,13 +269,13 @@ def columnExistsThread():
269269
clearConsoleLine(True)
270270
dataToStdout("\n")
271271

272-
if not threadData.shared.value:
272+
if not threadData.shared.files:
273273
warnMsg = "no column(s) found"
274274
logger.warn(warnMsg)
275275
else:
276276
columns = {}
277277

278-
for column in threadData.shared.value:
278+
for column in threadData.shared.files:
279279
if Backend.getIdentifiedDbms() in (DBMS.MYSQL,):
280280
result = not inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %s FROM %s WHERE %s REGEXP '[^0-9]')", (column, table, column)))
281281
else:
@@ -327,7 +327,7 @@ def fileExists(pathFile):
327327
threadData = getCurrentThreadData()
328328
threadData.shared.count = 0
329329
threadData.shared.limit = len(paths)
330-
threadData.shared.value = []
330+
threadData.shared.files = []
331331

332332
def fileExistsThread():
333333
threadData = getCurrentThreadData()
@@ -350,9 +350,9 @@ def fileExistsThread():
350350
kb.locks.io.acquire()
351351

352352
if not isNoneValue(result):
353-
threadData.shared.value.append(result)
353+
threadData.shared.files.append(result)
354354

355-
if conf.verbose in (1, 2) and not conf.api:
355+
if not conf.api:
356356
clearConsoleLine(True)
357357
infoMsg = "[%s] [INFO] retrieved: '%s'\n" % (time.strftime("%X"), path)
358358
dataToStdout(infoMsg, True)
@@ -379,10 +379,10 @@ def fileExistsThread():
379379
clearConsoleLine(True)
380380
dataToStdout("\n")
381381

382-
if not threadData.shared.value:
382+
if not threadData.shared.files:
383383
warnMsg = "no file(s) found"
384384
logger.warn(warnMsg)
385385
else:
386-
retVal = threadData.shared.value
386+
retVal = threadData.shared.files
387387

388388
return retVal

0 commit comments

Comments
 (0)