diff --git a/customized.xml b/customized.xml new file mode 100644 index 000000000..39eec7da1 --- /dev/null +++ b/customized.xml @@ -0,0 +1,176 @@ + + + + + + + Testing Customized Payload + 7 + 1 + 1 + 1,2,3,4,5 + 1 + [UNION] + + + [GENERIC_SQL_COMMENT] + NULL + 1-10 + + + + + + + diff --git a/enums.py b/enums.py new file mode 100644 index 000000000..c7bb5f3ad --- /dev/null +++ b/enums.py @@ -0,0 +1,437 @@ +#!/usr/bin/env python + +""" +Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/) +See the file 'LICENSE' for copying permission +""" + +class PRIORITY(object): + LOWEST = -100 + LOWER = -50 + LOW = -10 + NORMAL = 0 + HIGH = 10 + HIGHER = 50 + HIGHEST = 100 + +class SORT_ORDER(object): + FIRST = 0 + SECOND = 1 + THIRD = 2 + FOURTH = 3 + FIFTH = 4 + LAST = 100 + +# Reference: https://docs.python.org/2/library/logging.html#logging-levels +class LOGGING_LEVELS(object): + NOTSET = 0 + DEBUG = 10 + INFO = 20 + WARNING = 30 + ERROR = 40 + CRITICAL = 50 + +class DBMS(object): + ACCESS = "Microsoft Access" + DB2 = "IBM DB2" + FIREBIRD = "Firebird" + MAXDB = "SAP MaxDB" + MSSQL = "Microsoft SQL Server" + MYSQL = "MySQL" + ORACLE = "Oracle" + PGSQL = "PostgreSQL" + SQLITE = "SQLite" + SYBASE = "Sybase" + INFORMIX = "Informix" + HSQLDB = "HSQLDB" + H2 = "H2" + MONETDB = "MonetDB" + DERBY = "Apache Derby" + VERTICA = "Vertica" + MCKOI = "Mckoi" + PRESTO = "Presto" + ALTIBASE = "Altibase" + MIMERSQL = "MimerSQL" + CRATEDB = "CrateDB" + CUBRID = "Cubrid" + CACHE = "InterSystems Cache" + EXTREMEDB = "eXtremeDB" + FRONTBASE = "FrontBase" + +class DBMS_DIRECTORY_NAME(object): + ACCESS = "access" + DB2 = "db2" + FIREBIRD = "firebird" + MAXDB = "maxdb" + MSSQL = "mssqlserver" + MYSQL = "mysql" + ORACLE = "oracle" + PGSQL = "postgresql" + SQLITE = "sqlite" + SYBASE = "sybase" + HSQLDB = "hsqldb" + H2 = "h2" + INFORMIX = "informix" + MONETDB = "monetdb" + DERBY = "derby" + VERTICA = "vertica" + MCKOI = "mckoi" + PRESTO = "presto" + ALTIBASE = "altibase" + MIMERSQL = "mimersql" + CRATEDB = "cratedb" + CUBRID = "cubrid" + CACHE = "cache" + EXTREMEDB = "extremedb" + FRONTBASE = "frontbase" + +class FORK(object): + MARIADB = "MariaDB" + MEMSQL = "MemSQL" + PERCONA = "Percona" + COCKROACHDB = "CockroachDB" + TIDB = "TiDB" + REDSHIFT = "Amazon Redshift" + GREENPLUM = "Greenplum" + DRIZZLE = "Drizzle" + IGNITE = "Apache Ignite" + AURORA = "Aurora" + ENTERPRISEDB = "EnterpriseDB" + YELLOWBRICK = "Yellowbrick" + IRIS = "Iris" + +class CUSTOM_LOGGING(object): + PAYLOAD = 9 + TRAFFIC_OUT = 8 + TRAFFIC_IN = 7 + +class OS(object): + LINUX = "Linux" + WINDOWS = "Windows" + +class PLACE(object): + GET = "GET" + POST = "POST" + URI = "URI" + COOKIE = "Cookie" + USER_AGENT = "User-Agent" + REFERER = "Referer" + HOST = "Host" + CUSTOM_POST = "(custom) POST" + CUSTOM_HEADER = "(custom) HEADER" + +class POST_HINT(object): + SOAP = "SOAP" + JSON = "JSON" + JSON_LIKE = "JSON-like" + MULTIPART = "MULTIPART" + XML = "XML (generic)" + ARRAY_LIKE = "Array-like" + +class HTTPMETHOD(object): + GET = "GET" + POST = "POST" + HEAD = "HEAD" + PUT = "PUT" + DELETE = "DELETE" + TRACE = "TRACE" + OPTIONS = "OPTIONS" + CONNECT = "CONNECT" + PATCH = "PATCH" + +class NULLCONNECTION(object): + HEAD = "HEAD" + RANGE = "Range" + SKIP_READ = "skip-read" + +class REFLECTIVE_COUNTER(object): + MISS = "MISS" + HIT = "HIT" + +class CHARSET_TYPE(object): + BINARY = 1 + DIGITS = 2 + HEXADECIMAL = 3 + ALPHA = 4 + ALPHANUM = 5 + +class HEURISTIC_TEST(object): + CASTED = 1 + NEGATIVE = 2 + POSITIVE = 3 + +class HASH(object): + MYSQL = r'(?i)\A\*[0-9a-f]{40}\Z' + MYSQL_OLD = r'(?i)\A(?![0-9]+\Z)[0-9a-f]{16}\Z' + POSTGRES = r'(?i)\Amd5[0-9a-f]{32}\Z' + MSSQL = r'(?i)\A0x0100[0-9a-f]{8}[0-9a-f]{40}\Z' + MSSQL_OLD = r'(?i)\A0x0100[0-9a-f]{8}[0-9a-f]{80}\Z' + MSSQL_NEW = r'(?i)\A0x0200[0-9a-f]{8}[0-9a-f]{128}\Z' + ORACLE = r'(?i)\As:[0-9a-f]{60}\Z' + ORACLE_OLD = r'(?i)\A[0-9a-f]{16}\Z' + MD5_GENERIC = r'(?i)\A(0x)?[0-9a-f]{32}\Z' + SHA1_GENERIC = r'(?i)\A(0x)?[0-9a-f]{40}\Z' + SHA224_GENERIC = r'(?i)\A[0-9a-f]{56}\Z' + SHA256_GENERIC = r'(?i)\A(0x)?[0-9a-f]{64}\Z' + SHA384_GENERIC = r'(?i)\A[0-9a-f]{96}\Z' + SHA512_GENERIC = r'(?i)\A(0x)?[0-9a-f]{128}\Z' + CRYPT_GENERIC = r'\A(?!\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\Z)(?![0-9]+\Z)[./0-9A-Za-z]{13}\Z' + JOOMLA = r'\A[0-9a-f]{32}:\w{32}\Z' + WORDPRESS = r'\A\$P\$[./0-9a-zA-Z]{31}\Z' + APACHE_MD5_CRYPT = r'\A\$apr1\$.{1,8}\$[./a-zA-Z0-9]+\Z' + UNIX_MD5_CRYPT = r'\A\$1\$.{1,8}\$[./a-zA-Z0-9]+\Z' + APACHE_SHA1 = r'\A\{SHA\}[a-zA-Z0-9+/]+={0,2}\Z' + VBULLETIN = r'\A[0-9a-fA-F]{32}:.{30}\Z' + VBULLETIN_OLD = r'\A[0-9a-fA-F]{32}:.{3}\Z' + SSHA = r'\A\{SSHA\}[a-zA-Z0-9+/]+={0,2}\Z' + SSHA256 = r'\A\{SSHA256\}[a-zA-Z0-9+/]+={0,2}\Z' + SSHA512 = r'\A\{SSHA512\}[a-zA-Z0-9+/]+={0,2}\Z' + DJANGO_MD5 = r'\Amd5\$[^$]+\$[0-9a-f]{32}\Z' + DJANGO_SHA1 = r'\Asha1\$[^$]+\$[0-9a-f]{40}\Z' + MD5_BASE64 = r'\A[a-zA-Z0-9+/]{22}==\Z' + SHA1_BASE64 = r'\A[a-zA-Z0-9+/]{27}=\Z' + SHA256_BASE64 = r'\A[a-zA-Z0-9+/]{43}=\Z' + SHA512_BASE64 = r'\A[a-zA-Z0-9+/]{86}==\Z' + +# Reference: http://www.zytrax.com/tech/web/mobile_ids.html +class MOBILES(object): + BLACKBERRY = ("BlackBerry Z10", "Mozilla/5.0 (BB10; Kbd) AppleWebKit/537.35+ (KHTML, like Gecko) Version/10.3.3.2205 Mobile Safari/537.35+") + GALAXY = ("Samsung Galaxy S7", "Mozilla/5.0 (Linux; Android 7.0; SM-G930V Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.125 Mobile Safari/537.36") + HP = ("HP iPAQ 6365", "Mozilla/4.0 (compatible; MSIE 4.01; Windows CE; PPC; 240x320; HP iPAQ h6300)") + HTC = ("HTC 10", "Mozilla/5.0 (Linux; Android 8.0.0; HTC 10 Build/OPR1.170623.027) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Mobile Safari/537.36") + HUAWEI = ("Huawei P8", "Mozilla/5.0 (Linux; Android 4.4.4; HUAWEI H891L Build/HuaweiH891L) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/33.0.0.0 Mobile Safari/537.36") + IPHONE = ("Apple iPhone 8", "Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1") + LUMIA = ("Microsoft Lumia 950", "Mozilla/5.0 (Windows Phone 10.0; Android 6.0.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Mobile Safari/537.36 Edge/15.14977") + NEXUS = ("Google Nexus 7", "Mozilla/5.0 (Linux; Android 4.1.1; Nexus 7 Build/JRO03D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19") + NOKIA = ("Nokia N97", "Mozilla/5.0 (SymbianOS/9.4; Series60/5.0 NokiaN97-1/10.0.012; Profile/MIDP-2.1 Configuration/CLDC-1.1; en-us) AppleWebKit/525 (KHTML, like Gecko) WicKed/7.1.12344") + PIXEL = ("Google Pixel", "Mozilla/5.0 (Linux; Android 8.0.0; Pixel Build/OPR3.170623.013) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.111 Mobile Safari/537.36") + XIAOMI = ("Xiaomi Mi 3", "Mozilla/5.0 (Linux; U; Android 4.4.4; en-gb; MI 3W Build/KTU84P) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/39.0.0.0 Mobile Safari/537.36 XiaoMi/MiuiBrowser/2.1.1") + +class PROXY_TYPE(object): + HTTP = "HTTP" + HTTPS = "HTTPS" + SOCKS4 = "SOCKS4" + SOCKS5 = "SOCKS5" + +class REGISTRY_OPERATION(object): + READ = "read" + ADD = "add" + DELETE = "delete" + +class DUMP_FORMAT(object): + CSV = "CSV" + HTML = "HTML" + SQLITE = "SQLITE" + +class HTTP_HEADER(object): + ACCEPT = "Accept" + ACCEPT_CHARSET = "Accept-Charset" + ACCEPT_ENCODING = "Accept-Encoding" + ACCEPT_LANGUAGE = "Accept-Language" + AUTHORIZATION = "Authorization" + CACHE_CONTROL = "Cache-Control" + CONNECTION = "Connection" + CONTENT_ENCODING = "Content-Encoding" + CONTENT_LENGTH = "Content-Length" + CONTENT_RANGE = "Content-Range" + CONTENT_TYPE = "Content-Type" + COOKIE = "Cookie" + EXPIRES = "Expires" + HOST = "Host" + IF_MODIFIED_SINCE = "If-Modified-Since" + LAST_MODIFIED = "Last-Modified" + LOCATION = "Location" + PRAGMA = "Pragma" + PROXY_AUTHORIZATION = "Proxy-Authorization" + PROXY_CONNECTION = "Proxy-Connection" + RANGE = "Range" + REFERER = "Referer" + REFRESH = "Refresh" # Reference: http://stackoverflow.com/a/283794 + SERVER = "Server" + SET_COOKIE = "Set-Cookie" + TRANSFER_ENCODING = "Transfer-Encoding" + URI = "URI" + USER_AGENT = "User-Agent" + VIA = "Via" + X_POWERED_BY = "X-Powered-By" + X_DATA_ORIGIN = "X-Data-Origin" + +class EXPECTED(object): + BOOL = "bool" + INT = "int" + +class OPTION_TYPE(object): + BOOLEAN = "boolean" + INTEGER = "integer" + FLOAT = "float" + STRING = "string" + +class HASHDB_KEYS(object): + DBMS = "DBMS" + DBMS_FORK = "DBMS_FORK" + CHECK_WAF_RESULT = "CHECK_WAF_RESULT" + CHECK_NULL_CONNECTION_RESULT = "CHECK_NULL_CONNECTION_RESULT" + CONF_TMP_PATH = "CONF_TMP_PATH" + KB_ABS_FILE_PATHS = "KB_ABS_FILE_PATHS" + KB_BRUTE_COLUMNS = "KB_BRUTE_COLUMNS" + KB_BRUTE_TABLES = "KB_BRUTE_TABLES" + KB_CHARS = "KB_CHARS" + KB_DYNAMIC_MARKINGS = "KB_DYNAMIC_MARKINGS" + KB_INJECTIONS = "KB_INJECTIONS" + KB_ERROR_CHUNK_LENGTH = "KB_ERROR_CHUNK_LENGTH" + KB_XP_CMDSHELL_AVAILABLE = "KB_XP_CMDSHELL_AVAILABLE" + OS = "OS" + +class REDIRECTION(object): + YES = 'Y' + NO = 'N' + +class PAYLOAD(object): + SQLINJECTION = { + 1: "boolean-based blind", + 2: "error-based", + 3: "inline query", + 4: "stacked queries", + 5: "time-based blind", + 6: "UNION query", + 7: "Customized" + } + + PARAMETER = { + 1: "Unescaped numeric", + 2: "Single quoted string", + 3: "LIKE single quoted string", + 4: "Double quoted string", + 5: "LIKE double quoted string", + 6: "Identifier (e.g. column name)", + } + + RISK = { + 0: "No risk", + 1: "Low risk", + 2: "Medium risk", + 3: "High risk", + } + + CLAUSE = { + 0: "Always", + 1: "WHERE", + 2: "GROUP BY", + 3: "ORDER BY", + 4: "LIMIT", + 5: "OFFSET", + 6: "TOP", + 7: "Table name", + 8: "Column name", + 9: "Pre-WHERE (non-query)", + } + + class METHOD(object): + COMPARISON = "comparison" + GREP = "grep" + TIME = "time" + UNION = "union" + + class TECHNIQUE(object): + BOOLEAN = 1 + ERROR = 2 + QUERY = 3 + STACKED = 4 + TIME = 5 + UNION = 6 + CUSTOM = 7 + + class WHERE(object): + ORIGINAL = 1 + NEGATIVE = 2 + REPLACE = 3 + +class WIZARD(object): + BASIC = ("getBanner", "getCurrentUser", "getCurrentDb", "isDba") + INTERMEDIATE = ("getBanner", "getCurrentUser", "getCurrentDb", "isDba", "getUsers", "getDbs", "getTables", "getSchema", "excludeSysDbs") + ALL = ("getBanner", "getCurrentUser", "getCurrentDb", "isDba", "getHostname", "getUsers", "getPasswordHashes", "getPrivileges", "getRoles", "dumpAll") + +class ADJUST_TIME_DELAY(object): + DISABLE = -1 + NO = 0 + YES = 1 + +class WEB_PLATFORM(object): + PHP = "php" + ASP = "asp" + ASPX = "aspx" + JSP = "jsp" + +class CONTENT_TYPE(object): + TARGET = 0 + TECHNIQUES = 1 + DBMS_FINGERPRINT = 2 + BANNER = 3 + CURRENT_USER = 4 + CURRENT_DB = 5 + HOSTNAME = 6 + IS_DBA = 7 + USERS = 8 + PASSWORDS = 9 + PRIVILEGES = 10 + ROLES = 11 + DBS = 12 + TABLES = 13 + COLUMNS = 14 + SCHEMA = 15 + COUNT = 16 + DUMP_TABLE = 17 + SEARCH = 18 + SQL_QUERY = 19 + COMMON_TABLES = 20 + COMMON_COLUMNS = 21 + FILE_READ = 22 + FILE_WRITE = 23 + OS_CMD = 24 + REG_READ = 25 + STATEMENTS = 26 + +class CONTENT_STATUS(object): + IN_PROGRESS = 0 + COMPLETE = 1 + +class AUTH_TYPE(object): + BASIC = "basic" + DIGEST = "digest" + NTLM = "ntlm" + PKI = "pki" + +class AUTOCOMPLETE_TYPE(object): + SQL = 0 + OS = 1 + SQLMAP = 2 + API = 3 + +class NOTE(object): + FALSE_POSITIVE_OR_UNEXPLOITABLE = "false positive or unexploitable" + +class MKSTEMP_PREFIX(object): + HASHES = "sqlmaphashes-" + CRAWLER = "sqlmapcrawler-" + IPC = "sqlmapipc-" + CONFIG = "sqlmapconfig-" + TESTING = "sqlmaptesting-" + RESULTS = "sqlmapresults-" + COOKIE_JAR = "sqlmapcookiejar-" + BIG_ARRAY = "sqlmapbigarray-" + SPECIFIC_RESPONSE = "sqlmapresponse-" + PREPROCESS = "sqlmappreprocess-" + +class TIMEOUT_STATE(object): + NORMAL = 0 + EXCEPTION = 1 + TIMEOUT = 2 + +class HINT(object): + PREPEND = 0 + APPEND = 1 + +class FUZZ_UNION_COLUMN: + STRING = "" + INTEGER = "" + NULL = "NULL" diff --git a/settings.py b/settings.py new file mode 100644 index 000000000..c36d0018e --- /dev/null +++ b/settings.py @@ -0,0 +1,940 @@ +#!/usr/bin/env python + +""" +Copyright (c) 2006-2020 sqlmap developers (http://sqlmap.org/) +See the file 'LICENSE' for copying permission +""" + +import codecs +import os +import random +import re +import string +import sys + +from lib.core.enums import DBMS +from lib.core.enums import DBMS_DIRECTORY_NAME +from lib.core.enums import OS +from thirdparty.six import unichr as _unichr + +# sqlmap version (...) +VERSION = "1.4.5.34" +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) +DESCRIPTION = "automatic SQL injection and database takeover tool" +SITE = "http://sqlmap.org" +DEFAULT_USER_AGENT = "%s (%s)" % (VERSION_STRING, SITE) +DEV_EMAIL_ADDRESS = "dev@sqlmap.org" +ISSUES_PAGE = "https://github.com/sqlmapproject/sqlmap/issues/new" +GIT_REPOSITORY = "https://github.com/sqlmapproject/sqlmap.git" +GIT_PAGE = "https://github.com/sqlmapproject/sqlmap" +WIKI_PAGE = "https://github.com/sqlmapproject/sqlmap/wiki/" +ZIPBALL_PAGE = "https://github.com/sqlmapproject/sqlmap/zipball/master" + +# colorful banner +BANNER = """\033[01;33m\ + ___ + __H__ + ___ ___[.]_____ ___ ___ \033[01;37m{\033[01;%dm%s\033[01;37m}\033[01;33m +|_ -| . [.] | .'| . | +|___|_ [.]_|_|_|__,| _| + |_|V... |_| \033[0m\033[4;37m%s\033[0m\n +""" % (TYPE_COLORS.get(TYPE, 31), VERSION_STRING.split('/')[-1], SITE) + +# Minimum distance of ratio from kb.matchRatio to result in True +DIFF_TOLERANCE = 0.05 +CONSTANT_RATIO = 0.9 + +# Ratio used in heuristic check for WAF/IPS protected targets +IPS_WAF_CHECK_RATIO = 0.5 + +# Timeout used in heuristic check for WAF/IPS protected targets +IPS_WAF_CHECK_TIMEOUT = 10 + +# Lower and upper values for match ratio in case of stable page +LOWER_RATIO_BOUND = 0.02 +UPPER_RATIO_BOUND = 0.98 + +# Markers for special cases when parameter values contain html encoded characters +PARAMETER_AMP_MARKER = "__AMP__" +PARAMETER_SEMICOLON_MARKER = "__SEMICOLON__" +BOUNDARY_BACKSLASH_MARKER = "__BACKSLASH__" +PARAMETER_PERCENTAGE_MARKER = "__PERCENTAGE__" +PARTIAL_VALUE_MARKER = "__PARTIAL_VALUE__" +PARTIAL_HEX_VALUE_MARKER = "__PARTIAL_HEX_VALUE__" +URI_QUESTION_MARKER = "__QUESTION_MARK__" +ASTERISK_MARKER = "__ASTERISK_MARK__" +REPLACEMENT_MARKER = "__REPLACEMENT_MARK__" +BOUNDED_INJECTION_MARKER = "__BOUNDED_INJECTION_MARK__" +SAFE_VARIABLE_MARKER = "__SAFE__" +SAFE_HEX_MARKER = "__SAFE_HEX__" + +RANDOM_INTEGER_MARKER = "[RANDINT]" +RANDOM_STRING_MARKER = "[RANDSTR]" +SLEEP_TIME_MARKER = "[SLEEPTIME]" +INFERENCE_MARKER = "[INFERENCE]" +SINGLE_QUOTE_MARKER = "[SINGLE_QUOTE]" +GENERIC_SQL_COMMENT_MARKER = "[GENERIC_SQL_COMMENT]" + +PAYLOAD_DELIMITER = "__PAYLOAD_DELIMITER__" +CHAR_INFERENCE_MARK = "%c" +PRINTABLE_CHAR_REGEX = r"[^\x00-\x1f\x7f-\xff]" + +# Regular expression used for extraction of table names (useful for (e.g.) MsAccess) +SELECT_FROM_TABLE_REGEX = r"\bSELECT\b.+?\bFROM\s+(?P([\w.]|`[^`<>]+`)+)" + +# Regular expression used for recognition of textual content-type +TEXT_CONTENT_TYPE_REGEX = r"(?i)(text|form|message|xml|javascript|ecmascript|json)" + +# Regular expression used for recognition of generic permission messages +PERMISSION_DENIED_REGEX = r"(?P(command|permission|access)\s*(was|is)?\s*denied)" + +# Regular expression used in recognition of generic protection mechanisms +GENERIC_PROTECTION_REGEX = r"(?i)\b(rejected|blocked|protection|incident|denied|detected|dangerous|firewall)\b" + +# Regular expression used to detect errors in fuzz(y) UNION test +FUZZ_UNION_ERROR_REGEX = r"(?i)data\s?type|comparable|compatible|conversion|converting|failed|error" + +# Upper threshold for starting the fuzz(y) UNION test +FUZZ_UNION_MAX_COLUMNS = 10 + +# Regular expression used for recognition of generic maximum connection messages +MAX_CONNECTIONS_REGEX = r"\bmax.+?\bconnection" + +# Maximum consecutive connection errors before asking the user if he wants to continue +MAX_CONSECUTIVE_CONNECTION_ERRORS = 15 + +# Timeout before the pre-connection candidate is being disposed (because of high probability that the web server will reset it) +PRECONNECT_CANDIDATE_TIMEOUT = 10 + +# Servers known to cause issue with pre-connection mechanism (because of lack of multi-threaded support) +PRECONNECT_INCOMPATIBLE_SERVERS = ("SimpleHTTP", "BaseHTTP") + +# Identify WAF/IPS inside limited number of responses (Note: for optimization purposes) +IDENTYWAF_PARSE_LIMIT = 10 + +# Maximum sleep time in "Murphy" (testing) mode +MAX_MURPHY_SLEEP_TIME = 3 + +# Regular expression used for extracting results from Google search +GOOGLE_REGEX = r"webcache\.googleusercontent\.com/search\?q=cache:[^:]+:([^+]+)\+&cd=|url\?\w+=((?![^>]+webcache\.googleusercontent\.com)http[^>]+)&(sa=U|rct=j)" + +# Regular expression used for extracting results from DuckDuckGo search +DUCKDUCKGO_REGEX = r'= 7) +TIME_STDEV_COEFF = 7 + +# Minimum response time that can be even considered as delayed (not a complete requirement) +MIN_VALID_DELAYED_RESPONSE = 0.5 + +# Standard deviation after which a warning message should be displayed about connection lags +WARN_TIME_STDEV = 0.5 + +# Minimum length of usable union injected response (quick defense against substr fields) +UNION_MIN_RESPONSE_CHARS = 10 + +# Coefficient used for a union-based number of columns checking (must be >= 7) +UNION_STDEV_COEFF = 7 + +# Length of queue for candidates for time delay adjustment +TIME_DELAY_CANDIDATES = 3 + +# Default value for HTTP Accept header +HTTP_ACCEPT_HEADER_VALUE = "*/*" + +# Default value for HTTP Accept-Encoding header +HTTP_ACCEPT_ENCODING_HEADER_VALUE = "gzip,deflate" + +# Default timeout for running commands over backdoor +BACKDOOR_RUN_CMD_TIMEOUT = 5 + +# Number of seconds to wait for thread finalization at program end +THREAD_FINALIZATION_TIMEOUT = 1 + +# Maximum number of techniques used in inject.py/getValue() per one value +MAX_TECHNIQUES_PER_VALUE = 2 + +# In case of missing piece of partial union dump, buffered array must be flushed after certain size +MAX_BUFFERED_PARTIAL_UNION_LENGTH = 1024 + +# Maximum size of cache used in @cachedmethod decorator +MAX_CACHE_ITEMS = 256 + +# Suffix used for naming meta databases in DBMS(es) without explicit database name +METADB_SUFFIX = "_masterdb" + +# Number of times to retry the pushValue during the exceptions (e.g. KeyboardInterrupt) +PUSH_VALUE_EXCEPTION_RETRY_COUNT = 3 + +# Minimum time response set needed for time-comparison based on standard deviation +MIN_TIME_RESPONSES = 30 + +# Maximum time response set used during time-comparison based on standard deviation +MAX_TIME_RESPONSES = 200 + +# Minimum comparison ratio set needed for searching valid union column number based on standard deviation +MIN_UNION_RESPONSES = 5 + +# After these number of blanks at the end inference should stop (just in case) +INFERENCE_BLANK_BREAK = 5 + +# Use this replacement character for cases when inference is not able to retrieve the proper character value +INFERENCE_UNKNOWN_CHAR = '?' + +# Character used for operation "greater" in inference +INFERENCE_GREATER_CHAR = ">" + +# Character used for operation "greater or equal" in inference +INFERENCE_GREATER_EQUALS_CHAR = ">=" + +# Character used for operation "equals" in inference +INFERENCE_EQUALS_CHAR = "=" + +# Character used for operation "not-equals" in inference +INFERENCE_NOT_EQUALS_CHAR = "!=" + +# String used for representation of unknown DBMS +UNKNOWN_DBMS = "Unknown" + +# String used for representation of unknown DBMS version +UNKNOWN_DBMS_VERSION = "Unknown" + +# Dynamicity boundary length used in dynamicity removal engine +DYNAMICITY_BOUNDARY_LENGTH = 20 + +# Dummy user prefix used in dictionary attack +DUMMY_USER_PREFIX = "__dummy__" + +# Reference: http://en.wikipedia.org/wiki/ISO/IEC_8859-1 +DEFAULT_PAGE_ENCODING = "iso-8859-1" + +try: + codecs.lookup(DEFAULT_PAGE_ENCODING) +except LookupError: + DEFAULT_PAGE_ENCODING = "utf8" + +# Marker for program piped input +STDIN_PIPE_DASH = '-' + +# URL used in dummy runs +DUMMY_URL = "http://foo/bar?id=1" + +# Timeout used during initial websocket (pull) testing +WEBSOCKET_INITIAL_TIMEOUT = 3 + +# The name of the operating system dependent module imported. The following names have currently been registered: 'posix', 'nt', 'mac', 'os2', 'ce', 'java', 'riscos' +PLATFORM = os.name +PYVERSION = sys.version.split()[0] +IS_WIN = PLATFORM == "nt" + +# Check if running in terminal +IS_TTY = hasattr(sys.stdout, "fileno") and os.isatty(sys.stdout.fileno()) + +# DBMS system databases +MSSQL_SYSTEM_DBS = ("Northwind", "master", "model", "msdb", "pubs", "tempdb", "Resource", "ReportServer", "ReportServerTempDB") +MYSQL_SYSTEM_DBS = ("information_schema", "mysql", "performance_schema", "sys") +PGSQL_SYSTEM_DBS = ("information_schema", "pg_catalog", "pg_toast", "pgagent") +ORACLE_SYSTEM_DBS = ("ADAMS", "ANONYMOUS", "APEX_030200", "APEX_PUBLIC_USER", "APPQOSSYS", "AURORA$ORB$UNAUTHENTICATED", "AWR_STAGE", "BI", "BLAKE", "CLARK", "CSMIG", "CTXSYS", "DBSNMP", "DEMO", "DIP", "DMSYS", "DSSYS", "EXFSYS", "FLOWS_%", "FLOWS_FILES", "HR", "IX", "JONES", "LBACSYS", "MDDATA", "MDSYS", "MGMT_VIEW", "OC", "OE", "OLAPSYS", "ORACLE_OCM", "ORDDATA", "ORDPLUGINS", "ORDSYS", "OUTLN", "OWBSYS", "PAPER", "PERFSTAT", "PM", "SCOTT", "SH", "SI_INFORMTN_SCHEMA", "SPATIAL_CSW_ADMIN_USR", "SPATIAL_WFS_ADMIN_USR", "SYS", "SYSMAN", "SYSTEM", "TRACESVR", "TSMSYS", "WK_TEST", "WKPROXY", "WKSYS", "WMSYS", "XDB", "XS$NULL") +SQLITE_SYSTEM_DBS = ("sqlite_master", "sqlite_temp_master") +ACCESS_SYSTEM_DBS = ("MSysAccessObjects", "MSysACEs", "MSysObjects", "MSysQueries", "MSysRelationships", "MSysAccessStorage", "MSysAccessXML", "MSysModules", "MSysModules2") +FIREBIRD_SYSTEM_DBS = ("RDB$BACKUP_HISTORY", "RDB$CHARACTER_SETS", "RDB$CHECK_CONSTRAINTS", "RDB$COLLATIONS", "RDB$DATABASE", "RDB$DEPENDENCIES", "RDB$EXCEPTIONS", "RDB$FIELDS", "RDB$FIELD_DIMENSIONS", " RDB$FILES", "RDB$FILTERS", "RDB$FORMATS", "RDB$FUNCTIONS", "RDB$FUNCTION_ARGUMENTS", "RDB$GENERATORS", "RDB$INDEX_SEGMENTS", "RDB$INDICES", "RDB$LOG_FILES", "RDB$PAGES", "RDB$PROCEDURES", "RDB$PROCEDURE_PARAMETERS", "RDB$REF_CONSTRAINTS", "RDB$RELATIONS", "RDB$RELATION_CONSTRAINTS", "RDB$RELATION_FIELDS", "RDB$ROLES", "RDB$SECURITY_CLASSES", "RDB$TRANSACTIONS", "RDB$TRIGGERS", "RDB$TRIGGER_MESSAGES", "RDB$TYPES", "RDB$USER_PRIVILEGES", "RDB$VIEW_RELATIONS") +MAXDB_SYSTEM_DBS = ("SYSINFO", "DOMAIN") +SYBASE_SYSTEM_DBS = ("master", "model", "sybsystemdb", "sybsystemprocs") +DB2_SYSTEM_DBS = ("NULLID", "SQLJ", "SYSCAT", "SYSFUN", "SYSIBM", "SYSIBMADM", "SYSIBMINTERNAL", "SYSIBMTS", "SYSPROC", "SYSPUBLIC", "SYSSTAT", "SYSTOOLS") +HSQLDB_SYSTEM_DBS = ("INFORMATION_SCHEMA", "SYSTEM_LOB") +H2_SYSTEM_DBS = ("INFORMATION_SCHEMA",) + ("IGNITE", "ignite-sys-cache") +INFORMIX_SYSTEM_DBS = ("sysmaster", "sysutils", "sysuser", "sysadmin") +MONETDB_SYSTEM_DBS = ("tmp", "json", "profiler") +DERBY_SYSTEM_DBS = ("NULLID", "SQLJ", "SYS", "SYSCAT", "SYSCS_DIAG", "SYSCS_UTIL", "SYSFUN", "SYSIBM", "SYSPROC", "SYSSTAT") +VERTICA_SYSTEM_DBS = ("v_catalog", "v_internal", "v_monitor",) +MCKOI_SYSTEM_DBS = ("",) +PRESTO_SYSTEM_DBS = ("information_schema",) +ALTIBASE_SYSTEM_DBS = ("SYSTEM_",) +MIMERSQL_SYSTEM_DBS = ("information_schema", "SYSTEM",) +CRATEDB_SYSTEM_DBS = ("information_schema", "pg_catalog", "sys") +CUBRID_SYSTEM_DBS = ("DBA",) +CACHE_SYSTEM_DBS = ("%Dictionary", "INFORMATION_SCHEMA", "%SYS") +EXTREMEDB_SYSTEM_DBS = ("",) +FRONTBASE_SYSTEM_DBS = ("DEFINITION_SCHEMA", "INFORMATION_SCHEMA") + +# Note: () + () +MSSQL_ALIASES = ("microsoft sql server", "mssqlserver", "mssql", "ms") +MYSQL_ALIASES = ("mysql", "my") + ("mariadb", "maria", "memsql", "tidb", "percona") +PGSQL_ALIASES = ("postgresql", "postgres", "pgsql", "psql", "pg") + ("cockroach", "cockroachdb", "redshift", "greenplum", "yellowbrick", "enterprisedb", "aurora") +ORACLE_ALIASES = ("oracle", "orcl", "ora", "or") +SQLITE_ALIASES = ("sqlite", "sqlite3") +ACCESS_ALIASES = ("msaccess", "access", "jet", "microsoft access") +FIREBIRD_ALIASES = ("firebird", "mozilla firebird", "interbase", "ibase", "fb") +MAXDB_ALIASES = ("max", "maxdb", "sap maxdb", "sap db") +SYBASE_ALIASES = ("sybase", "sybase sql server") +DB2_ALIASES = ("db2", "ibm db2", "ibmdb2") +HSQLDB_ALIASES = ("hsql", "hsqldb", "hs", "hypersql") +H2_ALIASES = ("h2",) +INFORMIX_ALIASES = ("informix", "ibm informix", "ibminformix") +MONETDB_ALIASES = ("monet", "monetdb",) +DERBY_ALIASES = ("derby", "apache derby",) +VERTICA_ALIASES = ("vertica",) +MCKOI_ALIASES = ("mckoi",) +PRESTO_ALIASES = ("presto",) +ALTIBASE_ALIASES = ("altibase",) +MIMERSQL_ALIASES = ("mimersql", "mimer") +CRATEDB_ALIASES = ("cratedb", "crate") +CUBRID_ALIASES = ("cubrid",) +CACHE_ALIASES = ("intersystems cache", "cachedb", "cache") +EXTREMEDB_ALIASES = ("extremedb", "extreme") +FRONTBASE_ALIASES = ("frontbase",) + +DBMS_DIRECTORY_DICT = dict((getattr(DBMS, _), getattr(DBMS_DIRECTORY_NAME, _)) for _ in dir(DBMS) if not _.startswith("_")) + +SUPPORTED_DBMS = set(MSSQL_ALIASES + MYSQL_ALIASES + PGSQL_ALIASES + ORACLE_ALIASES + SQLITE_ALIASES + ACCESS_ALIASES + FIREBIRD_ALIASES + MAXDB_ALIASES + SYBASE_ALIASES + DB2_ALIASES + HSQLDB_ALIASES + H2_ALIASES + INFORMIX_ALIASES + MONETDB_ALIASES + DERBY_ALIASES + VERTICA_ALIASES + MCKOI_ALIASES + PRESTO_ALIASES + ALTIBASE_ALIASES + MIMERSQL_ALIASES + CRATEDB_ALIASES + CUBRID_ALIASES + CACHE_ALIASES + EXTREMEDB_ALIASES) +SUPPORTED_OS = ("linux", "windows") + +DBMS_ALIASES = ((DBMS.MSSQL, MSSQL_ALIASES), (DBMS.MYSQL, MYSQL_ALIASES), (DBMS.PGSQL, PGSQL_ALIASES), (DBMS.ORACLE, ORACLE_ALIASES), (DBMS.SQLITE, SQLITE_ALIASES), (DBMS.ACCESS, ACCESS_ALIASES), (DBMS.FIREBIRD, FIREBIRD_ALIASES), (DBMS.MAXDB, MAXDB_ALIASES), (DBMS.SYBASE, SYBASE_ALIASES), (DBMS.DB2, DB2_ALIASES), (DBMS.HSQLDB, HSQLDB_ALIASES), (DBMS.H2, H2_ALIASES), (DBMS.INFORMIX, INFORMIX_ALIASES), (DBMS.MONETDB, MONETDB_ALIASES), (DBMS.DERBY, DERBY_ALIASES), (DBMS.VERTICA, VERTICA_ALIASES), (DBMS.MCKOI, MCKOI_ALIASES), (DBMS.PRESTO, PRESTO_ALIASES), (DBMS.ALTIBASE, ALTIBASE_ALIASES), (DBMS.MIMERSQL, MIMERSQL_ALIASES), (DBMS.CRATEDB, CRATEDB_ALIASES), (DBMS.CUBRID, CUBRID_ALIASES), (DBMS.CACHE, CACHE_ALIASES), (DBMS.EXTREMEDB, EXTREMEDB_ALIASES), (DBMS.FRONTBASE, FRONTBASE_ALIASES)) + +USER_AGENT_ALIASES = ("ua", "useragent", "user-agent") +REFERER_ALIASES = ("ref", "referer", "referrer") +HOST_ALIASES = ("host",) + +# DBMSes with upper case identifiers +UPPER_CASE_DBMSES = set((DBMS.ORACLE, DBMS.DB2, DBMS.FIREBIRD, DBMS.HSQLDB, DBMS.MAXDB, DBMS.H2, DBMS.DERBY, DBMS.ALTIBASE)) + +# Default schemas to use (when unable to enumerate) +H2_DEFAULT_SCHEMA = HSQLDB_DEFAULT_SCHEMA = "PUBLIC" +VERTICA_DEFAULT_SCHEMA = "public" +MCKOI_DEFAULT_SCHEMA = "APP" +CACHE_DEFAULT_SCHEMA = "SQLUser" + +# DBMSes where OFFSET mechanism starts from 1 +PLUS_ONE_DBMSES = set((DBMS.ORACLE, DBMS.DB2, DBMS.ALTIBASE, DBMS.MSSQL, DBMS.CACHE)) + +# Names that can't be used to name files on Windows OS +WINDOWS_RESERVED_NAMES = ("CON", "PRN", "AUX", "NUL", "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9") + +# Items displayed in basic help (-h) output +BASIC_HELP_ITEMS = ( + "url", + "googleDork", + "data", + "cookie", + "randomAgent", + "proxy", + "testParameter", + "dbms", + "level", + "risk", + "technique", + "getAll", + "getBanner", + "getCurrentUser", + "getCurrentDb", + "getPasswordHashes", + "getTables", + "getColumns", + "getSchema", + "dumpTable", + "dumpAll", + "db", + "tbl", + "col", + "osShell", + "osPwn", + "batch", + "checkTor", + "flushSession", + "tor", + "sqlmapShell", + "wizard", +) + +# Tags used for value replacements inside shell scripts +SHELL_WRITABLE_DIR_TAG = "%WRITABLE_DIR%" +SHELL_RUNCMD_EXE_TAG = "%RUNCMD_EXE%" + +# String representation for NULL value +NULL = "NULL" + +# String representation for blank ('') value +BLANK = "" + +# String representation for current database +CURRENT_DB = "CD" + +# String representation for current user +CURRENT_USER = "CU" + +# Name of SQLite file used for storing session data +SESSION_SQLITE_FILE = "session.sqlite" + +# Regular expressions used for finding file paths in error messages +FILE_PATH_REGEXES = (r"(?P[^<>]+?) on line \d+", r"\bin (?P[^<>'\"]+?)['\"]? on line \d+", r"(?:[>(\[\s])(?P[A-Za-z]:[\\/][\w. \\/-]*)", r"(?:[>(\[\s])(?P/\w[/\w.~-]+)", r"\bhref=['\"]file://(?P/[^'\"]+)", r"\bin (?P[^<]+): line \d+") + +# Regular expressions used for parsing error messages (--parse-errors) +ERROR_PARSING_REGEXES = ( + r"\[Microsoft\]\[ODBC SQL Server Driver\]\[SQL Server\](?P[^<]+)", + r"[^<]*(fatal|error|warning|exception)[^<]*:?\s*(?P[^<]+)", + r"(?m)^\s*(fatal|error|warning|exception):?\s*(?P[^\n]+?)$", + r"(sql|dbc)[^>'\"]{0,32}(fatal|error|warning|exception)()?:\s*(?P[^<>]+)", + r"(?P[^\n>]*SQL Syntax[^\n<]+)", + r"(?s)
  • Error Type:
    (?P.+?)
  • ", + r"CDbCommand (?P[^<>\n]*SQL[^<>\n]+)", + r"error '[0-9a-f]{8}'((<[^>]+>)|\s)+(?P[^<>]+)", + r"\[[^\n\]]+(ODBC|JDBC)[^\n\]]+\](\[[^\]]+\])?(?P[^\n]+(in query expression|\(SQL| at /[^ ]+pdo)[^\n<]+)", + r"(?Pquery error: SELECT[^<>]+)" +) + +# Regular expression used for parsing charset info from meta html headers +META_CHARSET_REGEX = r'(?si).*]+charset="?(?P[^"> ]+).*' + +# Regular expression used for parsing refresh info from meta html headers +META_REFRESH_REGEX = r'(?i)]+content="?[^">]+;\s*(url=)?["\']?(?P[^\'">]+)' + +# Regular expression used for parsing Javascript redirect request +JAVASCRIPT_HREF_REGEX = r'',table_name FROM information_schema.tables WHERE 2>1--/**/; EXEC xp_cmdshell('cat ../../../etc/passwd')#" + +# Vectors used for provoking specific WAF/IPS behavior(s) +WAF_ATTACK_VECTORS = ( + "", # NIL + "search=", + "file=../../../../etc/passwd", + "q=foobar", + "id=1 %s" % IPS_WAF_CHECK_PAYLOAD +) + +# Used for status representation in dictionary attack phase +ROTATING_CHARS = ('\\', '|', '|', '/', '-') + +# Approximate chunk length (in bytes) used by BigArray objects (only last chunk and cached one are held in memory) +BIGARRAY_CHUNK_SIZE = 1024 * 1024 + +# Compress level used for storing BigArray chunks to disk (0-9) +BIGARRAY_COMPRESS_LEVEL = 9 + +# Maximum number of socket pre-connects +SOCKET_PRE_CONNECT_QUEUE_SIZE = 3 + +# Only console display last n table rows +TRIM_STDOUT_DUMP_SIZE = 256 + +# Reference: http://stackoverflow.com/a/3168436 +# Reference: https://support.microsoft.com/en-us/kb/899149 +DUMP_FILE_BUFFER_SIZE = 1024 + +# Parse response headers only first couple of times +PARSE_HEADERS_LIMIT = 3 + +# Step used in ORDER BY technique used for finding the right number of columns in UNION query injections +ORDER_BY_STEP = 10 + +# Maximum value used in ORDER BY technique used for finding the right number of columns in UNION query injections +ORDER_BY_MAX = 1000 + +# Maximum number of times for revalidation of a character in inference (as required) +MAX_REVALIDATION_STEPS = 5 + +# Characters that can be used to split parameter values in provided command line (e.g. in --tamper) +PARAMETER_SPLITTING_REGEX = r"[,|;]" + +# Regular expression describing possible union char value (e.g. used in --union-char) +UNION_CHAR_REGEX = r"\A\w+\Z" + +# Attribute used for storing original parameter value in special cases (e.g. POST) +UNENCODED_ORIGINAL_VALUE = "original" + +# Common column names containing usernames (used for hash cracking in some cases) +COMMON_USER_COLUMNS = ("login", "user", "username", "user_name", "user_login", "benutzername", "benutzer", "utilisateur", "usager", "consommateur", "utente", "utilizzatore", "utilizator", "utilizador", "usufrutuario", "korisnik", "uporabnik", "usuario", "consumidor", "client", "cuser") + +# Default delimiter in GET/POST values +DEFAULT_GET_POST_DELIMITER = '&' + +# Default delimiter in cookie values +DEFAULT_COOKIE_DELIMITER = ';' + +# Unix timestamp used for forcing cookie expiration when provided with --load-cookies +FORCE_COOKIE_EXPIRATION_TIME = "9999999999" + +# Github OAuth token used for creating an automatic Issue for unhandled exceptions +GITHUB_REPORT_OAUTH_TOKEN = "NTYzYjhmZWJjYzc0Njg2ODJhNzhmNDg1YzM0YzlkYjk3N2JiMzE3Nw==" + +# Skip unforced HashDB flush requests below the threshold number of cached items +HASHDB_FLUSH_THRESHOLD = 32 + +# Number of retries for unsuccessful HashDB flush attempts +HASHDB_FLUSH_RETRIES = 3 + +# Number of retries for unsuccessful HashDB retrieve attempts +HASHDB_RETRIEVE_RETRIES = 3 + +# Number of retries for unsuccessful HashDB end transaction attempts +HASHDB_END_TRANSACTION_RETRIES = 3 + +# Unique milestone value used for forced deprecation of old HashDB values (e.g. when changing hash/pickle mechanism) +HASHDB_MILESTONE_VALUE = "OdqjeUpBLc" # python -c 'import random, string; print "".join(random.sample(string.ascii_letters, 10))' + +# Pickle protocl used for storage of serialized data inside HashDB (https://docs.python.org/3/library/pickle.html#data-stream-format) +PICKLE_PROTOCOL = 2 + +# Warn user of possible delay due to large page dump in full UNION query injections +LARGE_OUTPUT_THRESHOLD = 1024 ** 2 + +# On huge tables there is a considerable slowdown if every row retrieval requires ORDER BY (most noticable in table dumping using ERROR injections) +SLOW_ORDER_COUNT_THRESHOLD = 10000 + +# Give up on hash recognition if nothing was found in first given number of rows +HASH_RECOGNITION_QUIT_THRESHOLD = 1000 + +# Regular expression used for automatic hex conversion and hash cracking of (RAW) binary column values +HASH_BINARY_COLUMNS_REGEX = r"(?i)pass|psw|hash" + +# Maximum number of redirections to any single URL - this is needed because of the state that cookies introduce +MAX_SINGLE_URL_REDIRECTIONS = 4 + +# Maximum total number of redirections (regardless of URL) - before assuming we're in a loop +MAX_TOTAL_REDIRECTIONS = 10 + +# Maximum (deliberate) delay used in page stability check +MAX_STABILITY_DELAY = 0.5 + +# Reference: http://www.tcpipguide.com/free/t_DNSLabelsNamesandSyntaxRules.htm +MAX_DNS_LABEL = 63 + +# Alphabet used for prefix and suffix strings of name resolution requests in DNS technique (excluding hexadecimal chars for not mixing with inner content) +DNS_BOUNDARIES_ALPHABET = re.sub(r"[a-fA-F]", "", string.ascii_letters) + +# Alphabet used for heuristic checks +HEURISTIC_CHECK_ALPHABET = ('"', '\'', ')', '(', ',', '.') + +# Minor artistic touch +BANNER = re.sub(r"\[.\]", lambda _: "[\033[01;41m%s\033[01;49m]" % random.sample(HEURISTIC_CHECK_ALPHABET, 1)[0], BANNER) + +# String used for dummy non-SQLi (e.g. XSS) heuristic checks of a tested parameter value +DUMMY_NON_SQLI_CHECK_APPENDIX = "<'\">" + +# Regular expression used for recognition of file inclusion errors +FI_ERROR_REGEX = r"(?i)[^\n]{0,100}(no such file|failed (to )?open)[^\n]{0,100}" + +# Length of prefix and suffix used in non-SQLI heuristic checks +NON_SQLI_CHECK_PREFIX_SUFFIX_LENGTH = 6 + +# Connection read size (processing large responses in parts to avoid MemoryError crashes - e.g. large table dump in full UNION injections) +MAX_CONNECTION_READ_SIZE = 10 * 1024 * 1024 + +# Maximum response total page size (trimmed if larger) +MAX_CONNECTION_TOTAL_SIZE = 100 * 1024 * 1024 + +# For preventing MemoryError exceptions (caused when using large sequences in difflib.SequenceMatcher) +MAX_DIFFLIB_SEQUENCE_LENGTH = 10 * 1024 * 1024 + +# Maximum (multi-threaded) length of entry in bisection algorithm +MAX_BISECTION_LENGTH = 50 * 1024 * 1024 + +# Mark used for trimming unnecessary content in large connection reads +LARGE_READ_TRIM_MARKER = "__TRIMMED_CONTENT__" + +# Generic SQL comment formation +GENERIC_SQL_COMMENT = "-- [RANDSTR]" + +# Threshold value for turning back on time auto-adjustment mechanism +VALID_TIME_CHARS_RUN_THRESHOLD = 100 + +# Check for empty columns only if table is sufficiently large +CHECK_ZERO_COLUMNS_THRESHOLD = 10 + +# Boldify all logger messages containing these "patterns" +BOLD_PATTERNS = ("' injectable", "provided empty", "leftover chars", "might be injectable", "' is vulnerable", "is not injectable", "does not seem to be", "test failed", "test passed", "live test final result", "test shows that", "the back-end DBMS is", "created Github", "blocked by the target server", "protection is involved", "CAPTCHA", "specific response", "NULL connection is supported", "PASSED", "FAILED", "for more than", "connection to ") + +# TLDs used in randomization of email-alike parameter values +RANDOMIZATION_TLDS = ("com", "net", "ru", "org", "de", "jp", "cn", "fr", "it", "pl", "tv", "edu", "in", "ir", "es", "me", "info", "gr", "gov", "ca", "co", "se", "cz", "to", "vn", "nl", "cc", "az", "hu", "ua", "be", "no", "biz", "io", "ch", "ro", "sk", "eu", "us", "tw", "pt", "fi", "at", "lt", "kz", "cl", "hr", "pk", "lv", "la", "pe") + +# Generic www root directory names +GENERIC_DOC_ROOT_DIRECTORY_NAMES = ("htdocs", "httpdocs", "public", "wwwroot", "www") + +# Maximum length of a help part containing switch/option name(s) +MAX_HELP_OPTION_LENGTH = 18 + +# Maximum number of connection retries (to prevent problems with recursion) +MAX_CONNECT_RETRIES = 100 + +# Strings for detecting formatting errors +FORMAT_EXCEPTION_STRINGS = ("Type mismatch", "Error converting", "Please enter a", "Conversion failed", "String or binary data would be truncated", "Failed to convert", "unable to interpret text value", "Input string was not in a correct format", "System.FormatException", "java.lang.NumberFormatException", "ValueError: invalid literal", "TypeMismatchException", "CF_SQL_INTEGER", "CF_SQL_NUMERIC", " for CFSQLTYPE ", "cfqueryparam cfsqltype", "InvalidParamTypeException", "Invalid parameter type", "Attribute validation error for tag", "is not of type numeric", "__VIEWSTATE[^"]*)[^>]+value="(?P[^"]+)' + +# Regular expression used for extracting ASP.NET event validation values +EVENTVALIDATION_REGEX = r'(?i)(?P__EVENTVALIDATION[^"]*)[^>]+value="(?P[^"]+)' + +# Number of rows to generate inside the full union test for limited output (mustn't be too large to prevent payload length problems) +LIMITED_ROWS_TEST_NUMBER = 15 + +# Default adapter to use for bottle server +RESTAPI_DEFAULT_ADAPTER = "wsgiref" + +# Default REST-JSON API server listen address +RESTAPI_DEFAULT_ADDRESS = "127.0.0.1" + +# Default REST-JSON API server listen port +RESTAPI_DEFAULT_PORT = 8775 + +# Use "Supplementary Private Use Area-A" +INVALID_UNICODE_PRIVATE_AREA = False + +# Format used for representing invalid unicode characters +INVALID_UNICODE_CHAR_FORMAT = r"\x%02x" + +# Regular expression for XML POST data +XML_RECOGNITION_REGEX = r"(?s)\A\s*<[^>]+>(.+>)?\s*\Z" + +# Regular expression used for detecting JSON POST data +JSON_RECOGNITION_REGEX = r'(?s)\A(\s*\[)*\s*\{.*"[^"]+"\s*:\s*("[^"]*"|\d+|true|false|null|\[).*\}\s*(\]\s*)*\Z' + +# Regular expression used for detecting JSON-like POST data +JSON_LIKE_RECOGNITION_REGEX = r"(?s)\A(\s*\[)*\s*\{.*'[^']+'\s*:\s*('[^']+'|\d+).*\}\s*(\]\s*)*\Z" + +# Regular expression used for detecting multipart POST data +MULTIPART_RECOGNITION_REGEX = r"(?i)Content-Disposition:[^;]+;\s*name=" + +# Regular expression used for detecting Array-like POST data +ARRAY_LIKE_RECOGNITION_REGEX = r"(\A|%s)(\w+)\[\]=.+%s\2\[\]=" % (DEFAULT_GET_POST_DELIMITER, DEFAULT_GET_POST_DELIMITER) + +# Default POST data content-type +DEFAULT_CONTENT_TYPE = "application/x-www-form-urlencoded; charset=utf-8" + +# Raw text POST data content-type +PLAIN_TEXT_CONTENT_TYPE = "text/plain; charset=utf-8" + +# Length used while checking for existence of Suhosin-patch (like) protection mechanism +SUHOSIN_MAX_VALUE_LENGTH = 512 + +# Minimum size of an (binary) entry before it can be considered for dumping to disk +MIN_BINARY_DISK_DUMP_SIZE = 100 + +# Filenames of payloads xml files (in order of loading) +PAYLOAD_XML_FILES = ("boolean_blind.xml", "error_based.xml", "inline_query.xml", "stacked_queries.xml", "time_blind.xml", "union_query.xml", "customized.xml") + +# Regular expression used for extracting form tags +FORM_SEARCH_REGEX = r"(?si)" + +# Maximum number of lines to save in history file +MAX_HISTORY_LENGTH = 1000 + +# Minimum field entry length needed for encoded content (hex, base64,...) check +MIN_ENCODED_LEN_CHECK = 5 + +# Timeout in seconds in which Metasploit remote session has to be initialized +METASPLOIT_SESSION_TIMEOUT = 120 + +# Reference: http://www.postgresql.org/docs/9.0/static/catalog-pg-largeobject.html +LOBLKSIZE = 2048 + +# Prefix used to mark special variables (e.g. keywords, having special chars, etc.) +EVALCODE_ENCODED_PREFIX = "EVAL_" + +# Reference: https://en.wikipedia.org/wiki/Zip_(file_format) +ZIP_HEADER = b"\x50\x4b\x03\x04" + +# Reference: http://www.cookiecentral.com/faq/#3.5 +NETSCAPE_FORMAT_HEADER_COOKIES = "# Netscape HTTP Cookie File." + +# Infixes used for automatic recognition of parameters carrying anti-CSRF tokens +CSRF_TOKEN_PARAMETER_INFIXES = ("csrf", "xsrf", "token") + +# Prefixes used in brute force search for web server document root +BRUTE_DOC_ROOT_PREFIXES = { + OS.LINUX: ("/var/www", "/usr/local/apache", "/usr/local/apache2", "/usr/local/www/apache22", "/usr/local/www/apache24", "/usr/local/httpd", "/var/www/nginx-default", "/srv/www", "/var/www/%TARGET%", "/var/www/vhosts/%TARGET%", "/var/www/virtual/%TARGET%", "/var/www/clients/vhosts/%TARGET%", "/var/www/clients/virtual/%TARGET%"), + OS.WINDOWS: ("/xampp", "/Program Files/xampp", "/wamp", "/Program Files/wampp", "/apache", "/Program Files/Apache Group/Apache", "/Program Files/Apache Group/Apache2", "/Program Files/Apache Group/Apache2.2", "/Program Files/Apache Group/Apache2.4", "/Inetpub/wwwroot", "/Inetpub/wwwroot/%TARGET%", "/Inetpub/vhosts/%TARGET%") +} + +# Suffixes used in brute force search for web server document root +BRUTE_DOC_ROOT_SUFFIXES = ("", "html", "htdocs", "httpdocs", "php", "public", "src", "site", "build", "web", "www", "data", "sites/all", "www/build") + +# String used for marking target name inside used brute force web server document root +BRUTE_DOC_ROOT_TARGET_MARK = "%TARGET%" + +# Character used as a boundary in kb.chars (preferably less frequent letter) +KB_CHARS_BOUNDARY_CHAR = 'q' + +# Letters of lower frequency used in kb.chars +KB_CHARS_LOW_FREQUENCY_ALPHABET = "zqxjkvbp" + +# SQL keywords used for splitting in HTTP chunked transfer encoded requests (switch --chunk) +HTTP_CHUNKED_SPLIT_KEYWORDS = ("SELECT", "UPDATE", "INSERT", "FROM", "LOAD_FILE", "UNION", "information_schema", "sysdatabases", "msysaccessobjects", "msysqueries", "sysmodules") + +# CSS style used in HTML dump format +HTML_DUMP_CSS_STYLE = """""" + +# Leaving (dirty) possibility to change values from here (e.g. `export SQLMAP__MAX_NUMBER_OF_THREADS=20`) +for key, value in os.environ.items(): + if key.upper().startswith("%s_" % SQLMAP_ENVIRONMENT_PREFIX): + _ = key[len(SQLMAP_ENVIRONMENT_PREFIX) + 1:].upper() + if _ in globals(): + original = globals()[_] + if isinstance(original, int): + try: + globals()[_] = int(value) + except ValueError: + pass + elif isinstance(original, bool): + globals()[_] = value.lower() in ('1', 'true') + elif isinstance(original, (list, tuple)): + globals()[_] = [__.strip() for __ in _.split(',')] + else: + globals()[_] = value + +# Installing "reversible" unicode (decoding) error handler +def _reversible(ex): + if INVALID_UNICODE_PRIVATE_AREA: + return (u"".join(_unichr(int('000f00%2x' % (_ if isinstance(_, int) else ord(_)), 16)) for _ in ex.object[ex.start:ex.end]), ex.end) + else: + return (u"".join(INVALID_UNICODE_CHAR_FORMAT % (_ if isinstance(_, int) else ord(_)) for _ in ex.object[ex.start:ex.end]), ex.end) + +codecs.register_error("reversible", _reversible)