first commit with mysql/error/substringing

This commit is contained in:
Miroslav Stampar 2011-02-08 16:23:33 +00:00
parent c3eb82e60b
commit 37f7001143
2 changed files with 42 additions and 25 deletions

View File

@ -248,7 +248,7 @@ MAX_RATIO = 1.0
URI_INJECTION_MARK_CHAR = '*' 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_TRIM_LENGTH = 100 MYSQL_ERROR_CHUNK_LENGTH = 50
# 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 ") EXCLUDE_UNESCAPE = ("WAITFOR DELAY ", " INTO DUMPFILE ", " INTO OUTFILE ", "CREATE ", "BULK ", "EXEC ", "RECONFIGURE ", "DECLARE ")

View File

@ -29,7 +29,7 @@ from lib.core.enums import DBMS
from lib.core.enums import EXPECTED from lib.core.enums import EXPECTED
from lib.core.enums import PAYLOAD from lib.core.enums import PAYLOAD
from lib.core.settings import FROM_TABLE from lib.core.settings import FROM_TABLE
from lib.core.settings import MYSQL_ERROR_TRIM_LENGTH from lib.core.settings import MYSQL_ERROR_CHUNK_LENGTH
from lib.core.unescaper import unescaper from lib.core.unescaper import unescaper
from lib.request.connect import Connect as Request from lib.request.connect import Connect as Request
from lib.utils.resume import resume from lib.utils.resume import resume
@ -39,12 +39,14 @@ reqCount = 0
def __oneShotErrorUse(expression, field): def __oneShotErrorUse(expression, field):
global reqCount global reqCount
offset = 1
retVal = None
while True:
check = "%s(?P<result>.*?)%s" % (kb.misc.start, kb.misc.stop) check = "%s(?P<result>.*?)%s" % (kb.misc.start, kb.misc.stop)
nulledCastedField = agent.nullAndCastField(field) nulledCastedField = agent.nullAndCastField(field)
if Backend.getIdentifiedDbms() == DBMS.MYSQL: if Backend.getIdentifiedDbms() == DBMS.MYSQL:
# Fix for MySQL odd behaviour ('Subquery returns more than 1 row') nulledCastedField = queries[Backend.getIdentifiedDbms()].substring.query % (nulledCastedField, offset, MYSQL_ERROR_CHUNK_LENGTH)
nulledCastedField = nulledCastedField.replace("AS CHAR)", "AS CHAR(%d))" % MYSQL_ERROR_TRIM_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
@ -54,6 +56,7 @@ def __oneShotErrorUse(expression, field):
injExpression = unescaper.unescape(injExpression) injExpression = unescaper.unescape(injExpression)
injExpression = query.replace("[QUERY]", injExpression) injExpression = query.replace("[QUERY]", injExpression)
payload = agent.payload(newValue=injExpression) payload = agent.payload(newValue=injExpression)
print payload
# Perform the request # Perform the request
page, headers = Request.queryPage(payload, content=True) page, headers = Request.queryPage(payload, content=True)
@ -65,9 +68,23 @@ def __oneShotErrorUse(expression, field):
or extractRegexResult(check, listToStrValue(headers.headers \ or extractRegexResult(check, listToStrValue(headers.headers \
if headers else None), re.DOTALL | re.IGNORECASE) if headers else None), re.DOTALL | re.IGNORECASE)
dataToSessionFile("[%s][%s][%s][%s][%s]\n" % (conf.url, kb.injection.place, conf.parameters[kb.injection.place], expression, replaceNewlineTabs(output))) if Backend.getIdentifiedDbms() == DBMS.MYSQL:
if offset == 1:
retVal = output
else:
retVal += output if output else ''
return output if not (output and len(output) >= MYSQL_ERROR_CHUNK_LENGTH):
break
else:
offset += MYSQL_ERROR_CHUNK_LENGTH
else:
retVal = output
break
dataToSessionFile("[%s][%s][%s][%s][%s]\n" % (conf.url, kb.injection.place, conf.parameters[kb.injection.place], expression, replaceNewlineTabs(retVal)))
return retVal
def __errorFields(expression, expressionFields, expressionFieldsList, expected=None, num=None, resumeValue=True): def __errorFields(expression, expressionFields, expressionFieldsList, expected=None, num=None, resumeValue=True):
outputs = [] outputs = []