示例#1
0
    def getCVEList(self):
        """
        Create a dictionary where we link CVE Numbers to CANVAS module instances
        """
        self.log("Finding CVEs for all installed modules...")
        canvasengine.registerAllModules()
        exploitmods_old = canvasengine.exploitmodsGet(False)
        bunkList = [
            "N/A", '', 'Unknown', 'Unkown', 'None', 'None/SilentlyPatched'
        ]
        cveDict = {}  # {str(CVE-Num): module Instance}
        skipList = 0
        for key in exploitmods_old.keys():
            try:
                exploitmods_old[key].DOCUMENTATION["CVE Name"]
                if exploitmods_old[key].DOCUMENTATION[
                        "CVE Name"] not in bunkList and exploitmods_old[
                            key].PROPERTY['SITE'] == 'Remote':
                    # If it has a legitimate CVE number and it is a remote
                    cveDict[
                        exploitmods_old[key].DOCUMENTATION["CVE Name"]] = key

            except:
                skipList += 1

        self.log(
            "Found %d remote exploit modules with CVEs, skipped %d non-applicable modules"
            % (len(cveDict), skipList))
        return cveDict, exploitmods_old
示例#2
0
    def lpe_special_privs(self, node):
        exploit_list = []
        exploit_modules = canvasengine.exploitmodsGet()

        get_token_privs = self.engine.getModuleExploit("get_token_info")
        get_token_privs.link(self)

        get_token_privs.argsDict["passednodes"] = [node]
        info_success = get_token_privs.run()
        if not info_success:
            logging.warning("Failed to obtain token privileges")
            return []

        token_info = get_token_privs.privileges[node]

        for (token_type, privileges) in token_info.iteritems():
            if token_type == "process":
                if privileges and privileges.get("SeImpersonatePrivilege"):
                    logging.info("Process has SeImpersonatePrivilege")
                    logging.info("Prioritizing configuration abusing seimpersonatepriv_lpe")

                    # lpe = self.engine.getModuleExploit("seimpersonatepriv_lpe")
                    lpe = exploit_modules["seimpersonatepriv_lpe"]
                    exploit_list.append(lpe)

        return exploit_list
示例#3
0
    def build_autohack_list(self, ban_types=["DoS", "Tools", "Recon"]):
        """
        Autogenerate the list of modules to include in autohack

        *If your exploit is unreliable then set the AUTOHACK_EXCLUDE key in its properties*
        """
        self.autohack_dict = {}
        e_modules = canvasengine.exploitmodsGet()
        for exploit_mod in e_modules.values():

            ##Are we a known class of stuff that should be excluded?
            if exploit_mod.PROPERTY["TYPE"] in ban_types:
                self.banned.append(exploit_mod.NAME.lower())
                continue

            ##Have we declared that this shouldn't be included in the PROPERTY dict
            elif exploit_mod.PROPERTY.has_key("AUTOHACK_EXCLUDE"):
                self.banned.append(exploit_mod.NAME.lower())
                continue

            ##Use this exploit in autohack
            else:
                self.autohack_dict[exploit_mod.NAME.lower()] = exploit_mod

        # self.log("Modules INCLUDED in autohack: %s"%(self.autohack_dict))
        return
示例#4
0
    def get_client_sides( self ):
        useable_exploits = []
        mod_list = canvasengine.exploitmodsGet()

        for mod in mod_list:
            try:
                if mod_list[mod].PROPERTY["SITE"] == "Clientside" and mod_list[mod].PROPERTY['DELIVERY'] == "HTTP":
                    logging.debug("Added: %s" % mod_list[mod].NAME)
                    useable_exploits.append( mod )
            except:
                logging.warning("Skipped: %s" % mod_list[mod].NAME)

        return useable_exploits
示例#5
0
def dialog_update(gtk, wTree):

    import gobject
    treemodel = gtk.TreeStore(gobject.TYPE_STRING, gobject.TYPE_STRING)
    treeview = wTree.get_widget('treeview1')
    singleexploit = wTree.get_widget('singleexploit')

    # do not initialize twice
    if len(treeview.get_columns()) != 0:
        return

    useable_exploits = []
    mod_list = canvasengine.exploitmodsGet()

    for mod in mod_list:
        try:
            if mod_list[mod].PROPERTY["SITE"] == "Clientside" and mod_list[mod].PROPERTY['DELIVERY'] == "HTTP":
                treemodel.append( None, [mod, mod_list[mod].DESCRIPTION] )
        except:
            pass

    nameColumn = gtk.TreeViewColumn('Name')
    descrColumn = gtk.TreeViewColumn('Description')

    treeview.append_column(nameColumn)
    treeview.append_column(descrColumn)

    nameCell = gtk.CellRendererText()
    descrCell = gtk.CellRendererText()

    # add the cell to the tvcolumn and allow it to expand
    nameColumn.pack_start(nameCell, True)
    descrColumn.pack_start(descrCell, True)

    # set the cell "text" attribute to column 0 - retrieve text
    # from that column in treestore
    nameColumn.add_attribute(nameCell, 'text', 0)
    descrColumn.add_attribute(descrCell, 'text', 1)

    # make it searchable
    treeview.set_search_column(0)

    # Allow sorting on the column
    nameColumn.set_sort_column_id(0)

    treeview.set_headers_visible(True)
    treeview.set_model(treemodel)
    treeview.show()

    selection = treeview.get_selection()
    selection.connect('changed', on_selection_changed, singleexploit)
示例#6
0
def get_linux_modules(exploitsOnly=False):
    #Returns a dictionary, dict[module_name] = module_instance.
    #If exploits want to be excluded, then exploitsOnly can be set.
    candidates = canvasengine.exploitmodsGet(True)
    output_list = dict()
    for candidate in candidates:
        candidate = candidates[candidate].mod
        for arch in candidate.PROPERTY['ARCH']:
            if 'Linux' in arch or 'Unix' in arch:
                if candidate.PROPERTY['SITE'].lower() == 'local':
                    if not exploitsOnly or candidate.PROPERTY['TYPE'].lower(
                    ) == 'exploit':
                        output_list[candidate.__name__] = candidate
    return output_list
示例#7
0
 def exploit_list_win8(self):
     exploit_modules = canvasengine.exploitmodsGet()
     return [
             exploit_modules['menu_confusion_lpe'],
             exploit_modules['tpminit_wbemcomn'],
             exploit_modules['ms16_111'],
             exploit_modules['ms16_032'],
             exploit_modules['ms15_102'],
             exploit_modules['unmarshal_to_system'],
             exploit_modules['atmfd_pool_buffer_underflow'],
             exploit_modules['ms14_040'],
             exploit_modules['ms15_051'],
             exploit_modules['menu_confusion_lpe']
            ]
示例#8
0
    def get_windows_local_map(self):
        canvasengine.registerAllModules()

        exploit_modules = canvasengine.exploitmodsGet()

        patch_map = {}

        for (module_name, exploit_module) in exploit_modules.iteritems():
            if hasattr(exploit_module, "PROPERTY"):
                if all(["local" in exploit_module.PROPERTY["SITE"].lower(),
                        "exploit" in exploit_module.PROPERTY["TYPE"].lower()]):

                    if "MS PATCHES" in exploit_module.PROPERTY:
                        for patch in exploit_module.PROPERTY["MS PATCHES"]:
                            patch_map[patch] = exploit_module

        return patch_map
示例#9
0
 def exploit_list_win10(self):
     exploit_modules = canvasengine.exploitmodsGet()
     return [
             exploit_modules['smbghost_lpe'],
             exploit_modules['alpc_takeover_lpe'],
             exploit_modules['alpc_appxedge_lpe'],
             exploit_modules['error_reporting_lpe'],
             exploit_modules['sdclt_uac_bypass'],
             exploit_modules['unmarshal_to_system'],
             exploit_modules['ms16_032'],
             exploit_modules['setwindowfnid_lpe'],
             exploit_modules['special_lnk'],
             exploit_modules['dde_closehandle_lpe'],
             exploit_modules['ms16_111'],
             exploit_modules['tpminit_wbemcomn'],
             exploit_modules['ms16_135'],
             exploit_modules['menu_confusion_lpe']
            ]
示例#10
0
    def getCVEList(self):
        """
        Return a dict where {cve number : module name}
        """
        canvasengine.registerAllModules()
        exploitmods_old = canvasengine.exploitmodsGet(False)
        bunkList        = ["N/A", '', 'Unknown' , 'Unkown', 'None', 'None/SilentlyPatched']
        cveDict         = {}
        skipList        = 0

        for key in exploitmods_old.keys():
            try:
                exploitmods_old[key].DOCUMENTATION["CVE Name"]
                if exploitmods_old[key].DOCUMENTATION["CVE Name"] not in bunkList:
                    cveDict[exploitmods_old[key].DOCUMENTATION["CVE Name"]] = key
            except:
                skipList += 1
        self.log_info("Found %d modules with CVEs, skipped %d" % (len(cveDict), skipList))
        return cveDict
示例#11
0
    def get_blacklist(self, os_info):
        blacklist_map = {"Windows Server 2008": ["MS11-032",
                                                 "MS11-054",
                                                 # "win32k.sys bServerSideWindowProc",
                                                 "atmfd",
                                                 "MS10-048",
                                                 "MS16-135",
                                                 "ms14_025",
                                                 "MS12-042", # this doesn't crash but it generates a /ton/ of output
        ],
                         "Windows 10": ["alpc_tasksched_lpe"],
                         "Windows Server 2012": ["MS16-111"],
                         "Windows 8.1": ["MS16-111"],
                         "Windows Server 2016": ["MS16-135"],
                         "all": ["ms_ntvdm", "event_viewer_mscfile"],

        }
        blacklist_names = blacklist_map.get(os_info["os_name"],[]) + blacklist_map.get("all", [])
        exploit_modules = canvasengine.exploitmodsGet()
        blacklist_modules = []
        for exploit_name in blacklist_names:
            blacklist_modules.append(exploit_modules[exploit_name])

        return blacklist_modules
示例#12
0
    def run_on_host(self, target):
        """
        runs once on each host that is alive in the netrange
        """
        host = target.interface
        self.log("Running on %s" % host)
        exploitmods = canvasengine.exploitmodsGet()
        try:
            app = self.engine.getModuleExploit("osdetect")
            app.link(self)
            app.target = target
            app.run()
            myos = app.result
        except:
            import traceback
            traceback.print_exc(file=sys.__stdout__)
            self.log("Not determining OS - use osdetect exploit module")
            myos = "Unknown"

            target.add_knowledge("OS", myos, 100)

        totalmods = len(exploitmods)
        currentmod = 1
        for module in exploitmods.values():
            if self.state == self.HALT:
                self.log("Halted.")
                self.setInfo("%s - (halted)" % NAME)
                return 0
            try:
                str = "Scanning with %s" % module.DESCRIPTION
            except:
                try:
                    print "Could not find a description in %s" % module.NAME
                    str = module.NAME
                except:
                    print "Error: Module has no name?"
            self.log(str)
            #debug
            print str
            progress = round((currentmod * 100) / totalmods)
            #print "CurrentMod %d Total Modules: %d Progress %d"%(currentmod,totalmods,progress)
            self.setProgress(progress)
            currentmod += 1
            try:
                app = module.theexploit()
            except:
                try:
                    mystr = "No theexploit class in module %s" % module.DESCRIPTION
                except:
                    mystr = "No theexploit class in module!"
                self.log(mystr)
                continue
            app.link(self)

            #set the defaults for exploits not using correct syntax
            defaultlist = ["port", "user", "password", "filename"]
            for i in defaultlist:
                if i in dir(app):
                    #print "FOUND: %s"%i
                    app.argsDict[i] = getattr(app, i)

            app.argsDict["passednodes"] = self.argsDict["passednodes"]
            app.argsDict["autohack_state"] = self.autohack_state
            defaultlist = ["user", "password", "filename"]
            for i in defaultlist:
                if i in self.argsDict:
                    app.argsDict[i] = self.argsDict[i]
            app.target = target
            #print "ArgsDict=%s"%app.argsDict
            try:
                if app.test():
                    self.log(
                        "Module %s said host %s is potentially vulnerable" %
                        (module.NAME, host))
                    self.vulns.append((host, module.NAME, module))
                    fromhost = "127.0.0.1"  #hard coded for now
                    #if self.engine:
                    #    self.engine.registerPotentialVuln(fromhost,host,module.__name__,module.DESCRIPTION)
                else:
                    #import traceback
                    #traceback.print_exc(file=sys.stdout)
                    self.log(
                        "Module %s said host %s is not potentially vulnerable"
                        % (module.NAME, host))
            except:
                self.log("Test returned exception: fix this.")
                import traceback
                traceback.print_exc(file=sys.stdout)
        return
示例#13
0
    def run_on_host(self, target):
        if self.version == 0:
            kprim = target.get_knowledge("OS")
            if kprim == None:
                self.set_current_attack_module("osdetect")
                self.doRecon("osdetect", target)
                self.set_current_attack_module("autohack")
                kprim = target.get_knowledge("OS")

            if kprim:
                myos = kprim.known
            else:
                myos = "UKNOWN"  # This is not supposed to happen
            if (myos == "UNKNOWN"
                    or str(myos) == "") and self.ignore_unidentified_hosts:
                self.log("Ignoring host %s since it cannot be os-id'd" %
                         self.host)
                return 0
        elif self.version == 1:
            # Create a new canvasos object set to Windows
            # XXX: JMS - is this a sane default? Perhaps 2k3?
            myos = canvasos.new("Windows")
        else:
            # Create a default Linux canvasos object
            myos = canvasos.new("Linux")

        objos = myos
        myos = str(
            myos
        )  #switch this to a string, even though it is an object that is returned
        self.log("Os detected: %s" % myos)

        #now check netbios if available against engine's smartlist
        #assuming self.engine exists and is initialized
        allKnowledge = target.get_all_knowledge_as_text()
        self.log("All Knowledge=%s" % allKnowledge)

        netbios = target.get_knowledge("SMBServer", None)
        dontattack = False
        if netbios:
            dontattack = self.engine.smartlist.check_netbios(netbios)
        if dontattack:
            self.log("SmartList check told me not to attack this host")
            return 0

        if myos.count("Unknown"):
            logging.critical("OS is Unknown, exiting")
            return 0

        if int(self.argsDict.get("portscan", 1)):
            self.doRecon("portscan", target)

        #theoretically could do a portscan to filter this list down
        #with mode="chosen ports"

        kprim = target.get_knowledge("TCPPORTS")
        openports = []

        if kprim and isinstance(kprim.known, list):
            openports = kprim.known
            #need to convert this to a list of integers, if it's not
            #already. In our knowledge base this is stored as a list of strings
            #instead
            openports = map(int, openports)
        else:
            #just some default ports
            openports = [135, 139, 143, 161, 445, 80, 21, 25, 23, 7100]

        self.log("Open Ports: %s" % openports)

        ##Rich mod - if no 'web ports' are open remove any exploits that are web exploits
        if 0:
            if not set(self.web_ports).intersection(openports):
                self.log(
                    "No ports defined as web ports (%s) in open port list" %
                    (self.web_ports))
                ##Rebuild list defining webexploits as banned type
                self.build_autohack_list(
                    ban_types=["DoS", "Tools", "Recon", "Web Exploits"])

        affected = self.getAffectsList(myos)
        if affected == "Unknown":
            logging.critical("Unsupported OS (%s), exiting")
            return 0

        ##Do we have an explicit list of modules ala VulnAssess2 or just do all we can ala massattack2 ?
        if self.exploit_modules:
            exploitmods = {}
            self.log(
                "Using a list of exploit modules that was passed into us: %s" %
                repr(self.exploit_modules))
            if type(self.exploit_modules) == type(""):
                #this should never happen, but I added it for "hardness"'s sake
                self.exploit_modules = self.exploit_modules.split(",")
            for mod in self.exploit_modules:
                exploitmods[mod] = canvasengine.getModule(mod)
        else:
            exploitmods = canvasengine.exploitmodsGet()

        # if 1:
        #debug
        # for mod in exploitmods:
        # self.log("Loaded: %s"%(str(mod)))

        totalmods = len(exploitmods)
        currentmod = 1
        self.log("Testing against: ")

        for module in exploitmods.values():
            if self.state == self.HALT:
                break

            #run all the exploits on this host
            if hasattr(module, "NAME"):
                name = module.NAME  #save this off
            else:
                raise Exception, "Module %s does not have a NAME" % str(module)

            goodOS = False
            for tos in module.TARGET_CANVASOS_LIST:
                if objos.isSameAs(tos):
                    goodOS = True
                    break

            if not goodOS:
                # self.log("Autohack considered module %s not suitable for remote os %s"  % (module.NAME, objos))
                continue
            if name.lower() in self.banned:
                # logging.warning("Module %s is banned" % name)
                continue
            if not isexploit(module):
                continue

            logging.info("Executing (%s)" % name)

            progress = round((currentmod * 100) / totalmods)
            # self.log("CurrentMod %d Total Modules: %d Progress %d" % (currentmod, totalmods, progress))
            self.setProgress(progress)
            currentmod += 1
            try:
                self.set_current_attack_module(name)
                app = module.theexploit()
            except:
                logging.error("theexploit class not found in module %s" % name)
                continue

            app.link(self)
            self.log("openports = %s" % openports)
            if app.port not in openports and app.port != 0:
                self.log("Port %s not in %s" % (app.port, openports))
                self.log("Skipped module %s" % name)
                continue

            try:
                manager = self.setExploit(app, module)
                if manager.test():
                    vuln = "Vulnerable"
                else:
                    vuln = "Not Vulnerable"
                    self.log("(%s) %s: Possible %s" %
                             (app.port, module.NAME, vuln))
                    continue

            except:
                import traceback
                print "\t ==> Error"
                traceback.print_exc(file=sys.stderr)
                continue

            ret = self.runExploit(app)

            # The exploit returned us the result no need to do anything further
            if type(ret) == str:
                return ret

            print "RET:"
            print ret

            if app.ISucceeded():
                self.log("Exploit returned %s" % ret)
                self.target.add_knowledge("Exploited using", app.name, 100)
                self.log("Exploited using %s!" % app.name)
                newnode = ret
                if newnode in [0, 1, None]:
                    #BUG BUG what if exploit returned multiple nodes?
                    self.log(
                        "Exploit succeeded but did not return a node - getting new node from exploit manager"
                    )
                    #we sleep until the manager has finished waiting for the new node
                    #to be set up. He'll only wait if there was a callback
                    #which means things like dcedump don't mess with us here.
                    #any exceptions in manager.run() might though, so we have to be careful of that
                    while self.manager.state != "Done":
                        time.sleep(1)
                    newnode = self.manager.newnode
                    if not newnode:
                        self.log("Did not get a node from the exploit")
                    else:
                        self.log("Got node from callback!")
                else:
                    self.log("Target returned a node of type %s" %
                             newnode.nodetype)
                self.result += [(target, app.name, newnode)]
                #we don't return ret because startup has already been called on it
                return 1

        return 0
示例#14
0
文件: autohack.py 项目: tsondt/Canvas
    def run_on_host(self, target):
        if self.version == 0:
            kprim = target.get_knowledge("OS")
            if kprim == None:
                self.set_current_attack_module("osdetect")
                self.doRecon("osdetect", target)
                self.set_current_attack_module("autohack")
                kprim = target.get_knowledge("OS")

            if kprim:
                myos = kprim.known
            else:
                myos = "UKNOWN"  # This is not supposed to happen
            if (myos == "UNKNOWN"
                    or str(myos) == "") and self.ignore_unidentified_hosts:
                self.log("Ignoring host %s since it cannot be os-id'd" %
                         self.host)
                return 0
        elif self.version == 1:
            # Create a new canvasos object set to Windows
            # XXX: JMS - is this a sane default? Perhaps 2k3?
            myos = canvasos.new("Windows")
        else:
            # Create a default Linux canvasos object
            myos = canvasos.new("Linux")

        objos = myos
        myos = str(
            myos
        )  #switch this to a string, even though it is an object that is returned
        self.log("Os detected: %s" % myos)

        #now check netbios if available against engine's smartlist
        #assuming self.engine exists and is initialized
        allKnowledge = target.get_all_knowledge_as_text()
        self.log("All Knowledge=%s" % allKnowledge)

        netbios = target.get_knowledge("SMBServer", None)
        dontattack = False
        if netbios:
            dontattack = self.engine.smartlist.check_netbios(netbios)
        if dontattack:
            self.log("SmartList check told me not to attack this host")
            return 0

        if myos.count("Unknown"):
            self.log("OS is Unknown , not continuing Autohack!")
            return 0

        if int(self.argsDict.get("portscan", 1)):
            self.doRecon("portscan", target)

        #theoretically could do a portscan to filter this list down
        #with mode="chosen ports"

        kprim = target.get_knowledge("TCPPORTS")
        openports = []

        if kprim and isinstance(kprim.known, list):
            openports = kprim.known
            #need to convert this to a list of integers, if it's not
            #already. In our knowledge base this is stored as a list of strings
            #instead
            openports = map(int, openports)
        else:
            #just some default ports
            openports = [135, 139, 143, 445, 80, 21, 25, 23, 7100]

        self.log("Open Ports: %s" % openports)

        affected = self.getAffectsList(myos)
        if affected == "Unknown":
            self.log("Not attacking unknown target")
            return 0

        ##Do we have an explicit list of modules ala VulnAssess2 or just do all we can ala massattack2 ?
        if self.exploit_modules:
            for mod in self.exploit_modules:
                exploitmods[mod] = canvasengine.getModule(mod)
        else:
            ##Nope use them all .....
            exploitmods = canvasengine.exploitmodsGet()

        if 1:
            #debug
            for mod in exploitmods:
                self.log("Loaded: %s" % (str(mod)))

        totalmods = len(exploitmods)
        currentmod = 1
        self.log("Testing against: ")
        for module in exploitmods.values():
            if self.state == self.HALT:
                break
            #run all the exploits on this host
            if hasattr(module, "DESCRIPTION"):
                description = module.DESCRIPTION  #save this off
            else:
                raise Exception, "Module %s does not have a DESCRIPTION" % str(
                    module)
            self.log("Trying %s" % description)

            goodOS = False
            for tos in module.TARGET_CANVASOS_LIST:
                if objos.isSameAs(tos):
                    goodOS = True
                    break

            if not goodOS:
                self.log(
                    "Autohack considered module %s not suitable for remote os %s"
                    % (module.NAME, objos))
                continue
            """
            #quick test to see if the affectsList even exists
            propcheck = 0
            a = []
            if not hasattr(module, "affectsList") or module.affectsList == "":
                # try to be backwards compatible for now
                # we have to be consistent in Solaris/MacOSX/etc. case sensitivity
                # maybe toupper or tolower that when we're moving fully
                propcheck = 1

            # who wrote autohack btw?, anyhoo ugly because we need to be b.c.
            if propcheck:
                try:
                    a = []
                    for x in module.PROPERTY['ARCH']:
                        if isinstance(x, list):
                            a.append(x[0])
                        else:
                            a.append(x)
                except:
                    self.log("No ARCH property on %s"%description)
                    continue

            # check teh list
            if propcheck:
                print "Autohaxx Considering architectures: %s %s" % (module.NAME, a)
                aFound = 0
                for l in a: #for item in affectsList
                    if affected in str(l):
                        aFound = 1
                if not aFound:
                    self.log("ARCH not found: %s in %s"%(affected,a))
                    continue
                try:
                    if len(module.PROPERTY["VERSION"]):
                        if objos.version in module.PROPERTY["VERSION"] or "All" in module.PROPERTY["VERSION"] :
                            print "Autohack version check says yes for %s: os version (%s) in list: %s" % (module.NAME, objos.version, module.PROPERTY["VERSION"])
                            pass
                        else:
                            print "Autohack not proceeding with %s, as OS version (%s) not in version list: %s" % (module.NAME, objos.version, module.PROPERTY["VERSION"])
                            continue
                except KeyError:
                    print "Autohack module %s has no VERSION" % module.NAME
                    # No version property, so nothing to check.
                    pass
            else:
                if a and affected not in str(a):
                    self.log("Arch not found: %s in %s"%(affected,a))
                    #we move on to the next module
                    continue
            """

            if module.NAME.lower() in self.banned:
                self.log("Module %s is banned" % module.NAME)
                continue

            if not isexploit(module):
                self.log("Not a remote exploit: %s" % module.NAME)
                continue

            self.log("Scanning with %s" % module.NAME)
            progress = round((currentmod * 100) / totalmods)
            self.log("CurrentMod %d Total Modules: %d Progress %d" %
                     (currentmod, totalmods, progress))
            self.setProgress(progress)
            currentmod += 1
            try:
                self.set_current_attack_module(module.NAME)
                app = module.theexploit()
            except:
                self.log("No theexploit class in module %s" %
                         module.DESCRIPTION)
                continue
            app.link(self)
            self.log("openports=%s" % openports)
            if app.port not in openports and app.port != 0:
                self.log("Port %s not in %s" % (app.port, openports))
                self.log("Skipped module %s" % module.DESCRIPTION)
                continue
            else:
                self.log("Running %s" % module.DESCRIPTION)

            try:
                manager = self.setExploit(app, module)
                if manager.test():
                    vuln = "Vulnerable"
                else:
                    vuln = "Not Vulnerable"
                    self.log("(%s) %s: Possible %s" %
                             (app.port, module.NAME, vuln))
                    continue

            except:
                import traceback
                print "\t ==> Error"
                traceback.print_exc(file=sys.stderr)
                continue

            ret = self.runExploit(app)

            # The exploit returned us the result no need to do anything further
            if type(ret) == str:
                return ret

            if app.ISucceeded():
                self.log("Exploit returned %s" % ret)
                self.target.add_knowledge("Exploited using", app.name, 100)
                self.log("Exploited using %s!" % app.name)
                newnode = ret
                if newnode in [0, 1, None]:
                    #BUG BUG what if exploit returned multiple nodes?
                    self.log(
                        "Exploit succeeded but did not return a node - getting new node from exploit manager"
                    )
                    #we sleep until the manager has finished waiting for the new node
                    #to be set up. He'll only wait if there was a callback
                    #which means things like dcedump don't mess with us here.
                    #any exceptions in manager.run() might though, so we have to be careful of that
                    while self.manager.state != "Done":
                        time.sleep(1)
                    newnode = self.manager.newnode
                    if not newnode:
                        self.log("Did not get a node from the exploit")
                    else:
                        self.log("Got node from callback!")
                else:
                    self.log("Target returned a node of type %s" %
                             newnode.nodetype)
                self.result += [(target, app.name, newnode)]
                #we don't return ret because startup has already been called on it
                return 1

        self.set_current_attack_module("autohack")
        return 0