Initial support for partial UNION query sql injection

This commit is contained in:
Bernardo Damele 2008-12-02 21:56:23 +00:00
parent f97585c593
commit 578bcb9140
5 changed files with 41 additions and 15 deletions

View File

@ -47,7 +47,7 @@ class Agent:
temp.stop = randomStr(6) temp.stop = randomStr(6)
def payload(self, place=None, parameter=None, value=None, newValue=None): def payload(self, place=None, parameter=None, value=None, newValue=None, negative=False):
""" """
This method replaces the affected parameter with the SQL This method replaces the affected parameter with the SQL
injection statement to request injection statement to request
@ -55,16 +55,21 @@ class Agent:
retValue = "" retValue = ""
if negative == True or conf.paramNegative == True:
negValue = "-"
else:
negValue = ""
# After identifing the injectable parameter # After identifing the injectable parameter
if kb.injPlace == "User-Agent": if kb.injPlace == "User-Agent":
retValue = kb.injParameter.replace(kb.injParameter, retValue = kb.injParameter.replace(kb.injParameter,
kb.injParameter + newValue) "%s%s" % (negValue, kb.injParameter + newValue))
elif kb.injParameter: elif kb.injParameter:
paramString = conf.parameters[kb.injPlace] paramString = conf.parameters[kb.injPlace]
paramDict = conf.paramDict[kb.injPlace] paramDict = conf.paramDict[kb.injPlace]
value = paramDict[kb.injParameter] value = paramDict[kb.injParameter]
retValue = paramString.replace("%s=%s" % (kb.injParameter, value), retValue = paramString.replace("%s=%s" % (kb.injParameter, value),
"%s=%s" % (kb.injParameter, value + newValue)) "%s=%s%s" % (kb.injParameter, negValue, value + newValue))
# Before identifing the injectable parameter # Before identifing the injectable parameter
elif parameter == "User-Agent": elif parameter == "User-Agent":

View File

@ -540,6 +540,7 @@ def __setConfAttributes():
conf.outputPath = None conf.outputPath = None
conf.paramDict = {} conf.paramDict = {}
conf.parameters = {} conf.parameters = {}
conf.paramNegative = False
conf.path = None conf.path = None
conf.port = None conf.port = None
conf.scheme = None conf.scheme = None

View File

@ -95,7 +95,7 @@ def unionTest():
query = agent.prefixQuery(" UNION ALL SELECT NULL") query = agent.prefixQuery(" UNION ALL SELECT NULL")
for comment in ("", queries[kb.dbms].comment): for comment in (queries[kb.dbms].comment, ""):
value = __effectiveUnionTest(query, comment) value = __effectiveUnionTest(query, comment)
if value: if value:

View File

@ -40,8 +40,13 @@ from lib.request.connect import Connect as Request
from lib.techniques.inband.union.test import unionTest from lib.techniques.inband.union.test import unionTest
def __unionPosition(count, expression): def __unionPosition(count, expression, negative=False):
logMsg = "confirming inband sql injection on parameter " if negative:
negLogMsg = "partial"
else:
negLogMsg = "full"
logMsg = "confirming %s inband sql injection on parameter " % negLogMsg
logMsg += "'%s'" % kb.injParameter logMsg += "'%s'" % kb.injParameter
logger.info(logMsg) logger.info(logMsg)
@ -63,7 +68,7 @@ def __unionPosition(count, expression):
# Forge the inband SQL injection request # Forge the inband SQL injection request
query = agent.forgeInbandQuery(randQueryUnescaped, exprPosition) query = agent.forgeInbandQuery(randQueryUnescaped, exprPosition)
payload = agent.payload(newValue=query) payload = agent.payload(newValue=query, negative=negative)
# Perform the request # Perform the request
resultPage = Request.queryPage(payload, content=True) resultPage = Request.queryPage(payload, content=True)
@ -82,13 +87,16 @@ def __unionPosition(count, expression):
if isinstance(kb.unionPosition, int): if isinstance(kb.unionPosition, int):
logMsg = "the target url is affected by an exploitable " logMsg = "the target url is affected by an exploitable "
logMsg += "inband sql injection vulnerability" logMsg += "%s inband sql injection vulnerability" % negLogMsg
logger.info(logMsg) logger.info(logMsg)
else: else:
warnMsg = "the target url is not affected by an exploitable " warnMsg = "the target url is not affected by an exploitable "
warnMsg += "inband sql injection vulnerability, sqlmap will " warnMsg += "%s inband sql injection vulnerability" % negLogMsg
warnMsg += "retrieve the expression output through blind sql "
warnMsg += "injection technique" if negLogMsg == "partial":
warnMsg += ", sqlmap will retrieve the expression output "
warnMsg += "through blind sql injection technique"
logger.warn(warnMsg) logger.warn(warnMsg)
return count return count
@ -101,9 +109,9 @@ def unionUse(expression):
inband SQL injection on the affected url inband SQL injection on the affected url
""" """
count = 0 count = 0
origExpr = expression origExpr = expression
start = time.time() start = time.time()
if not kb.unionCount: if not kb.unionCount:
unionTest() unionTest()
@ -120,10 +128,21 @@ def unionUse(expression):
if not isinstance(kb.unionPosition, int): if not isinstance(kb.unionPosition, int):
count = __unionPosition(count, expression) count = __unionPosition(count, expression)
# Assure that the above function found the exploitable inband # Assure that the above function found the exploitable full inband
# SQL injection position # SQL injection position
if not isinstance(kb.unionPosition, int): if not isinstance(kb.unionPosition, int):
return count = __unionPosition(count, expression, True)
# Assure that the above function found the exploitable partial
# inband SQL injection position
if not isinstance(kb.unionPosition, int):
return
else:
conf.paramNegative = True
# TODO: if conf.paramNegative == True and query can returns multiple
# entries, get once per time in a for cycle, see lib/request/inject.py
# like for --sql-query and --sql-shell
# Forge the inband SQL injection request # Forge the inband SQL injection request
query = agent.forgeInbandQuery(expression) query = agent.forgeInbandQuery(expression)

View File

@ -4,6 +4,7 @@
# Example: http://192.168.1.121/sqlmap/mysql/get_int.php?id=1&cat=2 # Example: http://192.168.1.121/sqlmap/mysql/get_int.php?id=1&cat=2
# PHP and MySQL (local) # PHP and MySQL (local)
url = http://127.0.0.1/sqlmap/mysql/get_int.php?id=1 url = http://127.0.0.1/sqlmap/mysql/get_int.php?id=1
#url = http://127.0.0.1/sqlmap/mysql/get_int_partialunion.php?id=1
# PHP and Oracle (local) # PHP and Oracle (local)
#url = http://127.0.0.1/sqlmap/oracle/get_int.php?id=1 #url = http://127.0.0.1/sqlmap/oracle/get_int.php?id=1
# PHP and PostgreSQL (local) # PHP and PostgreSQL (local)