mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2026-10-12 02:22:55 +00:00
Minor patches
This commit is contained in:
@@ -20,7 +20,7 @@ from lib.core.enums import OS
|
||||
from thirdparty import six
|
||||
|
||||
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
||||
VERSION = "1.10.7.80"
|
||||
VERSION = "1.10.7.81"
|
||||
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)
|
||||
|
||||
@@ -5,6 +5,7 @@ Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
|
||||
See the file 'LICENSE' for copying permission
|
||||
"""
|
||||
|
||||
import binascii
|
||||
import re
|
||||
import time
|
||||
|
||||
@@ -29,6 +30,20 @@ from lib.core.settings import UNICODE_ENCODING
|
||||
from lib.utils.safe2bin import safecharencode
|
||||
from lib.utils.timeout import timeout
|
||||
|
||||
def _hexifyBinary(value):
|
||||
"""
|
||||
Renders a raw binary cell returned by a driver in -d mode as uppercase hex, instead of letting it reach
|
||||
the text channel as a str() like '<memory at 0x...>' (PostgreSQL bytea -> psycopg2 memoryview) or a
|
||||
control-character blob that gets blanked/corrupted (e.g. MSSQL varbinary -> bytes). Text columns come back
|
||||
as native strings, so only genuine binary values are converted (matches HEX()-based rendering elsewhere).
|
||||
"""
|
||||
|
||||
if isinstance(value, memoryview):
|
||||
value = value.tobytes()
|
||||
if isinstance(value, (bytes, bytearray)):
|
||||
return getUnicode(binascii.hexlify(value)).upper()
|
||||
return value
|
||||
|
||||
def direct(query, content=True):
|
||||
select = True
|
||||
query = agent.payloadDirect(query)
|
||||
@@ -63,6 +78,8 @@ def direct(query, content=True):
|
||||
timeout(func=conf.dbmsConnector.execute, args=(query,), duration=conf.timeout, default=None)
|
||||
elif not (output and ("%soutput" % conf.tablePrefix) not in query and ("%sfile" % conf.tablePrefix) not in query):
|
||||
output, state = timeout(func=conf.dbmsConnector.select, args=(query,), duration=conf.timeout, default=None)
|
||||
if output and isListLike(output):
|
||||
output = [tuple(_hexifyBinary(_) for _ in row) if isListLike(row) else _hexifyBinary(row) for row in output]
|
||||
if state == TIMEOUT_STATE.NORMAL:
|
||||
hashDBWrite(query, output, True)
|
||||
elif state == TIMEOUT_STATE.TIMEOUT:
|
||||
|
||||
+15
-4
@@ -117,7 +117,7 @@ class SQLAlchemy(GenericConnector):
|
||||
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % getSafeExString(ex))
|
||||
return None
|
||||
|
||||
def execute(self, query):
|
||||
def execute(self, query, commit=True):
|
||||
retVal = False
|
||||
|
||||
# Reference: https://stackoverflow.com/a/69491015
|
||||
@@ -126,10 +126,14 @@ class SQLAlchemy(GenericConnector):
|
||||
|
||||
try:
|
||||
self.cursor = self.connector.execute(query)
|
||||
if hasattr(self.connector, "commit"): # Note: SQLAlchemy 2.0+ dropped implicit autocommit (otherwise DML changes - e.g. via --sql-query - would be silently lost)
|
||||
# Note: SQLAlchemy 2.0+ dropped implicit autocommit (otherwise DML changes - e.g. via --sql-query -
|
||||
# would be silently lost). SELECT goes through select() with commit=False so the result set is
|
||||
# fetched BEFORE committing: on some drivers (e.g. pymssql) commit() discards the open cursor, which
|
||||
# otherwise made every MSSQL '-d' query silently return empty (banner/is-dba/dump all blank).
|
||||
if commit and hasattr(self.connector, "commit"):
|
||||
self.connector.commit()
|
||||
retVal = True
|
||||
except (_sqlalchemy.exc.OperationalError, _sqlalchemy.exc.ProgrammingError) as ex:
|
||||
except (_sqlalchemy.exc.OperationalError, _sqlalchemy.exc.ProgrammingError, _sqlalchemy.exc.DataError, _sqlalchemy.exc.IntegrityError) as ex:
|
||||
logger.log(logging.WARN if conf.dbmsHandler else logging.DEBUG, "(remote) %s" % getSafeExString(ex))
|
||||
# Roll back the failed statement's transaction so it does not poison every following query with
|
||||
# 'InFailedSqlTransaction' (SQLAlchemy 2.0+ keeps the transaction open after an error). Without this
|
||||
@@ -148,7 +152,14 @@ class SQLAlchemy(GenericConnector):
|
||||
def select(self, query):
|
||||
retVal = None
|
||||
|
||||
if self.execute(query):
|
||||
# Fetch BEFORE committing (commit=False): committing can discard the open result cursor on some drivers
|
||||
# (e.g. pymssql), which silently emptied every MSSQL '-d' result. No DML is persisted by a SELECT anyway.
|
||||
if self.execute(query, commit=False):
|
||||
retVal = self.fetchall()
|
||||
if hasattr(self.connector, "commit"):
|
||||
try:
|
||||
self.connector.commit()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return retVal
|
||||
|
||||
Reference in New Issue
Block a user