mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2024-11-29 04:53:48 +03:00
Update for an Issue #2384
This commit is contained in:
parent
15f86e85b1
commit
38f16decef
|
@ -20,6 +20,7 @@ from lib.core.common import extractRegexResult
|
||||||
from lib.core.common import extractTextTagContent
|
from lib.core.common import extractTextTagContent
|
||||||
from lib.core.common import findDynamicContent
|
from lib.core.common import findDynamicContent
|
||||||
from lib.core.common import Format
|
from lib.core.common import Format
|
||||||
|
from lib.core.common import getFilteredPageContent
|
||||||
from lib.core.common import getLastRequestHTTPError
|
from lib.core.common import getLastRequestHTTPError
|
||||||
from lib.core.common import getPublicTypeMembers
|
from lib.core.common import getPublicTypeMembers
|
||||||
from lib.core.common import getSafeExString
|
from lib.core.common import getSafeExString
|
||||||
|
@ -63,6 +64,7 @@ from lib.core.exception import SqlmapConnectionException
|
||||||
from lib.core.exception import SqlmapNoneDataException
|
from lib.core.exception import SqlmapNoneDataException
|
||||||
from lib.core.exception import SqlmapSilentQuitException
|
from lib.core.exception import SqlmapSilentQuitException
|
||||||
from lib.core.exception import SqlmapUserQuitException
|
from lib.core.exception import SqlmapUserQuitException
|
||||||
|
from lib.core.settings import CANDIDATE_SENTENCE_MIN_LENGTH
|
||||||
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
|
from lib.core.settings import DEFAULT_GET_POST_DELIMITER
|
||||||
from lib.core.settings import DUMMY_NON_SQLI_CHECK_APPENDIX
|
from lib.core.settings import DUMMY_NON_SQLI_CHECK_APPENDIX
|
||||||
from lib.core.settings import FI_ERROR_REGEX
|
from lib.core.settings import FI_ERROR_REGEX
|
||||||
|
@ -478,6 +480,26 @@ def checkSqlInjection(place, parameter, value):
|
||||||
|
|
||||||
injectable = True
|
injectable = True
|
||||||
|
|
||||||
|
elif threadData.lastComparisonRatio > UPPER_RATIO_BOUND and not any((conf.string, conf.notString, conf.regexp, conf.code, kb.nullConnection)):
|
||||||
|
originalSet = set(getFilteredPageContent(kb.pageTemplate, True, "\n").split("\n"))
|
||||||
|
trueSet = set(getFilteredPageContent(truePage, True, "\n").split("\n"))
|
||||||
|
falseSet = set(getFilteredPageContent(falsePage, True, "\n").split("\n"))
|
||||||
|
|
||||||
|
if originalSet == trueSet != falseSet:
|
||||||
|
candidates = trueSet - falseSet
|
||||||
|
|
||||||
|
if candidates:
|
||||||
|
candidates = sorted(candidates, key=lambda _: len(_))
|
||||||
|
for candidate in candidates:
|
||||||
|
if re.match(r"\A[\w.,! ]+\Z", candidate) and ' ' in candidate and len(candidate) > CANDIDATE_SENTENCE_MIN_LENGTH:
|
||||||
|
conf.string = candidate
|
||||||
|
injectable = True
|
||||||
|
|
||||||
|
infoMsg = "%s parameter '%s' appears to be '%s' injectable (with --string=\"%s\")" % (paramType, parameter, title, repr(conf.string).lstrip('u').strip("'"))
|
||||||
|
logger.info(infoMsg)
|
||||||
|
|
||||||
|
break
|
||||||
|
|
||||||
if injectable:
|
if injectable:
|
||||||
if kb.pageStable and not any((conf.string, conf.notString, conf.regexp, conf.code, kb.nullConnection)):
|
if kb.pageStable and not any((conf.string, conf.notString, conf.regexp, conf.code, kb.nullConnection)):
|
||||||
if all((falseCode, trueCode)) and falseCode != trueCode:
|
if all((falseCode, trueCode)) and falseCode != trueCode:
|
||||||
|
|
|
@ -1755,7 +1755,7 @@ def safeStringFormat(format_, params):
|
||||||
break
|
break
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
def getFilteredPageContent(page, onlyText=True):
|
def getFilteredPageContent(page, onlyText=True, split=" "):
|
||||||
"""
|
"""
|
||||||
Returns filtered page content without script, style and/or comments
|
Returns filtered page content without script, style and/or comments
|
||||||
or all HTML tags
|
or all HTML tags
|
||||||
|
@ -1768,10 +1768,10 @@ def getFilteredPageContent(page, onlyText=True):
|
||||||
|
|
||||||
# only if the page's charset has been successfully identified
|
# only if the page's charset has been successfully identified
|
||||||
if isinstance(page, unicode):
|
if isinstance(page, unicode):
|
||||||
retVal = re.sub(r"(?si)<script.+?</script>|<!--.+?-->|<style.+?</style>%s" % (r"|<[^>]+>|\t|\n|\r" if onlyText else ""), " ", page)
|
retVal = re.sub(r"(?si)<script.+?</script>|<!--.+?-->|<style.+?</style>%s" % (r"|<[^>]+>|\t|\n|\r" if onlyText else ""), split, page)
|
||||||
while retVal.find(" ") != -1:
|
while retVal.find(2 * split) != -1:
|
||||||
retVal = retVal.replace(" ", " ")
|
retVal = retVal.replace(2 * split, split)
|
||||||
retVal = htmlunescape(retVal.strip())
|
retVal = htmlunescape(retVal.strip().strip(split))
|
||||||
|
|
||||||
return retVal
|
return retVal
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME
|
||||||
from lib.core.enums import OS
|
from lib.core.enums import OS
|
||||||
|
|
||||||
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
||||||
VERSION = "1.1.2.3"
|
VERSION = "1.1.2.4"
|
||||||
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
|
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
|
||||||
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
|
TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34}
|
||||||
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
|
VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE)
|
||||||
|
@ -359,6 +359,9 @@ MIN_RATIO = 0.0
|
||||||
# Maximum value for comparison ratio
|
# Maximum value for comparison ratio
|
||||||
MAX_RATIO = 1.0
|
MAX_RATIO = 1.0
|
||||||
|
|
||||||
|
# Minimum length of sentence for automatic choosing of --string (in case of high matching ratio)
|
||||||
|
CANDIDATE_SENTENCE_MIN_LENGTH = 10
|
||||||
|
|
||||||
# Character used for marking injectable position inside provided data
|
# Character used for marking injectable position inside provided data
|
||||||
CUSTOM_INJECTION_MARK_CHAR = '*'
|
CUSTOM_INJECTION_MARK_CHAR = '*'
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ class _ThreadData(threading.local):
|
||||||
self.lastComparisonPage = None
|
self.lastComparisonPage = None
|
||||||
self.lastComparisonHeaders = None
|
self.lastComparisonHeaders = None
|
||||||
self.lastComparisonCode = None
|
self.lastComparisonCode = None
|
||||||
|
self.lastComparisonRatio = None
|
||||||
self.lastErrorPage = None
|
self.lastErrorPage = None
|
||||||
self.lastHTTPError = None
|
self.lastHTTPError = None
|
||||||
self.lastRedirectMsg = None
|
self.lastRedirectMsg = None
|
||||||
|
|
|
@ -144,6 +144,9 @@ def _comparison(page, headers, code, getRatioValue, pageLength):
|
||||||
kb.matchRatio = ratio
|
kb.matchRatio = ratio
|
||||||
logger.debug("setting match ratio for current parameter to %.3f" % kb.matchRatio)
|
logger.debug("setting match ratio for current parameter to %.3f" % kb.matchRatio)
|
||||||
|
|
||||||
|
if kb.testMode:
|
||||||
|
threadData.lastComparisonRatio = ratio
|
||||||
|
|
||||||
# If it has been requested to return the ratio and not a comparison
|
# If it has been requested to return the ratio and not a comparison
|
||||||
# response
|
# response
|
||||||
if getRatioValue:
|
if getRatioValue:
|
||||||
|
|
|
@ -20,13 +20,13 @@ c55b400b72acc43e0e59c87dd8bb8d75 extra/shellcodeexec/windows/shellcodeexec.x32.
|
||||||
310efc965c862cfbd7b0da5150a5ad36 extra/sqlharvest/__init__.py
|
310efc965c862cfbd7b0da5150a5ad36 extra/sqlharvest/__init__.py
|
||||||
7713aa366c983cdf1f3dbaa7383ea9e1 extra/sqlharvest/sqlharvest.py
|
7713aa366c983cdf1f3dbaa7383ea9e1 extra/sqlharvest/sqlharvest.py
|
||||||
5df358defc488bee9b40084892e3d1cb lib/controller/action.py
|
5df358defc488bee9b40084892e3d1cb lib/controller/action.py
|
||||||
699fd4757390aedb5ad17f4316d17972 lib/controller/checks.py
|
9cb94acd4c59822a5e1a258c4d1a4860 lib/controller/checks.py
|
||||||
fa72e4d6eda241725d90738d61e7d55d lib/controller/controller.py
|
fa72e4d6eda241725d90738d61e7d55d lib/controller/controller.py
|
||||||
b3eec7f44bcc5d784d171a187b7fe8cb lib/controller/handler.py
|
b3eec7f44bcc5d784d171a187b7fe8cb lib/controller/handler.py
|
||||||
310efc965c862cfbd7b0da5150a5ad36 lib/controller/__init__.py
|
310efc965c862cfbd7b0da5150a5ad36 lib/controller/__init__.py
|
||||||
19905ecb4437b94512cf21d5f1720091 lib/core/agent.py
|
19905ecb4437b94512cf21d5f1720091 lib/core/agent.py
|
||||||
6cc95a117fbd34ef31b9aa25520f0e31 lib/core/bigarray.py
|
6cc95a117fbd34ef31b9aa25520f0e31 lib/core/bigarray.py
|
||||||
9ca4206c06f8a2a859b076ab7520c3ea lib/core/common.py
|
15c19630897cff73744fb2866719d1e9 lib/core/common.py
|
||||||
5065a4242a8cccf72f91e22e1007ae63 lib/core/convert.py
|
5065a4242a8cccf72f91e22e1007ae63 lib/core/convert.py
|
||||||
a8143dab9d3a27490f7d49b6b29ea530 lib/core/data.py
|
a8143dab9d3a27490f7d49b6b29ea530 lib/core/data.py
|
||||||
7936d78b1a7f1f008ff92bf2f88574ba lib/core/datatype.py
|
7936d78b1a7f1f008ff92bf2f88574ba lib/core/datatype.py
|
||||||
|
@ -45,12 +45,12 @@ e544108e2238d756c94a240e8a1ce061 lib/core/optiondict.py
|
||||||
d8e9250f3775119df07e9070eddccd16 lib/core/replication.py
|
d8e9250f3775119df07e9070eddccd16 lib/core/replication.py
|
||||||
785f86e3f963fa3798f84286a4e83ff2 lib/core/revision.py
|
785f86e3f963fa3798f84286a4e83ff2 lib/core/revision.py
|
||||||
40c80b28b3a5819b737a5a17d4565ae9 lib/core/session.py
|
40c80b28b3a5819b737a5a17d4565ae9 lib/core/session.py
|
||||||
38927d9aadc879d0ee2493813ee288b7 lib/core/settings.py
|
bb7501fea707b51516519ea84f42de7d lib/core/settings.py
|
||||||
d91291997d2bd2f6028aaf371bf1d3b6 lib/core/shell.py
|
d91291997d2bd2f6028aaf371bf1d3b6 lib/core/shell.py
|
||||||
2ad85c130cc5f2b3701ea85c2f6bbf20 lib/core/subprocessng.py
|
2ad85c130cc5f2b3701ea85c2f6bbf20 lib/core/subprocessng.py
|
||||||
afd0636d2e93c23f4f0a5c9b6023ea17 lib/core/target.py
|
afd0636d2e93c23f4f0a5c9b6023ea17 lib/core/target.py
|
||||||
8970b88627902239d695280b1160e16c lib/core/testing.py
|
8970b88627902239d695280b1160e16c lib/core/testing.py
|
||||||
1504e8c6bdd69edc17b5f240eaa73fb2 lib/core/threads.py
|
5521241c750855a4e44747fbac7771c6 lib/core/threads.py
|
||||||
ad74fc58fc7214802fd27067bce18dd2 lib/core/unescaper.py
|
ad74fc58fc7214802fd27067bce18dd2 lib/core/unescaper.py
|
||||||
1f1fa616b5b19308d78c610ec8046399 lib/core/update.py
|
1f1fa616b5b19308d78c610ec8046399 lib/core/update.py
|
||||||
4d13ed693401a498b6d073a2a494bd83 lib/core/wordlist.py
|
4d13ed693401a498b6d073a2a494bd83 lib/core/wordlist.py
|
||||||
|
@ -66,7 +66,7 @@ ad74fc58fc7214802fd27067bce18dd2 lib/core/unescaper.py
|
||||||
a0444cc351cd6d29015ad16d9eb46ff4 lib/parse/sitemap.py
|
a0444cc351cd6d29015ad16d9eb46ff4 lib/parse/sitemap.py
|
||||||
403d873f1d2fd0c7f73d83f104e41850 lib/request/basicauthhandler.py
|
403d873f1d2fd0c7f73d83f104e41850 lib/request/basicauthhandler.py
|
||||||
6d04ee525e75bf0082e9f1f6d8506546 lib/request/basic.py
|
6d04ee525e75bf0082e9f1f6d8506546 lib/request/basic.py
|
||||||
4e89d0e13de2eb3576f5412b21e9b648 lib/request/comparison.py
|
ef48de622b0a6b4a71df64b0d2785ef8 lib/request/comparison.py
|
||||||
1d4955fa22ca6ba17ce4fc2e0d93f1e2 lib/request/connect.py
|
1d4955fa22ca6ba17ce4fc2e0d93f1e2 lib/request/connect.py
|
||||||
fb6b788d0016ab4ec5e5f661f0f702ad lib/request/direct.py
|
fb6b788d0016ab4ec5e5f661f0f702ad lib/request/direct.py
|
||||||
cc1163d38e9b7ee5db2adac6784c02bb lib/request/dns.py
|
cc1163d38e9b7ee5db2adac6784c02bb lib/request/dns.py
|
||||||
|
|
Loading…
Reference in New Issue
Block a user