Skip to content

Commit 1ae413a

Browse files
committed
some refactoring/speedup around UNION technique
1 parent b77e204 commit 1ae413a

5 files changed

Lines changed: 21 additions & 31 deletions

File tree

lib/core/common.py

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,39 +1328,29 @@ def getRange(count, dump=False, plusOne=False):
13281328

13291329
return indexRange
13301330

1331-
def parseUnionPage(output, expression, partial=False, sort=True):
1331+
def parseUnionPage(output, expression, partial=False, unique=True):
13321332
if output is None:
13331333
return None
13341334

13351335
data = BigArray()
13361336

13371337
if output.startswith(kb.chars.start) and output.endswith(kb.chars.stop):
13381338
regExpr = '%s(.*?)%s' % (kb.chars.start, kb.chars.stop)
1339-
13401339
output = re.findall(regExpr, output, re.DOTALL | re.IGNORECASE)
1340+
_ = set()
13411341

1342-
if sort:
1343-
_ = []
1344-
unique = set()
1345-
for entry in output:
1342+
for entry in output:
1343+
if unique:
13461344
key = entry.lower()
1347-
if key not in unique:
1348-
unique.add(key)
1349-
_.append(entry)
1350-
output = _
1345+
if key not in _:
1346+
_.add(key)
1347+
else:
1348+
continue
13511349

1352-
for entry in output:
13531350
entry = safecharencode(entry) if kb.safeCharEncode else entry
1351+
entry = entry.split(DUMP_DEL_MARKER if DUMP_DEL_MARKER in entry else kb.chars.delimiter)
13541352

1355-
if DUMP_DEL_MARKER in entry:
1356-
entry = entry.split(DUMP_DEL_MARKER)
1357-
else:
1358-
entry = entry.split(kb.chars.delimiter)
1359-
1360-
if len(entry) == 1:
1361-
data.append(entry[0])
1362-
else:
1363-
data.append(entry)
1353+
data.append(entry[0] if len(entry) == 1 else entry)
13641354
else:
13651355
data = output
13661356

lib/request/inject.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -368,7 +368,7 @@ def __goError(expression, expected=None, resumeValue=True, dump=False):
368368

369369
return output
370370

371-
def __goInband(expression, expected=None, sort=True, resumeValue=True, unpack=True, dump=False):
371+
def __goInband(expression, expected=None, unique=True, resumeValue=True, unpack=True, dump=False):
372372
"""
373373
Retrieve the output of a SQL query taking advantage of an inband SQL
374374
injection vulnerability on the affected parameter.
@@ -384,11 +384,11 @@ def __goInband(expression, expected=None, sort=True, resumeValue=True, unpack=Tr
384384
if isinstance(output, list):
385385
data = output
386386
else:
387-
data = parseUnionPage(output, expression, partial, sort)
387+
data = parseUnionPage(output, expression, partial, unique)
388388

389389
return data
390390

391-
def getValue(expression, blind=True, inband=True, error=True, time=True, fromUser=False, expected=None, batch=False, unpack=True, sort=True, resumeValue=True, charsetType=None, firstChar=None, lastChar=None, dump=False, suppressOutput=None, expectingNone=False, safeCharEncode=True):
391+
def getValue(expression, blind=True, inband=True, error=True, time=True, fromUser=False, expected=None, batch=False, unpack=True, unique=True, resumeValue=True, charsetType=None, firstChar=None, lastChar=None, dump=False, suppressOutput=None, expectingNone=False, safeCharEncode=True):
392392
"""
393393
Called each time sqlmap inject a SQL query on the SQL injection
394394
affected parameter. It can call a function to retrieve the output
@@ -429,9 +429,9 @@ def getValue(expression, blind=True, inband=True, error=True, time=True, fromUse
429429
kb.technique = PAYLOAD.TECHNIQUE.UNION
430430

431431
if expected == EXPECTED.BOOL:
432-
value = __goInband(forgeCaseExpression, expected, sort, resumeValue, unpack, dump)
432+
value = __goInband(forgeCaseExpression, expected, unique, resumeValue, unpack, dump)
433433
else:
434-
value = __goInband(query, expected, sort, resumeValue, unpack, dump)
434+
value = __goInband(query, expected, unique, resumeValue, unpack, dump)
435435

436436
count += 1
437437
found = (value is not None) or (value is None and expectingNone) or count >= MAX_TECHNIQUES_PER_VALUE

lib/takeover/xp_cmdshell.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ def xpCmdshellEvalCmd(self, cmd, first=None, last=None):
121121

122122
self.delRemoteFile(tmpFile)
123123

124-
output = inject.getValue("SELECT %s FROM %s" % (self.tblField, self.cmdTblName), resumeValue=False, sort=False, firstChar=first, lastChar=last, safeCharEncode=False)
124+
output = inject.getValue("SELECT %s FROM %s" % (self.tblField, self.cmdTblName), resumeValue=False, unique=False, firstChar=first, lastChar=last, safeCharEncode=False)
125125
inject.goStacked("DELETE FROM %s" % self.cmdTblName)
126126

127127
if output and isinstance(output, (list, tuple)):

plugins/dbms/mssqlserver/filesystem.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ def stackedReadFile(self, rFile):
9494
inject.goStacked(binToHexQuery)
9595

9696
if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION):
97-
result = inject.getValue("SELECT %s FROM %s ORDER BY id ASC" % (self.tblField, hexTbl), sort=False, resumeValue=False, blind=False, error=False)
97+
result = inject.getValue("SELECT %s FROM %s ORDER BY id ASC" % (self.tblField, hexTbl), unique=False, resumeValue=False, blind=False, error=False)
9898

9999
if not result:
100100
result = []
@@ -108,7 +108,7 @@ def stackedReadFile(self, rFile):
108108
indexRange = getRange(count)
109109

110110
for index in indexRange:
111-
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, sort=False, charsetType=3)
111+
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)
112112
result.append(chunk)
113113

114114
inject.goStacked("DROP TABLE %s" % hexTbl)

plugins/dbms/mysql/filesystem.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def stackedReadFile(self, rFile):
5252
logger.debug(debugMsg)
5353
inject.goStacked("LOAD DATA INFILE '%s' INTO TABLE %s FIELDS TERMINATED BY '%s' (%s)" % (tmpFile, self.fileTblName, randomStr(10), self.tblField))
5454

55-
length = unArrayizeValue(inject.getValue("SELECT LENGTH(%s) FROM %s" % (self.tblField, self.fileTblName), sort=False, resumeValue=False, charsetType=2))
55+
length = unArrayizeValue(inject.getValue("SELECT LENGTH(%s) FROM %s" % (self.tblField, self.fileTblName), unique=False, resumeValue=False, charsetType=2))
5656

5757
if not isNumPosStrValue(length):
5858
errMsg = "unable to retrieve the content of the "
@@ -66,11 +66,11 @@ def stackedReadFile(self, rFile):
6666
result = []
6767

6868
for i in xrange(1, length, sustrLen):
69-
chunk = inject.getValue("SELECT MID(%s, %d, %d) FROM %s" % (self.tblField, i, sustrLen, self.fileTblName), unpack=False, sort=False, resumeValue=False, charsetType=3)
69+
chunk = inject.getValue("SELECT MID(%s, %d, %d) FROM %s" % (self.tblField, i, sustrLen, self.fileTblName), unpack=False, unique=False, resumeValue=False, charsetType=3)
7070

7171
result.append(chunk)
7272
else:
73-
result = inject.getValue("SELECT %s FROM %s" % (self.tblField, self.fileTblName), sort=False, resumeValue=False, charsetType=3)
73+
result = inject.getValue("SELECT %s FROM %s" % (self.tblField, self.fileTblName), unique=False, resumeValue=False, charsetType=3)
7474

7575
return result
7676

0 commit comments

Comments
 (0)