Minor patches

This commit is contained in:
Miroslav Štampar
2026-07-11 15:18:42 +02:00
parent 97c8b45ccc
commit ab59a4b72a
8 changed files with 62 additions and 13 deletions
+1 -1
View File
@@ -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)
+17
View File
@@ -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
View File
@@ -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