mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2024-11-25 02:53:46 +03:00
ORDER BY technique used for finding proper UNION col count (dramatical improvement of speed and capabilities) and one minor bug fix
This commit is contained in:
parent
07afcd5440
commit
9423d15fb3
|
@ -532,6 +532,9 @@ Anthony Zboralski <anthony.zboralski@bellua.com>
|
||||||
Thierry Zoller <thierry@zoller.lu>
|
Thierry Zoller <thierry@zoller.lu>
|
||||||
for reporting a couple of major bugs
|
for reporting a couple of major bugs
|
||||||
|
|
||||||
|
Zhen Zhou <zhouzhenster@gmail.com>
|
||||||
|
for suggesting a feature
|
||||||
|
|
||||||
-insane- <insane_@gmx.de>
|
-insane- <insane_@gmx.de>
|
||||||
for reporting a minor bug
|
for reporting a minor bug
|
||||||
|
|
||||||
|
|
|
@ -1424,6 +1424,7 @@ def __setKnowledgeBaseAttributes(flushAll=True):
|
||||||
kb.nullConnection = None
|
kb.nullConnection = None
|
||||||
kb.pageTemplate = None
|
kb.pageTemplate = None
|
||||||
kb.pageTemplates = dict()
|
kb.pageTemplates = dict()
|
||||||
|
kb.orderByColumns = None
|
||||||
kb.originalPage = None
|
kb.originalPage = None
|
||||||
|
|
||||||
# Back-end DBMS underlying operating system fingerprint via banner (-b)
|
# Back-end DBMS underlying operating system fingerprint via banner (-b)
|
||||||
|
|
|
@ -388,3 +388,6 @@ BIGARRAY_CHUNK_LENGTH = 4096
|
||||||
|
|
||||||
# Only console display last n table rows
|
# Only console display last n table rows
|
||||||
TRIM_STDOUT_DUMP_SIZE = 1024
|
TRIM_STDOUT_DUMP_SIZE = 1024
|
||||||
|
|
||||||
|
# Step used in ORDER BY technique used for finding the right number of columns in UNION query injections
|
||||||
|
ORDER_BY_STEP = 10
|
||||||
|
|
|
@ -21,8 +21,10 @@ from lib.core.common import getUnicode
|
||||||
from lib.core.common import listToStrValue
|
from lib.core.common import listToStrValue
|
||||||
from lib.core.common import popValue
|
from lib.core.common import popValue
|
||||||
from lib.core.common import pushValue
|
from lib.core.common import pushValue
|
||||||
|
from lib.core.common import randomInt
|
||||||
from lib.core.common import randomStr
|
from lib.core.common import randomStr
|
||||||
from lib.core.common import removeReflectiveValues
|
from lib.core.common import removeReflectiveValues
|
||||||
|
from lib.core.common import singleTimeLogMessage
|
||||||
from lib.core.common import singleTimeWarnMessage
|
from lib.core.common import singleTimeWarnMessage
|
||||||
from lib.core.common import stdev
|
from lib.core.common import stdev
|
||||||
from lib.core.common import wasLastRequestDBMSError
|
from lib.core.common import wasLastRequestDBMSError
|
||||||
|
@ -39,6 +41,7 @@ from lib.core.settings import MIN_RATIO
|
||||||
from lib.core.settings import MAX_RATIO
|
from lib.core.settings import MAX_RATIO
|
||||||
from lib.core.settings import MIN_STATISTICAL_RANGE
|
from lib.core.settings import MIN_STATISTICAL_RANGE
|
||||||
from lib.core.settings import MIN_UNION_RESPONSES
|
from lib.core.settings import MIN_UNION_RESPONSES
|
||||||
|
from lib.core.settings import ORDER_BY_STEP
|
||||||
from lib.core.unescaper import unescaper
|
from lib.core.unescaper import unescaper
|
||||||
from lib.parse.html import htmlParser
|
from lib.parse.html import htmlParser
|
||||||
from lib.request.comparison import comparison
|
from lib.request.comparison import comparison
|
||||||
|
@ -50,11 +53,53 @@ def __findUnionCharCount(comment, place, parameter, value, prefix, suffix, where
|
||||||
"""
|
"""
|
||||||
retVal = None
|
retVal = None
|
||||||
|
|
||||||
|
def __orderByTechnique():
|
||||||
|
def __orderByTest(cols):
|
||||||
|
query = agent.prefixQuery("ORDER BY %d" % cols, prefix=prefix)
|
||||||
|
query = agent.suffixQuery(query, suffix=suffix, comment=comment)
|
||||||
|
payload = agent.payload(newValue=query, place=place, parameter=parameter, where=where)
|
||||||
|
page, _ = Request.queryPage(payload, place=place, content=True, raise404=False)
|
||||||
|
return not re.search(r"((warning|error)[^\n]*order)|(order by)", page or "", re.I)
|
||||||
|
|
||||||
|
if __orderByTest(1) and not __orderByTest(randomInt()):
|
||||||
|
infoMsg = "ORDER BY technique seems to be usable. "
|
||||||
|
infoMsg += "this should dramatically reduce the "
|
||||||
|
infoMsg += "time needed to find the right number "
|
||||||
|
infoMsg += "of query columns. Automatically extending the "
|
||||||
|
infoMsg += "range for UNION query injection technique"
|
||||||
|
singleTimeLogMessage(infoMsg)
|
||||||
|
|
||||||
|
lowCols, highCols = 1, ORDER_BY_STEP
|
||||||
|
found = None
|
||||||
|
while not found:
|
||||||
|
if __orderByTest(highCols):
|
||||||
|
lowCols = highCols
|
||||||
|
highCols += ORDER_BY_STEP
|
||||||
|
else:
|
||||||
|
while not found:
|
||||||
|
mid = highCols - (highCols - lowCols) / 2
|
||||||
|
if __orderByTest(mid):
|
||||||
|
lowCols = mid
|
||||||
|
else:
|
||||||
|
highCols = mid
|
||||||
|
if (highCols - lowCols) < 2:
|
||||||
|
found = lowCols
|
||||||
|
|
||||||
|
return found
|
||||||
|
|
||||||
pushValue(kb.errorIsNone)
|
pushValue(kb.errorIsNone)
|
||||||
items, ratios = [], []
|
items, ratios = [], []
|
||||||
kb.errorIsNone = False
|
kb.errorIsNone = False
|
||||||
lowerCount, upperCount = conf.uColsStart, conf.uColsStop
|
lowerCount, upperCount = conf.uColsStart, conf.uColsStop
|
||||||
|
|
||||||
|
if lowerCount == 1:
|
||||||
|
found = kb.orderByColumns or __orderByTechnique()
|
||||||
|
if found:
|
||||||
|
kb.orderByColumns = found
|
||||||
|
infoMsg = "target url appears to have %d columns in query" % found
|
||||||
|
singleTimeLogMessage(infoMsg)
|
||||||
|
return found
|
||||||
|
|
||||||
if abs(upperCount - lowerCount) < MIN_UNION_RESPONSES:
|
if abs(upperCount - lowerCount) < MIN_UNION_RESPONSES:
|
||||||
upperCount = lowerCount + MIN_UNION_RESPONSES
|
upperCount = lowerCount + MIN_UNION_RESPONSES
|
||||||
|
|
||||||
|
|
|
@ -2031,10 +2031,8 @@ class Enumeration:
|
||||||
query += exclDbsQuery
|
query += exclDbsQuery
|
||||||
values = inject.getValue(query, blind=False)
|
values = inject.getValue(query, blind=False)
|
||||||
|
|
||||||
if not isNoneValue(values):
|
if not any([isNoneValue(values), isinstance(values, basestring)]):
|
||||||
if isinstance(values, basestring):
|
values = filter(lambda x: isinstance(x, (tuple, list, set)) and len(x) == 2, values)
|
||||||
values = [ values ]
|
|
||||||
|
|
||||||
for foundDb, foundTbl in values:
|
for foundDb, foundTbl in values:
|
||||||
foundDb = safeSQLIdentificatorNaming(foundDb)
|
foundDb = safeSQLIdentificatorNaming(foundDb)
|
||||||
foundTbl = safeSQLIdentificatorNaming(foundTbl, True)
|
foundTbl = safeSQLIdentificatorNaming(foundTbl, True)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user