diff --git a/lib/core/option.py b/lib/core/option.py index 4afb109c7..1d9a6bf2d 100644 --- a/lib/core/option.py +++ b/lib/core/option.py @@ -2063,7 +2063,7 @@ def _setKnowledgeBaseAttributes(flushAll=True): kb.lastParserStatus = None kb.locks = AttribDict() - for _ in ("cache", "connError", "count", "handlers", "hint", "index", "io", "limit", "log", "socket", "redirect", "request", "value"): + for _ in ("cache", "connError", "count", "handlers", "hint", "index", "io", "limit", "liveCookies", "log", "socket", "redirect", "request", "value"): kb.locks[_] = threading.Lock() kb.matchRatio = None diff --git a/lib/core/optiondict.py b/lib/core/optiondict.py index c0cfe5d0d..402c983e2 100644 --- a/lib/core/optiondict.py +++ b/lib/core/optiondict.py @@ -27,6 +27,7 @@ optDict = { "paramDel": "string", "cookie": "string", "cookieDel": "string", + "liveCookies": "string", "loadCookies": "string", "dropSetCookie": "boolean", "agent": "string", diff --git a/lib/core/settings.py b/lib/core/settings.py index 04f5b6142..87c20dbfe 100644 --- a/lib/core/settings.py +++ b/lib/core/settings.py @@ -18,7 +18,7 @@ from lib.core.enums import OS from thirdparty.six import unichr as _unichr # sqlmap version (...) -VERSION = "1.4.10.27" +VERSION = "1.4.10.28" 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) @@ -52,6 +52,9 @@ IPS_WAF_CHECK_RATIO = 0.5 # Timeout used in heuristic check for WAF/IPS protected targets IPS_WAF_CHECK_TIMEOUT = 10 +# Timeout used in checking for existence of live-cookies file +LIVE_COOKIES_TIMEOUT = 120 + # Lower and upper values for match ratio in case of stable page LOWER_RATIO_BOUND = 0.02 UPPER_RATIO_BOUND = 0.98 diff --git a/lib/parse/cmdline.py b/lib/parse/cmdline.py index a198a300b..10d98e148 100644 --- a/lib/parse/cmdline.py +++ b/lib/parse/cmdline.py @@ -168,6 +168,9 @@ def cmdLineParser(argv=None): request.add_argument("--cookie-del", dest="cookieDel", help="Character used for splitting cookie values (e.g. ;)") + request.add_argument("--live-cookies", dest="liveCookies", + help="Live cookies file used for loading up-to-date values") + request.add_argument("--load-cookies", dest="loadCookies", help="File containing cookies in Netscape/wget format") diff --git a/lib/request/connect.py b/lib/request/connect.py index 739d4dd13..bcbed1724 100644 --- a/lib/request/connect.py +++ b/lib/request/connect.py @@ -7,6 +7,7 @@ See the file 'LICENSE' for copying permission import binascii import logging +import os import random import re import socket @@ -25,6 +26,7 @@ except ImportError: from lib.core.agent import agent from lib.core.common import asciifyUrl from lib.core.common import calculateDeltaSeconds +from lib.core.common import checkFile from lib.core.common import checkSameHost from lib.core.common import chunkSplitPostData from lib.core.common import clearConsoleLine @@ -100,6 +102,7 @@ from lib.core.settings import IPS_WAF_CHECK_PAYLOAD from lib.core.settings import IS_WIN from lib.core.settings import JAVASCRIPT_HREF_REGEX from lib.core.settings import LARGE_READ_TRIM_MARKER +from lib.core.settings import LIVE_COOKIES_TIMEOUT from lib.core.settings import MAX_CONNECTION_READ_SIZE from lib.core.settings import MAX_CONNECTIONS_REGEX from lib.core.settings import MAX_CONNECTION_TOTAL_SIZE @@ -292,6 +295,30 @@ class Connect(object): return page, headers, code + if conf.liveCookies: + with kb.locks.liveCookies: + if not checkFile(conf.liveCookies, raiseOnError=False) or os.path.getsize(conf.liveCookies) == 0: + warnMsg = "[%s] [WARNING] live cookies file '%s' is empty or non-existent. Waiting for timeout (%d seconds)" % (time.strftime("%X"), conf.liveCookies, LIVE_COOKIES_TIMEOUT) + dataToStdout(warnMsg) + + valid = False + for _ in xrange(LIVE_COOKIES_TIMEOUT): + if checkFile(conf.liveCookies, raiseOnError=False) and os.path.getsize(conf.liveCookies) > 0: + valid = True + break + else: + dataToStdout('.') + time.sleep(1) + + dataToStdout("\n") + + if not valid: + errMsg = "problem occurred while loading cookies from file '%s'" % conf.liveCookies + raise SqlmapValueException(errMsg) + + cookie = openFile(conf.liveCookies).read().strip() + cookie = re.sub(r"(?i)\ACookie:\s*", "", cookie) + if multipart: post = multipart else: diff --git a/lib/techniques/union/use.py b/lib/techniques/union/use.py index 241fcea7e..14ae60ef9 100644 --- a/lib/techniques/union/use.py +++ b/lib/techniques/union/use.py @@ -5,11 +5,9 @@ Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/) See the file 'LICENSE' for copying permission """ -import binascii import json import re import time -import xml.etree.ElementTree from lib.core.agent import agent from lib.core.bigarray import BigArray @@ -33,14 +31,11 @@ from lib.core.common import isNumPosStrValue from lib.core.common import listToStrValue from lib.core.common import parseUnionPage from lib.core.common import removeReflectiveValues -from lib.core.common import safeStringFormat from lib.core.common import singleTimeDebugMessage from lib.core.common import singleTimeWarnMessage from lib.core.common import unArrayizeValue from lib.core.common import wasLastResponseDBMSError from lib.core.compat import xrange -from lib.core.convert import decodeBase64 -from lib.core.convert import getBytes from lib.core.convert import getUnicode from lib.core.convert import htmlUnescape from lib.core.data import conf diff --git a/plugins/generic/databases.py b/plugins/generic/databases.py index eb2061753..3f73e4adc 100644 --- a/plugins/generic/databases.py +++ b/plugins/generic/databases.py @@ -10,7 +10,6 @@ import re from lib.core.agent import agent from lib.core.common import arrayizeValue from lib.core.common import Backend -from lib.core.common import extractRegexResult from lib.core.common import filterNone from lib.core.common import filterPairValues from lib.core.common import flattenValue @@ -23,7 +22,6 @@ from lib.core.common import isTechniqueAvailable from lib.core.common import parseSqliteTableSchema from lib.core.common import popValue from lib.core.common import pushValue -from lib.core.common import randomStr from lib.core.common import readInput from lib.core.common import safeSQLIdentificatorNaming from lib.core.common import safeStringFormat @@ -54,7 +52,6 @@ from lib.core.settings import REFLECTED_VALUE_MARKER from lib.core.settings import UPPER_CASE_DBMSES from lib.core.settings import VERTICA_DEFAULT_SCHEMA from lib.request import inject -from lib.techniques.union.use import unionUse from lib.utils.brute import columnExists from lib.utils.brute import tableExists from thirdparty import six diff --git a/sqlmap.conf b/sqlmap.conf index 480cb27c3..b5f3cfced 100644 --- a/sqlmap.conf +++ b/sqlmap.conf @@ -51,6 +51,9 @@ cookie = # Character used for splitting cookie values (e.g. ;). cookieDel = +# Live cookies file used for loading up-to-date values. +liveCookies = + # File containing cookies in Netscape/wget format. loadCookies =