def __saveCmdline(): """ Saves the commandlineoptionsona sqlmap configuration INI file Format. """
if not conf.saveCmdline: return
debugMsg = "saving command line options on a sqlmap configuration INI file" logger.debug(debugMsg)
config = UnicodeRawConfigParser() userOpts = {}
for family in optDict.keys(): userOpts[family] = []
for option, value in conf.items(): for family, optionData in optDict.items(): if option in optionData: userOpts[family].append((option, value, optionData[option]))
for family, optionData in userOpts.items(): config.add_section(family)
optionData.sort()
for option, value, datatype in optionData: if isinstance(datatype, (list, tuple, set)): datatype = datatype[0]
if value is None: if datatype == "boolean": value = "False" elif datatype in ( "integer", "float" ): if option in ( "threads", "verbose" ): value = "1" elif option == "timeout": value = "10" else: value = "0" elif datatype == "string": value = ""
if isinstance(value, basestring): value = value.replace("\n", "\n ")
def__setRequestFromFile(): """ This function checks if the way to make a HTTP request is through supplied textual file, parses it and saves the information into the knowledge base. """
if method.upper() == "POST": warnMsg = "POST requests from WebScarab logs aren't supported " warnMsg += "as their body content is stored in separate files. " warnMsg += "Nevertheless you can use -r to load them individually." logger.warning(warnMsg) continue
开始解包 __parseWebScarabLog(content)
分割出数据传输方式以及端口号
1 2 3 4 5 6
if scheme is None: schemePort = re.search("\d\d[\:|\.]\d\d[\:|\.]\d\d\s+(http[\w]*)\:\/\/.*?\:([\d]+)", request, re.I)
if schemePort: scheme = schemePort.group(1) port = schemePort.group(2)
跳过一些无用的行,re.search如果搜索不到就会返回None
1 2 3 4 5
if not re.search ("^[\n]*(GET|POST).*?\sHTTP\/", request, re.I): continue
if re.search("^[\n]*(GET|POST).*?\.(gif|jpg|png)\sHTTP\/", request, re.I): continue
# Headers elif ": "in line: key, value = line.split(": ", 1)
# Cookie and Host headers if key.lower() == "cookie": cookie = value elif key.lower() == "host": if'://'in value: scheme, value = value.split('://')[:2] splitValue = value.split(":") host = splitValue[0]
if len(splitValue) > 1: port = filterStringValue(splitValue[1], '[0-9]')
ifnot scheme and port == "443": scheme = "https"
# Avoid toadd a static content length header to # conf.httpHeaders and consider the following lines as # POSTed data if key == "Content-Length": params = True
# Avoid proxy and connection type related headers elif key notin ( "Proxy-Connection", "Connection" ): conf.httpHeaders.append((str(key), str(value)))
ifconf.limitStart is not None and not (isinstance(conf.limitStart, int) andconf.limitStart > 0): errMsg = "value for --start (limitStart) option must be an integer value greater than zero (>0)" raise sqlmapSyntaxException, errMsg
ifconf.limitStop is not None and not (isinstance(conf.limitStop, int) andconf.limitStop > 0): errMsg = "value for --stop (limitStop) option must be an integer value greater than zero (>0)" raise sqlmapSyntaxException, errMsg
ifconf.limitStart is not None and isinstance(conf.limitStart, int) andconf.limitStart > 0and \ conf.limitStop is not None and isinstance(conf.limitStop, int) andconf.limitStop <= conf.limitStart: errMsg = "value for --start (limitStart) option must be smaller than value for --stop (limitStop) option" raise sqlmapSyntaxException, errMsg
ifconf.firstChar is not None and isinstance(conf.firstChar, int) andconf.firstChar > 0and \ conf.lastChar is not None and isinstance(conf.lastChar, int) andconf.lastChar < conf.firstChar: errMsg = "value for --first (firstChar) option must be smaller than or equal to value for --last (lastChar) option" raise sqlmapSyntaxException, errMsg
ifconf.cpuThrottle is not None and isinstance(conf.cpuThrottle, int) and (conf.cpuThrottle > 100orconf.cpuThrottle < 0): errMsg = "value for --cpu-throttle (cpuThrottle) option must be in range [0,100]" raise sqlmapSyntaxException, errMsg
ifconf.textOnly andconf.nullConnection: errMsg = "switch --text-only is incompatible with switch --null-connection" raise sqlmapSyntaxException, errMsg
ifconf.data andconf.nullConnection: errMsg = "switch --data is incompatible with switch --null-connection" raise sqlmapSyntaxException, errMsg
ifconf.predictOutput andconf.threads > 1: errMsg = "switch --predict-output is incompatible with switch --threads" raise sqlmapSyntaxException, errMsg
ifconf.threads > MAX_NUMBER_OF_THREADS: errMsg = "maximum number of used threads is %d avoiding possible connection issues" % MAX_NUMBER_OF_THREADS raise sqlmapSyntaxException, errMsg
ifconf.forms and not conf.url: errMsg = "switch --forms requires usage of -u (--url) switch" raise sqlmapSyntaxException, errMsg
ifconf.proxy andconf.ignoreProxy: errMsg = "switch --proxy is incompatible with switch --ignore-proxy" raise sqlmapSyntaxException, errMsg
ifconf.forms and (conf.listorconf.direct orconf.requestFile orconf.googleDork): errMsg = "switch --forms is compatible only with -u (--url) target switch" raise sqlmapSyntaxException, errMsg
ifconf.timeSec < 1: errMsg = "value for --time-sec option must be an integer greater than 0" raise sqlmapSyntaxException, errMsg
if isinstance(conf.uCols, basestring) and ("-" not in conf.uCols orlen(conf.uCols.split("-")) != 2): errMsg = "value for --union-cols must be a range with hyphon (e.g. 1-10)" raise sqlmapSyntaxException, errMsg
if dbmsName in (DBMS.MSSQL, DBMS.SYBASE): import _mssql import pymssql
if not hasattr(pymssql, "__version__") or pymssql.__version__ < "1.0.2": errMsg = "pymssql library on your system must be " errMsg += "version 1.0.2 to work, get it from " errMsg += "http://sourceforge.net/projects/pymssql/files/pymssql/1.0.2/" raise sqlmapMissingDependence, errMsg
ifconf.headers: debugMsg = "setting extra HTTP headers" logger.debug(debugMsg)
conf.headers = conf.headers.split("\n") if"\n" in conf.headers elseconf.headers.split("\\n")
for headerValue in conf.headers: if not headerValue.strip(): continue
if headerValue.count(':') >= 1: header, value = (_.lstrip() for _ in headerValue.split(":", 1))
if header and value: conf.httpHeaders.append((header, value)) else: errMsg = "invalid header value: %s. Valid header format is 'name:value'" % repr(headerValue).lstrip('u') raise SqlmapSyntaxException(errMsg)
elif not conf.requestFile andlen(conf.httpHeaders or []) < 2: conf.httpHeaders.append((HTTP_HEADER.ACCEPT_LANGUAGE, "en-us,en;q=0.5")) if not conf.charset: conf.httpHeaders.append((HTTP_HEADER.ACCEPT_CHARSET, "ISO-8859-15,utf-8;q=0.7,*;q=0.7")) else: conf.httpHeaders.append((HTTP_HEADER.ACCEPT_CHARSET, "%s;q=0.7,*;q=0.1" % conf.charset))
# Invalidating any caching mechanism in between # Reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html conf.httpHeaders.append((HTTP_HEADER.CACHE_CONTROL, "no-cache,no-store")) conf.httpHeaders.append((HTTP_HEADER.PRAGMA, "no-cache"))
设置cookie
_setHTTPCookies()
把cookie加入到conf.httpHeaders列表中
1 2 3 4 5
ifconf.cookie: debugMsg = "setting the HTTP Cookie header" logger.debug(debugMsg)
forline in raw[raw.find('\n') + 1:].split('\n'): line = line.strip() iflineand':' in line: key, value = line.split(':', 1) value = value.strip() kb.safeReq.headers[key] = value if key == HTTP_HEADER.HOST: if not value.startswith("http"): scheme = "http" if value.endswith(":443"): scheme = "https" value = "%s://%s" % (scheme, value) kb.safeReq.url = urlparse.urljoin(value, kb.safeReq.url) else: break
post = None
if'\r\n\r\n' in raw: post = raw[raw.find('\r\n\r\n') + 4:] elif '\n\n' in raw: post = raw[raw.find('\n\n') + 2:]
if post and post.strip(): kb.safeReq.post = post else: kb.safeReq.post = None
conf.dbms = conf.dbms.lower() regex = re.search("%s ([\d\.]+)" % ("(%s)" % "|".join([alias for alias in SUPPORTED_DBMS])), conf.dbms, re.I)
if regex: conf.dbms = regex.group(1) Backend.setVersion(regex.group(2))
ifconf.dbms not in SUPPORTED_DBMS: errMsg = "you provided an unsupported back-end database management " errMsg += "system. Supported DBMSes are as follows: %s. " % ', '.join(sorted(_ for _ in DBMS_DICT)) errMsg += "If you do not know the back-end DBMS, do not provide " errMsg += "it and sqlmap will fingerprint it for you." raise SqlmapUnsupportedDBMSException(errMsg)
for dbms, aliases in DBMS_ALIASES: ifconf.dbms in aliases: conf.dbms = dbms
if conf.tech and isinstance(conf.tech, basestring): _ = []
for letter in conf.tech.upper(): if letter notin validLetters: errMsg = "value for --technique must be a string composed " errMsg += "by the letters %s. Refer to the "%", ".join(validLetters) errMsg += "user's manual for details" raise SqlmapSyntaxException(errMsg)
for validTech, validInt in validTechniques: if letter == validTech[0]: _.append(validInt) break
conf.tech = _
设置线程数
1 2
if not isinstance(conf.threads, int) orconf.threads <= 0: conf.threads = 1
检查后端数据库系统
_setOS() 简单的处理和判定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
if not conf.os: return
if conf.os.lower() not in SUPPORTED_OS: errMsg = "you provided an unsupported back-end DBMS operating " errMsg += "system. The supported DBMS operating systems for OS " errMsg += "andfilesystemaccessare %s. " % ', '.join([o.capitalize() for o in SUPPORTED_OS]) errMsg += "If you donot know the back-end DBMS underlying OS, " errMsg += "donot provide it and sqlmap will fingerprint it for" errMsg += "you." raise SqlmapUnsupportedDBMSException(errMsg) debugMsg = "forcing back-end DBMS operating systemtouser defined " debugMsg += "value'%s'" % conf.os logger.debug(debugMsg) Backend.setOs(conf.os)
检查写文件目录
_setWriteFile()
没什么特别的,就是基本的判定
1 2 3 4 5 6 7 8 9 10
if not os.path.exists(conf.wFile): errMsg = "the provided local file '%s' does not exist" % conf.wFile raise SqlmapFilePathException(errMsg)
if not conf.dFile: errMsg = "you did not provide the back-end DBMS absolute path " errMsg += "where you want to write the local file '%s'" % conf.wFile raise SqlmapMissingMandatoryOptionException(errMsg)
conf.wFileType = getFileType(conf.wFile)
检查Metasploit的设置
本地Metasploit的一些配置,就不贴代码了
检查设置的数据库身份验证语句
没什么可说的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
if not conf.dbmsCred: return
debugMsg = "setting the DBMS authentication credentials" logger.debug(debugMsg)
match = re.search("^(.+?):(.*?)$", conf.dbmsCred)
if not match: errMsg = "DBMS authentication credentials value must be in format " errMsg += "username:password" raise SqlmapSyntaxException(errMsg)
defloadBoundaries(): try: doc = et.parse(paths.BOUNDARIES_XML) exceptException, ex: errMsg = "something appears to be wrong with " errMsg+= "the file '%s' ('%s'). Please make " % (paths.BOUNDARIES_XML, getSafeExString(ex)) errMsg+= "sure that you haven't made any changes to it" raiseSqlmapInstallationException, errMsg root = doc.getroot() parseXmlNode(root)
加载payload格式
然后是加载payload格式
1 2 3 4 5 6 7 8 9 10 11 12 13 14
defloadPayloads(): forpayloadFile in PAYLOAD_XML_FILES: payloadFilePath = os.path.join(paths.SQLMAP_XML_PAYLOADS_PATH, payloadFile)
try: doc = et.parse(payloadFilePath) exceptException, ex: errMsg = "something appears to be wrong with " errMsg+= "the file '%s' ('%s'). Please make " % (payloadFilePath, getSafeExString(ex)) errMsg+= "sure that you haven't made any changes to it" raiseSqlmapInstallationException, errMsg
if not os.path.exists(os.path.join(paths.SQLMAP_ROOT_PATH, ".git")): errMsg = "not a git repository. Please checkout the 'sqlmapproject/sqlmap' repository " errMsg += "from GitHub (e.g. 'git clone https://github.com/sqlmapproject/sqlmap.git sqlmap')" logger.error(errMsg) else: infoMsg = "updating sqlmap to the latest development version from the " infoMsg += "GitHub repository" logger.info(infoMsg)
debugMsg = "sqlmap will try to update itself using 'git' command" logger.debug(debugMsg)
dataToStdout("\r[%s] [INFO] update in progress " % time.strftime("%X"))
if success: import lib.core.settings _ = lib.core.settings.REVISION = getRevisionNumber() logger.info("%s the latest revision '%s'" % ("already at"if"Already"in stdout else"updated to", _)) else: if"Not a git repository"in stderr: errMsg = "not a valid git repository. Please checkout the 'sqlmapproject/sqlmap' repository " errMsg += "from GitHub (e.g. 'git clone https://github.com/sqlmapproject/sqlmap.git sqlmap')" logger.error(errMsg) else: logger.error("update could not be completed ('%s')" % re.sub(r"\W+", " ", stderr).strip())
if not success: if IS_WIN: infoMsg = "for Windows platform it's recommended " infoMsg += "to use a GitHub for Windows client for updating " infoMsg += "purposes (http://windows.github.com/) or just " infoMsg += "download the latest snapshot from " infoMsg += "https://github.com/sqlmapproject/sqlmap/downloads" else: infoMsg = "for Linux platform it's required " infoMsg += "to install a standard 'git' package (e.g.: 'sudo apt-get install git')"
def__contains__(self, name): return name in self.__dict__
if retVal isNone: retVal = DictObject()
for child in node.findall("*"): instance = DictObject() retVal.__dict__[child.tag] = instance if child.attrib: instance.__dict__.update(child.attrib) else: iterate(child, instance)
return retVal
tree = ElementTree() try: tree.parse(paths.QUERIES_XML) except Exception, ex: errMsg = "something appears to be wrong with " errMsg += "the file '%s' ('%s'). Please make " % (paths.QUERIES_XML, getSafeExString(ex)) errMsg += "sure that you haven't made any changes to it" raise SqlmapInstallationException, errMsg
for node in tree.findall("*"): queries[node.attrib['value']] = iterate(node)