From 4147f44e6359ac0ecd42a4aea79a4016d5617eee Mon Sep 17 00:00:00 2001 From: Miroslav Stampar Date: Sun, 1 Apr 2018 12:45:47 +0200 Subject: [PATCH] Potential patch for Issues like #3013 and #3017 --- lib/controller/checks.py | 8 ++++++++ lib/controller/controller.py | 2 ++ lib/core/decorators.py | 17 +++++++++++++++++ lib/core/settings.py | 2 +- lib/request/connect.py | 2 ++ lib/request/inject.py | 2 ++ lib/takeover/xp_cmdshell.py | 2 ++ lib/techniques/union/test.py | 2 ++ lib/utils/search.py | 2 ++ plugins/dbms/mysql/filesystem.py | 2 ++ plugins/generic/databases.py | 2 ++ txt/checksum.md5 | 22 +++++++++++----------- 12 files changed, 53 insertions(+), 12 deletions(-) diff --git a/lib/controller/checks.py b/lib/controller/checks.py index a66540995..2de2bca42 100644 --- a/lib/controller/checks.py +++ b/lib/controller/checks.py @@ -54,6 +54,7 @@ from lib.core.data import logger from lib.core.datatype import AttribDict from lib.core.datatype import InjectionDict from lib.core.decorators import cachedmethod +from lib.core.decorators import stackedmethod from lib.core.dicts import FROM_DUMMY_TABLE from lib.core.enums import DBMS from lib.core.enums import HASHDB_KEYS @@ -832,6 +833,7 @@ def checkSqlInjection(place, parameter, value): return injection +@stackedmethod def heuristicCheckDbms(injection): """ This functions is called when boolean-based blind is identified with a @@ -868,6 +870,7 @@ def heuristicCheckDbms(injection): return retVal +@stackedmethod def checkFalsePositives(injection): """ Checks for false positives (only in single special cases) @@ -929,6 +932,7 @@ def checkFalsePositives(injection): return retVal +@stackedmethod def checkSuhosinPatch(injection): """ Checks for existence of Suhosin-patch (and alike) protection mechanism(s) @@ -952,6 +956,7 @@ def checkSuhosinPatch(injection): kb.injection = popValue() +@stackedmethod def checkFilteredChars(injection): debugMsg = "checking for filtered characters" logger.debug(debugMsg) @@ -1314,6 +1319,7 @@ def checkRegexp(): return True +@stackedmethod def checkWaf(): """ Reference: http://seclists.org/nmap-dev/2011/q2/att-1005/http-waf-detect.nse @@ -1379,6 +1385,7 @@ def checkWaf(): return retVal +@stackedmethod def identifyWaf(): if not conf.identifyWaf: return None @@ -1463,6 +1470,7 @@ def identifyWaf(): return retVal +@stackedmethod def checkNullConnection(): """ Reference: http://www.wisec.it/sectou.php?id=472f952d79293 diff --git a/lib/controller/controller.py b/lib/controller/controller.py index 9c3239d03..ad12620c7 100644 --- a/lib/controller/controller.py +++ b/lib/controller/controller.py @@ -43,6 +43,7 @@ from lib.core.common import urldecode from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger +from lib.core.decorators import stackedmethod from lib.core.enums import CONTENT_TYPE from lib.core.enums import HASHDB_KEYS from lib.core.enums import HEURISTIC_TEST @@ -253,6 +254,7 @@ def _saveToResultsFile(): conf.resultsFP.flush() +@stackedmethod def start(): """ This function calls a function that performs checks on both URL diff --git a/lib/core/decorators.py b/lib/core/decorators.py index c4040f267..94d0925c1 100644 --- a/lib/core/decorators.py +++ b/lib/core/decorators.py @@ -7,6 +7,8 @@ See the file 'LICENSE' for copying permission import hashlib +from lib.core.threads import getCurrentThreadData + def cachedmethod(f, cache={}): """ Method with a cached content @@ -22,3 +24,18 @@ def cachedmethod(f, cache={}): return cache[key] return _ + +def stackedmethod(f): + def _(*args, **kwargs): + threadData = getCurrentThreadData() + originalLevel = len(threadData.valueStack) + + try: + result = f(*args, **kwargs) + finally: + if len(threadData.valueStack) > originalLevel: + threadData.valueStack = threadData.valueStack[:originalLevel] + + return result + + return _ \ No newline at end of file diff --git a/lib/core/settings.py b/lib/core/settings.py index b238cf13e..2ded39583 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -19,7 +19,7 @@ from lib.core.enums import DBMS_DIRECTORY_NAME from lib.core.enums import OS # sqlmap version (...) -VERSION = "1.2.4.0" +VERSION = "1.2.4.1" TYPE = "dev" if VERSION.count('.') > 2 and VERSION.split('.')[-1] != '0' else "stable" TYPE_COLORS = {"dev": 33, "stable": 90, "pip": 34} VERSION_STRING = "sqlmap/%s#%s" % ('.'.join(VERSION.split('.')[:-1]) if VERSION.count('.') > 2 and VERSION.split('.')[-1] == '0' else VERSION, TYPE) diff --git a/lib/request/connect.py b/lib/request/connect.py index dc2714bf2..0c130916a 100644 --- a/lib/request/connect.py +++ b/lib/request/connect.py @@ -63,6 +63,7 @@ from lib.core.common import urlencode from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger +from lib.core.decorators import stackedmethod from lib.core.dicts import POST_HINT_CONTENT_TYPES from lib.core.enums import ADJUST_TIME_DELAY from lib.core.enums import AUTH_TYPE @@ -768,6 +769,7 @@ class Connect(object): return page, responseHeaders, code @staticmethod + @stackedmethod def queryPage(value=None, place=None, content=False, getRatioValue=False, silent=False, method=None, timeBasedCompare=False, noteResponseTime=True, auxHeaders=None, response=False, raise404=None, removeReflection=True): """ This method calls a function to get the target URL page content diff --git a/lib/request/inject.py b/lib/request/inject.py index 35b0ad910..cfe69a6ba 100644 --- a/lib/request/inject.py +++ b/lib/request/inject.py @@ -33,6 +33,7 @@ from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger from lib.core.data import queries +from lib.core.decorators import stackedmethod from lib.core.dicts import FROM_DUMMY_TABLE from lib.core.enums import CHARSET_TYPE from lib.core.enums import DBMS @@ -333,6 +334,7 @@ def _goUnion(expression, unpack=True, dump=False): return output +@stackedmethod def getValue(expression, blind=True, union=True, error=True, time=True, fromUser=False, expected=None, batch=False, unpack=True, resumeValue=True, charsetType=None, firstChar=None, lastChar=None, dump=False, suppressOutput=None, expectingNone=False, safeCharEncode=True): """ Called each time sqlmap inject a SQL query on the SQL injection diff --git a/lib/takeover/xp_cmdshell.py b/lib/takeover/xp_cmdshell.py index bb99a7dc7..19b06d8e8 100644 --- a/lib/takeover/xp_cmdshell.py +++ b/lib/takeover/xp_cmdshell.py @@ -24,6 +24,7 @@ from lib.core.convert import hexencode from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger +from lib.core.decorators import stackedmethod from lib.core.enums import CHARSET_TYPE from lib.core.enums import DBMS from lib.core.enums import EXPECTED @@ -96,6 +97,7 @@ class XP_cmdshell: return wasLastResponseDelayed() + @stackedmethod def _xpCmdshellTest(self): threadData = getCurrentThreadData() pushValue(threadData.disableStdOut) diff --git a/lib/techniques/union/test.py b/lib/techniques/union/test.py index 0e692bbbc..7a63bc37f 100644 --- a/lib/techniques/union/test.py +++ b/lib/techniques/union/test.py @@ -27,6 +27,7 @@ from lib.core.common import wasLastResponseDBMSError from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger +from lib.core.decorators import stackedmethod from lib.core.dicts import FROM_DUMMY_TABLE from lib.core.enums import PAYLOAD from lib.core.settings import LIMITED_ROWS_TEST_NUMBER @@ -48,6 +49,7 @@ def _findUnionCharCount(comment, place, parameter, value, prefix, suffix, where= """ retVal = None + @stackedmethod def _orderByTechnique(lowerCount, upperCount): def _orderByTest(cols): query = agent.prefixQuery("ORDER BY %d" % cols, prefix=prefix) diff --git a/lib/utils/search.py b/lib/utils/search.py index 0d6e770b7..8c49b534e 100644 --- a/lib/utils/search.py +++ b/lib/utils/search.py @@ -20,6 +20,7 @@ from lib.core.common import urlencode from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger +from lib.core.decorators import stackedmethod from lib.core.enums import CUSTOM_LOGGING from lib.core.enums import HTTP_HEADER from lib.core.enums import REDIRECTION @@ -165,6 +166,7 @@ def _search(dork): return retVal +@stackedmethod def search(dork): pushValue(kb.redirectChoice) kb.redirectChoice = REDIRECTION.YES diff --git a/plugins/dbms/mysql/filesystem.py b/plugins/dbms/mysql/filesystem.py index d28d12312..1181d3a86 100644 --- a/plugins/dbms/mysql/filesystem.py +++ b/plugins/dbms/mysql/filesystem.py @@ -14,6 +14,7 @@ from lib.core.common import singleTimeWarnMessage from lib.core.data import conf from lib.core.data import kb from lib.core.data import logger +from lib.core.decorators import stackedmethod from lib.core.enums import CHARSET_TYPE from lib.core.enums import EXPECTED from lib.core.enums import PAYLOAD @@ -81,6 +82,7 @@ class Filesystem(GenericFilesystem): return result + @stackedmethod def unionWriteFile(self, wFile, dFile, fileType, forceCheck=False): logger.debug("encoding file to its hexadecimal string value") diff --git a/plugins/generic/databases.py b/plugins/generic/databases.py index 75a9c704c..b17ff722a 100644 --- a/plugins/generic/databases.py +++ b/plugins/generic/databases.py @@ -32,6 +32,7 @@ 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.decorators import stackedmethod from lib.core.dicts import FIREBIRD_TYPES from lib.core.dicts import INFORMIX_TYPES from lib.core.enums import CHARSET_TYPE @@ -806,6 +807,7 @@ class Databases: return kb.data.cachedColumns + @stackedmethod def getSchema(self): infoMsg = "enumerating database management system schema" logger.info(infoMsg) diff --git a/txt/checksum.md5 b/txt/checksum.md5 index 27fe9b461..c4011e714 100644 --- a/txt/checksum.md5 +++ b/txt/checksum.md5 @@ -21,8 +21,8 @@ c88d66597f4aab719bde4542b0a1a6e0 extra/shutils/regressiontest.py 1e5532ede194ac9c083891c2f02bca93 extra/sqlharvest/__init__.py b3e60ea4e18a65c48515d04aab28ff68 extra/sqlharvest/sqlharvest.py 0f581182871148b0456a691ae85b04c0 lib/controller/action.py -8901cbab8f3885c554fe9ac43a1e5f14 lib/controller/checks.py -33689bb1b064d4eebc216934795a595f lib/controller/controller.py +84c8694d4ecacd843b6d745f032ff41f lib/controller/checks.py +c414cecdb0472c92cf50ed5b01e4438c lib/controller/controller.py c7443613a0a2505b1faec931cee2a6ef lib/controller/handler.py 1e5532ede194ac9c083891c2f02bca93 lib/controller/__init__.py b1990c7805943f0c973a853bba981d96 lib/core/agent.py @@ -31,7 +31,7 @@ fd8f239e259afaf5f24bcf34a0ad187f lib/core/bigarray.py 0d082da16c388b3445e656e0760fb582 lib/core/convert.py 9f87391b6a3395f7f50830b391264f27 lib/core/data.py 72016ea5c994a711a262fd64572a0fcd lib/core/datatype.py -12e80071013606f01822c3823fb51054 lib/core/decorators.py +04638422b6ad1613238a9abf4fdf6491 lib/core/decorators.py fbb55cc6100318ff922957b6577dc58f lib/core/defaults.py da98f5288aad57855c6d287ba3b397a1 lib/core/dicts.py 9ea8a043030796e6faef7f7e957729d5 lib/core/dump.py @@ -46,7 +46,7 @@ ffa5f01f39b17c8d73423acca6cfe86a lib/core/readlineng.py 0c3eef46bdbf87e29a3f95f90240d192 lib/core/replication.py a7db43859b61569b601b97f187dd31c5 lib/core/revision.py fcb74fcc9577523524659ec49e2e964b lib/core/session.py -88d4f1d18b6919f1ad5f179ed959e7a7 lib/core/settings.py +f0f522f95a11b24bec01d42a9a535e23 lib/core/settings.py 0dfc2ed40adf72e302291f6ecd4406f6 lib/core/shell.py a7edc9250d13af36ac0108f259859c19 lib/core/subprocessng.py a35efa7bec9f1e6cedf17c9830a79241 lib/core/target.py @@ -68,12 +68,12 @@ ec4e56bbb1349176b2a22e0b99ba6a55 lib/parse/payloads.py 30eed3a92a04ed2c29770e1b10d39dc0 lib/request/basicauthhandler.py 7e8e0a3fdebbe443832c1bab2f8d3869 lib/request/basic.py c0cabedead14b8a23353b606672cff42 lib/request/comparison.py -a42707d6e89312659d3bdc8fb4ad1336 lib/request/connect.py +acc31fac4efc25741c061bf8d7f8c3a2 lib/request/connect.py dd4598675027fae99f2e2475b05986da lib/request/direct.py 2044fce3f4ffa268fcfaaf63241b1e64 lib/request/dns.py eee965d781546d05f36cfd14af050913 lib/request/httpshandler.py 1e5532ede194ac9c083891c2f02bca93 lib/request/__init__.py -cb05d965aa3d5871d14b5e45fe9128b4 lib/request/inject.py +b188a11542a996276abbbc48913501c3 lib/request/inject.py aaf956c1e9855836c3f372e29d481393 lib/request/methodrequest.py 51eeaa8abf5ba62aaaade66d46ff8b00 lib/request/pkihandler.py aa7cb67139bbc57d67a728fd2abf80ed lib/request/rangehandler.py @@ -86,7 +86,7 @@ b1a6689e92e6ce998337bd41d8b09d6e lib/takeover/metasploit.py fb9e34d558293b5d6b9727f440712886 lib/takeover/registry.py 48575dde7bb867b7937769f569a98309 lib/takeover/udf.py 4584ac6ee5c13d4d395f0a7a21d8478c lib/takeover/web.py -79d1ba3ab7b2552c5f09992ce08e765d lib/takeover/xp_cmdshell.py +f1decf0a987bd3a4bc757212cbe6a6c8 lib/takeover/xp_cmdshell.py 2543e14cc7f6e239b49dd40f41bc34fa lib/techniques/blind/inference.py 1e5532ede194ac9c083891c2f02bca93 lib/techniques/blind/__init__.py 1e5532ede194ac9c083891c2f02bca93 lib/techniques/dns/__init__.py @@ -96,7 +96,7 @@ fb9e34d558293b5d6b9727f440712886 lib/takeover/registry.py f999f2e88dea9ac8831eb2f468478b5f lib/techniques/error/use.py 1e5532ede194ac9c083891c2f02bca93 lib/techniques/__init__.py 1e5532ede194ac9c083891c2f02bca93 lib/techniques/union/__init__.py -36c49359a110fe0f797b2eb9e2d694ed lib/techniques/union/test.py +cbe59feb11526068bbbd35dca97b3b37 lib/techniques/union/test.py 11ecf2effbe9f40b361843d546c3c521 lib/techniques/union/use.py c552f8d924d962a26f2ded250bcea3b8 lib/utils/api.py 37dfb641358669f62c2acedff241348b lib/utils/brute.py @@ -111,7 +111,7 @@ cc1cfe36057f1d9bbdcba1bcc03359f9 lib/utils/hash.py 010d8327239d33af4ce9f25683cfc012 lib/utils/pivotdumptable.py 5cb78b0e60fd7fd84502d62cf85d2064 lib/utils/progress.py 0ec5cec9d93d5ffd1eaeda6e942ecadf lib/utils/purge.py -fb6cf3415fbbf117e2dc87aae2f35993 lib/utils/search.py +2e3e7213f50b52fc4d5a014a2ff8d163 lib/utils/search.py 236a8d9e596602b53f8e0aa09c30c0ef lib/utils/sqlalchemy.py dcc25183c6bd85b172c87cfcbc305ab6 lib/utils/timeout.py 3d230e342a6c8d60ac7c68c556fbba9b lib/utils/versioncheck.py @@ -168,7 +168,7 @@ affef90b1442285da7e89e46603c502e plugins/dbms/mssqlserver/__init__.py 08fe8ac7acdfc0e3168b5b069a7c73bf plugins/dbms/mssqlserver/takeover.py f6e1f3f09f32b9cb2ca11c016d373423 plugins/dbms/mysql/connector.py 445164daf59b890aeacc968af58fcb53 plugins/dbms/mysql/enumeration.py -f36e09edc3eafedd989fbe44ec048e71 plugins/dbms/mysql/filesystem.py +4578fa29f04d0a75499f9668466ded07 plugins/dbms/mysql/filesystem.py fcbf7ff279c527b4aca0dac94c28d20c plugins/dbms/mysql/fingerprint.py 30065993f8300994e4658634121609e9 plugins/dbms/mysql/__init__.py 0e2adbee217f5b94dcc124d24b8dde99 plugins/dbms/mysql/syntax.py @@ -203,7 +203,7 @@ a3db8618eed5bb2807b6f77605cba9cc plugins/dbms/sybase/__init__.py 79f6c7017db4ded8f74a0117188836ff plugins/dbms/sybase/takeover.py 34d181a7086d6dfc7e72ae5f8a4cfe0f plugins/generic/connector.py e6cd1c5a5244d83396b401f7db43d323 plugins/generic/custom.py -dc07665887191ac977e5377f5a66d288 plugins/generic/databases.py +79c6dbcb7e6ad5e993a44aa52fdc36ed plugins/generic/databases.py a9c8637f0526d751cd1a6a18f91967f5 plugins/generic/entries.py d82f2c78c1d4d7c6487e94fd3a68a908 plugins/generic/enumeration.py 0c8abe66a78edca0660bfb8049d109e2 plugins/generic/filesystem.py