mirror of
https://github.com/sqlmapproject/sqlmap.git
synced 2026-10-12 02:22:55 +00:00
Minor patch
This commit is contained in:
@@ -33,6 +33,7 @@ optDict = {
|
||||
"liveCookies": "string",
|
||||
"loadCookies": "string",
|
||||
"dropSetCookie": "boolean",
|
||||
"http10": "boolean",
|
||||
"http2": "boolean",
|
||||
"agent": "string",
|
||||
"mobile": "boolean",
|
||||
@@ -120,6 +121,7 @@ optDict = {
|
||||
|
||||
"Techniques": {
|
||||
"technique": "string",
|
||||
"disableStats": "boolean",
|
||||
"nosql": "boolean",
|
||||
"graphql": "boolean",
|
||||
"ldap": "boolean",
|
||||
@@ -260,6 +262,7 @@ optDict = {
|
||||
"scope": "string",
|
||||
"skipHeuristics": "boolean",
|
||||
"skipWaf": "boolean",
|
||||
"tablePrefix": "string",
|
||||
"testFilter": "string",
|
||||
"testSkip": "string",
|
||||
"timeLimit": "float",
|
||||
|
||||
@@ -20,7 +20,7 @@ from lib.core.enums import OS
|
||||
from thirdparty import six
|
||||
|
||||
# sqlmap version (<major>.<minor>.<month>.<monthly commit>)
|
||||
VERSION = "1.10.8.24"
|
||||
VERSION = "1.10.8.25"
|
||||
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)
|
||||
|
||||
+5
-13
@@ -32,6 +32,10 @@ requestFile =
|
||||
# Example: +ext:php +inurl:"&id=" +intext:"powered by "
|
||||
googleDork =
|
||||
|
||||
# Load session from a stored (.sqlite) file
|
||||
# Example: output/www.target.com/session.sqlite
|
||||
sessionFile =
|
||||
|
||||
|
||||
# These options can be used to specify how to connect to the target URL.
|
||||
[Request]
|
||||
@@ -240,10 +244,6 @@ evalCode =
|
||||
# Valid: True or False
|
||||
optimize = False
|
||||
|
||||
# Predict common queries output.
|
||||
# Valid: True or False
|
||||
predictOutput = False
|
||||
|
||||
# Use persistent HTTP(s) connections.
|
||||
keepAlive = False
|
||||
|
||||
@@ -606,7 +606,7 @@ sqlFile =
|
||||
|
||||
|
||||
# These options can be used to run brute force checks.
|
||||
[Brute force]
|
||||
[Brute]
|
||||
|
||||
# Check existence of common tables.
|
||||
# Valid: True or False
|
||||
@@ -720,10 +720,6 @@ regType =
|
||||
# These options can be used to set some general working parameters.
|
||||
[General]
|
||||
|
||||
# Load session from a stored (.sqlite) file
|
||||
# Example: output/www.target.com/session.sqlite
|
||||
sessionFile =
|
||||
|
||||
# Log all HTTP traffic into a textual file.
|
||||
trafficFile =
|
||||
|
||||
@@ -861,10 +857,6 @@ alert =
|
||||
# Valid: True or False
|
||||
beep = False
|
||||
|
||||
# Offline WAF/IPS payload detection testing.
|
||||
# Valid: True or False
|
||||
checkPayload = False
|
||||
|
||||
# Check for missing (optional) sqlmap dependencies.
|
||||
# Valid: True or False
|
||||
dependencies = False
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Copyright (c) 2006-2026 sqlmap developers (https://sqlmap.org)
|
||||
See the file 'LICENSE' for copying permission
|
||||
|
||||
Offline tests for the '-c' configuration-file contract.
|
||||
|
||||
configFileParser() walks optDict and reads an option only from the section named after the family that
|
||||
declares it, so an option is silently dropped - a debug line, nothing else - when the shipped template
|
||||
and optDict disagree about either its NAME or its SECTION. Both halves of that contract are pinned here
|
||||
because both had already drifted: three real switches were missing from optDict entirely, the
|
||||
[Brute force] section could never match the "Brute" family, 'sessionFile' sat under [General] while it
|
||||
is declared under Target, and two options outlived the switches they configured.
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
||||
from _testutils import bootstrap
|
||||
bootstrap()
|
||||
|
||||
from lib.core.optiondict import optDict
|
||||
|
||||
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||
CONFIG = os.path.join(ROOT, "sqlmap.conf")
|
||||
|
||||
_SECTION_REGEX = re.compile(r"^\[(?P<name>.+)\]\s*$")
|
||||
_OPTION_REGEX = re.compile(r"^(?P<name>[A-Za-z][A-Za-z0-9_]*)\s*=")
|
||||
|
||||
|
||||
def _configOptions():
|
||||
"""Every (section, option) pair the shipped template declares, in file order."""
|
||||
|
||||
retVal, section = [], None
|
||||
|
||||
with open(CONFIG) as f:
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
match = _SECTION_REGEX.match(line)
|
||||
if match:
|
||||
section = match.group("name")
|
||||
continue
|
||||
match = _OPTION_REGEX.match(line)
|
||||
if match:
|
||||
retVal.append((section, match.group("name")))
|
||||
|
||||
return retVal
|
||||
|
||||
|
||||
def _sources():
|
||||
retVal = []
|
||||
|
||||
for root in ("lib", "plugins"):
|
||||
for base, _, files in os.walk(os.path.join(ROOT, root)):
|
||||
for name in files:
|
||||
if name.endswith(".py"):
|
||||
with open(os.path.join(base, name)) as f:
|
||||
retVal.append(f.read())
|
||||
|
||||
return "\n".join(retVal)
|
||||
|
||||
|
||||
class TestConfigFileContract(unittest.TestCase):
|
||||
def test_template_is_not_empty(self):
|
||||
self.assertGreater(len(_configOptions()), 100)
|
||||
|
||||
def test_every_option_is_readable_from_its_section(self):
|
||||
"""The actual lookup configFileProxy() performs: optDict[section][option]."""
|
||||
|
||||
unreadable = ["[%s] %s" % (section, option) for section, option in _configOptions()
|
||||
if option not in optDict.get(section, {})]
|
||||
self.assertEqual(unreadable, [], "silently ignored when set via '-c': %s" % ", ".join(unreadable))
|
||||
|
||||
def test_every_section_names_a_family(self):
|
||||
sections = set(section for section, _ in _configOptions())
|
||||
self.assertEqual(sorted(sections - set(optDict)), [])
|
||||
|
||||
def test_no_option_outlives_its_switch(self):
|
||||
"""An option nothing reads any more is worse than absent: it reads as supported and does
|
||||
nothing. Consumption is either a 'conf.<name>' reference or a lookup by name (the API and the
|
||||
library facade address options as strings)."""
|
||||
|
||||
sources = _sources()
|
||||
orphans = sorted(set(option for _, option in _configOptions()
|
||||
if not re.search(r"\bconf\.%s\b" % option, sources) and '"%s"' % option not in sources))
|
||||
self.assertEqual(orphans, [], "configure nothing: %s" % ", ".join(orphans))
|
||||
|
||||
|
||||
class TestConfigFileRoundTrip(unittest.TestCase):
|
||||
"""'--save' writes through the same optDict families, and the library facade serializes its kwargs
|
||||
that way before handing them over as '-c'. So a config sqlmap writes must be one sqlmap can read."""
|
||||
|
||||
def test_saved_config_reads_back(self):
|
||||
import tempfile
|
||||
|
||||
from lib.core.common import saveConfig
|
||||
from lib.core.data import conf
|
||||
from lib.parse.configfile import configFileParser
|
||||
|
||||
handle, path = tempfile.mkstemp(suffix=".ini")
|
||||
os.close(handle)
|
||||
|
||||
try:
|
||||
conf.url = "http://127.0.0.1:1/?id=1"
|
||||
conf.commonTables = True
|
||||
conf.tablePrefix = "zzz"
|
||||
saveConfig(conf, path)
|
||||
|
||||
conf.clear()
|
||||
configFileParser(path)
|
||||
|
||||
self.assertEqual(conf.url, "http://127.0.0.1:1/?id=1")
|
||||
self.assertTrue(conf.commonTables)
|
||||
self.assertEqual(conf.tablePrefix, "zzz")
|
||||
finally:
|
||||
os.unlink(path)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main(verbosity=2)
|
||||
Reference in New Issue
Block a user