From c517e97a447db12a0dd41923f785765506ea3e97 Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Fri, 8 Jul 2011 06:02:31 +0000 Subject: [PATCH] few fixes and minor cosmetics --- lib/controller/checks.py | 8 ++++---- lib/core/agent.py | 2 +- lib/core/common.py | 4 +--- lib/core/data.py | 10 +++++----- lib/core/datatype.py | 26 ++++++++++++++++++++------ lib/core/defaults.py | 4 ++-- lib/core/option.py | 22 +++++++++++----------- lib/core/session.py | 2 +- lib/core/threads.py | 4 ++-- lib/core/unescaper.py | 4 ++-- lib/parse/payloads.py | 8 ++++---- plugins/generic/enumeration.py | 14 +++----------- xml/queries.xml | 5 +++-- 13 files changed, 59 insertions(+), 54 deletions(-) diff --git a/lib/controller/checks.py b/lib/controller/checks.py index d86ece261..696a6c146 100644 --- a/lib/controller/checks.py +++ b/lib/controller/checks.py @@ -41,8 +41,8 @@ from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger from lib.core.data import paths -from lib.core.datatype import advancedDict -from lib.core.datatype import injectionDict +from lib.core.datatype import AttribDict +from lib.core.datatype import InjectionDict from lib.core.enums import HTTPHEADER from lib.core.enums import HTTPMETHOD from lib.core.enums import NULLCONNECTION @@ -68,7 +68,7 @@ from lib.techniques.union.use import configUnion def checkSqlInjection(place, parameter, value): # Store here the details about boundaries and payload used to # successfully inject - injection = injectionDict() + injection = InjectionDict() # Localized thread data needed for some methods threadData = getCurrentThreadData() @@ -452,7 +452,7 @@ def checkSqlInjection(place, parameter, value): if vector is None and "vector" in test and test.vector is not None: vector = "%s%s" % (test.vector, comment) - injection.data[stype] = advancedDict() + injection.data[stype] = AttribDict() injection.data[stype].title = title injection.data[stype].payload = agent.removePayloadDelimiters(reqPayload) injection.data[stype].where = where diff --git a/lib/core/agent.py b/lib/core/agent.py index c77efb313..e9f92eb5c 100644 --- a/lib/core/agent.py +++ b/lib/core/agent.py @@ -21,7 +21,7 @@ from lib.core.convert import urlencode from lib.core.data import conf from lib.core.data import kb from lib.core.data import queries -from lib.core.datatype import advancedDict +from lib.core.datatype import AttribDict from lib.core.enums import DBMS from lib.core.enums import PAYLOAD from lib.core.enums import PLACE diff --git a/lib/core/common.py b/lib/core/common.py index 6b67afb18..d4f12183f 100644 --- a/lib/core/common.py +++ b/lib/core/common.py @@ -1925,9 +1925,7 @@ def pushValue(value): Push value to the stack (thread dependent) """ - # TODO: quick fix - #getCurrentThreadData().valueStack.append(copy.deepcopy(value)) - getCurrentThreadData().valueStack.append(value) + getCurrentThreadData().valueStack.append(copy.deepcopy(value)) def popValue(): """ diff --git a/lib/core/data.py b/lib/core/data.py index 53b5635bb..cf9523711 100644 --- a/lib/core/data.py +++ b/lib/core/data.py @@ -7,21 +7,21 @@ Copyright (c) 2006-2011 sqlmap developers (http://www.sqlmap.org/) See the file 'doc/COPYING' for copying permission """ -from lib.core.datatype import advancedDict +from lib.core.datatype import AttribDict from lib.core.settings import LOGGER # sqlmap paths -paths = advancedDict() +paths = AttribDict() # object to store original command line options -cmdLineOptions = advancedDict() +cmdLineOptions = AttribDict() # object to share within function and classes command # line options and settings -conf = advancedDict() +conf = AttribDict() # object to share within function and classes results -kb = advancedDict() +kb = AttribDict() # object with each database management system specific queries queries = {} diff --git a/lib/core/datatype.py b/lib/core/datatype.py index 33402a394..37c681b2f 100644 --- a/lib/core/datatype.py +++ b/lib/core/datatype.py @@ -7,9 +7,12 @@ Copyright (c) 2006-2011 sqlmap developers (http://www.sqlmap.org/) See the file 'doc/COPYING' for copying permission """ +import copy +import types + from lib.core.exception import sqlmapDataException -class advancedDict(dict): +class AttribDict(dict): """ This class defines the sqlmap object, inheriting from Python data type dictionary. @@ -46,7 +49,7 @@ class advancedDict(dict): """ # This test allows attributes to be set in the __init__ method - if not self.__dict__.has_key('_advancedDict__initialised'): + if not self.__dict__.has_key('_AttribDict__initialised'): return dict.__setattr__(self, item, value) # Any normal attributes are handled normally @@ -62,9 +65,20 @@ class advancedDict(dict): def __setstate__(self, dict): self.__dict__ = dict -class injectionDict(advancedDict): + def __deepcopy__(self, memo): + retVal = self.__class__() + memo[id(self)] = retVal + for attr in dir(self): + if not attr.startswith('_'): + value = getattr(self, attr) + if not isinstance(value, (types.BuiltinFunctionType, types.BuiltinFunctionType, types.FunctionType, types.MethodType)): + setattr(retVal, attr, copy.deepcopy(value, memo)) + + return retVal + +class InjectionDict(AttribDict): def __init__(self): - advancedDict.__init__(self) + AttribDict.__init__(self) self.place = None self.parameter = None @@ -75,11 +89,11 @@ class injectionDict(advancedDict): # data is a dict with various stype, each which is a dict with # all the information specific for that stype - self.data = advancedDict() + self.data = AttribDict() # conf is a dict which stores current snapshot of important # options used during detection - self.conf = advancedDict() + self.conf = AttribDict() self.dbms = None self.dbms_version = None diff --git a/lib/core/defaults.py b/lib/core/defaults.py index 4e4617578..fd64ee4da 100644 --- a/lib/core/defaults.py +++ b/lib/core/defaults.py @@ -7,7 +7,7 @@ Copyright (c) 2006-2011 sqlmap developers (http://www.sqlmap.org/) See the file 'doc/COPYING' for copying permission """ -from lib.core.datatype import advancedDict +from lib.core.datatype import AttribDict _defaults = { "timeSec": 5, @@ -25,4 +25,4 @@ _defaults = { "tech": "BEUST" } -defaults = advancedDict(_defaults) +defaults = AttribDict(_defaults) diff --git a/lib/core/option.py b/lib/core/option.py index 745335f7a..96c4f5d68 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -55,8 +55,8 @@ 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.datatype import advancedDict -from lib.core.datatype import injectionDict +from lib.core.datatype import AttribDict +from lib.core.datatype import InjectionDict from lib.core.defaults import defaults from lib.core.enums import DBMS from lib.core.enums import HTTPHEADER @@ -963,7 +963,7 @@ def __setPrefixSuffix(): if conf.prefix is not None and conf.suffix is not None: # Create a custom boundary object for user's supplied prefix # and suffix - boundary = advancedDict() + boundary = AttribDict() boundary.level = 1 boundary.clause = [ 0 ] @@ -1381,18 +1381,18 @@ def __setKnowledgeBaseAttributes(flushAll=True): kb.alwaysRefresh = None kb.arch = None kb.authHeader = None - kb.bannerFp = advancedDict() + kb.bannerFp = AttribDict() - kb.brute = advancedDict({'tables':[], 'columns':[]}) + kb.brute = AttribDict({'tables':[], 'columns':[]}) kb.bruteMode = False - kb.cache = advancedDict() + kb.cache = AttribDict() kb.cache.content = {} kb.cache.regex = {} kb.cache.stdev = {} kb.commonOutputs = None - kb.data = advancedDict() + kb.data = AttribDict() kb.dataOutputFlag = False # Active back-end DBMS fingerprint @@ -1415,10 +1415,10 @@ def __setKnowledgeBaseAttributes(flushAll=True): kb.hintValue = None kb.htmlFp = [] kb.ignoreTimeout = False - kb.injection = injectionDict() + kb.injection = InjectionDict() kb.injections = [] - kb.locks = advancedDict() + kb.locks = AttribDict() kb.locks.cacheLock = threading.Lock() kb.locks.logLock = threading.Lock() kb.locks.ioLock = threading.Lock() @@ -1459,7 +1459,7 @@ def __setKnowledgeBaseAttributes(flushAll=True): kb.uChar = "NULL" kb.xpCmdshellAvailable = False - kb.misc = advancedDict() + kb.misc = AttribDict() kb.misc.delimiter = randomStr(length=6, lowercase=True) kb.misc.start = ":%s:" % randomStr(length=3, lowercase=True) kb.misc.stop = ":%s:" % randomStr(length=3, lowercase=True) @@ -1795,7 +1795,7 @@ def __resolveCrossReferences(): lib.core.threads.readInput = readInput lib.core.common.getPageTemplate = getPageTemplate -def init(inputOptions=advancedDict(), overrideOptions=False): +def init(inputOptions=AttribDict(), overrideOptions=False): """ Set attributes into both configuration and knowledge base singletons based upon command line and configuration file options. diff --git a/lib/core/session.py b/lib/core/session.py index 335d86a9e..3d6f00ebf 100644 --- a/lib/core/session.py +++ b/lib/core/session.py @@ -20,7 +20,7 @@ from lib.core.convert import base64unpickle from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger -from lib.core.datatype import injectionDict +from lib.core.datatype import InjectionDict from lib.core.enums import DBMS from lib.core.enums import OS from lib.core.enums import PAYLOAD diff --git a/lib/core/threads.py b/lib/core/threads.py index 1d45bc373..a00ad4a20 100644 --- a/lib/core/threads.py +++ b/lib/core/threads.py @@ -15,7 +15,7 @@ from thread import error as threadError from lib.core.data import kb from lib.core.data import logger -from lib.core.datatype import advancedDict +from lib.core.datatype import AttribDict from lib.core.enums import PAYLOAD from lib.core.exception import sqlmapConnectionException from lib.core.exception import sqlmapThreadException @@ -23,7 +23,7 @@ from lib.core.exception import sqlmapValueException from lib.core.settings import MAX_NUMBER_OF_THREADS from lib.core.settings import PYVERSION -shared = advancedDict() +shared = AttribDict() class _ThreadData(threading.local): """ diff --git a/lib/core/unescaper.py b/lib/core/unescaper.py index ba5227f94..a9ad6b3f1 100644 --- a/lib/core/unescaper.py +++ b/lib/core/unescaper.py @@ -8,10 +8,10 @@ See the file 'doc/COPYING' for copying permission """ from lib.core.common import Backend -from lib.core.datatype import advancedDict +from lib.core.datatype import AttribDict from lib.core.settings import EXCLUDE_UNESCAPE -class Unescaper(advancedDict): +class Unescaper(AttribDict): def unescape(self, expression, quote=True, dbms=None): if expression is None: return expression diff --git a/lib/parse/payloads.py b/lib/parse/payloads.py index c54e74361..b26244139 100644 --- a/lib/parse/payloads.py +++ b/lib/parse/payloads.py @@ -11,7 +11,7 @@ from xml.etree import ElementTree as et from lib.core.data import conf from lib.core.data import paths -from lib.core.datatype import advancedDict +from lib.core.datatype import AttribDict def cleanupVals(text, tag): if tag in ("clause", "where"): @@ -42,7 +42,7 @@ def cleanupVals(text, tag): def parseXmlNode(node): for element in node.getiterator('boundary'): - boundary = advancedDict() + boundary = AttribDict() for child in element.getchildren(): if child.text: @@ -54,7 +54,7 @@ def parseXmlNode(node): conf.boundaries.append(boundary) for element in node.getiterator('test'): - test = advancedDict() + test = AttribDict() for child in element.getchildren(): if child.text and child.text.strip(): @@ -65,7 +65,7 @@ def parseXmlNode(node): test[child.tag] = None continue else: - test[child.tag] = advancedDict() + test[child.tag] = AttribDict() for gchild in child.getchildren(): if gchild.tag in test[child.tag]: diff --git a/plugins/generic/enumeration.py b/plugins/generic/enumeration.py index 9c19bc424..3b21bcb47 100644 --- a/plugins/generic/enumeration.py +++ b/plugins/generic/enumeration.py @@ -881,19 +881,11 @@ class Enumeration: query = safeStringFormat(query, conf.db) value = inject.getValue(query, blind=False) - value = filter(lambda x: x, value) + value = arrayizeValue(filter(lambda x: x, value)) if not isNoneValue(value): - if Backend.isDbms(DBMS.SQLITE): - if isinstance(value, basestring): - value = [[ DBMS.SQLITE, value ]] - elif isinstance(value, (list, tuple, set)): - newValue = [] - - for v in value: - newValue.append([ DBMS.SQLITE, v]) - - value = newValue + if len(value) > 0 and not isinstance(value[0], (list, tuple)): + value = zip([conf.db for i in xrange(len(value))], value) for db, table in value: db = safeSQLIdentificatorNaming(db) diff --git a/xml/queries.xml b/xml/queries.xml index eaeb00438..3af8e9dff 100644 --- a/xml/queries.xml +++ b/xml/queries.xml @@ -48,7 +48,7 @@ - + @@ -366,6 +366,7 @@ + @@ -465,7 +466,7 @@ - +