Retrieve the output of a SQL query taking advantage of the error-based SQL injection vulnerability on the affected parameter.
(expression, dump=False)
| 297 | return value |
| 298 | |
| 299 | def errorUse(expression, dump=False): |
| 300 | """ |
| 301 | Retrieve the output of a SQL query taking advantage of the error-based |
| 302 | SQL injection vulnerability on the affected parameter. |
| 303 | """ |
| 304 | |
| 305 | initTechnique(getTechnique()) |
| 306 | |
| 307 | abortedFlag = False |
| 308 | count = None |
| 309 | emptyFields = [] |
| 310 | start = time.time() |
| 311 | startLimit = 0 |
| 312 | stopLimit = None |
| 313 | value = None |
| 314 | |
| 315 | _, _, _, _, _, expressionFieldsList, expressionFields, _ = agent.getFields(expression) |
| 316 | |
| 317 | # Set kb.partRun in case the engine is called from the API |
| 318 | kb.partRun = getPartRun(alias=False) if conf.api else None |
| 319 | |
| 320 | # We have to check if the SQL query might return multiple entries |
| 321 | # and in such case forge the SQL limiting the query output one |
| 322 | # entry at a time |
| 323 | # NOTE: we assume that only queries that get data from a table can |
| 324 | # return multiple entries |
| 325 | if (dump and (conf.limitStart or conf.limitStop)) or (" FROM " in expression.upper() and ((Backend.getIdentifiedDbms() not in FROM_DUMMY_TABLE) or (Backend.getIdentifiedDbms() in FROM_DUMMY_TABLE and not expression.upper().endswith(FROM_DUMMY_TABLE[Backend.getIdentifiedDbms()]))) and ("(CASE" not in expression.upper() or ("(CASE" in expression.upper() and "WHEN use" in expression))) and not re.search(SQL_SCALAR_REGEX, expression, re.I): |
| 326 | expression, limitCond, topLimit, startLimit, stopLimit = agent.limitCondition(expression, dump) |
| 327 | |
| 328 | if limitCond: |
| 329 | # Count the number of SQL query entries output |
| 330 | countedExpression = expression.replace(expressionFields, queries[Backend.getIdentifiedDbms()].count.query % ('*' if len(expressionFieldsList) > 1 else expressionFields), 1) |
| 331 | |
| 332 | if " ORDER BY " in countedExpression.upper(): |
| 333 | _ = countedExpression.upper().rindex(" ORDER BY ") |
| 334 | countedExpression = countedExpression[:_] |
| 335 | |
| 336 | _, _, _, _, _, _, countedExpressionFields, _ = agent.getFields(countedExpression) |
| 337 | count = unArrayizeValue(_oneShotErrorUse(countedExpression, countedExpressionFields)) |
| 338 | |
| 339 | if isNumPosStrValue(count): |
| 340 | if isinstance(stopLimit, int) and stopLimit > 0: |
| 341 | stopLimit = min(int(count), int(stopLimit)) |
| 342 | else: |
| 343 | stopLimit = int(count) |
| 344 | |
| 345 | debugMsg = "used SQL query returns " |
| 346 | debugMsg += "%d %s" % (stopLimit, "entries" if stopLimit > 1 else "entry") |
| 347 | logger.debug(debugMsg) |
| 348 | |
| 349 | elif count and not count.isdigit(): |
| 350 | warnMsg = "it was not possible to count the number " |
| 351 | warnMsg += "of entries for the SQL query provided. " |
| 352 | warnMsg += "sqlmap will assume that it returns only " |
| 353 | warnMsg += "one entry" |
| 354 | logger.warning(warnMsg) |
| 355 | |
| 356 | stopLimit = 1 |
no test coverage detected
searching dependent graphs…