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

Skip to content

Commit b8ffcf9

Browse files
committed
few fixes here and there and multi-core processing for dictionary based hash attack
1 parent da04911 commit b8ffcf9

8 files changed

Lines changed: 223 additions & 99 deletions

File tree

extra/odict/odict.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333

3434
import types, warnings
3535

36-
class OrderedDict(dict):
36+
class _OrderedDict(dict):
3737
"""
3838
A class of dictionary that keeps the insertion order of keys.
3939
@@ -869,6 +869,11 @@ def sort(self, *args, **kwargs):
869869
"""
870870
self._sequence.sort(*args, **kwargs)
871871

872+
if INTP_VER >= (2, 7):
873+
from collections import OrderedDict
874+
else:
875+
OrderedDict = _OrderedDict
876+
872877
class Keys(object):
873878
# FIXME: should this object be a subclass of list?
874879
"""

lib/controller/controller.py

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -60,17 +60,22 @@ def __selectInjection():
6060
Selection function for injection place, parameters and type.
6161
"""
6262

63-
points = []
63+
points = {}
6464

65-
for i in xrange(0, len(kb.injections)):
66-
place = kb.injections[i].place
67-
parameter = kb.injections[i].parameter
68-
ptype = kb.injections[i].ptype
65+
for injection in kb.injections:
66+
place = injection.place
67+
parameter = injection.parameter
68+
ptype = injection.ptype
6969

7070
point = (place, parameter, ptype)
7171

7272
if point not in points:
73-
points.append(point)
73+
points[point] = injection
74+
else:
75+
for key in points[point].keys():
76+
if key != 'data':
77+
points[point][key] = points[point][key] or injection[key]
78+
points[point]['data'].update(injection['data'])
7479

7580
if len(points) == 1:
7681
kb.injection = kb.injections[0]
@@ -126,19 +131,11 @@ def __formatInjection(inj):
126131
def __showInjections():
127132
header = "sqlmap identified the following injection points with "
128133
header += "a total of %d HTTP(s) requests" % kb.testQueryCount
129-
data = ""
130-
131-
for inj in kb.injections:
132-
data += __formatInjection(inj)
133134

134-
data = data.rstrip("\n")
135+
data = "".join(set(map(lambda x: __formatInjection(x), kb.injections))).rstrip("\n")
135136

136137
conf.dumper.technic(header, data)
137138

138-
if inj.place in (HTTPMETHOD.GET, HTTPMETHOD.POST):
139-
debugMsg = "usage of %s payloads requires manual url-encoding" % inj.place
140-
logger.debug(debugMsg)
141-
142139
if conf.tamper:
143140
infoMsg = "changes made by tampering scripts are not "
144141
infoMsg += "included in shown payload content(s)"

lib/core/option.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1453,7 +1453,6 @@ def __setKnowledgeBaseAttributes(flushAll=True):
14531453
kb.testQueryCount = 0
14541454
kb.threadContinue = True
14551455
kb.threadException = False
1456-
kb.threadData = {}
14571456
kb.uChar = "NULL"
14581457
kb.xpCmdshellAvailable = False
14591458

@@ -1650,6 +1649,9 @@ def __mergeOptions(inputOptions, overrideOptions):
16501649
conf[key] = value
16511650

16521651
def __setTrafficOutputFP():
1652+
infoMsg = "setting file for logging HTTP traffic"
1653+
logger.info(infoMsg)
1654+
16531655
if conf.trafficFile:
16541656
conf.trafficFP = openFile(conf.trafficFile, "w+")
16551657

lib/core/settings.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,7 @@
300300
MSSQL_ERROR_CHUNK_LENGTH = 100
301301

302302
# Do not unescape the injected statement if it contains any of the following SQL words
303-
EXCLUDE_UNESCAPE = ("WAITFOR DELAY ", " INTO DUMPFILE ", " INTO OUTFILE ", "CREATE ", "BULK ", "EXEC ", "RECONFIGURE ", "DECLARE ", CHAR_INFERENCE_MARK)
303+
EXCLUDE_UNESCAPE = ("WAITFOR DELAY ", " INTO DUMPFILE ", " INTO OUTFILE ", "CREATE ", "BULK ", "EXEC ", "RECONFIGURE ", "DECLARE ", "'%s'" % CHAR_INFERENCE_MARK)
304304

305305
# Mark used for replacement of reflected values
306306
REFLECTED_VALUE_MARKER = '__REFLECTED_VALUE__'
@@ -364,3 +364,9 @@
364364

365365
# Extensions skipped by crawler
366366
CRAWL_EXCLUDE_EXTENSIONS = ("gif","jpg","jar","tif","bmp","war","ear","mpg","wmv","mpeg","scm","iso","dmp","dll","cab","so","avi","bin","exe","iso","tar","png","pdf","ps","mp3","zip","rar","gz")
367+
368+
# Template used for common table existence check
369+
BRUTE_TABLE_EXISTS_TEMPLATE = "EXISTS(SELECT %d FROM %s)"
370+
371+
# Template used for common column existence check
372+
BRUTE_COLUMN_EXISTS_TEMPLATE = "EXISTS(SELECT %s FROM %s)"

lib/core/threads.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
shared = advancedDict()
2727

28-
class ThreadData():
28+
class _ThreadData(threading.local):
2929
"""
3030
Represents thread independent data
3131
"""
@@ -44,6 +44,8 @@ def __init__(self):
4444
self.shared = shared
4545
self.valueStack = []
4646

47+
ThreadData = _ThreadData()
48+
4749
def getCurrentThreadUID():
4850
return hash(threading.currentThread())
4951

@@ -52,13 +54,12 @@ def readInput(message, default=None):
5254

5355
def getCurrentThreadData():
5456
"""
55-
Returns current thread's dependent data
57+
Returns current thread's local data
5658
"""
5759

58-
threadUID = getCurrentThreadUID()
59-
if threadUID not in kb.threadData:
60-
kb.threadData[threadUID] = ThreadData()
61-
return kb.threadData[threadUID]
60+
global ThreadData
61+
62+
return ThreadData
6263

6364
def exceptionHandledFunction(threadFunction):
6465
try:

lib/techniques/brute/use.py

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,21 @@
2020
from lib.core.common import popValue
2121
from lib.core.common import pushValue
2222
from lib.core.common import randomInt
23+
from lib.core.common import randomStr
2324
from lib.core.common import readInput
2425
from lib.core.common import safeStringFormat
2526
from lib.core.common import safeSQLIdentificatorNaming
2627
from lib.core.data import conf
2728
from lib.core.data import kb
2829
from lib.core.data import logger
2930
from lib.core.enums import DBMS
31+
from lib.core.exception import sqlmapDataException
3032
from lib.core.exception import sqlmapMissingMandatoryOptionException
3133
from lib.core.exception import sqlmapThreadException
3234
from lib.core.settings import MAX_NUMBER_OF_THREADS
3335
from lib.core.settings import METADB_SUFFIX
36+
from lib.core.settings import BRUTE_COLUMN_EXISTS_TEMPLATE
37+
from lib.core.settings import BRUTE_TABLE_EXISTS_TEMPLATE
3438
from lib.core.session import safeFormatString
3539
from lib.core.threads import getCurrentThreadData
3640
from lib.core.threads import runThreads
@@ -52,6 +56,13 @@ def __addPageTextWords():
5256
return wordsList
5357

5458
def tableExists(tableFile, regex=None):
59+
result = inject.checkBooleanExpression("%s" % safeStringFormat(BRUTE_TABLE_EXISTS_TEMPLATE, (randomInt(1), randomStr())))
60+
if result:
61+
errMsg = "can't use table existence check because of detected invalid results "
62+
errMsg += "(most probably caused by inability of the used injection "
63+
errMsg += "to distinguish errornous results)"
64+
raise sqlmapDataException, errMsg
65+
5566
tables = getFileItems(tableFile, lowercase=Backend.getIdentifiedDbms() in (DBMS.ACCESS), unique=True)
5667

5768
infoMsg = "checking table existence using items from '%s'" % tableFile
@@ -84,7 +95,7 @@ def tableExistsThread():
8495
else:
8596
fullTableName = table
8697

87-
result = inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %d FROM %s)", (randomInt(1), fullTableName)))
98+
result = inject.checkBooleanExpression("%s" % safeStringFormat(BRUTE_TABLE_EXISTS_TEMPLATE, (randomInt(1), fullTableName)))
8899

89100
kb.locks.ioLock.acquire()
90101

@@ -135,6 +146,13 @@ def columnExists(columnFile, regex=None):
135146
errMsg = "missing table parameter"
136147
raise sqlmapMissingMandatoryOptionException, errMsg
137148

149+
result = inject.checkBooleanExpression(safeStringFormat(BRUTE_COLUMN_EXISTS_TEMPLATE, (randomStr(), randomStr())))
150+
if result:
151+
errMsg = "can't use column existence check because of detected invalid results "
152+
errMsg += "(most probably caused by inability of the used injection "
153+
errMsg += "to distinguish errornous results)"
154+
raise sqlmapDataException, errMsg
155+
138156
infoMsg = "checking column existence using items from '%s'" % columnFile
139157
logger.info(infoMsg)
140158

@@ -169,7 +187,7 @@ def columnExistsThread():
169187
kb.locks.countLock.release()
170188
break
171189

172-
result = inject.checkBooleanExpression("%s" % safeStringFormat("EXISTS(SELECT %s FROM %s)", (column, table)))
190+
result = inject.checkBooleanExpression(safeStringFormat(BRUTE_COLUMN_EXISTS_TEMPLATE, (column, table)))
173191

174192
kb.locks.ioLock.acquire()
175193

0 commit comments

Comments
 (0)