periodical commit

This commit is contained in:
Miroslav Stampar 2010-05-21 09:35:36 +00:00
parent 9c1d82c9f7
commit 68e13c3872
6 changed files with 113 additions and 7 deletions

View File

@ -1086,6 +1086,40 @@ def isBase64EncodedString(subject):
def isHexEncodedString(subject): def isHexEncodedString(subject):
return re.match(r"\A[0-9a-fA-F]+\Z", subject) is not None return re.match(r"\A[0-9a-fA-F]+\Z", subject) is not None
def profile(profileOutputFile='sqlmap.profile', imageOutputFile='profile.png'):
import cProfile
cProfile.run("start()", profileOutputFile)
graphScript = 'gprof2dot.py'
graphScriptRepositoryUrl = 'http://gprof2dot.jrfonseca.googlecode.com/hg/'
graphScriptPath = os.path.join(paths.SQLMAP_ROOT_PATH, graphScript)
if not os.path.exists(graphScriptPath):
errMsg = "unable to find Jose Fonseca's '%s' graph " % graphScript
errMsg += "conversion script. please download it from "
errMsg += "official repository at '%s' " % graphScriptRepositoryUrl
errMsg += "and put it inside sqlmap's root directory ('%s')." % paths.SQLMAP_ROOT_PATH
logger.error(errMsg)
return
infoMsg = "converting profile data to an image."
logger.info(infoMsg)
if os.path.exists(imageOutputFile):
os.remove(imageOutputFile)
msg = subprocess.Popen('python %s -f pstats %s | dot -Tpng -o %s' % (graphScriptPath, profileOutputFile, imageOutputFile), shell=True, stderr=subprocess.PIPE).stderr.read()
if msg:
errMsg = "there was an error while converting ('%s')." % msg.strip()
logger.error(errMsg)
else:
if os.name == 'mac':
subprocess.call(('open', imageOutputFile))
elif os.name == 'posix':
subprocess.call(('xdg-open', imageOutputFile))
elif os.name == 'nt':
subprocess.call(('start', imageOutputFile))
def getConsoleWidth(default=80): def getConsoleWidth(default=80):
width = None width = None
@ -1118,3 +1152,51 @@ def parseXmlFile(xmlFile, handler):
def calculateDeltaSeconds(start, epsilon=0.05): def calculateDeltaSeconds(start, epsilon=0.05):
return int(time.time() - start + epsilon) return int(time.time() - start + epsilon)
def getCommonPredictionTables(value, originalTable):
if not kb.commonTables:
kb.commonTables = {}
fileName = os.path.join(paths.SQLMAP_TXT_PATH, 'common-tables.txt')
file = open(fileName, 'r')
key = None
for line in file.xreadlines():
line = line.strip()
if len(line) > 1:
if line[0] == '[' and line[-1] == ']':
key = line[1:-1]
elif key:
if key not in kb.commonTables:
kb.commonTables[key] = []
kb.commonTables[key].append(line.strip())
predictionSet = set()
wildIndexes = []
kb.dbms = 'MySQL'
if value[-1] != '.':
value += '.'
charIndex = 0
findIndex = value.find('.', charIndex)
while findIndex != -1:
wildIndexes.append(findIndex)
charIndex += 1
findIndex = value.find('.', charIndex)
if kb.dbms in kb.commonTables:
for item in kb.commonTables[kb.dbms]:
if re.search('\A%s' % value, item):
for index in wildIndexes:
char = item[index]
if char not in predictionSet:
predictionSet.add(char)
predictionTable = []
otherTable = []
for ordChar in originalTable:
if chr(ordChar) not in predictionSet:
otherTable.append(ordChar)
else:
predictionTable.append(ordChar)
predictionTable.sort()
return predictionTable, otherTable
else:
return None, originalTable

View File

@ -882,7 +882,6 @@ def __setConfAttributes():
debugMsg = "initializing the configuration" debugMsg = "initializing the configuration"
logger.debug(debugMsg) logger.debug(debugMsg)
conf.cpuThrottleDelay = 0.001
conf.cj = None conf.cj = None
conf.dbmsConnector = None conf.dbmsConnector = None
conf.dbmsHandler = None conf.dbmsHandler = None
@ -929,6 +928,7 @@ def __setKnowledgeBaseAttributes():
kb.absFilePaths = set() kb.absFilePaths = set()
kb.bannerFp = advancedDict() kb.bannerFp = advancedDict()
kb.data = advancedDict() kb.data = advancedDict()
kb.commonTables = None
# Basic back-end DBMS fingerprint # Basic back-end DBMS fingerprint
kb.dbms = None kb.dbms = None

View File

@ -27,6 +27,7 @@ import sys
from optparse import OptionError from optparse import OptionError
from optparse import OptionGroup from optparse import OptionGroup
from optparse import OptionParser from optparse import OptionParser
from optparse import SUPPRESS_HELP
from lib.core.data import logger from lib.core.data import logger
from lib.core.settings import VERSION_STRING from lib.core.settings import VERSION_STRING
@ -415,10 +416,10 @@ def cmdLineParser():
miscellaneous.add_option("-s", dest="sessionFile", miscellaneous.add_option("-s", dest="sessionFile",
help="Save and resume all data retrieved " help="Save and resume all data retrieved "
"on a session file") "on a session file")
miscellaneous.add_option("--flush-session", dest="flushSession", action="store_true", miscellaneous.add_option("--flush-session", dest="flushSession", action="store_true",
help="Flush session file for current target") help="Flush session file for current target")
miscellaneous.add_option("--eta", dest="eta", action="store_true", miscellaneous.add_option("--eta", dest="eta", action="store_true",
help="Display for each output the " help="Display for each output the "
"estimated time of arrival") "estimated time of arrival")
@ -439,6 +440,16 @@ def cmdLineParser():
help="Clean up the DBMS by sqlmap specific " help="Clean up the DBMS by sqlmap specific "
"UDF and tables") "UDF and tables")
# Hidden and/or experimental options
parser.add_option("--profile", dest="profile", action="store_true",
help=SUPPRESS_HELP)
parser.add_option("--cpu-throttle", dest="cpuThrottle", type="int", default=10,
help=SUPPRESS_HELP)
parser.add_option("--common-prediction", dest="useCommonPrediction", action="store_true",
help=SUPPRESS_HELP)
parser.add_option_group(target) parser.add_option_group(target)
parser.add_option_group(request) parser.add_option_group(request)
parser.add_option_group(injection) parser.add_option_group(injection)

View File

@ -260,7 +260,10 @@ class Connect:
logger.log(8, responseMsg) logger.log(8, responseMsg)
time.sleep(conf.cpuThrottleDelay) if conf.cpuThrottle:
minThrottleDelay, maxThrottleDelay = 0.0001, 0.1
delay = minThrottleDelay + (maxThrottleDelay-minThrottleDelay) * conf.cpuThrottle
time.sleep(delay)
return page, responseHeaders return page, responseHeaders

View File

@ -340,7 +340,14 @@ def bisection(payload, expression, length=None, charsetType=None, firstChar=None
while True: while True:
index += 1 index += 1
charStart = time.time() charStart = time.time()
val = getChar(index, asciiTbl)
if conf.useCommonPrediction:
commonTbl, otherTbl = getCommonPredictionTables(finalValue, asciiTbl)
val = getChar(index, commonTbl) if commonTbl else None
if not val:
val = getChar(index, otherTbl)
else:
val = getChar(index, asciiTbl)
if val is None or ( lastChar > 0 and index > lastChar ): if val is None or ( lastChar > 0 and index > lastChar ):
break break

View File

@ -39,6 +39,7 @@ except ImportError, _:
from lib.controller.controller import start from lib.controller.controller import start
from lib.core.common import banner from lib.core.common import banner
from lib.core.common import profile
from lib.core.common import setPaths from lib.core.common import setPaths
from lib.core.common import weAreFrozen from lib.core.common import weAreFrozen
from lib.core.data import conf from lib.core.data import conf
@ -75,8 +76,10 @@ def main():
try: try:
init(cmdLineOptions) init(cmdLineOptions)
start() if not conf.profile:
start()
else:
profile()
except exceptionsTuple, e: except exceptionsTuple, e:
e = str(e) e = str(e)
logger.error(e) logger.error(e)