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

Skip to content

Commit be9381a

Browse files
committed
Implements #1845
1 parent 5d09f7b commit be9381a

7 files changed

Lines changed: 36 additions & 23 deletions

File tree

lib/controller/checks.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
from lib.core.enums import HEURISTIC_TEST
5656
from lib.core.enums import HTTP_HEADER
5757
from lib.core.enums import HTTPMETHOD
58+
from lib.core.enums import NOTE
5859
from lib.core.enums import NULLCONNECTION
5960
from lib.core.enums import PAYLOAD
6061
from lib.core.enums import PLACE
@@ -696,10 +697,10 @@ def genCmpPayload():
696697
warnMsg += "problems during data retrieval"
697698
logger.warn(warnMsg)
698699

699-
injection = checkFalsePositives(injection)
700-
701-
if not injection:
700+
if not checkFalsePositives(injection):
702701
kb.vulnHosts.remove(conf.hostname)
702+
injection.notes.add(NOTE.FALSE_POSITIVE_OR_UNEXPLOITABLE)
703+
703704
else:
704705
injection = None
705706

@@ -748,7 +749,7 @@ def checkFalsePositives(injection):
748749
Checks for false positives (only in single special cases)
749750
"""
750751

751-
retVal = injection
752+
retVal = True
752753

753754
if all(_ in (PAYLOAD.TECHNIQUE.BOOLEAN, PAYLOAD.TECHNIQUE.TIME, PAYLOAD.TECHNIQUE.STACKED) for _ in injection.data) or\
754755
(len(injection.data) == 1 and PAYLOAD.TECHNIQUE.UNION in injection.data and "Generic" in injection.data[PAYLOAD.TECHNIQUE.UNION].title):
@@ -774,30 +775,30 @@ def _():
774775
break
775776

776777
if not checkBooleanExpression("%d=%d" % (randInt1, randInt1)):
777-
retVal = None
778+
retVal = False
778779
break
779780

780781
# Just in case if DBMS hasn't properly recovered from previous delayed request
781782
if PAYLOAD.TECHNIQUE.BOOLEAN not in injection.data:
782783
checkBooleanExpression("%d=%d" % (randInt1, randInt2))
783784

784785
if checkBooleanExpression("%d=%d" % (randInt1, randInt3)): # this must not be evaluated to True
785-
retVal = None
786+
retVal = False
786787
break
787788

788789
elif checkBooleanExpression("%d=%d" % (randInt3, randInt2)): # this must not be evaluated to True
789-
retVal = None
790+
retVal = False
790791
break
791792

792793
elif not checkBooleanExpression("%d=%d" % (randInt2, randInt2)): # this must be evaluated to True
793-
retVal = None
794+
retVal = False
794795
break
795796

796797
elif checkBooleanExpression("%d %d" % (randInt3, randInt2)): # this must not be evaluated to True (invalid statement)
797-
retVal = None
798+
retVal = False
798799
break
799800

800-
if retVal is None:
801+
if not retVal:
801802
warnMsg = "false positive or unexploitable injection point detected"
802803
logger.warn(warnMsg)
803804

lib/controller/controller.py

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
from lib.core.enums import HASHDB_KEYS
4646
from lib.core.enums import HEURISTIC_TEST
4747
from lib.core.enums import HTTPMETHOD
48+
from lib.core.enums import NOTE
4849
from lib.core.enums import PAYLOAD
4950
from lib.core.enums import PLACE
5051
from lib.core.exception import SqlmapBaseException
@@ -225,23 +226,23 @@ def _saveToResultsFile():
225226
results = {}
226227
techniques = dict(map(lambda x: (x[1], x[0]), getPublicTypeMembers(PAYLOAD.TECHNIQUE)))
227228

228-
for inj in kb.injections:
229+
for inj in kb.injections + kb.falsePositives:
229230
if inj.place is None or inj.parameter is None:
230231
continue
231232

232-
key = (inj.place, inj.parameter)
233+
key = (inj.place, inj.parameter, ';'.join(inj.notes))
233234
if key not in results:
234235
results[key] = []
235236

236237
results[key].extend(inj.data.keys())
237238

238239
for key, value in results.items():
239-
place, parameter = key
240-
line = "%s,%s,%s,%s%s" % (safeCSValue(kb.originalUrls.get(conf.url) or conf.url), place, parameter, "".join(map(lambda x: techniques[x][0].upper(), sorted(value))), os.linesep)
240+
place, parameter, notes = key
241+
line = "%s,%s,%s,%s,%s%s" % (safeCSValue(kb.originalUrls.get(conf.url) or conf.url), place, parameter, "".join(map(lambda x: techniques[x][0].upper(), sorted(value))), notes, os.linesep)
241242
conf.resultsFP.writelines(line)
242243

243244
if not results:
244-
line = "%s,,,%s" % (conf.url, os.linesep)
245+
line = "%s,,,,%s" % (conf.url, os.linesep)
245246
conf.resultsFP.writelines(line)
246247

247248
def start():
@@ -522,7 +523,10 @@ def start():
522523
proceed = not kb.endDetection
523524

524525
if getattr(injection, "place", None) is not None:
525-
kb.injections.append(injection)
526+
if NOTE.FALSE_POSITIVE_OR_UNEXPLOITABLE in injection.notes:
527+
kb.falsePositives.append(injection)
528+
else:
529+
kb.injections.append(injection)
526530

527531
# In case when user wants to end detection phase (Ctrl+C)
528532
if not proceed:
@@ -651,6 +655,8 @@ def start():
651655
errMsg = getSafeExString(ex)
652656

653657
if conf.multipleTargets:
658+
_saveToResultsFile()
659+
654660
errMsg += ", skipping to the next %s" % ("form" if conf.forms else "URL")
655661
logger.error(errMsg)
656662
else:
@@ -669,9 +675,10 @@ def start():
669675
if kb.dataOutputFlag and not conf.multipleTargets:
670676
logger.info("fetched data logged to text files under '%s'" % conf.outputPath)
671677

672-
if conf.multipleTargets and conf.resultsFilename:
673-
infoMsg = "you can find results of scanning in multiple targets "
674-
infoMsg += "mode inside the CSV file '%s'" % conf.resultsFilename
675-
logger.info(infoMsg)
678+
if conf.multipleTargets:
679+
if conf.resultsFilename:
680+
infoMsg = "you can find results of scanning in multiple targets "
681+
infoMsg += "mode inside the CSV file '%s'" % conf.resultsFilename
682+
logger.info(infoMsg)
676683

677684
return True

lib/core/datatype.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ def __init__(self):
9393
self.prefix = None
9494
self.suffix = None
9595
self.clause = None
96+
self.notes = set()
9697

9798
# data is a dict with various stype, each which is a dict with
9899
# all the information specific for that stype

lib/core/enums.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,3 +351,6 @@ class AUTOCOMPLETE_TYPE:
351351
SQL = 0
352352
OS = 1
353353
SQLMAP = 2
354+
355+
class NOTE:
356+
FALSE_POSITIVE_OR_UNEXPLOITABLE = "false positive or unexploitable"

lib/core/option.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1838,6 +1838,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
18381838
kb.extendTests = None
18391839
kb.errorChunkLength = None
18401840
kb.errorIsNone = True
1841+
kb.falsePositives = []
18411842
kb.fileReadMode = False
18421843
kb.followSitemapRecursion = None
18431844
kb.forcedDbms = None

lib/core/settings.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
from lib.core.revision import getRevisionNumber
2020

2121
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
22-
VERSION = "1.0.5.14"
22+
VERSION = "1.0.5.15"
2323
REVISION = getRevisionNumber()
2424
STABLE = VERSION.count('.') <= 2
2525
VERSION_STRING = "sqlmap/%s#%s" % (VERSION, "stable" if STABLE else "dev")
@@ -530,7 +530,7 @@
530530
HASHDB_END_TRANSACTION_RETRIES = 3
531531

532532
# Unique milestone value used for forced deprecation of old HashDB values (e.g. when changing hash/pickle mechanism)
533-
HASHDB_MILESTONE_VALUE = "WVMqopmuzX" # "".join(random.sample(string.ascii_letters, 10))
533+
HASHDB_MILESTONE_VALUE = "zYwqRDymvj" # "".join(random.sample(string.ascii_letters, 10))
534534

535535
# Warn user of possible delay due to large page dump in full UNION query injections
536536
LARGE_OUTPUT_THRESHOLD = 1024 ** 2

lib/core/target.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,7 @@ def _setResultsFile():
542542
errMsg += "create temporary files and/or directories"
543543
raise SqlmapSystemException(errMsg)
544544

545-
conf.resultsFP.writelines("Target URL,Place,Parameter,Techniques%s" % os.linesep)
545+
conf.resultsFP.writelines("Target URL,Place,Parameter,Technique(s),Note(s)%s" % os.linesep)
546546

547547
logger.info("using '%s' as the CSV results file in multiple targets mode" % conf.resultsFilename)
548548

0 commit comments

Comments
 (0)