|
22 | 22 | from lib.core.common import findDynamicContent |
23 | 23 | from lib.core.common import Format |
24 | 24 | from lib.core.common import getLastRequestHTTPError |
| 25 | +from lib.core.common import getPublicTypeMembers |
25 | 26 | from lib.core.common import getSortedInjectionTests |
26 | 27 | from lib.core.common import getUnicode |
27 | 28 | from lib.core.common import intersect |
|
42 | 43 | from lib.core.data import logger |
43 | 44 | from lib.core.datatype import AttribDict |
44 | 45 | from lib.core.datatype import InjectionDict |
| 46 | +from lib.core.dicts import FROM_DUMMY_TABLE |
| 47 | +from lib.core.enums import DBMS |
45 | 48 | from lib.core.enums import HEURISTIC_TEST |
46 | 49 | from lib.core.enums import HTTPHEADER |
47 | 50 | from lib.core.enums import HTTPMETHOD |
|
55 | 58 | from lib.core.settings import FORMAT_EXCEPTION_STRINGS |
56 | 59 | from lib.core.settings import HEURISTIC_CHECK_ALPHABET |
57 | 60 | from lib.core.settings import SUHOSIN_MAX_VALUE_LENGTH |
58 | | -from lib.core.settings import UNKNOWN_DBMS_VERSION |
| 61 | +from lib.core.settings import UNKNOWN_DBMS |
59 | 62 | from lib.core.settings import LOWER_RATIO_BOUND |
60 | 63 | from lib.core.settings import UPPER_RATIO_BOUND |
61 | 64 | from lib.core.settings import IDS_WAF_CHECK_PAYLOAD |
@@ -441,11 +444,17 @@ def genCmpPayload(): |
441 | 444 | configUnion(test.request.char, test.request.columns) |
442 | 445 |
|
443 | 446 | if not Backend.getIdentifiedDbms(): |
444 | | - warnMsg = "using unescaped version of the test " |
445 | | - warnMsg += "because of zero knowledge of the " |
446 | | - warnMsg += "back-end DBMS. You can try to " |
447 | | - warnMsg += "explicitly set it using option '--dbms'" |
448 | | - singleTimeWarnMessage(warnMsg) |
| 447 | + if not kb.heuristicDbms: |
| 448 | + kb.heuristicDbms = heuristicCheckDbms(injection) or UNKNOWN_DBMS |
| 449 | + |
| 450 | + if kb.heuristicDbms == UNKNOWN_DBMS: |
| 451 | + warnMsg = "using unescaped version of the test " |
| 452 | + warnMsg += "because of zero knowledge of the " |
| 453 | + warnMsg += "back-end DBMS. You can try to " |
| 454 | + warnMsg += "explicitly set it using option '--dbms'" |
| 455 | + singleTimeWarnMessage(warnMsg) |
| 456 | + else: |
| 457 | + Backend.forceDbms(kb.heuristicDbms) |
449 | 458 |
|
450 | 459 | if unionExtended: |
451 | 460 | infoMsg = "automatically extending ranges " |
@@ -582,6 +591,32 @@ def genCmpPayload(): |
582 | 591 |
|
583 | 592 | return injection |
584 | 593 |
|
| 594 | +def heuristicCheckDbms(injection): |
| 595 | + retVal = None |
| 596 | + |
| 597 | + if not Backend.getIdentifiedDbms() and len(injection.data) == 1 and PAYLOAD.TECHNIQUE.BOOLEAN in injection.data: |
| 598 | + pushValue(kb.injection) |
| 599 | + kb.injection = injection |
| 600 | + randStr1, randStr2 = randomStr(), randomStr() |
| 601 | + |
| 602 | + for dbms in getPublicTypeMembers(DBMS, True): |
| 603 | + Backend.forceDbms(dbms) |
| 604 | + |
| 605 | + if checkBooleanExpression("(SELECT '%s'%s)='%s'" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), randStr1)): |
| 606 | + if not checkBooleanExpression("(SELECT '%s'%s)='%s'" % (randStr1, FROM_DUMMY_TABLE.get(dbms, ""), randStr2)): |
| 607 | + retVal = dbms |
| 608 | + break |
| 609 | + |
| 610 | + Backend.flushForcedDbms() |
| 611 | + kb.injection = popValue() |
| 612 | + |
| 613 | + if retVal: |
| 614 | + infoMsg = "heuristic test showed that the back-end DBMS " |
| 615 | + infoMsg += "could be '%s' " % retVal |
| 616 | + logger.info(infoMsg) |
| 617 | + |
| 618 | + return retVal |
| 619 | + |
585 | 620 | def checkFalsePositives(injection): |
586 | 621 | """ |
587 | 622 | Checks for false positives (only in single special cases) |
@@ -723,7 +758,7 @@ def _(page): |
723 | 758 | kb.ignoreCasted = readInput(message, default='Y' if conf.multipleTargets else 'N').upper() != 'N' |
724 | 759 |
|
725 | 760 | elif result: |
726 | | - infoMsg += "be injectable (possible DBMS: %s)" % (Format.getErrorParsedDBMSes() or UNKNOWN_DBMS_VERSION) |
| 761 | + infoMsg += "be injectable (possible DBMS: %s)" % (Format.getErrorParsedDBMSes() or UNKNOWN_DBMS) |
727 | 762 | logger.info(infoMsg) |
728 | 763 |
|
729 | 764 | else: |
|
0 commit comments