major improvement of ERROR data retrieval on MSSQL

This commit is contained in:
Miroslav Stampar 2011-05-03 13:25:20 +00:00
parent 2a7838928e
commit 742b0ef76e
2 changed files with 13 additions and 4 deletions

View File

@ -295,6 +295,9 @@ URI_INJECTION_MARK_CHAR = '*'
# Maximum length used for retrieving data over MySQL error based payload due to "known" problems with longer result strings # Maximum length used for retrieving data over MySQL error based payload due to "known" problems with longer result strings
MYSQL_ERROR_CHUNK_LENGTH = 50 MYSQL_ERROR_CHUNK_LENGTH = 50
# Maximum length used for retrieving data over MSSQL error based payload due to trimming problems with longer result strings
MSSQL_ERROR_CHUNK_LENGTH = 100
# Do not unescape the injected statement if it contains any of the following SQL words # Do not unescape the injected statement if it contains any of the following SQL words
EXCLUDE_UNESCAPE = ("WAITFOR DELAY ", " INTO DUMPFILE ", " INTO OUTFILE ", "CREATE ", "BULK ", "EXEC ", "RECONFIGURE ", "DECLARE ", CHAR_INFERENCE_MARK) EXCLUDE_UNESCAPE = ("WAITFOR DELAY ", " INTO DUMPFILE ", " INTO OUTFILE ", "CREATE ", "BULK ", "EXEC ", "RECONFIGURE ", "DECLARE ", CHAR_INFERENCE_MARK)

View File

@ -35,6 +35,7 @@ from lib.core.enums import PAYLOAD
from lib.core.exception import sqlmapConnectionException from lib.core.exception import sqlmapConnectionException
from lib.core.settings import FROM_TABLE from lib.core.settings import FROM_TABLE
from lib.core.settings import MYSQL_ERROR_CHUNK_LENGTH from lib.core.settings import MYSQL_ERROR_CHUNK_LENGTH
from lib.core.settings import MSSQL_ERROR_CHUNK_LENGTH
from lib.core.settings import TURN_OFF_RESUME_INFO_LIMIT from lib.core.settings import TURN_OFF_RESUME_INFO_LIMIT
from lib.core.threads import getCurrentThreadData from lib.core.threads import getCurrentThreadData
from lib.core.unescaper import unescaper from lib.core.unescaper import unescaper
@ -50,6 +51,7 @@ def __oneShotErrorUse(expression, field):
retVal = None retVal = None
offset = 1 offset = 1
chunk_length = None
while True: while True:
check = "%s(?P<result>.*?)%s" % (kb.misc.start, kb.misc.stop) check = "%s(?P<result>.*?)%s" % (kb.misc.start, kb.misc.stop)
@ -58,7 +60,11 @@ def __oneShotErrorUse(expression, field):
nulledCastedField = agent.nullAndCastField(field) nulledCastedField = agent.nullAndCastField(field)
if Backend.isDbms(DBMS.MYSQL): if Backend.isDbms(DBMS.MYSQL):
nulledCastedField = queries[DBMS.MYSQL].substring.query % (nulledCastedField, offset, MYSQL_ERROR_CHUNK_LENGTH) chunk_length = MYSQL_ERROR_CHUNK_LENGTH
nulledCastedField = queries[DBMS.MYSQL].substring.query % (nulledCastedField, offset, chunk_length)
elif Backend.isDbms(DBMS.MSSQL):
chunk_length = MSSQL_ERROR_CHUNK_LENGTH
nulledCastedField = queries[DBMS.MSSQL].substring.query % (nulledCastedField, offset, chunk_length)
# Forge the error-based SQL injection request # Forge the error-based SQL injection request
vector = kb.injection.data[PAYLOAD.TECHNIQUE.ERROR].vector vector = kb.injection.data[PAYLOAD.TECHNIQUE.ERROR].vector
@ -101,16 +107,16 @@ def __oneShotErrorUse(expression, field):
if isinstance(output, basestring): if isinstance(output, basestring):
output = htmlunescape(output).replace("<br>", "\n") output = htmlunescape(output).replace("<br>", "\n")
if Backend.isDbms(DBMS.MYSQL): if any(map(lambda dbms: Backend.isDbms(dbms), [DBMS.MYSQL, DBMS.MSSQL])):
if offset == 1: if offset == 1:
retVal = output retVal = output
else: else:
retVal += output if output else '' retVal += output if output else ''
if not (output and len(output) == MYSQL_ERROR_CHUNK_LENGTH): if not (output and len(output) == chunk_length):
break break
else: else:
offset += MYSQL_ERROR_CHUNK_LENGTH offset += chunk_length
else: else:
retVal = output retVal = output
break break