sqlmap/lib/core/target.py

251 lines
7.8 KiB
Python
Raw Normal View History

2008-10-15 19:38:22 +04:00
#!/usr/bin/env python
"""
2008-10-15 19:56:32 +04:00
$Id$
2008-10-15 19:38:22 +04:00
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
2010-03-03 18:26:27 +03:00
Copyright (c) 2007-2010 Bernardo Damele A. G. <bernardo.damele@gmail.com>
Copyright (c) 2006 Daniele Bellucci <daniele.bellucci@gmail.com>
2008-10-15 19:38:22 +04:00
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 codecs
2008-10-15 19:38:22 +04:00
import os
import time
from lib.core.common import dataToSessionFile
from lib.core.common import paramToDict
from lib.core.data import conf
from lib.core.data import kb
from lib.core.data import logger
2008-10-15 19:38:22 +04:00
from lib.core.data import paths
from lib.core.dump import dumper
from lib.core.exception import sqlmapFilePathException
from lib.core.exception import sqlmapGenericException
from lib.core.exception import sqlmapSyntaxException
from lib.core.session import resumeConfKb
def __setRequestParams():
"""
Check and set the parameters and perform checks on 'data' option for
HTTP method POST.
"""
if conf.direct:
conf.parameters[None] = "direct connection"
return
2008-10-15 19:38:22 +04:00
__testableParameters = False
# Perform checks on GET parameters
if conf.parameters.has_key("GET") and conf.parameters["GET"]:
parameters = conf.parameters["GET"]
__paramDict = paramToDict("GET", parameters)
if __paramDict:
conf.paramDict["GET"] = __paramDict
__testableParameters = True
# Perform checks on POST parameters
if conf.method == "POST" and not conf.data:
errMsg = "HTTP POST method depends on HTTP data value to be posted"
raise sqlmapSyntaxException, errMsg
if conf.data:
conf.parameters["POST"] = conf.data
__paramDict = paramToDict("POST", conf.data)
2008-10-15 19:38:22 +04:00
if __paramDict:
conf.paramDict["POST"] = __paramDict
__testableParameters = True
conf.method = "POST"
2008-10-15 19:38:22 +04:00
# Perform checks on Cookie parameters
if conf.cookie:
conf.parameters["Cookie"] = conf.cookie
__paramDict = paramToDict("Cookie", conf.cookie)
2008-10-15 19:38:22 +04:00
if __paramDict:
conf.paramDict["Cookie"] = __paramDict
__testableParameters = True
# Perform checks on User-Agent header value
if conf.httpHeaders:
for httpHeader, headerValue in conf.httpHeaders:
if httpHeader == "User-Agent":
# No need for url encoding/decoding the user agent
conf.parameters["User-Agent"] = headerValue
2008-10-15 19:38:22 +04:00
condition = not conf.testParameter
condition |= "User-Agent" in conf.testParameter
condition |= "user-agent" in conf.testParameter
condition |= "useragent" in conf.testParameter
condition |= "ua" in conf.testParameter
if condition:
conf.paramDict["User-Agent"] = { "User-Agent": headerValue }
__testableParameters = True
if not conf.parameters:
errMsg = "you did not provide any GET, POST and Cookie "
errMsg += "parameter, neither an User-Agent header"
raise sqlmapGenericException, errMsg
elif not __testableParameters:
errMsg = "all testable parameters you provided are not present "
errMsg += "within the GET, POST and Cookie parameters"
raise sqlmapGenericException, errMsg
def __setOutputResume():
"""
Check and set the output text file and the resume functionality.
"""
if not conf.sessionFile:
conf.sessionFile = "%s%ssession" % (conf.outputPath, os.sep)
logger.info("using '%s' as session file" % conf.sessionFile)
if os.path.exists(conf.sessionFile):
2010-03-04 16:01:18 +03:00
if not conf.flushSession:
2010-05-24 15:12:40 +04:00
readSessionFP = codecs.open(conf.sessionFile, "r", conf.dataEncoding)
__url_cache = set()
__expression_cache = {}
for line in readSessionFP.readlines(): #xreadlines doesn't return unicode strings when codec.open used
2010-03-04 16:01:18 +03:00
if line.count("][") == 4:
line = line.split("][")
2010-03-04 16:01:18 +03:00
if len(line) != 5:
continue
2010-03-04 16:01:18 +03:00
url, _, _, expression, value = line
if not value:
continue
if url[0] == "[":
url = url[1:]
value = value.rstrip('\r\n') #strips both chars independently
if url not in ( conf.url, conf.hostname ):
2010-03-04 16:01:18 +03:00
continue
if url not in __url_cache:
2010-03-04 16:01:18 +03:00
kb.resumedQueries[url] = {}
kb.resumedQueries[url][expression] = value
__url_cache.add(url)
2010-05-11 17:55:30 +04:00
__expression_cache[url] = set(expression)
2010-03-04 16:01:18 +03:00
resumeConfKb(expression, url, value)
if expression not in __expression_cache[url]:
2010-03-04 16:01:18 +03:00
kb.resumedQueries[url][expression] = value
__expression_cache[url].add(value)
2010-03-04 16:01:18 +03:00
elif len(value) >= len(kb.resumedQueries[url][expression]):
kb.resumedQueries[url][expression] = value
2010-03-04 16:01:18 +03:00
readSessionFP.close()
else:
try:
os.remove(conf.sessionFile)
logger.info("flushing session file")
except OSError, msg:
errMsg = "unable to flush the session file (%s)" % msg
raise sqlmapFilePathException, errMsg
2008-10-15 19:38:22 +04:00
try:
2010-05-24 15:12:40 +04:00
conf.sessionFP = codecs.open(conf.sessionFile, "a", conf.dataEncoding)
dataToSessionFile("\n[%s]\n" % time.strftime("%X %x"))
except IOError:
errMsg = "unable to write on the session file specified"
raise sqlmapFilePathException, errMsg
2008-10-15 19:38:22 +04:00
def __createFilesDir():
"""
Create the file directory.
"""
if not conf.rFile:
return
conf.filePath = paths.SQLMAP_FILES_PATH % conf.hostname
if not os.path.isdir(conf.filePath):
os.makedirs(conf.filePath, 0755)
def __createDumpDir():
"""
Create the dump directory.
"""
if not conf.dumpTable and not conf.dumpAll:
return
conf.dumpPath = paths.SQLMAP_DUMP_PATH % conf.hostname
if not os.path.isdir(conf.dumpPath):
os.makedirs(conf.dumpPath, 0755)
2010-03-15 14:55:13 +03:00
def __createTargetDirs():
"""
Create the output directory.
"""
conf.outputPath = "%s%s%s" % (paths.SQLMAP_OUTPUT_PATH, os.sep, conf.hostname)
if not os.path.isdir(paths.SQLMAP_OUTPUT_PATH):
os.makedirs(paths.SQLMAP_OUTPUT_PATH, 0755)
if not os.path.isdir(conf.outputPath):
os.makedirs(conf.outputPath, 0755)
dumper.setOutputFile()
__createDumpDir()
__createFilesDir()
2008-10-15 19:38:22 +04:00
def initTargetEnv():
"""
Initialize target environment.
"""
if conf.multipleTargets:
2010-04-06 14:15:19 +04:00
if conf.cj:
conf.cj.clear()
2010-04-06 14:15:19 +04:00
2010-03-15 14:33:34 +03:00
conf.paramDict = {}
conf.parameters = {}
conf.sessionFile = None
2010-04-06 14:15:19 +04:00
kb.dbms = None
kb.dbmsDetected = False
kb.dbmsVersion = [ "Unknown" ]
kb.injParameter = None
kb.injPlace = None
kb.injType = None
kb.parenthesis = None
kb.unionComment = ""
kb.unionCount = None
kb.unionPosition = None
2010-03-15 14:33:34 +03:00
def setupTargetEnv():
2010-03-15 14:55:13 +03:00
__createTargetDirs()
2008-10-15 19:38:22 +04:00
__setRequestParams()
__setOutputResume()