Minot improvement of JSON/eval (#5013)

This commit is contained in:
Miroslav Stampar 2022-03-07 20:17:51 +01:00
parent a2fcab448c
commit acd5ef055a
3 changed files with 49 additions and 2 deletions

View File

@ -104,6 +104,7 @@ from lib.core.log import LOGGER_HANDLER
from lib.core.optiondict import optDict from lib.core.optiondict import optDict
from lib.core.settings import BANNER from lib.core.settings import BANNER
from lib.core.settings import BOLD_PATTERNS from lib.core.settings import BOLD_PATTERNS
from lib.core.settings import BOUNDARY_BACKSLASH_MARKER
from lib.core.settings import BOUNDED_INJECTION_MARKER from lib.core.settings import BOUNDED_INJECTION_MARKER
from lib.core.settings import BRUTE_DOC_ROOT_PREFIXES from lib.core.settings import BRUTE_DOC_ROOT_PREFIXES
from lib.core.settings import BRUTE_DOC_ROOT_SUFFIXES from lib.core.settings import BRUTE_DOC_ROOT_SUFFIXES
@ -1384,6 +1385,38 @@ def banner():
dataToStdout(result, forceOutput=True) dataToStdout(result, forceOutput=True)
def parseJson(content):
"""
This function parses POST_HINT.JSON and POST_HINT.JSON_LIKE content
>>> parseJson("{'id':1}")["id"] == 1
True
>>> parseJson('{"id":1}')["id"] == 1
True
"""
quote = None
retVal = None
for regex in (r"'[^']+'\s*:", r'"[^"]+"\s*:'):
match = re.search(regex, content)
if match:
quote = match.group(0)[0]
try:
if quote == '"':
retVal = json.loads(content)
elif quote == "'":
content = content.replace('"', '\\"')
content = content.replace("\\'", BOUNDARY_BACKSLASH_MARKER)
content = content.replace("'", '"')
content = content.replace(BOUNDARY_BACKSLASH_MARKER, "'")
retVal = json.loads(content)
except:
pass
return retVal
def parsePasswordHash(password): def parsePasswordHash(password):
""" """
In case of Microsoft SQL Server password hash value is expanded to its components In case of Microsoft SQL Server password hash value is expanded to its components

View File

@ -20,7 +20,7 @@ from thirdparty import six
from thirdparty.six import unichr as _unichr from thirdparty.six import unichr as _unichr
# sqlmap version (<major>.<minor>.<month>.<monthly commit>) # sqlmap version (<major>.<minor>.<month>.<monthly commit>)
VERSION = "1.6.3.6" VERSION = "1.6.3.7"
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)

View File

@ -46,6 +46,7 @@ from lib.core.common import getSafeExString
from lib.core.common import logHTTPTraffic from lib.core.common import logHTTPTraffic
from lib.core.common import openFile from lib.core.common import openFile
from lib.core.common import popValue from lib.core.common import popValue
from lib.core.common import parseJson
from lib.core.common import pushValue from lib.core.common import pushValue
from lib.core.common import randomizeParameterValue from lib.core.common import randomizeParameterValue
from lib.core.common import randomInt from lib.core.common import randomInt
@ -1291,6 +1292,13 @@ class Connect(object):
value = urldecode(value, convall=True, spaceplus=(item == post and kb.postSpaceToPlus)) value = urldecode(value, convall=True, spaceplus=(item == post and kb.postSpaceToPlus))
variables[name] = value variables[name] = value
if post and kb.postHint in (POST_HINT.JSON, POST_HINT.JSON_LIKE):
for name, value in (parseJson(post) or {}).items():
if safeVariableNaming(name) != name:
conf.evalCode = re.sub(r"\b%s\b" % re.escape(name), safeVariableNaming(name), conf.evalCode)
name = safeVariableNaming(name)
variables[name] = value
if cookie: if cookie:
for part in cookie.split(conf.cookieDel or DEFAULT_COOKIE_DELIMITER): for part in cookie.split(conf.cookieDel or DEFAULT_COOKIE_DELIMITER):
if '=' in part: if '=' in part:
@ -1393,6 +1401,12 @@ class Connect(object):
if not found: if not found:
if post is not None: if post is not None:
if kb.postHint in (POST_HINT.JSON, POST_HINT.JSON_LIKE):
match = re.search(r"['\"]", post)
if match:
quote = match.group(0)
post = re.sub(r"\}\Z", "%s%s}" % (',' if re.search(r"\w", post) else "", "%s%s%s:%s" % (quote, name, quote, value if value.isdigit() else "%s%s%s" % (quote, value, quote))), post)
else:
post += "%s%s=%s" % (delimiter, name, value) post += "%s%s=%s" % (delimiter, name, value)
elif get is not None: elif get is not None:
get += "%s%s=%s" % (delimiter, name, value) get += "%s%s=%s" % (delimiter, name, value)