0x002 sqlmap的参数解析
重新看到cmdLineParser()
函数
首先检测是否存在argv
,如果没有则设置为系统默认的命令行参数
再调用checkSystemEncoding()
函数来检测系统的编码设置,确保后续能够正确的处理字符编码
调用os.path.basename(argv[0])
来获取脚本的文件名,再通过getUnicode()
函数来将其转换为合适的编码格式
构建命令行工具的使用说明usage
.根据当前环境的不同,将可执行文件的路径和脚本文件名组合成一个使用说明字符串
创建了参数解析器ArgumentParser
,设置了工具的使用说明为上一步构建的usage
字符串
再往下就是参数列表了(Target options
等等)
接下来我们回到init()
函数中
def init():
"""
Set attributes into both configuration and knowledge base singletons
based upon command line and configuration file options.
"""
_useWizardInterface()
setVerbosity() # 设置sqlmap输出的详细程度
_saveConfig() # 将命令行选项保存到sqlmap配置的ini文件中
_setRequestFromFile() # 从传入的文件中获取url
_cleanupOptions() # 清除配置文件
_cleanupEnvironment() # 清除环境变量
_purge() # 安全的删除sqlmap根目录下的数据
_checkDependencies() # 检查是否缺少依赖项
_createHomeDirectories()
_createTemporaryDirectory()
_basicOptionValidation()
_setProxyList()
_setTorProxySettings()
_setDNSServer()
_adjustLoggingFormatter()
_setMultipleTargets()
_listTamperingFunctions()
_setTamperingFunctions() # 设置tamper脚本
_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()
这边我们先看_setRequestFromFile()
方法,先来理解,如果我们通过-r
传递一个文本文件,sqlmap
是如何理解并转换成参数的呢
if conf.requestFile:
for requestFile in re.split(PARAMETER_SPLITTING_REGEX, conf.requestFile):
requestFile = safeExpandUser(requestFile)
url = None
seen = set()
if not checkFile(requestFile, False):
errMsg = "specified HTTP request file '%s' " % requestFile
errMsg += "does not exist"
raise SqlmapFilePathException(errMsg)
先调用了re.split()
方法对我们传入的conf.requestFile
变量进行拆分,查询setting.py
我们可以找到PARAMETER_SPLITTING_REGEX = r"[,|;]"
然后再调用safeExpandUser()
函数,确保路径的稳定性和可靠性
在调用checkFile()
函数确保文件的存在和可读.否则就报错specified HTTP request file
&&does not exist
当文件确认没有问题的时候,就开始获取目标的URL
for target in parseRequestFile(requestFile):
url = target[0]
if url not in seen:
kb.targets.add(target)
if len(kb.targets) > 1:
conf.multipleTargets = True
seen.add(url)
跟进parseRequestFile()
函数
def parseRequestFile(reqFile, checkParams=True):
"""
Parses WebScarab and Burp logs and adds results to the target URL list
>>> handle, reqFile = tempfile.mkstemp(suffix=".req")
>>> content = b"POST / HTTP/1.0\\nUser-agent: foobar\\nHost: www.example.com\\n\\nid=1\\n"
>>> _ = os.write(handle, content)
>>> os.close(handle)
>>> next(parseRequestFile(reqFile)) == ('http://www.example.com:80/', 'POST', 'id=1', None, (('User-agent', 'foobar'), ('Host', 'www.example.com')))
True
"""
这里并没有给出这个函数的实现方法,但是把返回值展示了出来,如果我们传入一个WebScarab
或者burp
日志,通过这个函数会返回一个数组,其中target[0]
就是URL
回到_setRequestFromFile()
函数,如果url
不在seen
中,就会自动把url
加入到seen
中
下面就是如果有第二个请求接下来的处理,我们先略过
经过_setRequestFromFile()
函数后,如果我们传入的req
文件没有问题的话,此时seen
中就有了url
属性
然后再经过init
后半段代码,将这些属性初始化