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.
|
|
|
|
|
|
|
|
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 cookielib
|
|
|
|
import logging
|
|
|
|
import os
|
|
|
|
import re
|
2008-12-04 20:40:03 +03:00
|
|
|
import socket
|
2008-10-15 19:38:22 +04:00
|
|
|
import time
|
|
|
|
import urllib2
|
|
|
|
import urlparse
|
|
|
|
|
|
|
|
from lib.core.common import parseTargetUrl
|
|
|
|
from lib.core.common import paths
|
|
|
|
from lib.core.common import randomRange
|
|
|
|
from lib.core.common import randomStr
|
|
|
|
from lib.core.common import readInput
|
|
|
|
from lib.core.common import sanitizeStr
|
|
|
|
from lib.core.data import conf
|
|
|
|
from lib.core.data import kb
|
|
|
|
from lib.core.data import logger
|
|
|
|
from lib.core.data import paths
|
|
|
|
from lib.core.datatype import advancedDict
|
|
|
|
from lib.core.exception import sqlmapFilePathException
|
|
|
|
from lib.core.exception import sqlmapGenericException
|
|
|
|
from lib.core.exception import sqlmapSyntaxException
|
|
|
|
from lib.core.exception import sqlmapUnsupportedDBMSException
|
|
|
|
from lib.core.optiondict import optDict
|
|
|
|
from lib.core.settings import MSSQL_ALIASES
|
|
|
|
from lib.core.settings import MYSQL_ALIASES
|
|
|
|
from lib.core.settings import SITE
|
|
|
|
from lib.core.settings import SUPPORTED_DBMS
|
|
|
|
from lib.core.settings import VERSION_STRING
|
|
|
|
from lib.core.update import update
|
|
|
|
from lib.parse.configfile import configFileParser
|
|
|
|
from lib.parse.queriesfile import queriesParser
|
|
|
|
from lib.request.proxy import ProxyHTTPSHandler
|
|
|
|
from lib.utils.google import Google
|
|
|
|
|
|
|
|
|
|
|
|
authHandler = urllib2.BaseHandler()
|
|
|
|
proxyHandler = urllib2.BaseHandler()
|
|
|
|
|
|
|
|
|
|
|
|
def __urllib2Opener():
|
|
|
|
"""
|
|
|
|
This function creates the urllib2 OpenerDirector.
|
|
|
|
"""
|
|
|
|
|
|
|
|
global authHandler
|
|
|
|
global proxyHandler
|
|
|
|
|
|
|
|
debugMsg = "creating HTTP requests opener object"
|
|
|
|
logger.debug(debugMsg)
|
|
|
|
|
|
|
|
conf.cj = cookielib.LWPCookieJar()
|
|
|
|
opener = urllib2.build_opener(proxyHandler, authHandler, urllib2.HTTPCookieProcessor(conf.cj))
|
|
|
|
|
|
|
|
urllib2.install_opener(opener)
|
|
|
|
|
|
|
|
|
2008-11-28 01:33:33 +03:00
|
|
|
def __feedTargetsDict(reqFile, addedTargetUrls):
|
2008-11-22 04:57:22 +03:00
|
|
|
fp = open(reqFile, "r")
|
|
|
|
|
|
|
|
fread = fp.read()
|
|
|
|
fread = fread.replace("\r", "")
|
|
|
|
|
2008-11-28 01:33:33 +03:00
|
|
|
reqResList = fread.split("======================================================")
|
2008-11-22 04:57:22 +03:00
|
|
|
|
|
|
|
for request in reqResList:
|
2008-11-28 01:33:33 +03:00
|
|
|
if not re.search ("^[\n]*(GET|POST).*?\sHTTP\/", request, re.I):
|
|
|
|
continue
|
|
|
|
|
2008-12-09 00:24:24 +03:00
|
|
|
if re.search("^[\n]*(GET|POST).*?\.(gif|jpg|png)\sHTTP\/", request, re.I):
|
|
|
|
continue
|
|
|
|
|
2008-11-28 01:33:33 +03:00
|
|
|
getPostReq = False
|
|
|
|
url = None
|
|
|
|
host = None
|
|
|
|
method = None
|
|
|
|
data = None
|
|
|
|
cookie = None
|
|
|
|
params = False
|
|
|
|
lines = request.split("\n")
|
2008-11-22 04:57:22 +03:00
|
|
|
|
|
|
|
for line in lines:
|
|
|
|
if len(line) == 0 or line == "\n":
|
2008-11-28 01:33:33 +03:00
|
|
|
continue
|
2008-11-22 04:57:22 +03:00
|
|
|
|
|
|
|
if line.startswith("GET ") or line.startswith("POST "):
|
|
|
|
if line.startswith("GET "):
|
|
|
|
index = 4
|
|
|
|
else:
|
|
|
|
index = 5
|
|
|
|
|
|
|
|
url = line[index:line.index(" HTTP/")]
|
|
|
|
method = line[:index-1]
|
|
|
|
|
|
|
|
if "?" in line and "=" in line:
|
|
|
|
params = True
|
|
|
|
|
2008-11-28 01:33:33 +03:00
|
|
|
getPostReq = True
|
|
|
|
|
|
|
|
elif "?" in line and "=" in line and ": " not in line:
|
2008-11-22 04:57:22 +03:00
|
|
|
data = line
|
|
|
|
params = True
|
|
|
|
|
|
|
|
elif ": " in line:
|
|
|
|
key, value = line.split(": ", 1)
|
|
|
|
|
|
|
|
if key.lower() == "cookie":
|
|
|
|
cookie = value
|
|
|
|
elif key.lower() == "host":
|
|
|
|
host = value
|
|
|
|
|
2008-11-28 01:33:33 +03:00
|
|
|
if getPostReq and params:
|
2008-11-22 04:57:22 +03:00
|
|
|
if not url.startswith("http"):
|
|
|
|
url = "http://%s%s" % (host, url)
|
|
|
|
|
2008-11-28 01:33:33 +03:00
|
|
|
if not kb.targetUrls or url not in addedTargetUrls:
|
|
|
|
kb.targetUrls.add(( url, method, data, cookie ))
|
|
|
|
addedTargetUrls.add(url)
|
2008-11-20 20:56:09 +03:00
|
|
|
|
|
|
|
|
|
|
|
def __setMultipleTargets():
|
|
|
|
"""
|
|
|
|
Define a configuration parameter if we are running in multiple target
|
|
|
|
mode.
|
|
|
|
"""
|
|
|
|
|
2008-11-22 04:57:22 +03:00
|
|
|
initialTargetsCount = len(kb.targetUrls)
|
2008-11-28 01:33:33 +03:00
|
|
|
addedTargetUrls = set()
|
2008-11-20 20:56:09 +03:00
|
|
|
|
|
|
|
if not conf.list:
|
|
|
|
return
|
|
|
|
|
2008-11-28 01:33:33 +03:00
|
|
|
debugMsg = "parsing targets list from '%s'" % conf.list
|
|
|
|
logger.debug(debugMsg)
|
|
|
|
|
2008-11-20 20:56:09 +03:00
|
|
|
if not os.path.exists(conf.list):
|
2008-11-28 01:33:33 +03:00
|
|
|
errMsg = "the specified list of targets does not exist"
|
2008-11-20 20:56:09 +03:00
|
|
|
raise sqlmapFilePathException, errMsg
|
|
|
|
|
|
|
|
if os.path.isfile(conf.list):
|
2008-11-28 01:33:33 +03:00
|
|
|
__feedTargetsDict(conf.list, addedTargetUrls)
|
2008-11-22 04:57:22 +03:00
|
|
|
|
2008-11-20 20:56:09 +03:00
|
|
|
elif os.path.isdir(conf.list):
|
|
|
|
files = os.listdir(conf.list)
|
|
|
|
files.sort()
|
|
|
|
|
|
|
|
for reqFile in files:
|
|
|
|
if not re.search("([\d]+)\-request", reqFile):
|
|
|
|
continue
|
|
|
|
|
2008-11-28 01:33:33 +03:00
|
|
|
__feedTargetsDict(os.path.join(conf.list, reqFile), addedTargetUrls)
|
2008-11-22 04:57:22 +03:00
|
|
|
|
2008-11-20 20:56:09 +03:00
|
|
|
else:
|
2008-11-28 01:33:33 +03:00
|
|
|
errMsg = "the specified list of targets is not a file "
|
2008-11-20 20:56:09 +03:00
|
|
|
errMsg += "nor a directory"
|
|
|
|
raise sqlmapFilePathException, errMsg
|
|
|
|
|
2008-11-22 04:57:22 +03:00
|
|
|
updatedTargetsCount = len(kb.targetUrls)
|
|
|
|
|
|
|
|
if updatedTargetsCount > initialTargetsCount:
|
2008-11-28 01:33:33 +03:00
|
|
|
infoMsg = "sqlmap parsed %d " % (updatedTargetsCount - initialTargetsCount)
|
|
|
|
infoMsg += "testable requests from the targets list"
|
2008-11-22 04:57:22 +03:00
|
|
|
logger.info(infoMsg)
|
|
|
|
|
2008-11-20 20:56:09 +03:00
|
|
|
|
2008-11-28 01:33:33 +03:00
|
|
|
def __setGoogleDorking():
|
|
|
|
"""
|
|
|
|
This function checks if the way to request testable hosts is through
|
|
|
|
Google dorking then requests to Google the search parameter, parses
|
|
|
|
the results and save the testable hosts into the knowledge base.
|
|
|
|
"""
|
|
|
|
|
|
|
|
global proxyHandler
|
|
|
|
|
|
|
|
if not conf.googleDork:
|
|
|
|
return
|
|
|
|
|
|
|
|
debugMsg = "initializing Google dorking requests"
|
|
|
|
logger.debug(debugMsg)
|
|
|
|
|
|
|
|
logMsg = "first request to Google to get the session cookie"
|
|
|
|
logger.info(logMsg)
|
|
|
|
|
|
|
|
googleObj = Google(proxyHandler)
|
|
|
|
googleObj.getCookie()
|
|
|
|
|
|
|
|
matches = googleObj.search(conf.googleDork)
|
|
|
|
|
|
|
|
if not matches:
|
|
|
|
errMsg = "unable to find results for your "
|
|
|
|
errMsg += "Google dork expression"
|
|
|
|
raise sqlmapGenericException, errMsg
|
|
|
|
|
|
|
|
googleObj.getTargetUrls()
|
|
|
|
|
|
|
|
if kb.targetUrls:
|
|
|
|
logMsg = "sqlmap got %d results for your " % len(matches)
|
|
|
|
logMsg += "Google dork expression, "
|
|
|
|
|
|
|
|
if len(matches) == len(kb.targetUrls):
|
|
|
|
logMsg += "all "
|
|
|
|
else:
|
|
|
|
logMsg += "%d " % len(kb.targetUrls)
|
|
|
|
|
|
|
|
logMsg += "of them are testable targets"
|
|
|
|
logger.info(logMsg)
|
|
|
|
else:
|
|
|
|
errMsg = "sqlmap got %d results " % len(matches)
|
|
|
|
errMsg += "for your Google dork expression, but none of them "
|
|
|
|
errMsg += "have GET parameters to test for SQL injection"
|
|
|
|
raise sqlmapGenericException, errMsg
|
|
|
|
|
|
|
|
|
2008-12-09 00:24:24 +03:00
|
|
|
def __setDBMS():
|
2008-10-15 19:38:22 +04:00
|
|
|
"""
|
2008-12-09 00:24:24 +03:00
|
|
|
Force the back-end DBMS option.
|
2008-10-15 19:38:22 +04:00
|
|
|
"""
|
|
|
|
|
|
|
|
if not conf.dbms:
|
|
|
|
return
|
|
|
|
|
|
|
|
debugMsg = "forcing back-end DBMS to user defined value"
|
|
|
|
logger.debug(debugMsg)
|
|
|
|
|
|
|
|
conf.dbms = conf.dbms.lower()
|
|
|
|
firstRegExp = "(%s|%s)" % ("|".join([alias for alias in MSSQL_ALIASES]),
|
|
|
|
"|".join([alias for alias in MYSQL_ALIASES]))
|
|
|
|
dbmsRegExp = re.search("%s ([\d\.]+)" % firstRegExp, conf.dbms)
|
|
|
|
|
|
|
|
if dbmsRegExp:
|
|
|
|
conf.dbms = dbmsRegExp.group(1)
|
|
|
|
kb.dbmsVersion = [dbmsRegExp.group(2)]
|
|
|
|
|
|
|
|
if conf.dbms not in SUPPORTED_DBMS:
|
|
|
|
errMsg = "you provided an unsupported back-end database management "
|
|
|
|
errMsg += "system. The supported DBMS are MySQL, PostgreSQL, "
|
|
|
|
errMsg += "Microsoft SQL Server and Oracle. If you do not know "
|
|
|
|
errMsg += "the back-end DBMS, do not provide it and sqlmap will "
|
|
|
|
errMsg += "fingerprint it for you."
|
|
|
|
raise sqlmapUnsupportedDBMSException, errMsg
|
|
|
|
|
|
|
|
|
|
|
|
def __setThreads():
|
2008-12-04 20:40:03 +03:00
|
|
|
if not isinstance(conf.threads, int) or conf.threads <= 0:
|
2008-10-15 19:38:22 +04:00
|
|
|
conf.threads = 1
|
|
|
|
|
|
|
|
|
|
|
|
def __setHTTPProxy():
|
|
|
|
"""
|
|
|
|
Check and set the HTTP proxy to pass by all HTTP requests.
|
|
|
|
"""
|
|
|
|
|
|
|
|
global proxyHandler
|
|
|
|
|
|
|
|
if not conf.proxy:
|
|
|
|
return
|
|
|
|
|
|
|
|
parseTargetUrl()
|
|
|
|
|
|
|
|
debugMsg = "setting the HTTP proxy to pass by all HTTP requests"
|
|
|
|
logger.debug(debugMsg)
|
|
|
|
|
|
|
|
__proxySplit = urlparse.urlsplit(conf.proxy)
|
|
|
|
__hostnamePort = __proxySplit[1].split(":")
|
|
|
|
|
|
|
|
__scheme = __proxySplit[0]
|
|
|
|
__hostname = __hostnamePort[0]
|
|
|
|
__port = None
|
|
|
|
|
|
|
|
if len(__hostnamePort) == 2:
|
|
|
|
__port = int(__hostnamePort[1])
|
|
|
|
|
|
|
|
if not __scheme or not __hostname or not __port:
|
|
|
|
errMsg = "proxy value must be in format 'http://url:port'"
|
|
|
|
raise sqlmapSyntaxException, errMsg
|
|
|
|
|
|
|
|
__proxyString = "%s:%d" % (__hostname, __port)
|
|
|
|
|
|
|
|
# Workaround for http://bugs.python.org/issue1424152 (urllib/urllib2:
|
|
|
|
# HTTPS over (Squid) Proxy fails) as long as HTTP over SSL requests
|
|
|
|
# can't be tunneled over an HTTP proxy natively by Python urllib2
|
|
|
|
# standard library
|
|
|
|
if conf.scheme == "https":
|
|
|
|
proxyHandler = ProxyHTTPSHandler(__proxyString)
|
|
|
|
else:
|
|
|
|
proxyHandler = urllib2.ProxyHandler({"http": __proxyString})
|
|
|
|
|
|
|
|
|
|
|
|
def __setHTTPAuthentication():
|
|
|
|
"""
|
|
|
|
Check and set the HTTP authentication method (Basic or Digest),
|
|
|
|
username and password to perform HTTP requests with.
|
|
|
|
"""
|
|
|
|
|
|
|
|
global authHandler
|
|
|
|
|
|
|
|
if not conf.aType and not conf.aCred:
|
|
|
|
return
|
|
|
|
|
|
|
|
elif conf.aType and not conf.aCred:
|
|
|
|
errMsg = "you specified the HTTP Authentication type, but "
|
|
|
|
errMsg += "did not provide the credentials"
|
|
|
|
raise sqlmapSyntaxException, errMsg
|
|
|
|
|
|
|
|
elif not conf.aType and conf.aCred:
|
|
|
|
errMsg = "you specified the HTTP Authentication credentials, "
|
|
|
|
errMsg += "but did not provide the type"
|
|
|
|
raise sqlmapSyntaxException, errMsg
|
|
|
|
|
|
|
|
parseTargetUrl()
|
|
|
|
|
|
|
|
debugMsg = "setting the HTTP Authentication type and credentials"
|
|
|
|
logger.debug(debugMsg)
|
|
|
|
|
|
|
|
aTypeLower = conf.aType.lower()
|
|
|
|
|
|
|
|
if aTypeLower not in ( "basic", "digest" ):
|
|
|
|
errMsg = "HTTP Authentication type value must be "
|
|
|
|
errMsg += "Basic or Digest"
|
|
|
|
raise sqlmapSyntaxException, errMsg
|
|
|
|
|
|
|
|
aCredRegExp = re.search("^(.*?)\:(.*?)$", conf.aCred)
|
|
|
|
|
|
|
|
if not aCredRegExp:
|
|
|
|
errMsg = "HTTP Authentication credentials value must be "
|
|
|
|
errMsg += "in format username:password"
|
|
|
|
raise sqlmapSyntaxException, errMsg
|
|
|
|
|
|
|
|
authUsername = aCredRegExp.group(1)
|
|
|
|
authPassword = aCredRegExp.group(2)
|
|
|
|
|
|
|
|
passwordMgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
|
|
|
|
passwordMgr.add_password(None, "%s://%s" % (conf.scheme, conf.hostname), authUsername, authPassword)
|
|
|
|
|
|
|
|
if aTypeLower == "basic":
|
|
|
|
authHandler = urllib2.HTTPBasicAuthHandler(passwordMgr)
|
|
|
|
elif aTypeLower == "digest":
|
|
|
|
authHandler = urllib2.HTTPDigestAuthHandler(passwordMgr)
|
|
|
|
|
|
|
|
|
|
|
|
def __setHTTPMethod():
|
|
|
|
"""
|
|
|
|
Check and set the HTTP method to perform HTTP requests through.
|
|
|
|
"""
|
|
|
|
|
|
|
|
if conf.method:
|
|
|
|
conf.method = conf.method.upper()
|
|
|
|
|
|
|
|
if conf.method not in ("GET", "POST"):
|
|
|
|
warnMsg = "'%s' " % conf.method
|
|
|
|
warnMsg += "is an unsupported HTTP method, "
|
|
|
|
warnMsg += "setting to default method, GET"
|
|
|
|
logger.warn(warnMsg)
|
|
|
|
|
|
|
|
conf.method = "GET"
|
|
|
|
else:
|
|
|
|
conf.method = "GET"
|
|
|
|
|
2008-11-28 01:33:33 +03:00
|
|
|
debugMsg = "setting the HTTP method to %s" % conf.method
|
|
|
|
logger.debug(debugMsg)
|
|
|
|
|
2008-10-15 19:38:22 +04:00
|
|
|
|
2008-12-09 00:24:24 +03:00
|
|
|
def __setHTTPExtraHeaders():
|
|
|
|
if conf.headers:
|
|
|
|
debugMsg = "setting extra HTTP headers"
|
|
|
|
logger.debug(debugMsg)
|
|
|
|
|
|
|
|
conf.headers = conf.headers.split("\n")
|
|
|
|
|
|
|
|
for headerValue in conf.headers:
|
|
|
|
header, value = headerValue.split(": ")
|
|
|
|
|
|
|
|
if header and value:
|
|
|
|
conf.httpHeaders.append((header, value))
|
|
|
|
|
|
|
|
else:
|
|
|
|
conf.httpHeaders.append(("Accept", "text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"))
|
|
|
|
conf.httpHeaders.append(("Accept-Language", "en-us,en;q=0.5"))
|
|
|
|
conf.httpHeaders.append(("Accept-Charset", "ISO-8859-15,utf-8;q=0.7,*;q=0.7"))
|
2008-11-15 15:25:19 +03:00
|
|
|
|
|
|
|
|
2008-10-15 19:38:22 +04:00
|
|
|
def __defaultHTTPUserAgent():
|
|
|
|
"""
|
|
|
|
@return: default sqlmap HTTP User-Agent header
|
|
|
|
@rtype: C{str}
|
|
|
|
"""
|
|
|
|
|
|
|
|
return "%s (%s)" % (VERSION_STRING, SITE)
|
|
|
|
|
|
|
|
|
|
|
|
def __setHTTPUserAgent():
|
|
|
|
"""
|
|
|
|
Set the HTTP User-Agent header.
|
|
|
|
Depending on the user options it can be:
|
|
|
|
|
|
|
|
* The default sqlmap string
|
|
|
|
* A default value read as user option
|
|
|
|
* A random value read from a list of User-Agent headers from a
|
|
|
|
file choosed as user option
|
|
|
|
"""
|
|
|
|
|
|
|
|
if conf.agent:
|
|
|
|
debugMsg = "setting the HTTP User-Agent header"
|
|
|
|
logger.debug(debugMsg)
|
|
|
|
|
|
|
|
conf.httpHeaders.append(("User-Agent", conf.agent))
|
|
|
|
return
|
|
|
|
|
|
|
|
if not conf.userAgentsFile:
|
|
|
|
conf.httpHeaders.append(("User-Agent", __defaultHTTPUserAgent()))
|
|
|
|
return
|
|
|
|
|
|
|
|
debugMsg = "fetching random HTTP User-Agent header from "
|
|
|
|
debugMsg += "file '%s'" % conf.userAgentsFile
|
|
|
|
logger.debug(debugMsg)
|
|
|
|
|
|
|
|
try:
|
2008-10-31 02:20:14 +03:00
|
|
|
fd = open(conf.userAgentsFile, "r")
|
2008-10-15 19:38:22 +04:00
|
|
|
except IOError:
|
|
|
|
warnMsg = "unable to read HTTP User-Agent header "
|
|
|
|
warnMsg += "file '%s'" % conf.userAgentsFile
|
|
|
|
logger.warn(warnMsg)
|
|
|
|
|
|
|
|
conf.httpHeaders.append(("User-Agent", __defaultHTTPUserAgent()))
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
__count = 0
|
|
|
|
__userAgents = []
|
|
|
|
|
|
|
|
while True:
|
|
|
|
line = fd.readline()
|
|
|
|
|
|
|
|
if not line:
|
|
|
|
break
|
|
|
|
|
|
|
|
__userAgents.append(line)
|
|
|
|
__count += 1
|
|
|
|
|
|
|
|
fd.close()
|
|
|
|
|
|
|
|
if __count == 1:
|
|
|
|
__userAgent = __userAgents[0]
|
|
|
|
else:
|
|
|
|
__userAgent = __userAgents[randomRange(stop=__count)]
|
|
|
|
|
|
|
|
__userAgent = sanitizeStr(__userAgent)
|
|
|
|
conf.httpHeaders.append(("User-Agent", __userAgent))
|
|
|
|
|
|
|
|
logMsg = "fetched random HTTP User-Agent header from "
|
|
|
|
logMsg += "file '%s': %s" % (conf.userAgentsFile, __userAgent)
|
|
|
|
logger.info(logMsg)
|
|
|
|
|
|
|
|
|
|
|
|
def __setHTTPReferer():
|
|
|
|
"""
|
|
|
|
Set the HTTP Referer
|
|
|
|
"""
|
|
|
|
|
|
|
|
if conf.referer:
|
|
|
|
debugMsg = "setting the HTTP Referer header"
|
|
|
|
logger.debug(debugMsg)
|
|
|
|
|
|
|
|
conf.httpHeaders.append(("Referer", conf.referer))
|
|
|
|
|
|
|
|
|
|
|
|
def __setHTTPCookies():
|
|
|
|
"""
|
|
|
|
Set the HTTP Cookie header
|
|
|
|
"""
|
|
|
|
|
|
|
|
if conf.cookie:
|
|
|
|
debugMsg = "setting the HTTP Cookie header"
|
|
|
|
logger.debug(debugMsg)
|
|
|
|
|
|
|
|
conf.httpHeaders.append(("Connection", "Keep-Alive"))
|
|
|
|
conf.httpHeaders.append(("Cookie", conf.cookie))
|
|
|
|
|
|
|
|
|
2008-12-04 20:40:03 +03:00
|
|
|
def __setHTTPTimeout():
|
|
|
|
"""
|
|
|
|
Set the HTTP timeout
|
|
|
|
"""
|
|
|
|
|
|
|
|
if conf.timeout:
|
|
|
|
debugMsg = "setting the HTTP timeout"
|
|
|
|
logger.debug(debugMsg)
|
|
|
|
|
|
|
|
conf.timeout = float(conf.timeout)
|
|
|
|
|
|
|
|
if conf.timeout < 3.0:
|
|
|
|
warnMsg = "the minimum HTTP timeout is 3 seconds, sqlmap "
|
|
|
|
warnMsg += "will going to reset it"
|
|
|
|
logger.warn(warnMsg)
|
|
|
|
|
|
|
|
conf.timeout = 3.0
|
|
|
|
else:
|
2008-12-19 23:48:33 +03:00
|
|
|
conf.timeout = 30.0
|
2008-12-04 20:40:03 +03:00
|
|
|
|
|
|
|
socket.setdefaulttimeout(conf.timeout)
|
|
|
|
|
|
|
|
|
2008-10-15 19:38:22 +04:00
|
|
|
def __cleanupOptions():
|
|
|
|
"""
|
|
|
|
Cleanup configuration attributes.
|
|
|
|
"""
|
|
|
|
|
|
|
|
debugMsg = "cleaning up configuration parameters"
|
|
|
|
logger.debug(debugMsg)
|
|
|
|
|
|
|
|
if conf.testParameter:
|
|
|
|
conf.testParameter = conf.testParameter.replace(" ", "")
|
|
|
|
conf.testParameter = conf.testParameter.split(",")
|
|
|
|
else:
|
|
|
|
conf.testParameter = []
|
|
|
|
|
|
|
|
if conf.db:
|
|
|
|
conf.db = conf.db.replace(" ", "")
|
|
|
|
|
|
|
|
if conf.tbl:
|
|
|
|
conf.tbl = conf.tbl.replace(" ", "")
|
|
|
|
|
|
|
|
if conf.col:
|
|
|
|
conf.col = conf.col.replace(" ", "")
|
|
|
|
|
|
|
|
if conf.user:
|
|
|
|
conf.user = conf.user.replace(" ", "")
|
|
|
|
|
2008-11-09 19:57:47 +03:00
|
|
|
if conf.delay:
|
|
|
|
conf.delay = float(conf.delay)
|
|
|
|
|
2008-11-28 01:33:33 +03:00
|
|
|
if conf.googleDork or conf.list:
|
|
|
|
conf.multipleTargets = True
|
|
|
|
|
2008-10-15 19:38:22 +04:00
|
|
|
|
|
|
|
def __setConfAttributes():
|
|
|
|
"""
|
|
|
|
This function set some needed attributes into the configuration
|
|
|
|
singleton.
|
|
|
|
"""
|
|
|
|
|
|
|
|
debugMsg = "initializing the configuration"
|
|
|
|
logger.debug(debugMsg)
|
|
|
|
|
2008-11-20 20:56:09 +03:00
|
|
|
conf.cj = None
|
2008-12-19 23:09:46 +03:00
|
|
|
conf.pageLengths = []
|
2008-11-20 20:56:09 +03:00
|
|
|
conf.dbmsHandler = None
|
|
|
|
conf.dumpPath = None
|
2008-12-18 23:48:23 +03:00
|
|
|
conf.equalLines = []
|
2008-11-20 20:56:09 +03:00
|
|
|
conf.httpHeaders = []
|
|
|
|
conf.hostname = None
|
|
|
|
conf.loggedToOut = None
|
|
|
|
conf.multipleTargets = False
|
|
|
|
conf.outputPath = None
|
|
|
|
conf.paramDict = {}
|
|
|
|
conf.parameters = {}
|
2008-12-03 00:56:23 +03:00
|
|
|
conf.paramNegative = False
|
2008-11-20 20:56:09 +03:00
|
|
|
conf.path = None
|
|
|
|
conf.port = None
|
2008-12-04 20:40:03 +03:00
|
|
|
conf.retries = 0
|
2008-11-20 20:56:09 +03:00
|
|
|
conf.scheme = None
|
|
|
|
conf.sessionFP = None
|
|
|
|
conf.start = True
|
2008-12-04 20:40:03 +03:00
|
|
|
conf.threadException = False
|
2008-10-15 19:38:22 +04:00
|
|
|
|
|
|
|
|
|
|
|
def __setKnowledgeBaseAttributes():
|
|
|
|
"""
|
|
|
|
This function set some needed attributes into the knowledge base
|
|
|
|
singleton.
|
|
|
|
"""
|
|
|
|
|
|
|
|
debugMsg = "initializing the knowledge base"
|
|
|
|
logger.debug(debugMsg)
|
|
|
|
|
|
|
|
kb.absFilePaths = set()
|
|
|
|
kb.defaultResult = None
|
|
|
|
kb.docRoot = None
|
|
|
|
kb.dbms = None
|
|
|
|
kb.dbmsDetected = False
|
|
|
|
kb.dbmsVersion = None
|
2008-11-17 20:41:02 +03:00
|
|
|
kb.bannerFp = {}
|
2008-11-18 20:42:46 +03:00
|
|
|
kb.headersCount = 0
|
2008-11-17 03:00:54 +03:00
|
|
|
kb.headersFp = {}
|
2008-10-15 19:38:22 +04:00
|
|
|
kb.htmlFp = []
|
|
|
|
kb.injParameter = None
|
|
|
|
kb.injPlace = None
|
|
|
|
kb.injType = None
|
|
|
|
kb.parenthesis = None
|
|
|
|
kb.resumedQueries = {}
|
2008-12-17 00:30:24 +03:00
|
|
|
kb.stackedTest = None
|
2008-11-28 01:33:33 +03:00
|
|
|
kb.targetUrls = set()
|
2008-11-13 03:03:04 +03:00
|
|
|
kb.timeTest = None
|
2008-10-15 19:38:22 +04:00
|
|
|
kb.unionComment = ""
|
|
|
|
kb.unionCount = None
|
|
|
|
kb.unionPosition = None
|
|
|
|
|
|
|
|
|
|
|
|
def __saveCmdline():
|
|
|
|
"""
|
|
|
|
Saves the command line options on a sqlmap configuration INI file
|
|
|
|
format.
|
|
|
|
"""
|
|
|
|
|
|
|
|
if not conf.saveCmdline:
|
|
|
|
return
|
|
|
|
|
|
|
|
debugMsg = "saving command line options on a sqlmap configuration INI file"
|
|
|
|
logger.debug(debugMsg)
|
|
|
|
|
|
|
|
userOpts = {}
|
|
|
|
|
|
|
|
for family in optDict.keys():
|
|
|
|
userOpts[family] = []
|
|
|
|
|
|
|
|
for option, value in conf.items():
|
|
|
|
for family, optionData in optDict.items():
|
|
|
|
if option in optionData:
|
|
|
|
userOpts[family].append((option, value, optionData[option]))
|
|
|
|
|
|
|
|
confFP = open(paths.SQLMAP_CONFIG, "w")
|
|
|
|
|
|
|
|
for family, optionData in userOpts.items():
|
|
|
|
confFP.write("[%s]\n" % family)
|
|
|
|
|
|
|
|
optionData.sort()
|
|
|
|
|
|
|
|
for option, value, datatype in optionData:
|
|
|
|
if value == None:
|
|
|
|
if datatype == "boolean":
|
|
|
|
value = "False"
|
2008-11-09 19:57:47 +03:00
|
|
|
elif datatype in ( "integer", "float" ):
|
2008-12-02 02:07:41 +03:00
|
|
|
if option in ( "threads", "verbose" ):
|
2008-10-26 19:10:28 +03:00
|
|
|
value = "1"
|
2008-12-17 00:30:24 +03:00
|
|
|
elif option == "timeout":
|
|
|
|
value = "10"
|
2008-10-26 19:10:28 +03:00
|
|
|
else:
|
|
|
|
value = "0"
|
2008-10-15 19:38:22 +04:00
|
|
|
elif datatype == "string":
|
|
|
|
value = ""
|
|
|
|
|
2008-12-09 00:24:24 +03:00
|
|
|
if isinstance(value, str):
|
|
|
|
value = value.replace("\n", "\n ")
|
|
|
|
|
2008-10-15 19:38:22 +04:00
|
|
|
confFP.write("%s = %s\n" % (option, value))
|
|
|
|
|
|
|
|
confFP.write("\n")
|
|
|
|
|
|
|
|
confFP.flush()
|
|
|
|
confFP.close()
|
|
|
|
|
|
|
|
infoMsg = "saved command line options on '%s' configuration file" % paths.SQLMAP_CONFIG
|
|
|
|
logger.info(infoMsg)
|
|
|
|
|
|
|
|
|
|
|
|
def __setVerbosity():
|
|
|
|
"""
|
|
|
|
This function set the verbosity of sqlmap output messages.
|
|
|
|
"""
|
|
|
|
|
2008-12-02 02:07:41 +03:00
|
|
|
if conf.verbose == None:
|
|
|
|
conf.verbose = 1
|
2008-10-15 19:38:22 +04:00
|
|
|
|
|
|
|
conf.verbose = int(conf.verbose)
|
|
|
|
|
2008-12-02 02:07:41 +03:00
|
|
|
if conf.verbose == 1:
|
2008-10-15 19:38:22 +04:00
|
|
|
logger.setLevel(logging.INFO)
|
|
|
|
elif conf.verbose > 1 and conf.eta:
|
|
|
|
conf.verbose = 1
|
|
|
|
logger.setLevel(logging.INFO)
|
|
|
|
elif conf.verbose == 2:
|
|
|
|
logger.setLevel(logging.DEBUG)
|
|
|
|
elif conf.verbose == 3:
|
|
|
|
logger.setLevel(9)
|
|
|
|
elif conf.verbose >= 4:
|
|
|
|
logger.setLevel(8)
|
|
|
|
|
|
|
|
|
|
|
|
def __mergeOptions(inputOptions):
|
|
|
|
"""
|
|
|
|
Merge command line options with configuration file options.
|
|
|
|
|
|
|
|
@param inputOptions: optparse object with command line options.
|
|
|
|
@type inputOptions: C{instance}
|
|
|
|
"""
|
|
|
|
|
|
|
|
if inputOptions.configFile:
|
|
|
|
configFileParser(inputOptions.configFile)
|
|
|
|
|
|
|
|
for key, value in inputOptions.__dict__.items():
|
|
|
|
if not conf.has_key(key) or conf[key] == None or value != None:
|
|
|
|
conf[key] = value
|
|
|
|
|
|
|
|
|
|
|
|
def init(inputOptions=advancedDict()):
|
|
|
|
"""
|
|
|
|
Set attributes into both configuration and knowledge base singletons
|
|
|
|
based upon command line and configuration file options.
|
|
|
|
"""
|
|
|
|
|
|
|
|
__mergeOptions(inputOptions)
|
|
|
|
__setVerbosity()
|
|
|
|
__saveCmdline()
|
|
|
|
__setConfAttributes()
|
|
|
|
__setKnowledgeBaseAttributes()
|
|
|
|
__cleanupOptions()
|
2008-12-04 20:40:03 +03:00
|
|
|
__setHTTPTimeout()
|
2008-10-15 19:38:22 +04:00
|
|
|
__setHTTPCookies()
|
|
|
|
__setHTTPReferer()
|
|
|
|
__setHTTPUserAgent()
|
2008-12-09 00:24:24 +03:00
|
|
|
__setHTTPExtraHeaders()
|
2008-10-15 19:38:22 +04:00
|
|
|
__setHTTPMethod()
|
|
|
|
__setHTTPAuthentication()
|
|
|
|
__setHTTPProxy()
|
|
|
|
__setThreads()
|
2008-12-09 00:24:24 +03:00
|
|
|
__setDBMS()
|
2008-10-15 19:38:22 +04:00
|
|
|
__setGoogleDorking()
|
2008-11-28 01:33:33 +03:00
|
|
|
__setMultipleTargets()
|
2008-10-15 19:38:22 +04:00
|
|
|
__urllib2Opener()
|
|
|
|
|
|
|
|
update()
|
|
|
|
queriesParser()
|