mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2026-10-11 22:19:55 +00:00
Patching non-SQLi techniques regarding reflective values
This commit is contained in:
@@ -1194,6 +1194,18 @@ class ReqHandler(BaseHTTPRequestHandler):
|
||||
self.wfile.write(output.encode(UNICODE_ENCODING))
|
||||
return
|
||||
|
||||
if self.url == "/echo":
|
||||
# A pure reflector: no engine of any kind behind it, it only shows the parameter back. Every
|
||||
# non-SQL switch must stay silent here. A differential built on "the page changed" is
|
||||
# satisfied by reflection alone, which is how several engines reported this shape as
|
||||
# injectable - so this endpoint is the regression gate for that whole class.
|
||||
self.send_response(OK)
|
||||
self.send_header("Content-type", "text/html; charset=%s" % UNICODE_ENCODING)
|
||||
self.send_header("Connection", "close")
|
||||
self.end_headers()
|
||||
self.wfile.write(("<html><body>you searched for: %s</body></html>" % self.params.get("q", "")).encode(UNICODE_ENCODING))
|
||||
return
|
||||
|
||||
if self.url in ("/xslt/element", "/xslt/value"):
|
||||
# VULNERABLE: user input is concatenated into a stylesheet which is then compiled and applied
|
||||
element = self.url.endswith("element")
|
||||
|
||||
@@ -20,7 +20,7 @@ from lib.core.enums import OS
|
||||
from thirdparty import six
|
||||
|
||||
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
||||
VERSION = "1.10.8.14"
|
||||
VERSION = "1.10.8.15"
|
||||
TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable"
|
||||
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)
|
||||
|
||||
@@ -96,6 +96,10 @@ def vulnTest(tests=None, label="vuln"):
|
||||
("-u \"<base>nosql?name=luther&password=x\" -p password --nosql --flush-session", ("is vulnerable to NoSQL injection", "back-end: 'MongoDB'", "NoSQL: GET parameter 'password'", "s3cr3t")), # NoSQL (MongoDB) operator-injection detection + blind regexp extraction
|
||||
("-u \"<base>graphql\" --graphql --flush-session --disable-hashing", ("found GraphQL endpoint", "introspection returned", "enumerated 6 injectable argument slot(s): 4 query, 2 mutation", "SQL injection via GraphQL (boolean-based)", "in-band data exposure", "back-end DBMS: 'SQLite'", "banner: '3.", "GraphQL database tables", "fetched 30 entries from table 'creds'", "db3a16990a0008a3b04707fdef6584a0", "GraphQL scan complete")), # GraphQL: endpoint detection + introspection + query-slots-first (mutations only as fallback) + boolean-blind/in-band + back-end fingerprint + batched blind dump of an injection-only table (SQLite-backed)
|
||||
("-u \"<base>ldap/search?q=x\" --ldap --flush-session --disable-hashing", ("is vulnerable to LDAP injection", "Title: LDAP in-band data exposure", "LDAP: GET parameter 'q' in-band entries", "in-band data exposure", "LDAP scan complete")), # LDAP: error-based detection (unbalanced paren) + boolean oracle + directory attribute extraction via blind substring probing
|
||||
("-u \"<base>echo?q=x\" --xslt --flush-session --disable-hashing", ("no parameter appears to be injectable", "~is vulnerable to")), # reflection is not evaluation: a pure echo endpoint must not satisfy any non-SQL engine's oracle
|
||||
("-u \"<base>echo?q=x\" --xpath --flush-session --disable-hashing", ("no parameter appears to be injectable", "~is vulnerable to")), # same gate for --xpath (it used to confirm XPath injection from reflected text alone)
|
||||
("-u \"<base>echo?q=x\" --ldap --flush-session --disable-hashing", ("no parameter appears to be injectable", "~is vulnerable to", "~Traceback")), # same gate for --ldap (it used to CRASH here with an unhandled InconclusiveError)
|
||||
("-u \"<base>echo?q=x\" --nosql --flush-session --disable-hashing", ("no parameter appears to be injectable", "~is vulnerable to")), # same gate for --nosql (it used to report a "Lucene query_string-compatible back-end" from q=*)
|
||||
("-u \"<base>xslt/element?tpl=x\" --xslt --flush-session --disable-hashing", ("is vulnerable to XSLT injection", "element context", "Engine: libxslt", "Type: XSLT injection", "XSLT scan complete")), # XSLT: the engine names itself through system-property('xsl:vendor') in the element slot - a value the application cannot produce on its own
|
||||
("-u \"<base>xslt/value?sort=name\" --xslt --flush-session --disable-hashing", ("is vulnerable to XSLT injection", "value context", "XSLT compile-differential", "XSLT scan complete")), # XSLT: the value slot reflects nothing, so detection rests on the compile differential plus positive XPath-syntax evidence
|
||||
("-u \"<base>xpath/search?q=x\" --xpath --flush-session --disable-hashing", ("is vulnerable to XPath injection", "Title: XPath boolean-based blind", "XPath: GET parameter 'q' XML tree", "extracted", "XPath scan complete")), # XPath: error-based detection + boolean oracle + blind XML tree-walking via starts-with character extraction
|
||||
|
||||
@@ -12,6 +12,7 @@ from collections import namedtuple
|
||||
|
||||
from lib.core.common import beep
|
||||
from lib.core.common import randomStr
|
||||
from lib.core.common import removeReflectiveValues
|
||||
from lib.core.convert import getUnicode
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import logger
|
||||
@@ -173,7 +174,12 @@ def _send(place, parameter, value):
|
||||
# oracle sample - signal None so `_boolean`/`extract` (which reject None) can't decide on it
|
||||
if blockedStatus(code):
|
||||
return None
|
||||
return page or ""
|
||||
# Strip the payload back out before anything compares pages. An endpoint that merely ECHOES the
|
||||
# parameter differs between any two probes because the payloads differ, which satisfies a
|
||||
# true/false differential without a single expression being evaluated - that reported plain
|
||||
# reflective search pages as injectable. On a blind target the payload is not in the page, so
|
||||
# this is a no-op.
|
||||
return removeReflectiveValues(page, value, suppressWarning=True) or ""
|
||||
except Exception as ex:
|
||||
logger.debug("LDAP probe request failed: %s" % getUnicode(ex))
|
||||
return None
|
||||
|
||||
@@ -14,6 +14,7 @@ from collections import OrderedDict
|
||||
|
||||
from lib.core.common import beep
|
||||
from lib.core.common import randomStr
|
||||
from lib.core.common import removeReflectiveValues
|
||||
from lib.core.convert import getUnicode
|
||||
from lib.utils.nonsql import userDecision
|
||||
from lib.utils.nonsql import sqlErrorPresent
|
||||
@@ -366,7 +367,12 @@ def _send(place, parameter, segment=None, jsonValue=_UNSET):
|
||||
finally:
|
||||
conf.skipUrlEncode = skipUrlEncode
|
||||
|
||||
return page or ""
|
||||
# Strip the payload back out before anything compares pages. An endpoint that merely ECHOES the
|
||||
# parameter differs between any two probes because the payloads differ, which satisfies a true/false
|
||||
# differential - and the wildcard always-true check - without a single operator being interpreted.
|
||||
# That reported a plain reflective search page as a "Lucene query_string-compatible back-end". On a
|
||||
# blind target the payload is not in the page, so this is a no-op.
|
||||
return removeReflectiveValues(page, payload, suppressWarning=True) or ""
|
||||
|
||||
def _isError(page):
|
||||
# a server-error status, a recognizable NoSQL error body, OR a recognized SQL/DBMS error marks a
|
||||
|
||||
Reference in New Issue
Block a user