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

Skip to content

Commit e7b93b5

Browse files
committed
Implementation for an Issue #363
1 parent 231ea51 commit e7b93b5

3 files changed

Lines changed: 46 additions & 44 deletions

File tree

lib/controller/checks.py

Lines changed: 36 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,24 @@ def checkSqlInjection(place, parameter, value):
8585
if kb.endDetection:
8686
break
8787

88+
if conf.dbms is None:
89+
if not injection.dbms and PAYLOAD.TECHNIQUE.BOOLEAN in injection.data:
90+
if not Backend.getIdentifiedDbms() and not kb.heuristicDbms:
91+
kb.heuristicDbms = heuristicCheckDbms(injection) or UNKNOWN_DBMS
92+
93+
if not conf.testFilter and (Backend.getErrorParsedDBMSes() or kb.heuristicDbms) not in ([], None, UNKNOWN_DBMS):
94+
if kb.reduceTests is None and Backend.getErrorParsedDBMSes():
95+
msg = "heuristic (parsing) test showed that the "
96+
msg += "back-end DBMS could be '%s'. " % (Format.getErrorParsedDBMSes() if Backend.getErrorParsedDBMSes() else kb.heuristicDbms)
97+
msg += "Do you want to skip test payloads specific for other DBMSes? [Y/n]"
98+
kb.reduceTests = [] if readInput(msg, default='Y').upper() != 'Y' else (Backend.getErrorParsedDBMSes() or [kb.heuristicDbms])
99+
100+
if kb.extendTests is None:
101+
_ = (Format.getErrorParsedDBMSes() if Backend.getErrorParsedDBMSes() else kb.heuristicDbms)
102+
msg = "do you want to include all tests for '%s' " % _
103+
msg += "ignoring provided level (%d) and risk (%s)? [Y/n]" % (conf.level, conf.risk)
104+
kb.extendTests = [] if readInput(msg, default='Y').upper() != 'Y' else (Backend.getErrorParsedDBMSes() or [kb.heuristicDbms])
105+
88106
title = test.title
89107
stype = test.stype
90108
clause = test.clause
@@ -143,15 +161,24 @@ def checkSqlInjection(place, parameter, value):
143161
logger.debug(debugMsg)
144162
continue
145163

164+
165+
# Skip DBMS-specific test if it does not match either the
166+
# previously identified or the user's provided DBMS (either
167+
# from program switch or from parsed error message(s))
168+
if "details" in test and "dbms" in test.details:
169+
dbms = test.details.dbms
170+
else:
171+
dbms = None
172+
146173
# Skip tests if title is not included by the given filter
147174
if conf.testFilter:
148-
if not any(re.search(conf.testFilter, str(item), re.I) for item in (test.title, test.vector,\
149-
test.details.dbms if "details" in test and "dbms" in test.details else "")):
175+
if not any(re.search(conf.testFilter, str(item), re.I) for item in (test.title, test.vector, dbms)):
150176
debugMsg = "skipping test '%s' because " % title
151177
debugMsg += "its name/vector/dbms is not included by the given filter"
152178
logger.debug(debugMsg)
153179
continue
154-
else:
180+
181+
if not (kb.extendTests and intersect(dbms, kb.extendTests)):
155182
# Skip test if the risk is higher than the provided (or default)
156183
# value
157184
# Parse test's <risk>
@@ -170,14 +197,6 @@ def checkSqlInjection(place, parameter, value):
170197
logger.debug(debugMsg)
171198
continue
172199

173-
# Skip DBMS-specific test if it does not match either the
174-
# previously identified or the user's provided DBMS (either
175-
# from program switch or from parsed error message(s))
176-
if "details" in test and "dbms" in test.details:
177-
dbms = test.details.dbms
178-
else:
179-
dbms = None
180-
181200
if dbms is not None:
182201
if injection.dbms is not None and not intersect(injection.dbms, dbms):
183202
debugMsg = "skipping test '%s' because " % title
@@ -192,17 +211,7 @@ def checkSqlInjection(place, parameter, value):
192211
logger.debug(debugMsg)
193212
continue
194213

195-
if conf.dbms is None and len(Backend.getErrorParsedDBMSes()) > 0 and not intersect(dbms, Backend.getErrorParsedDBMSes()) and kb.skipOthersDbms is None:
196-
msg = "parsed error message(s) showed that the "
197-
msg += "back-end DBMS could be %s. " % Format.getErrorParsedDBMSes()
198-
msg += "Do you want to skip test payloads specific for other DBMSes? [Y/n]"
199-
200-
if readInput(msg, default="Y") in ("y", "Y"):
201-
kb.skipOthersDbms = Backend.getErrorParsedDBMSes()
202-
else:
203-
kb.skipOthersDbms = []
204-
205-
if kb.skipOthersDbms and not intersect(dbms, kb.skipOthersDbms):
214+
if kb.reduceTests and not intersect(dbms, kb.reduceTests):
206215
debugMsg = "skipping test '%s' because " % title
207216
debugMsg += "the parsed error message(s) showed "
208217
debugMsg += "that the back-end DBMS could be "
@@ -549,20 +558,12 @@ def genCmpPayload():
549558
# Reset forced back-end DBMS value
550559
Backend.flushForcedDbms()
551560

552-
if len(injection.data) == 1 and PAYLOAD.TECHNIQUE.BOOLEAN in injection.data:
553-
if not Backend.getIdentifiedDbms() and kb.heuristicDbms in (None, UNKNOWN_DBMS):
554-
kb.heuristicDbms = heuristicCheckDbms(injection) or UNKNOWN_DBMS
555-
556-
if Backend.getIdentifiedDbms() or kb.heuristicDbms not in (None, UNKNOWN_DBMS):
557-
#do you want to extend <- one time question!!!!!!!!!! (mirek)
558-
pass
559-
560561
except KeyboardInterrupt:
561562
warnMsg = "user aborted during detection phase"
562563
logger.warn(warnMsg)
563564

564-
message = "How do you want to proceed? [(S)kip current test/(e)nd detection phase/(n)ext parameter/(q)uit]"
565-
choice = readInput(message, default="S", checkBatch=False)
565+
msg = "How do you want to proceed? [(S)kip current test/(e)nd detection phase/(n)ext parameter/(q)uit]"
566+
choice = readInput(msg, default="S", checkBatch=False)
566567

567568
if choice[0] in ("s", "S"):
568569
pass
@@ -615,7 +616,7 @@ def heuristicCheckDbms(injection):
615616
kb.injection = popValue()
616617

617618
if retVal:
618-
infoMsg = "heuristic test showed that the back-end DBMS "
619+
infoMsg = "heuristic (extended) test shows that the back-end DBMS " # not as important as "parsing" counter-part (because of false-positives)
619620
infoMsg += "could be '%s' " % retVal
620621
logger.info(infoMsg)
621622

@@ -729,7 +730,7 @@ def heuristicCheckSqlInjection(place, parameter):
729730
parseFilePaths(page)
730731
result = wasLastResponseDBMSError()
731732

732-
infoMsg = "heuristic test shows that %s " % place
733+
infoMsg = "heuristic (parsing) test shows that %s " % place
733734
infoMsg += "parameter '%s' might " % parameter
734735

735736
def _(page):
@@ -762,7 +763,7 @@ def _(page):
762763
kb.ignoreCasted = readInput(message, default='Y' if conf.multipleTargets else 'N').upper() != 'N'
763764

764765
elif result:
765-
infoMsg += "be injectable (possible DBMS: %s)" % (Format.getErrorParsedDBMSes() or UNKNOWN_DBMS)
766+
infoMsg += "be injectable (possible DBMS: '%s')" % (Format.getErrorParsedDBMSes() or UNKNOWN_DBMS)
766767
logger.info(infoMsg)
767768

768769
else:

lib/core/option.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,6 +1525,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
15251525
kb.dynamicParameter = False
15261526
kb.endDetection = False
15271527
kb.explicitSettings = set()
1528+
kb.extendTests = None
15281529
kb.errorIsNone = True
15291530
kb.fileReadMode = False
15301531
kb.forcedDbms = None
@@ -1552,12 +1553,6 @@ def _setKnowledgeBaseAttributes(flushAll=True):
15521553
kb.multiThreadMode = False
15531554
kb.negativeLogic = False
15541555
kb.nullConnection = None
1555-
kb.pageCompress = True
1556-
kb.pageTemplate = None
1557-
kb.pageTemplates = dict()
1558-
kb.postHint = None
1559-
kb.previousMethod = None
1560-
kb.processUserMarks = None
15611556
kb.orderByColumns = None
15621557
kb.originalCode = None
15631558
kb.originalPage = None
@@ -1570,12 +1565,19 @@ def _setKnowledgeBaseAttributes(flushAll=True):
15701565
kb.osVersion = None
15711566
kb.osSP = None
15721567

1568+
kb.pageCompress = True
1569+
kb.pageTemplate = None
1570+
kb.pageTemplates = dict()
15731571
kb.pageEncoding = DEFAULT_PAGE_ENCODING
15741572
kb.pageStable = None
15751573
kb.partRun = None
15761574
kb.permissionFlag = False
1575+
kb.postHint = None
1576+
kb.postSpaceToPlus = False
15771577
kb.prependFlag = False
15781578
kb.processResponseCounter = 0
1579+
kb.previousMethod = None
1580+
kb.processUserMarks = None
15791581
kb.proxyAuthHeader = None
15801582
kb.queryCounter = 0
15811583
kb.redirectChoice = None
@@ -1588,8 +1590,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
15881590
kb.resumeValues = True
15891591
kb.safeCharEncode = False
15901592
kb.singleLogFlags = set()
1591-
kb.skipOthersDbms = None
1592-
kb.postSpaceToPlus = False
1593+
kb.reduceTests = None
15931594
kb.stickyDBMS = False
15941595
kb.stickyLevel = None
15951596
kb.suppressResumeInfo = False

lib/core/settings.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@
466466
CHECK_ZERO_COLUMNS_THRESHOLD = 10
467467

468468
# Boldify all logger messages containing these "patterns"
469-
BOLD_PATTERNS = ("' injectable", "might be injectable", "' is vulnerable", "is not injectable", "test failed", "test passed", "live test final result", "heuristic test showed")
469+
BOLD_PATTERNS = ("' injectable", "might be injectable", "' is vulnerable", "is not injectable", "test failed", "test passed", "live test final result", "test shows that")
470470

471471
# Generic www root directory names
472472
GENERIC_DOC_ROOT_DIRECTORY_NAMES = ("htdocs", "wwwroot", "www")

0 commit comments

Comments
 (0)