mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2025-12-07 05:01:30 +00:00
sqlmap 0.8-rc3: Merge from Miroslav Stampar's branch fixing a bug when verbosity > 2, another major bug with urlencoding/urldecoding of POST data and Cookies, adding --drop-set-cookie option, implementing support to automatically decode gzip and deflate HTTP responses, support for Google dork page result (--gpage) and a minor code cleanup.
This commit is contained in:
@@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
|
||||
|
||||
|
||||
import re
|
||||
|
||||
from lib.core.common import randomInt
|
||||
@@ -45,7 +43,6 @@ class Agent:
|
||||
temp.start = randomStr(6)
|
||||
temp.stop = randomStr(6)
|
||||
|
||||
|
||||
def payload(self, place=None, parameter=None, value=None, newValue=None, negative=False, falseCond=False):
|
||||
"""
|
||||
This method replaces the affected parameter with the SQL
|
||||
@@ -56,9 +53,9 @@ class Agent:
|
||||
negValue = ""
|
||||
retValue = ""
|
||||
|
||||
if negative == True or conf.paramNegative == True:
|
||||
if negative or conf.paramNegative:
|
||||
negValue = "-"
|
||||
elif falseCond == True or conf.paramFalseCond == True:
|
||||
elif falseCond or conf.paramFalseCond:
|
||||
randInt = randomInt()
|
||||
falseValue = " AND %d=%d" % (randInt, randInt + 1)
|
||||
|
||||
@@ -83,7 +80,6 @@ class Agent:
|
||||
|
||||
return retValue
|
||||
|
||||
|
||||
def fullPayload(self, query):
|
||||
query = self.prefixQuery(query)
|
||||
query = self.postfixQuery(query)
|
||||
@@ -91,7 +87,6 @@ class Agent:
|
||||
|
||||
return payload
|
||||
|
||||
|
||||
def prefixQuery(self, string):
|
||||
"""
|
||||
This method defines how the input string has to be escaped
|
||||
@@ -120,7 +115,6 @@ class Agent:
|
||||
|
||||
return query
|
||||
|
||||
|
||||
def postfixQuery(self, string, comment=None):
|
||||
"""
|
||||
This method appends the DBMS comment to the
|
||||
@@ -136,7 +130,7 @@ class Agent:
|
||||
if conf.postfix:
|
||||
string += " %s" % conf.postfix
|
||||
else:
|
||||
if kb.parenthesis != None:
|
||||
if kb.parenthesis is not None:
|
||||
string += " AND %s" % ("(" * kb.parenthesis)
|
||||
else:
|
||||
raise sqlmapNoneDataException, "unable to get the number of parenthesis"
|
||||
@@ -156,7 +150,6 @@ class Agent:
|
||||
|
||||
return string
|
||||
|
||||
|
||||
def nullAndCastField(self, field):
|
||||
"""
|
||||
Take in input a field string and return its processed nulled and
|
||||
@@ -195,7 +188,6 @@ class Agent:
|
||||
|
||||
return nulledCastedField
|
||||
|
||||
|
||||
def nullCastConcatFields(self, fields):
|
||||
"""
|
||||
Take in input a sequence of fields string and return its processed
|
||||
@@ -242,7 +234,6 @@ class Agent:
|
||||
|
||||
return nulledCastedConcatFields
|
||||
|
||||
|
||||
def getFields(self, query):
|
||||
"""
|
||||
Take in input a query string and return its fields (columns) and
|
||||
@@ -285,7 +276,6 @@ class Agent:
|
||||
|
||||
return fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsSelectCase, fieldsToCastList, fieldsToCastStr
|
||||
|
||||
|
||||
def simpleConcatQuery(self, query1, query2):
|
||||
concatenatedQuery = ""
|
||||
|
||||
@@ -300,7 +290,6 @@ class Agent:
|
||||
|
||||
return concatenatedQuery
|
||||
|
||||
|
||||
def concatQuery(self, query, unpack=True):
|
||||
"""
|
||||
Take in input a query string and return its processed nulled,
|
||||
@@ -327,7 +316,7 @@ class Agent:
|
||||
@rtype: C{str}
|
||||
"""
|
||||
|
||||
if unpack == True:
|
||||
if unpack:
|
||||
concatenatedQuery = ""
|
||||
query = query.replace(", ", ",")
|
||||
|
||||
@@ -386,7 +375,6 @@ class Agent:
|
||||
|
||||
return concatenatedQuery
|
||||
|
||||
|
||||
def forgeInbandQuery(self, query, exprPosition=None, nullChar="NULL"):
|
||||
"""
|
||||
Take in input an query (pseudo query) string and return its
|
||||
@@ -465,7 +453,6 @@ class Agent:
|
||||
|
||||
return inbandQuery
|
||||
|
||||
|
||||
def limitQuery(self, num, query, field):
|
||||
"""
|
||||
Take in input a query string and return its limited query string.
|
||||
@@ -529,7 +516,7 @@ class Agent:
|
||||
topNum = re.search("TOP\s+([\d]+)\s+", limitedQuery, re.I).group(1)
|
||||
limitedQuery = limitedQuery.replace("TOP %s " % topNum, "")
|
||||
|
||||
if forgeNotIn == True:
|
||||
if forgeNotIn:
|
||||
limitedQuery = limitedQuery.replace("SELECT ", (limitStr % 1), 1)
|
||||
if " WHERE " in limitedQuery:
|
||||
limitedQuery = "%s AND %s " % (limitedQuery, field)
|
||||
@@ -540,7 +527,6 @@ class Agent:
|
||||
|
||||
return limitedQuery
|
||||
|
||||
|
||||
def forgeCaseStatement(self, expression):
|
||||
"""
|
||||
Take in input a query string and return its CASE statement query
|
||||
@@ -560,6 +546,5 @@ class Agent:
|
||||
|
||||
return queries[kb.dbms].case % expression
|
||||
|
||||
|
||||
# SQL agent
|
||||
agent = Agent()
|
||||
|
||||
@@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
|
||||
|
||||
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
@@ -32,10 +30,7 @@ import string
|
||||
import sys
|
||||
import time
|
||||
import urlparse
|
||||
|
||||
|
||||
from lib.contrib import magic
|
||||
from lib.core.convert import urldecode
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
@@ -115,7 +110,6 @@ def paramToDict(place, parameters=None):
|
||||
|
||||
return testableParameters
|
||||
|
||||
|
||||
def formatDBMSfp(versions=None):
|
||||
"""
|
||||
This function format the back-end DBMS fingerprint value and return its
|
||||
@@ -139,13 +133,11 @@ def formatDBMSfp(versions=None):
|
||||
|
||||
return kb.dbms
|
||||
|
||||
|
||||
def formatFingerprintString(values, chain=" or "):
|
||||
strJoin = "|".join([v for v in values])
|
||||
|
||||
return strJoin.replace("|", chain)
|
||||
|
||||
|
||||
def formatFingerprint(target, info):
|
||||
"""
|
||||
This function format the back-end operating system fingerprint value
|
||||
@@ -198,7 +190,6 @@ def formatFingerprint(target, info):
|
||||
|
||||
return infoStr
|
||||
|
||||
|
||||
def getHtmlErrorFp():
|
||||
"""
|
||||
This function parses the knowledge base htmlFp list and return its
|
||||
@@ -222,7 +213,6 @@ def getHtmlErrorFp():
|
||||
|
||||
return htmlParsed
|
||||
|
||||
|
||||
def getDocRoot():
|
||||
docRoot = None
|
||||
pagePath = os.path.dirname(conf.path)
|
||||
@@ -236,7 +226,7 @@ def getDocRoot():
|
||||
for absFilePath in kb.absFilePaths:
|
||||
absFilePathWin = None
|
||||
|
||||
if re.search("([\w]\:[\/\\\\]+)", absFilePath):
|
||||
if re.search("[A-Za-z]:(\\[\w.\\]*)?", absFilePath):
|
||||
absFilePathWin = absFilePath
|
||||
absFilePath = absFilePath[2:].replace("\\", "/")
|
||||
|
||||
@@ -269,7 +259,6 @@ def getDocRoot():
|
||||
|
||||
return docRoot
|
||||
|
||||
|
||||
def getDirs():
|
||||
directories = set()
|
||||
|
||||
@@ -305,33 +294,28 @@ def getDirs():
|
||||
directories.add(defaultDir)
|
||||
|
||||
return directories
|
||||
|
||||
|
||||
|
||||
def filePathToString(filePath):
|
||||
strRepl = filePath.replace("/", "_").replace("\\", "_")
|
||||
strRepl = strRepl.replace(" ", "_").replace(":", "_")
|
||||
|
||||
return strRepl
|
||||
|
||||
|
||||
def dataToStdout(data):
|
||||
sys.stdout.write(data)
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
|
||||
def dataToSessionFile(data):
|
||||
if not conf.sessionFile:
|
||||
return
|
||||
|
||||
conf.sessionFP.write(data)
|
||||
conf.sessionFP.flush()
|
||||
|
||||
|
||||
|
||||
def dataToDumpFile(dumpFile, data):
|
||||
dumpFile.write(data)
|
||||
dumpFile.flush()
|
||||
|
||||
|
||||
|
||||
def dataToOutFile(data):
|
||||
if not data:
|
||||
return "No data retrieved"
|
||||
@@ -346,7 +330,6 @@ def dataToOutFile(data):
|
||||
|
||||
return rFilePath
|
||||
|
||||
|
||||
def strToHex(inpStr):
|
||||
"""
|
||||
@param inpStr: inpStr to be converted into its hexadecimal value.
|
||||
@@ -369,8 +352,7 @@ def strToHex(inpStr):
|
||||
hexStr += hexChar
|
||||
|
||||
return hexStr
|
||||
|
||||
|
||||
|
||||
def fileToStr(fileName):
|
||||
"""
|
||||
@param fileName: file path to read the content and return as a no
|
||||
@@ -384,13 +366,7 @@ def fileToStr(fileName):
|
||||
filePointer = open(fileName, "r")
|
||||
fileText = filePointer.read()
|
||||
|
||||
fileText = fileText.replace(" ", "")
|
||||
fileText = fileText.replace("\t", "")
|
||||
fileText = fileText.replace("\r", "")
|
||||
fileText = fileText.replace("\n", " ")
|
||||
|
||||
return fileText
|
||||
|
||||
return fileText.replace(" ", "").replace("\t", "").replace("\r", "").replace("\n", " ")
|
||||
|
||||
def fileToHex(fileName):
|
||||
"""
|
||||
@@ -407,7 +383,6 @@ def fileToHex(fileName):
|
||||
|
||||
return hexFile
|
||||
|
||||
|
||||
def readInput(message, default=None):
|
||||
"""
|
||||
@param message: message to display on terminal.
|
||||
@@ -435,8 +410,7 @@ def readInput(message, default=None):
|
||||
data = default
|
||||
|
||||
return data
|
||||
|
||||
|
||||
|
||||
def randomRange(start=0, stop=1000):
|
||||
"""
|
||||
@param start: starting number.
|
||||
@@ -451,7 +425,6 @@ def randomRange(start=0, stop=1000):
|
||||
|
||||
return int(random.randint(start, stop))
|
||||
|
||||
|
||||
def randomInt(length=4):
|
||||
"""
|
||||
@param length: length of the random string.
|
||||
@@ -463,7 +436,6 @@ def randomInt(length=4):
|
||||
|
||||
return int("".join([random.choice(string.digits) for _ in xrange(0, length)]))
|
||||
|
||||
|
||||
def randomStr(length=5, lowercase=False):
|
||||
"""
|
||||
@param length: length of the random string.
|
||||
@@ -473,14 +445,13 @@ def randomStr(length=5, lowercase=False):
|
||||
@rtype: C{str}
|
||||
"""
|
||||
|
||||
if lowercase == True:
|
||||
if lowercase:
|
||||
rndStr = "".join([random.choice(string.lowercase) for _ in xrange(0, length)])
|
||||
else:
|
||||
rndStr = "".join([random.choice(string.letters) for _ in xrange(0, length)])
|
||||
|
||||
return rndStr
|
||||
|
||||
|
||||
|
||||
def sanitizeStr(inpStr):
|
||||
"""
|
||||
@param inpStr: inpStr to sanitize: cast to str datatype and replace
|
||||
@@ -496,7 +467,6 @@ def sanitizeStr(inpStr):
|
||||
|
||||
return cleanString
|
||||
|
||||
|
||||
def checkFile(filename):
|
||||
"""
|
||||
@param filename: filename to check if it exists.
|
||||
@@ -505,15 +475,13 @@ def checkFile(filename):
|
||||
|
||||
if not os.path.exists(filename):
|
||||
raise sqlmapFilePathException, "unable to read file '%s'" % filename
|
||||
|
||||
|
||||
|
||||
def replaceNewlineTabs(inpStr):
|
||||
replacedString = inpStr.replace("\n", "__NEWLINE__").replace("\t", "__TAB__")
|
||||
replacedString = replacedString.replace(temp.delimiter, "__DEL__")
|
||||
|
||||
return replacedString
|
||||
|
||||
|
||||
def banner():
|
||||
"""
|
||||
This function prints sqlmap banner with its version
|
||||
@@ -523,8 +491,7 @@ def banner():
|
||||
%s
|
||||
by Bernardo Damele A. G. <bernardo.damele@gmail.com>
|
||||
""" % VERSION_STRING
|
||||
|
||||
|
||||
|
||||
def parsePasswordHash(password):
|
||||
blank = " " * 8
|
||||
|
||||
@@ -542,8 +509,7 @@ def parsePasswordHash(password):
|
||||
password += "%suppercase: %s" % (blank, hexPassword[54:])
|
||||
|
||||
return password
|
||||
|
||||
|
||||
|
||||
def cleanQuery(query):
|
||||
upperQuery = query
|
||||
|
||||
@@ -556,8 +522,7 @@ def cleanQuery(query):
|
||||
upperQuery = upperQuery.replace(queryMatch.group(1), sqlStatement.upper())
|
||||
|
||||
return upperQuery
|
||||
|
||||
|
||||
|
||||
def setPaths():
|
||||
# sqlmap paths
|
||||
paths.SQLMAP_CONTRIB_PATH = os.path.join(paths.SQLMAP_ROOT_PATH, "lib", "contrib")
|
||||
@@ -581,8 +546,7 @@ def setPaths():
|
||||
paths.MYSQL_XML = os.path.join(paths.SQLMAP_XML_BANNER_PATH, "mysql.xml")
|
||||
paths.ORACLE_XML = os.path.join(paths.SQLMAP_XML_BANNER_PATH, "oracle.xml")
|
||||
paths.PGSQL_XML = os.path.join(paths.SQLMAP_XML_BANNER_PATH, "postgresql.xml")
|
||||
|
||||
|
||||
|
||||
def weAreFrozen():
|
||||
"""
|
||||
Returns whether we are frozen via py2exe.
|
||||
@@ -592,7 +556,6 @@ def weAreFrozen():
|
||||
|
||||
return hasattr(sys, "frozen")
|
||||
|
||||
|
||||
def parseTargetUrl():
|
||||
"""
|
||||
Parse target url and set some attributes into the configuration
|
||||
@@ -623,11 +586,10 @@ def parseTargetUrl():
|
||||
conf.port = 80
|
||||
|
||||
if __urlSplit[3]:
|
||||
conf.parameters["GET"] = urldecode(__urlSplit[3]).replace("%", "%%")
|
||||
conf.parameters["GET"] = __urlSplit[3]
|
||||
|
||||
conf.url = "%s://%s:%d%s" % (conf.scheme, conf.hostname, conf.port, conf.path)
|
||||
|
||||
|
||||
|
||||
def expandAsteriskForColumns(expression):
|
||||
# If the user provided an asterisk rather than the column(s)
|
||||
# name, sqlmap will retrieve the columns itself and reprocess
|
||||
@@ -659,8 +621,7 @@ def expandAsteriskForColumns(expression):
|
||||
logger.info(infoMsg)
|
||||
|
||||
return expression
|
||||
|
||||
|
||||
|
||||
def getRange(count, dump=False, plusOne=False):
|
||||
count = int(count)
|
||||
indexRange = None
|
||||
@@ -674,14 +635,13 @@ def getRange(count, dump=False, plusOne=False):
|
||||
if isinstance(conf.limitStart, int) and conf.limitStart > 0 and conf.limitStart <= limitStop:
|
||||
limitStart = conf.limitStart
|
||||
|
||||
if kb.dbms == "Oracle" or plusOne == True:
|
||||
if kb.dbms == "Oracle" or plusOne:
|
||||
indexRange = range(limitStart, limitStop + 1)
|
||||
else:
|
||||
indexRange = range(limitStart - 1, limitStop)
|
||||
|
||||
return indexRange
|
||||
|
||||
|
||||
|
||||
def parseUnionPage(output, expression, partial=False, condition=None, sort=True):
|
||||
data = []
|
||||
|
||||
@@ -696,7 +656,7 @@ def parseUnionPage(output, expression, partial=False, condition=None, sort=True)
|
||||
|
||||
output = re.findall(regExpr, output, re.S)
|
||||
|
||||
if condition == None:
|
||||
if condition is None:
|
||||
condition = (
|
||||
kb.resumedQueries and conf.url in kb.resumedQueries.keys()
|
||||
and expression in kb.resumedQueries[conf.url].keys()
|
||||
@@ -731,27 +691,25 @@ def parseUnionPage(output, expression, partial=False, condition=None, sort=True)
|
||||
data = data[0]
|
||||
|
||||
return data
|
||||
|
||||
|
||||
|
||||
def getDelayQuery():
|
||||
query = None
|
||||
|
||||
if kb.dbms in ( "MySQL", "PostgreSQL" ):
|
||||
if kb.dbms in ("MySQL", "PostgreSQL"):
|
||||
if not kb.data.banner:
|
||||
conf.dbmsHandler.getVersionFromBanner()
|
||||
|
||||
banVer = kb.bannerFp["dbmsVersion"]
|
||||
|
||||
if ( kb.dbms == "MySQL" and banVer >= "5.0.12" ) or ( kb.dbms == "PostgreSQL" and banVer >= "8.2" ):
|
||||
if (kb.dbms == "MySQL" and banVer >= "5.0.12") or (kb.dbms == "PostgreSQL" and banVer >= "8.2"):
|
||||
query = queries[kb.dbms].timedelay % conf.timeSec
|
||||
else:
|
||||
query = queries[kb.dbms].timedelay2 % conf.timeSec
|
||||
else:
|
||||
else:
|
||||
query = queries[kb.dbms].timedelay % conf.timeSec
|
||||
|
||||
return query
|
||||
|
||||
|
||||
|
||||
def getLocalIP():
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
s.connect((conf.hostname, conf.port))
|
||||
@@ -760,11 +718,9 @@ def getLocalIP():
|
||||
|
||||
return ip
|
||||
|
||||
|
||||
def getRemoteIP():
|
||||
return socket.gethostbyname(conf.hostname)
|
||||
|
||||
|
||||
def getFileType(filePath):
|
||||
try:
|
||||
magicFileType = magic.from_file(filePath)
|
||||
@@ -775,8 +731,7 @@ def getFileType(filePath):
|
||||
return "text"
|
||||
else:
|
||||
return "binary"
|
||||
|
||||
|
||||
|
||||
def pollProcess(process):
|
||||
while True:
|
||||
dataToStdout(".")
|
||||
@@ -793,12 +748,11 @@ def pollProcess(process):
|
||||
dataToStdout(" quit unexpectedly with return code %d\n" % returncode)
|
||||
|
||||
break
|
||||
|
||||
|
||||
|
||||
def getCharset(charsetType=None):
|
||||
asciiTbl = []
|
||||
|
||||
if charsetType == None:
|
||||
if charsetType is None:
|
||||
asciiTbl = range(0, 128)
|
||||
|
||||
# 0 or 1
|
||||
@@ -832,22 +786,49 @@ def getCharset(charsetType=None):
|
||||
asciiTbl.extend(range(96, 123))
|
||||
|
||||
return asciiTbl
|
||||
|
||||
|
||||
|
||||
def searchEnvPath(fileName):
|
||||
envPaths = os.environ["PATH"]
|
||||
result = None
|
||||
result = None
|
||||
|
||||
if IS_WIN is True:
|
||||
if IS_WIN:
|
||||
envPaths = envPaths.split(";")
|
||||
else:
|
||||
envPaths = envPaths.split(":")
|
||||
|
||||
for envPath in envPaths:
|
||||
envPath = envPath.replace(";", "")
|
||||
result = os.path.exists(os.path.normpath(os.path.join(envPath, fileName)))
|
||||
result = os.path.exists(os.path.normpath(os.path.join(envPath, fileName)))
|
||||
|
||||
if result == True:
|
||||
if result:
|
||||
break
|
||||
|
||||
return result
|
||||
|
||||
def sanitizeCookie(cookieStr, warn=False):
|
||||
if cookieStr:
|
||||
result = ""
|
||||
changed = False
|
||||
for part in cookieStr.split(';'):
|
||||
index = part.find('=') + 1
|
||||
if index > 0:
|
||||
name = part[:index - 1].strip()
|
||||
value = part[index:].replace(",","%2C").replace(";","%3B").replace(" ","%20")
|
||||
if value != part[index:]:
|
||||
changed = True
|
||||
result += ";%s=%s" % (name, value)
|
||||
elif part.strip().lower() != "secure":
|
||||
result += "%s%s" % ("%3B", part.replace(",","%2C").replace(";","%3B").replace(" ","%20"))
|
||||
else:
|
||||
result += ";secure"
|
||||
if result.startswith(';'):
|
||||
result = result[1:]
|
||||
elif result.startswith('%3B'):
|
||||
result = result[3:]
|
||||
if changed and warn:
|
||||
warnMsg = "cookie is provided in HTTP unsafe format containing one "
|
||||
warnMsg += "of problematic characters: ' ,;'. temporary sanitized."
|
||||
logger.warn(warnMsg)
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
@@ -22,21 +22,17 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
|
||||
|
||||
import md5
|
||||
import sha
|
||||
import struct
|
||||
import urllib
|
||||
|
||||
|
||||
def base64decode(string):
|
||||
return string.decode("base64")
|
||||
|
||||
|
||||
def base64encode(string):
|
||||
return string.encode("base64")[:-1]
|
||||
|
||||
|
||||
def hexdecode(string):
|
||||
string = string.lower()
|
||||
|
||||
@@ -44,45 +40,40 @@ def hexdecode(string):
|
||||
string = string[2:]
|
||||
|
||||
return string.decode("hex")
|
||||
|
||||
|
||||
|
||||
def hexencode(string):
|
||||
return string.encode("hex")
|
||||
|
||||
|
||||
def md5hash(string):
|
||||
return md5.new(string).hexdigest()
|
||||
|
||||
|
||||
def orddecode(string):
|
||||
packedString = struct.pack("!"+"I" * len(string), *string)
|
||||
return "".join([chr(char) for char in struct.unpack("!"+"I"*(len(packedString)/4), packedString)])
|
||||
|
||||
|
||||
def ordencode(string):
|
||||
return tuple([ord(char) for char in string])
|
||||
|
||||
|
||||
def sha1hash(string):
|
||||
return sha.new(string).hexdigest()
|
||||
|
||||
|
||||
def urldecode(string):
|
||||
if not string:
|
||||
return
|
||||
|
||||
doublePercFreeString = string.replace("%%", "__DPERC__")
|
||||
unquotedString = urllib.unquote_plus(doublePercFreeString)
|
||||
unquotedString = unquotedString.replace("__DPERC__", "%%")
|
||||
|
||||
return unquotedString
|
||||
result = None
|
||||
|
||||
if string:
|
||||
result = urllib.unquote_plus(string)
|
||||
|
||||
return result
|
||||
|
||||
def urlencode(string, safe=":/?%&=", convall=False):
|
||||
if not string:
|
||||
return
|
||||
result = None
|
||||
|
||||
if convall == True:
|
||||
return urllib.quote(string)
|
||||
if string is None:
|
||||
return result
|
||||
|
||||
if convall:
|
||||
result = urllib.quote(string)
|
||||
else:
|
||||
return urllib.quote(string, safe)
|
||||
result = urllib.quote(string, safe)
|
||||
|
||||
return result
|
||||
|
||||
@@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
|
||||
|
||||
|
||||
from lib.core.datatype import advancedDict
|
||||
from lib.core.settings import LOGGER
|
||||
|
||||
|
||||
@@ -22,10 +22,8 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
|
||||
|
||||
from lib.core.exception import sqlmapDataException
|
||||
|
||||
|
||||
class advancedDict(dict):
|
||||
"""
|
||||
This class defines the sqlmap object, inheriting from Python data
|
||||
@@ -45,7 +43,6 @@ class advancedDict(dict):
|
||||
# After initialisation, setting attributes
|
||||
# is the same as setting an item
|
||||
|
||||
|
||||
def __getattr__(self, item):
|
||||
"""
|
||||
Maps values to attributes
|
||||
@@ -57,7 +54,6 @@ class advancedDict(dict):
|
||||
except KeyError:
|
||||
raise sqlmapDataException, "Unable to access item '%s'" % item
|
||||
|
||||
|
||||
def __setattr__(self, item, value):
|
||||
"""
|
||||
Maps attributes to values
|
||||
|
||||
@@ -22,16 +22,13 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
|
||||
|
||||
|
||||
import re
|
||||
import os
|
||||
import re
|
||||
|
||||
from lib.core.common import dataToDumpFile
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import logger
|
||||
|
||||
|
||||
class Dump:
|
||||
"""
|
||||
This class defines methods used to parse and output the results
|
||||
@@ -42,8 +39,7 @@ class Dump:
|
||||
def __init__(self):
|
||||
self.__outputFile = None
|
||||
self.__outputFP = None
|
||||
|
||||
|
||||
|
||||
def __write(self, data, n=True):
|
||||
if n:
|
||||
print data
|
||||
@@ -55,13 +51,11 @@ class Dump:
|
||||
self.__outputFP.flush()
|
||||
|
||||
conf.loggedToOut = True
|
||||
|
||||
|
||||
|
||||
def setOutputFile(self):
|
||||
self.__outputFile = "%s%slog" % (conf.outputPath, os.sep)
|
||||
self.__outputFP = open(self.__outputFile, "a")
|
||||
|
||||
|
||||
|
||||
def string(self, header, data, sort=True):
|
||||
if isinstance(data, (list, tuple, set)):
|
||||
self.lister(header, data, sort)
|
||||
@@ -81,13 +75,12 @@ class Dump:
|
||||
self.__write("%s: '%s'\n" % (header, data))
|
||||
else:
|
||||
self.__write("%s:\tNone\n" % header)
|
||||
|
||||
|
||||
|
||||
def lister(self, header, elements, sort=True):
|
||||
if elements:
|
||||
self.__write("%s [%d]:" % (header, len(elements)))
|
||||
|
||||
if sort == True:
|
||||
if sort:
|
||||
try:
|
||||
elements = set(elements)
|
||||
elements = list(elements)
|
||||
@@ -103,8 +96,7 @@ class Dump:
|
||||
|
||||
if elements:
|
||||
self.__write("")
|
||||
|
||||
|
||||
|
||||
def userSettings(self, header, userSettings, subHeader):
|
||||
self.__areAdmins = set()
|
||||
|
||||
@@ -131,8 +123,7 @@ class Dump:
|
||||
for setting in settings:
|
||||
self.__write(" %s: %s" % (subHeader, setting))
|
||||
print
|
||||
|
||||
|
||||
|
||||
def dbTables(self, dbTables):
|
||||
if not isinstance(dbTables, dict):
|
||||
self.string("tables", dbTables)
|
||||
@@ -164,8 +155,7 @@ class Dump:
|
||||
self.__write("| %s%s |" % (table, blank))
|
||||
|
||||
self.__write("+%s+\n" % lines)
|
||||
|
||||
|
||||
|
||||
def dbTableColumns(self, tableColumns):
|
||||
for db, tables in tableColumns.items():
|
||||
if not db:
|
||||
@@ -210,8 +200,7 @@ class Dump:
|
||||
self.__write("| %s%s | %s%s |" % (column, blank1, colType, blank2))
|
||||
|
||||
self.__write("+%s+%s+\n" % (lines1, lines2))
|
||||
|
||||
|
||||
|
||||
def dbTableValues(self, tableValues):
|
||||
db = tableValues["__infos__"]["db"]
|
||||
if not db:
|
||||
@@ -306,7 +295,6 @@ class Dump:
|
||||
|
||||
logger.info("Table '%s.%s' dumped to CSV file '%s'" % (db, table, dumpFileName))
|
||||
|
||||
|
||||
# object to manage how to print the retrieved queries output to
|
||||
# standard output and sessions file
|
||||
dumper = Dump()
|
||||
|
||||
@@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
|
||||
|
||||
|
||||
from lib.core.settings import PLATFORM
|
||||
from lib.core.settings import PYVERSION
|
||||
from lib.core.settings import VERSION
|
||||
@@ -33,67 +31,51 @@ from lib.core.settings import VERSION_STRING
|
||||
class sqlmapConnectionException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class sqlmapDataException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class sqlmapFilePathException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class sqlmapGenericException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class sqlmapMissingDependence(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class sqlmapMissingMandatoryOptionException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class sqlmapMissingPrivileges(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class sqlmapNoneDataException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class sqlmapNotVulnerableException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class sqlmapRegExprException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class sqlmapSyntaxException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class sqlmapThreadException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class sqlmapUndefinedMethod(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class sqlmapUnsupportedDBMSException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class sqlmapUnsupportedFeatureException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class sqlmapValueException(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def unhandledException():
|
||||
errMsg = "unhandled exception in %s, please copy " % VERSION_STRING
|
||||
errMsg += "the command line and the following text and send by e-mail "
|
||||
@@ -103,7 +85,6 @@ def unhandledException():
|
||||
errMsg += "Operating system: %s" % PLATFORM
|
||||
return errMsg
|
||||
|
||||
|
||||
exceptionsTuple = (
|
||||
sqlmapConnectionException,
|
||||
sqlmapDataException,
|
||||
|
||||
@@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
|
||||
|
||||
|
||||
import cookielib
|
||||
import ctypes
|
||||
import difflib
|
||||
@@ -40,6 +38,7 @@ from lib.core.common import getFileType
|
||||
from lib.core.common import parseTargetUrl
|
||||
from lib.core.common import paths
|
||||
from lib.core.common import randomRange
|
||||
from lib.core.common import sanitizeCookie
|
||||
from lib.core.common import sanitizeStr
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
@@ -70,11 +69,9 @@ 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.
|
||||
@@ -85,13 +82,15 @@ def __urllib2Opener():
|
||||
|
||||
debugMsg = "creating HTTP requests opener object"
|
||||
logger.debug(debugMsg)
|
||||
|
||||
conf.cj = cookielib.LWPCookieJar()
|
||||
opener = urllib2.build_opener(proxyHandler, authHandler, urllib2.HTTPCookieProcessor(conf.cj))
|
||||
|
||||
if conf.dropSetCookie:
|
||||
opener = urllib2.build_opener(proxyHandler, authHandler)
|
||||
else:
|
||||
conf.cj = cookielib.LWPCookieJar()
|
||||
opener = urllib2.build_opener(proxyHandler, authHandler, urllib2.HTTPCookieProcessor(conf.cj))
|
||||
|
||||
urllib2.install_opener(opener)
|
||||
|
||||
|
||||
def __feedTargetsDict(reqFile, addedTargetUrls):
|
||||
fp = open(reqFile, "r")
|
||||
|
||||
@@ -173,7 +172,6 @@ def __feedTargetsDict(reqFile, addedTargetUrls):
|
||||
kb.targetUrls.add(( url, method, data, cookie ))
|
||||
addedTargetUrls.add(url)
|
||||
|
||||
|
||||
def __setMultipleTargets():
|
||||
"""
|
||||
Define a configuration parameter if we are running in multiple target
|
||||
@@ -218,7 +216,6 @@ def __setMultipleTargets():
|
||||
infoMsg += "testable requests from the targets list"
|
||||
logger.info(infoMsg)
|
||||
|
||||
|
||||
def __setGoogleDorking():
|
||||
"""
|
||||
This function checks if the way to request testable hosts is through
|
||||
@@ -266,7 +263,6 @@ def __setGoogleDorking():
|
||||
errMsg += "have GET parameters to test for SQL injection"
|
||||
raise sqlmapGenericException, errMsg
|
||||
|
||||
|
||||
def __setMetasploit():
|
||||
if not conf.osPwn and not conf.osSmb and not conf.osBof:
|
||||
return
|
||||
@@ -276,7 +272,7 @@ def __setMetasploit():
|
||||
|
||||
msfEnvPathExists = False
|
||||
|
||||
if IS_WIN is True:
|
||||
if IS_WIN:
|
||||
warnMsg = "Metasploit's msfconsole and msfcli are not supported "
|
||||
warnMsg += "on the native Windows Ruby interpreter. Please "
|
||||
warnMsg += "install Metasploit, Python interpreter and sqlmap on "
|
||||
@@ -300,7 +296,7 @@ def __setMetasploit():
|
||||
if isinstance(isAdmin, (int, float, long)) and isAdmin == 0:
|
||||
isAdmin = True
|
||||
|
||||
elif IS_WIN is True:
|
||||
elif IS_WIN:
|
||||
isAdmin = ctypes.windll.shell32.IsUserAnAdmin()
|
||||
|
||||
if isinstance(isAdmin, (int, float, long)) and isAdmin == 1:
|
||||
@@ -349,14 +345,14 @@ def __setMetasploit():
|
||||
warnMsg += "Framework 3 is installed"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
if msfEnvPathExists != True:
|
||||
if not msfEnvPathExists:
|
||||
warnMsg = "sqlmap is going to look for Metasploit Framework 3 "
|
||||
warnMsg += "installation into the environment paths"
|
||||
logger.warn(warnMsg)
|
||||
|
||||
envPaths = os.environ["PATH"]
|
||||
|
||||
if IS_WIN is True:
|
||||
if IS_WIN:
|
||||
envPaths = envPaths.split(";")
|
||||
else:
|
||||
envPaths = envPaths.split(":")
|
||||
@@ -379,12 +375,11 @@ def __setMetasploit():
|
||||
|
||||
break
|
||||
|
||||
if msfEnvPathExists != True:
|
||||
if not msfEnvPathExists:
|
||||
errMsg = "unable to locate Metasploit Framework 3 installation. "
|
||||
errMsg += "Get it from http://metasploit.com/framework/download/"
|
||||
raise sqlmapFilePathException, errMsg
|
||||
|
||||
|
||||
def __setWriteFile():
|
||||
if not conf.wFile:
|
||||
return
|
||||
@@ -403,9 +398,8 @@ def __setWriteFile():
|
||||
|
||||
conf.wFileType = getFileType(conf.wFile)
|
||||
|
||||
|
||||
def __setUnionTech():
|
||||
if conf.uTech == None:
|
||||
if conf.uTech is None:
|
||||
conf.uTech = "NULL"
|
||||
|
||||
return
|
||||
@@ -428,7 +422,6 @@ def __setUnionTech():
|
||||
debugMsg += "'%s'" % uTechOriginal
|
||||
logger.debug(debugMsg)
|
||||
|
||||
|
||||
def __setOS():
|
||||
"""
|
||||
Force the back-end DBMS operating system option.
|
||||
@@ -451,7 +444,6 @@ def __setOS():
|
||||
errMsg += "you."
|
||||
raise sqlmapUnsupportedDBMSException, errMsg
|
||||
|
||||
|
||||
def __setDBMS():
|
||||
"""
|
||||
Force the back-end DBMS option.
|
||||
@@ -482,12 +474,10 @@ def __setDBMS():
|
||||
errMsg += "fingerprint it for you."
|
||||
raise sqlmapUnsupportedDBMSException, errMsg
|
||||
|
||||
|
||||
def __setThreads():
|
||||
if not isinstance(conf.threads, int) or conf.threads <= 0:
|
||||
conf.threads = 1
|
||||
|
||||
|
||||
def __setHTTPProxy():
|
||||
"""
|
||||
Check and set the HTTP proxy to pass by all HTTP requests.
|
||||
@@ -526,7 +516,6 @@ def __setHTTPProxy():
|
||||
else:
|
||||
proxyHandler = urllib2.ProxyHandler({"http": __proxyString})
|
||||
|
||||
|
||||
def __setHTTPAuthentication():
|
||||
"""
|
||||
Check and set the HTTP authentication method (Basic, Digest or NTLM),
|
||||
@@ -588,7 +577,6 @@ def __setHTTPAuthentication():
|
||||
|
||||
authHandler = HTTPNtlmAuthHandler.HTTPNtlmAuthHandler(passwordMgr)
|
||||
|
||||
|
||||
def __setHTTPMethod():
|
||||
"""
|
||||
Check and set the HTTP method to perform HTTP requests through.
|
||||
@@ -610,7 +598,6 @@ def __setHTTPMethod():
|
||||
debugMsg = "setting the HTTP method to %s" % conf.method
|
||||
logger.debug(debugMsg)
|
||||
|
||||
|
||||
def __setHTTPExtraHeaders():
|
||||
if conf.hostname:
|
||||
conf.httpHeaders.append(("Host", conf.hostname))
|
||||
@@ -632,7 +619,6 @@ def __setHTTPExtraHeaders():
|
||||
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"))
|
||||
|
||||
|
||||
def __defaultHTTPUserAgent():
|
||||
"""
|
||||
@return: default sqlmap HTTP User-Agent header
|
||||
@@ -648,7 +634,6 @@ def __defaultHTTPUserAgent():
|
||||
# updated at March 2009
|
||||
#return "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)"
|
||||
|
||||
|
||||
def __setHTTPUserAgent():
|
||||
"""
|
||||
Set the HTTP User-Agent header.
|
||||
@@ -712,7 +697,6 @@ def __setHTTPUserAgent():
|
||||
logMsg += "file '%s': %s" % (conf.userAgentsFile, __userAgent)
|
||||
logger.info(logMsg)
|
||||
|
||||
|
||||
def __setHTTPReferer():
|
||||
"""
|
||||
Set the HTTP Referer
|
||||
@@ -724,7 +708,6 @@ def __setHTTPReferer():
|
||||
|
||||
conf.httpHeaders.append(("Referer", conf.referer))
|
||||
|
||||
|
||||
def __setHTTPCookies():
|
||||
"""
|
||||
Set the HTTP Cookie header
|
||||
@@ -733,11 +716,12 @@ def __setHTTPCookies():
|
||||
if conf.cookie:
|
||||
debugMsg = "setting the HTTP Cookie header"
|
||||
logger.debug(debugMsg)
|
||||
|
||||
|
||||
conf.cookie = sanitizeCookie(conf.cookie, True)
|
||||
|
||||
conf.httpHeaders.append(("Connection", "Keep-Alive"))
|
||||
conf.httpHeaders.append(("Cookie", conf.cookie))
|
||||
|
||||
|
||||
def __setHTTPTimeout():
|
||||
"""
|
||||
Set the HTTP timeout
|
||||
@@ -760,7 +744,6 @@ def __setHTTPTimeout():
|
||||
|
||||
socket.setdefaulttimeout(conf.timeout)
|
||||
|
||||
|
||||
def __cleanupOptions():
|
||||
"""
|
||||
Cleanup configuration attributes.
|
||||
@@ -808,7 +791,6 @@ def __cleanupOptions():
|
||||
if conf.googleDork or conf.list:
|
||||
conf.multipleTargets = True
|
||||
|
||||
|
||||
def __setConfAttributes():
|
||||
"""
|
||||
This function set some needed attributes into the configuration
|
||||
@@ -843,7 +825,6 @@ def __setConfAttributes():
|
||||
conf.threadException = False
|
||||
conf.wFileType = None
|
||||
|
||||
|
||||
def __setKnowledgeBaseAttributes():
|
||||
"""
|
||||
This function set some needed attributes into the knowledge base
|
||||
@@ -862,7 +843,7 @@ def __setKnowledgeBaseAttributes():
|
||||
kb.dbmsDetected = False
|
||||
|
||||
# Active (extensive) back-end DBMS fingerprint
|
||||
kb.dbmsVersion = []
|
||||
kb.dbmsVersion = [ "Unknown" ]
|
||||
|
||||
kb.dep = None
|
||||
kb.docRoot = None
|
||||
@@ -888,7 +869,6 @@ def __setKnowledgeBaseAttributes():
|
||||
kb.unionCount = None
|
||||
kb.unionPosition = None
|
||||
|
||||
|
||||
def __saveCmdline():
|
||||
"""
|
||||
Saves the command line options on a sqlmap configuration INI file
|
||||
@@ -918,7 +898,7 @@ def __saveCmdline():
|
||||
optionData.sort()
|
||||
|
||||
for option, value, datatype in optionData:
|
||||
if value == None:
|
||||
if value is None:
|
||||
if datatype == "boolean":
|
||||
value = "False"
|
||||
elif datatype in ( "integer", "float" ):
|
||||
@@ -942,13 +922,12 @@ def __saveCmdline():
|
||||
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.
|
||||
"""
|
||||
|
||||
if conf.verbose == None:
|
||||
if conf.verbose is None:
|
||||
conf.verbose = 1
|
||||
|
||||
conf.verbose = int(conf.verbose)
|
||||
@@ -965,7 +944,6 @@ def __setVerbosity():
|
||||
elif conf.verbose >= 4:
|
||||
logger.setLevel(8)
|
||||
|
||||
|
||||
def __mergeOptions(inputOptions):
|
||||
"""
|
||||
Merge command line options with configuration file options.
|
||||
@@ -983,10 +961,9 @@ def __mergeOptions(inputOptions):
|
||||
inputOptionsItems = inputOptions.__dict__.items()
|
||||
|
||||
for key, value in inputOptionsItems:
|
||||
if not conf.has_key(key) or conf[key] == None or value != None:
|
||||
if not conf.has_key(key) or conf[key] is None or value is not None:
|
||||
conf[key] = value
|
||||
|
||||
|
||||
def init(inputOptions=advancedDict()):
|
||||
"""
|
||||
Set attributes into both configuration and knowledge base singletons
|
||||
|
||||
@@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
|
||||
|
||||
|
||||
optDict = {
|
||||
# Family: { "parameter_name": "parameter_datatype" },
|
||||
"Target": {
|
||||
@@ -36,6 +34,7 @@ optDict = {
|
||||
"method": "string",
|
||||
"data": "string",
|
||||
"cookie": "string",
|
||||
"dropSetCookie": "boolean",
|
||||
"referer": "string",
|
||||
"agent": "string",
|
||||
"userAgentsFile": "string",
|
||||
@@ -131,11 +130,12 @@ optDict = {
|
||||
},
|
||||
|
||||
"Miscellaneous": {
|
||||
"eta": "boolean",
|
||||
"verbose": "integer",
|
||||
"updateAll": "boolean",
|
||||
"sessionFile": "string",
|
||||
"eta": "boolean",
|
||||
"googlePage": "integer",
|
||||
"updateAll": "boolean",
|
||||
"batch": "boolean",
|
||||
"cleanup": "boolean"
|
||||
"cleanup": "boolean",
|
||||
"verbose": "integer"
|
||||
},
|
||||
}
|
||||
|
||||
@@ -22,11 +22,8 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
|
||||
|
||||
|
||||
from lib.core.common import dataToStdout
|
||||
|
||||
|
||||
class ProgressBar:
|
||||
"""
|
||||
This class defines methods to update and draw a progress bar
|
||||
@@ -42,7 +39,6 @@ class ProgressBar:
|
||||
self.__amount = 0
|
||||
self.update()
|
||||
|
||||
|
||||
def __convertSeconds(self, value):
|
||||
seconds = value
|
||||
minutes = seconds / 60
|
||||
@@ -50,7 +46,6 @@ class ProgressBar:
|
||||
|
||||
return "%.2d:%.2d" % (minutes, seconds)
|
||||
|
||||
|
||||
def update(self, newAmount=0):
|
||||
"""
|
||||
This method updates the progress bar
|
||||
@@ -87,7 +82,6 @@ class ProgressBar:
|
||||
percentString = str(percentDone) + "%"
|
||||
self.__progBar = "%s %s" % (percentString, self.__progBar)
|
||||
|
||||
|
||||
def draw(self, eta=0):
|
||||
"""
|
||||
This method draws the progress bar if it has changed
|
||||
@@ -102,7 +96,6 @@ class ProgressBar:
|
||||
blank = " " * (80 - len("\r%s %d/%d" % (self.__progBar, self.__amount, self.__max)))
|
||||
dataToStdout("\r%s %d/%d%s" % (self.__progBar, self.__amount, self.__max, blank))
|
||||
|
||||
|
||||
def __str__(self):
|
||||
"""
|
||||
This method returns the progress bar string
|
||||
|
||||
@@ -27,15 +27,12 @@ In addition to normal readline stuff, this module provides haveReadline
|
||||
boolean and _outputfile variable used in genutils.
|
||||
"""
|
||||
|
||||
|
||||
|
||||
import sys
|
||||
|
||||
from lib.core.data import logger
|
||||
from lib.core.settings import IS_WIN
|
||||
from lib.core.settings import PLATFORM
|
||||
|
||||
|
||||
try:
|
||||
from readline import *
|
||||
import readline as _rl
|
||||
@@ -50,7 +47,7 @@ except ImportError:
|
||||
except ImportError:
|
||||
haveReadline = False
|
||||
|
||||
if IS_WIN is True and haveReadline:
|
||||
if IS_WIN and haveReadline:
|
||||
try:
|
||||
_outputfile=_rl.GetOutputFile()
|
||||
except AttributeError:
|
||||
@@ -79,7 +76,6 @@ if PLATFORM == 'darwin' and haveReadline:
|
||||
|
||||
uses_libedit = True
|
||||
|
||||
|
||||
# the clear_history() function was only introduced in Python 2.4 and is
|
||||
# actually optional in the readline API, so we must explicitly check for its
|
||||
# existence. Some known platforms actually don't have it. This thread:
|
||||
|
||||
@@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
|
||||
|
||||
|
||||
import re
|
||||
|
||||
from lib.core.common import dataToSessionFile
|
||||
@@ -37,7 +35,6 @@ from lib.core.settings import MYSQL_ALIASES
|
||||
from lib.core.settings import PGSQL_ALIASES
|
||||
from lib.core.settings import ORACLE_ALIASES
|
||||
|
||||
|
||||
def setString():
|
||||
"""
|
||||
Save string to match in session file.
|
||||
@@ -51,7 +48,6 @@ def setString():
|
||||
if condition:
|
||||
dataToSessionFile("[%s][None][None][String][%s]\n" % (conf.url, conf.string))
|
||||
|
||||
|
||||
def setRegexp():
|
||||
"""
|
||||
Save regular expression to match in session file.
|
||||
@@ -65,7 +61,6 @@ def setRegexp():
|
||||
if condition:
|
||||
dataToSessionFile("[%s][None][None][Regular expression][%s]\n" % (conf.url, conf.regexp))
|
||||
|
||||
|
||||
def setMatchRatio():
|
||||
condition = (
|
||||
not kb.resumedQueries
|
||||
@@ -76,7 +71,6 @@ def setMatchRatio():
|
||||
if condition:
|
||||
dataToSessionFile("[%s][None][None][Match ratio][%s]\n" % (conf.url, conf.matchRatio))
|
||||
|
||||
|
||||
def setInjection():
|
||||
"""
|
||||
Save information retrieved about injection place and parameter in the
|
||||
@@ -100,7 +94,6 @@ def setInjection():
|
||||
dataToSessionFile("[%s][%s][%s][Injection parameter][%s]\n" % (conf.url, kb.injPlace, conf.parameters[kb.injPlace], kb.injParameter))
|
||||
dataToSessionFile("[%s][%s][%s][Injection type][%s]\n" % (conf.url, kb.injPlace, conf.parameters[kb.injPlace], kb.injType))
|
||||
|
||||
|
||||
def setParenthesis(parenthesisCount):
|
||||
"""
|
||||
@param parenthesisCount: number of parenthesis to be set into the
|
||||
@@ -118,7 +111,6 @@ def setParenthesis(parenthesisCount):
|
||||
|
||||
kb.parenthesis = parenthesisCount
|
||||
|
||||
|
||||
def setDbms(dbms):
|
||||
"""
|
||||
@param dbms: database management system to be set into the knowledge
|
||||
@@ -148,7 +140,6 @@ def setDbms(dbms):
|
||||
|
||||
logger.info("the back-end DBMS is %s" % kb.dbms)
|
||||
|
||||
|
||||
def setOs():
|
||||
"""
|
||||
Example of kb.bannerFp dictionary:
|
||||
@@ -196,7 +187,6 @@ def setOs():
|
||||
if condition:
|
||||
dataToSessionFile("[%s][%s][%s][OS][%s]\n" % (conf.url, kb.injPlace, conf.parameters[kb.injPlace], kb.os))
|
||||
|
||||
|
||||
def setStacked():
|
||||
condition = (
|
||||
not kb.resumedQueries or ( kb.resumedQueries.has_key(conf.url) and
|
||||
@@ -209,7 +199,6 @@ def setStacked():
|
||||
if condition:
|
||||
dataToSessionFile("[%s][%s][%s][Stacked queries][%s]\n" % (conf.url, kb.injPlace, conf.parameters[kb.injPlace], kb.stackedTest))
|
||||
|
||||
|
||||
def setUnion(comment=None, count=None, position=None):
|
||||
"""
|
||||
@param comment: union comment to save in session file
|
||||
@@ -249,7 +238,6 @@ def setUnion(comment=None, count=None, position=None):
|
||||
|
||||
kb.unionPosition = position
|
||||
|
||||
|
||||
def setRemoteTempPath():
|
||||
condition = (
|
||||
not kb.resumedQueries or ( kb.resumedQueries.has_key(conf.url) and
|
||||
@@ -259,7 +247,6 @@ def setRemoteTempPath():
|
||||
if condition:
|
||||
dataToSessionFile("[%s][%s][%s][Remote temp path][%s]\n" % (conf.url, kb.injPlace, conf.parameters[kb.injPlace], conf.tmpPath))
|
||||
|
||||
|
||||
def resumeConfKb(expression, url, value):
|
||||
if expression == "String" and url == conf.url:
|
||||
string = value[:-1]
|
||||
|
||||
@@ -22,15 +22,12 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
|
||||
|
||||
|
||||
import logging
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
# sqlmap version and site
|
||||
VERSION = "0.8-rc2"
|
||||
VERSION = "0.8-rc3"
|
||||
VERSION_STRING = "sqlmap/%s" % VERSION
|
||||
SITE = "http://sqlmap.sourceforge.net"
|
||||
|
||||
|
||||
@@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
|
||||
|
||||
|
||||
import atexit
|
||||
import os
|
||||
import rlcompleter
|
||||
@@ -33,19 +31,16 @@ from lib.core.data import kb
|
||||
from lib.core.data import paths
|
||||
from lib.core.data import queries
|
||||
|
||||
|
||||
def saveHistory():
|
||||
historyPath = os.path.expanduser(paths.SQLMAP_HISTORY)
|
||||
readline.write_history_file(historyPath)
|
||||
|
||||
|
||||
def loadHistory():
|
||||
historyPath = os.path.expanduser(paths.SQLMAP_HISTORY)
|
||||
|
||||
if os.path.exists(historyPath):
|
||||
readline.read_history_file(historyPath)
|
||||
|
||||
|
||||
def queriesForAutoCompletion():
|
||||
autoComplQueries = {}
|
||||
|
||||
@@ -61,7 +56,6 @@ def queriesForAutoCompletion():
|
||||
|
||||
return autoComplQueries
|
||||
|
||||
|
||||
class CompleterNG(rlcompleter.Completer):
|
||||
def global_matches(self, text):
|
||||
"""
|
||||
@@ -80,7 +74,6 @@ class CompleterNG(rlcompleter.Completer):
|
||||
|
||||
return matches
|
||||
|
||||
|
||||
def autoCompletion(sqlShell=False, osShell=False):
|
||||
# First of all we check if the readline is available, by default
|
||||
# it is not in Python default installation on Windows
|
||||
|
||||
@@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
|
||||
|
||||
|
||||
import errno
|
||||
import os
|
||||
import sys
|
||||
@@ -31,8 +29,7 @@ import time
|
||||
|
||||
from lib.core.settings import IS_WIN
|
||||
|
||||
|
||||
if IS_WIN is not True:
|
||||
if not IS_WIN:
|
||||
import fcntl
|
||||
|
||||
if (sys.hexversion >> 16) >= 0x202:
|
||||
@@ -40,7 +37,6 @@ if IS_WIN is not True:
|
||||
else:
|
||||
import FCNTL
|
||||
|
||||
|
||||
def blockingReadFromFD(fd):
|
||||
# Quick twist around original Twisted function
|
||||
# Blocking read from a non-blocking file descriptor
|
||||
@@ -62,8 +58,7 @@ def blockingReadFromFD(fd):
|
||||
if not output:
|
||||
raise EOFError, "fd %s has been closed." % fd
|
||||
|
||||
return output
|
||||
|
||||
return output
|
||||
|
||||
def blockingWriteToFD(fd, data):
|
||||
# Another quick twist
|
||||
@@ -82,7 +77,6 @@ def blockingWriteToFD(fd, data):
|
||||
|
||||
break
|
||||
|
||||
|
||||
def setNonBlocking(fd):
|
||||
"""
|
||||
Make a file descriptor non-blocking
|
||||
|
||||
@@ -22,15 +22,13 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
|
||||
|
||||
|
||||
import os
|
||||
import time
|
||||
|
||||
from lib.core.common import dataToSessionFile
|
||||
from lib.core.common import paramToDict
|
||||
from lib.core.common import parseTargetUrl
|
||||
from lib.core.convert import urldecode
|
||||
from lib.core.common import sanitizeCookie
|
||||
from lib.core.data import conf
|
||||
from lib.core.data import kb
|
||||
from lib.core.data import logger
|
||||
@@ -41,7 +39,6 @@ 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
|
||||
@@ -65,21 +62,20 @@ def __setRequestParams():
|
||||
raise sqlmapSyntaxException, errMsg
|
||||
|
||||
if conf.data:
|
||||
urlDecodedData = urldecode(conf.data).replace("%", "%%")
|
||||
conf.parameters["POST"] = urlDecodedData
|
||||
__paramDict = paramToDict("POST", urlDecodedData)
|
||||
conf.parameters["POST"] = conf.data
|
||||
__paramDict = paramToDict("POST", conf.data)
|
||||
|
||||
if __paramDict:
|
||||
conf.paramDict["POST"] = __paramDict
|
||||
__testableParameters = True
|
||||
|
||||
conf.method = "POST"
|
||||
|
||||
# Perform checks on Cookie parameters
|
||||
if conf.cookie:
|
||||
# TODO: sure about decoding the cookie?
|
||||
#urlDecodedCookie = urldecode(conf.cookie).replace("%", "%%")
|
||||
urlDecodedCookie = conf.cookie.replace("%", "%%")
|
||||
conf.parameters["Cookie"] = urlDecodedCookie
|
||||
__paramDict = paramToDict("Cookie", urlDecodedCookie)
|
||||
conf.cookie = sanitizeCookie(conf.cookie)
|
||||
conf.parameters["Cookie"] = conf.cookie
|
||||
__paramDict = paramToDict("Cookie", conf.cookie)
|
||||
|
||||
if __paramDict:
|
||||
conf.paramDict["Cookie"] = __paramDict
|
||||
@@ -89,7 +85,8 @@ def __setRequestParams():
|
||||
if conf.httpHeaders:
|
||||
for httpHeader, headerValue in conf.httpHeaders:
|
||||
if httpHeader == "User-Agent":
|
||||
conf.parameters["User-Agent"] = urldecode(headerValue).replace("%", "%%")
|
||||
# No need for url encoding/decoding the user agent
|
||||
conf.parameters["User-Agent"] = headerValue
|
||||
|
||||
condition = not conf.testParameter
|
||||
condition |= "User-Agent" in conf.testParameter
|
||||
@@ -111,7 +108,6 @@ def __setRequestParams():
|
||||
errMsg += "within the GET, POST and Cookie parameters"
|
||||
raise sqlmapGenericException, errMsg
|
||||
|
||||
|
||||
def __setOutputResume():
|
||||
"""
|
||||
Check and set the output text file and the resume functionality.
|
||||
@@ -167,7 +163,6 @@ def __setOutputResume():
|
||||
errMsg = "unable to write on the session file specified"
|
||||
raise sqlmapFilePathException, errMsg
|
||||
|
||||
|
||||
def __createFilesDir():
|
||||
"""
|
||||
Create the file directory.
|
||||
@@ -181,7 +176,6 @@ def __createFilesDir():
|
||||
if not os.path.isdir(conf.filePath):
|
||||
os.makedirs(conf.filePath, 0755)
|
||||
|
||||
|
||||
def __createDumpDir():
|
||||
"""
|
||||
Create the dump directory.
|
||||
@@ -195,7 +189,6 @@ def __createDumpDir():
|
||||
if not os.path.isdir(conf.dumpPath):
|
||||
os.makedirs(conf.dumpPath, 0755)
|
||||
|
||||
|
||||
def createTargetDirs():
|
||||
"""
|
||||
Create the output directory.
|
||||
@@ -214,7 +207,6 @@ def createTargetDirs():
|
||||
__createDumpDir()
|
||||
__createFilesDir()
|
||||
|
||||
|
||||
def initTargetEnv():
|
||||
"""
|
||||
Initialize target environment.
|
||||
|
||||
@@ -22,19 +22,14 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
|
||||
|
||||
|
||||
class Unescaper:
|
||||
def __init__(self):
|
||||
self.__unescaper = None
|
||||
|
||||
|
||||
def setUnescape(self, unescapeFunction):
|
||||
self.__unescaper = unescapeFunction
|
||||
|
||||
|
||||
def unescape(self, expression, quote=True):
|
||||
return self.__unescaper(expression, quote=quote)
|
||||
|
||||
|
||||
unescaper = Unescaper()
|
||||
|
||||
@@ -22,8 +22,6 @@ with sqlmap; if not, write to the Free Software Foundation, Inc., 51
|
||||
Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
"""
|
||||
|
||||
|
||||
|
||||
import difflib
|
||||
import os
|
||||
import re
|
||||
@@ -48,7 +46,6 @@ from lib.core.settings import SQLMAP_SOURCE_URL
|
||||
from lib.core.settings import VERSION
|
||||
from lib.request.connect import Connect as Request
|
||||
|
||||
|
||||
def __updateMSSQLXML():
|
||||
infoMsg = "updating Microsoft SQL Server XML versions file"
|
||||
logger.info(infoMsg)
|
||||
@@ -199,7 +196,6 @@ def __updateMSSQLXML():
|
||||
infoMsg += "last update"
|
||||
logger.info(infoMsg)
|
||||
|
||||
|
||||
def __createFile(pathname, data):
|
||||
mkpath(os.path.dirname(pathname))
|
||||
|
||||
@@ -207,7 +203,6 @@ def __createFile(pathname, data):
|
||||
fileFP.write(data)
|
||||
fileFP.close()
|
||||
|
||||
|
||||
def __extractZipFile(tempDir, zipFile):
|
||||
# Check if the saved binary file is really a ZIP file
|
||||
if zipfile.is_zipfile(zipFile):
|
||||
@@ -221,7 +216,6 @@ def __extractZipFile(tempDir, zipFile):
|
||||
data = sqlmapZipFile.read(info.filename)
|
||||
__createFile(os.path.join(tempDir, info.filename), data)
|
||||
|
||||
|
||||
def __updateSqlmap():
|
||||
infoMsg = "updating sqlmap"
|
||||
logger.info(infoMsg)
|
||||
@@ -292,8 +286,6 @@ def __updateSqlmap():
|
||||
|
||||
# For each file and directory in the temporary directory copy it
|
||||
# to the sqlmap root path and set right permission
|
||||
# TODO: remove files not needed anymore and all pyc within the
|
||||
# sqlmap root path in the end
|
||||
for root, _, files in os.walk(os.path.join(tempDir, "sqlmap-%s" % sqlmapNewestVersion)):
|
||||
# Just for development release
|
||||
if '.svn' in root:
|
||||
@@ -334,7 +326,6 @@ def __updateSqlmap():
|
||||
infoMsg = "sqlmap updated successfully"
|
||||
logger.info(infoMsg)
|
||||
|
||||
|
||||
def update():
|
||||
if not conf.updateAll:
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user