sqlmap源码阅读系列init中的_cleanupOptions
有很多人说sqlmap的源码很难,也有人说sqlmap的源码非常值得一读。我觉得这就像小马过河一样,你不读你就没有发言权。对我而言,截至目前,sqlmap的源码还在可以理解的范围内,至少要比unittest的源码简单。
看来init()
def init():
"""
Set attributes into both configuration and knowledge base singletons
based upon command line and configuration file options.
"""
# sqlmap --wizard 为了新手的提示页面
_useWizardInterface()
# sqlmap -v 来控制日志级别
setVerbosity()
# sqmap --save Save options to a configuration INI file
_saveConfig()
# sqlmap -r从文件里面载入http请求
_setRequestFromFile()
# 这里没有读懂 2021-12-2
_cleanupOptions()
_cleanupEnvironment()
_purge()
_checkDependencies()
_createHomeDirectories()
_createTemporaryDirectory()
_basicOptionValidation()
_setProxyList()
_setTorProxySettings()
_setDNSServer()
_adjustLoggingFormatter()
_setMultipleTargets()
_listTamperingFunctions()
_setTamperingFunctions()
_setPreprocessFunctions()
_setPostprocessFunctions()
_setTrafficOutputFP()
_setupHTTPCollector()
_setHttpChunked()
_checkWebSocket()
parseTargetDirect()
if any((conf.url, conf.logFile, conf.bulkFile, conf.requestFile, conf.googleDork, conf.stdinPipe)):
_setHostname()
_setHTTPTimeout()
_setHTTPExtraHeaders()
_setHTTPCookies()
_setHTTPReferer()
_setHTTPHost()
_setHTTPUserAgent()
_setHTTPAuthentication()
_setHTTPHandlers()
_setDNSCache()
_setSocketPreConnect()
_setSafeVisit()
_doSearch()
_setStdinPipeTargets()
_setBulkMultipleTargets()
_checkTor()
_setCrawler()
_findPageForms()
_setDBMS()
_setTechnique()
_setThreads()
_setOS()
_setWriteFile()
_setMetasploit()
_setDBMSAuthentication()
loadBoundaries()
loadPayloads()
_setPrefixSuffix()
update()
_loadQueries()
_cleanupOptions() 这个函数的阅读
def _cleanupOptions():
"""
Cleanup configuration attributes.
"""
if conf.encoding:
try:
codecs.lookup(conf.encoding)
except LookupError:
errMsg = "unknown encoding '%s'" % conf.encoding
raise SqlmapValueException(errMsg)
debugMsg = "cleaning up configuration parameters"
logger.debug(debugMsg)
width = getConsoleWidth()
if conf.eta:
conf.progressWidth = width - 26
else:
conf.progressWidth = width - 46
for key, value in conf.items():
if value and any(key.endswith(_) for _ in ("Path", "File", "Dir")):
if isinstance(value, str):
conf[key] = safeExpandUser(value)
# 获取测试参数,对应于sqlmap -p
if conf.testParameter:
conf.testParameter = urldecode(conf.testParameter)
conf.testParameter = [_.strip() for _ in re.split(PARAMETER_SPLITTING_REGEX, conf.testParameter)]
else:
conf.testParameter = []
if conf.ignoreCode:
if conf.ignoreCode == IGNORE_CODE_WILDCARD:
conf.ignoreCode = xrange(0, 1000)
else:
try:
conf.ignoreCode = [int(_) for _ in re.split(PARAMETER_SPLITTING_REGEX, conf.ignoreCode)]
except ValueError:
errMsg = "options '--ignore-code' should contain a list of integer values or a wildcard value '%s'" % IGNORE_CODE_WILDCARD
raise SqlmapSyntaxException(errMsg)
else:
conf.ignoreCode = []
# sqlmap --param-filter 选择可以测试的参数位置,例如 POST|GET|
if conf.paramFilter:
conf.paramFilter = [_.strip() for _ in re.split(PARAMETER_SPLITTING_REGEX, conf.paramFilter.upper())]
else:
conf.paramFilter = []
if conf.base64Parameter:
conf.base64Parameter = urldecode(conf.base64Parameter)
conf.base64Parameter = conf.base64Parameter.strip()
conf.base64Parameter = re.split(PARAMETER_SPLITTING_REGEX, conf.base64Parameter)
else:
conf.base64Parameter = []
# 对应于sqlmap --user-agent
if conf.agent:
conf.agent = re.sub(r"[\r\n]", "", conf.agent)
if conf.user:
conf.user = conf.user.replace(" ", "")
# 对应于sqlmap --randomize. Randomly change value for given parameter(s)
if conf.rParam:
if all(_ in conf.rParam for _ in ('=', ',')):
original = conf.rParam
conf.rParam = []
for part in original.split(';'):
if '=' in part:
left, right = part.split('=', 1)
conf.rParam.append(left)
kb.randomPool[left] = filterNone(_.strip() for _ in right.split(','))
else:
conf.rParam.append(part)
else:
conf.rParam = conf.rParam.replace(" ", "")
conf.rParam = re.split(PARAMETER_SPLITTING_REGEX, conf.rParam)
else:
conf.rParam = []
if conf.paramDel:
conf.paramDel = decodeStringEscape(conf.paramDel)
if conf.skip:
conf.skip = conf.skip.replace(" ", "")
conf.skip = re.split(PARAMETER_SPLITTING_REGEX, conf.skip)
else:
conf.skip = []
if conf.cookie:
conf.cookie = re.sub(r"[\r\n]", "", conf.cookie)
# 对应于sqlmap --delay, 后面有这样的代码time.sleep(conf.delay)
if conf.delay:
conf.delay = float(conf.delay)
if conf.url:
conf.url = conf.url.strip().lstrip('/')
if not re.search(r"\A\w+://", conf.url):
conf.url = "http://%s" % conf.url
if conf.fileRead:
conf.fileRead = ntToPosixSlashes(normalizePath(conf.fileRead))
if conf.fileWrite:
conf.fileWrite = ntToPosixSlashes(normalizePath(conf.fileWrite))
if conf.fileDest:
conf.fileDest = ntToPosixSlashes(normalizePath(conf.fileDest))
if conf.msfPath:
conf.msfPath = ntToPosixSlashes(normalizePath(conf.msfPath))
if conf.tmpPath:
conf.tmpPath = ntToPosixSlashes(normalizePath(conf.tmpPath))
if any((conf.googleDork, conf.logFile, conf.bulkFile, conf.forms, conf.crawlDepth, conf.stdinPipe)):
conf.multipleTargets = True
if conf.optimize:
setOptimize()
if conf.os:
conf.os = conf.os.capitalize()
if conf.forceDbms:
conf.dbms = conf.forceDbms
if conf.dbms:
kb.dbmsFilter = []
for _ in conf.dbms.split(','):
for dbms, aliases in DBMS_ALIASES:
if _.strip().lower() in aliases:
kb.dbmsFilter.append(dbms)
conf.dbms = dbms if conf.dbms and ',' not in conf.dbms else None
break
if conf.testFilter:
conf.testFilter = conf.testFilter.strip('*+')
conf.testFilter = re.sub(r"([^.])([*+])", r"\g<1>.\g<2>", conf.testFilter)
try:
re.compile(conf.testFilter)
except re.error:
conf.testFilter = re.escape(conf.testFilter)
if conf.csrfToken:
original = conf.csrfToken
try:
re.compile(conf.csrfToken)
if re.escape(conf.csrfToken) != conf.csrfToken:
message = "provided value for option '--csrf-token' is a regular expression? [y/N] "
if not readInput(message, default='N', boolean=True):
conf.csrfToken = re.escape(conf.csrfToken)
except re.error:
conf.csrfToken = re.escape(conf.csrfToken)
finally:
class _(six.text_type):
pass
conf.csrfToken = _(conf.csrfToken)
conf.csrfToken._original = original
if conf.testSkip:
conf.testSkip = conf.testSkip.strip('*+')
conf.testSkip = re.sub(r"([^.])([*+])", r"\g<1>.\g<2>", conf.testSkip)
try:
re.compile(conf.testSkip)
except re.error:
conf.testSkip = re.escape(conf.testSkip)
if "timeSec" not in kb.explicitSettings:
if conf.tor:
conf.timeSec = 2 * conf.timeSec
kb.adjustTimeDelay = ADJUST_TIME_DELAY.DISABLE
warnMsg = "increasing default value for "
warnMsg += "option '--time-sec' to %d because " % conf.timeSec
warnMsg += "switch '--tor' was provided"
logger.warn(warnMsg)
else:
kb.adjustTimeDelay = ADJUST_TIME_DELAY.DISABLE
if conf.retries:
conf.retries = min(conf.retries, MAX_CONNECT_RETRIES)
if conf.code:
conf.code = int(conf.code)
if conf.csvDel:
conf.csvDel = decodeStringEscape(conf.csvDel)
if conf.torPort and hasattr(conf.torPort, "isdigit") and conf.torPort.isdigit():
conf.torPort = int(conf.torPort)
if conf.torType:
conf.torType = conf.torType.upper()
if conf.outputDir:
paths.SQLMAP_OUTPUT_PATH = os.path.realpath(os.path.expanduser(conf.outputDir))
setPaths(paths.SQLMAP_ROOT_PATH)
if conf.string:
conf.string = decodeStringEscape(conf.string)
if conf.getAll:
for _ in WIZARD.ALL:
conf.__setitem__(_, True)
if conf.noCast:
DUMP_REPLACEMENTS.clear()
if conf.dumpFormat:
conf.dumpFormat = conf.dumpFormat.upper()
if conf.torType:
conf.torType = conf.torType.upper()
if conf.col:
conf.col = re.sub(r"\s*,\s*", ',', conf.col)
if conf.exclude:
regex = False
original = conf.exclude
if any(_ in conf.exclude for _ in ('+', '*')):
try:
re.compile(conf.exclude)
except re.error:
pass
else:
regex = True
if not regex:
conf.exclude = re.sub(r"\s*,\s*", ',', conf.exclude)
conf.exclude = r"\A%s\Z" % '|'.join(re.escape(_) for _ in conf.exclude.split(','))
else:
conf.exclude = re.sub(r"(\w+)\$", r"\g<1>\$", conf.exclude)
class _(six.text_type):
pass
conf.exclude = _(conf.exclude)
conf.exclude._original = original
if conf.binaryFields:
conf.binaryFields = conf.binaryFields.replace(" ", "")
conf.binaryFields = re.split(PARAMETER_SPLITTING_REGEX, conf.binaryFields)
envProxy = max(os.environ.get(_, "") for _ in PROXY_ENVIRONMENT_VARIABLES)
if re.search(r"\A(https?|socks[45])://.+:\d+\Z", envProxy) and conf.proxy is None:
debugMsg = "using environment proxy '%s'" % envProxy
logger.debug(debugMsg)
conf.proxy = envProxy
if any((conf.proxy, conf.proxyFile, conf.tor)):
conf.disablePrecon = True
if conf.dummy:
conf.batch = True
threadData = getCurrentThreadData()
threadData.reset()
sqlmap --param-filter Select testable parameter(s) by place
选择可供注入的参数的位置。
有哪些可以注入的位置可以参考下图
一个人走得很快,一群人走的更远,后续我打算搞个交流群,感兴趣的童鞋可以关注一波