Пример #1
0
    def stopscanmulti(self, ids):
        global globalScanStatus # running scans
        dbh = SpiderFootDb(self.config)
        error = list()

        for id in ids.split(","):
            errState = False
            scaninfo = dbh.scanInstanceGet(id)

            if globalScanStatus.getStatus(id) == "FINISHED" or scaninfo[5] == "FINISHED":
                error.append("Scan '" + scaninfo[0] + "' is in a finished state. <a href='/scandelete?id=" + \
                             id + "&confirm=1'>Maybe you want to delete it instead?</a>")
                errState = True

            if not errState and (globalScanStatus.getStatus(id) == "ABORTED" or scaninfo[5] == "ABORTED"):
                error.append("Scan '" + scaninfo[0] + "' is already aborted.")
                errState = True

            if not errState and globalScanStatus.getStatus(id) is None:
                error.append("Scan '" + scaninfo[0] + "' is not actually running. A data consistency " + \
                             "error for this scan probably exists. <a href='/scandelete?id=" + \
                             id + "&confirm=1'>Click here to delete it.</a>")
                errState = True
            
            if not errState:
                globalScanStatus.setStatus(id, "ABORT-REQUESTED")

        templ = Template(filename='dyn/scanlist.tmpl', lookup=self.lookup)
        return templ.render(pageid='SCANLIST', stoppedscan=True, 
                            errors=error, docroot=self.docroot)
Пример #2
0
    def scanopts(self, id):
        ret = dict()
        dbh = SpiderFootDb(self.config)
        ret['config'] = dbh.scanConfigGet(id)
        ret['configdesc'] = dict()
        for key in ret['config'].keys():
            if ':' not in key:
                ret['configdesc'][key] = self.config['__globaloptdescs__'][key]
            else:
                [modName, modOpt] = key.split(':')
                if modName not in self.config['__modules__'].keys():
                    continue

                if modOpt not in self.config['__modules__'][modName]['optdescs'].keys():
                    continue

                ret['configdesc'][key] = self.config['__modules__'][modName]['optdescs'][modOpt]

        sf = SpiderFoot(self.config)
        meta = dbh.scanInstanceGet(id)
        if meta[3] != 0:
            started = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(meta[3]))
        else:
            started = "Not yet"

        if meta[4] != 0:
            finished = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(meta[4]))
        else:
            finished = "Not yet"
        ret['meta'] = [meta[0], meta[1], meta[2], started, finished, meta[5]]

        return json.dumps(ret)
Пример #3
0
    def searchBase(self, id=None, eventType=None, value=None):
        regex = ""
        if [id, eventType, value].count('') == 2 or \
                        [id, eventType, value].count(None) == 2:
            return None

        if value.startswith("/") and value.endswith("/"):
            regex = value[1:len(value) - 1]
            value = ""

        value = value.replace('*', '%')
        if value in [None, ""] and regex in [None, ""]:
            value = "%"
            regex = ""

        dbh = SpiderFootDb(self.config)
        criteria = {
            'scan_id': None if id == '' else id,
            'type': None if eventType == '' else eventType,
            'value': None if value == '' else value,
            'regex': None if regex == '' else regex
        }

        data = dbh.search(criteria)
        retdata = []
        for row in data:
            lastseen = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(row[0]))
            escapeddata = cgi.escape(row[1])
            escapedsrc = cgi.escape(row[2])
            retdata.append([lastseen, escapeddata, escapedsrc,
                            row[3], row[5], row[6], row[7], row[8], row[10], 
                            row[11], row[4], row[13], row[14]])

        return retdata
Пример #4
0
    def savesettingsraw(self, allopts, token):
        if str(token) != str(self.token):
            return json.dumps(["ERROR", "Invalid token (" + str(self.token) + ")."])

        try:
            dbh = SpiderFootDb(self.config)
            # Reset config to default
            if allopts == "RESET":
                dbh.configClear()  # Clear it in the DB
                self.config = deepcopy(self.defaultConfig)  # Clear in memory
            else:
                useropts = json.loads(allopts)
                cleanopts = dict()
                for opt in useropts.keys():
                    cleanopts[opt] = self.cleanUserInput([useropts[opt]])[0]

                currentopts = deepcopy(self.config)

                # Make a new config where the user options override
                # the current system config.
                sf = SpiderFoot(self.config)
                self.config = sf.configUnserialize(cleanopts, currentopts)
                dbh.configSet(sf.configSerialize(currentopts))
        except Exception as e:
            return json.dumps(["ERROR", "Processing one or more of your inputs failed: " + str(e)])

        return json.dumps(["SUCCESS", ""])
Пример #5
0
 def newscan(self):
     dbh = SpiderFootDb(self.config)
     types = dbh.eventTypes()
     templ = Template(filename='dyn/newscan.tmpl', lookup=self.lookup)
     return templ.render(pageid='NEWSCAN', types=types, docroot=self.docroot,
                         modules=self.config['__modules__'], scanname="",
                         selectedmods="", scantarget="")
Пример #6
0
    def resultsetfp(self, id, resultids, fp):
        dbh = SpiderFootDb(self.config)
        if fp not in ["0", "1"]:
            return json.dumps(["ERROR", "No FP flag set or not set correctly."])

        ids = json.loads(resultids)
        if not ids:
            return json.dumps(["ERROR", "No IDs supplied."])

        # Cannot set FPs if a scan is not completed
        status = dbh.scanInstanceGet(id)
        if status[5] not in [ "ABORTED", "FINISHED", "ERROR-FAILED" ]:
            return json.dumps(["WARNING", "Scan must be in a finished state when " + \
                               "setting False Positives."])

        # Make sure the user doesn't set something as non-FP when the
        # parent is set as an FP.
        if fp == "0":
            data = dbh.scanElementSourcesDirect(id, ids)
            for row in data:
                if str(row[14]) == "1":
                    return json.dumps(["WARNING", 
                        "You cannot unset an element as False Positive " + \
                        "if a parent element is still False Positive."]);

        # Set all the children as FPs too.. it's only logical afterall, right?
        childs = dbh.scanElementChildrenAll(id, ids)
        allIds = ids + childs

        ret = dbh.scanResultsUpdateFP(id, allIds, fp)
        if not ret:
            return json.dumps(["ERROR", "Exception encountered."])
        else: 
            return json.dumps(["SUCCESS", ""])
Пример #7
0
    def savesettings(self, allopts, token):
        if str(token) != str(self.token):
            return self.error("Invalid token (" + str(self.token) + ").")

        try:
            dbh = SpiderFootDb(self.config)
            # Reset config to default
            if allopts == "RESET":
                dbh.configClear()  # Clear it in the DB
                self.config = deepcopy(self.defaultConfig)  # Clear in memory
            else:
                useropts = json.loads(allopts)
                cleanopts = dict()
                for opt in useropts.keys():
                    cleanopts[opt] = self.cleanUserInput([useropts[opt]])[0]

                currentopts = deepcopy(self.config)

                # Make a new config where the user options override
                # the current system config.
                sf = SpiderFoot(self.config)
                self.config = sf.configUnserialize(cleanopts, currentopts)
                dbh.configSet(sf.configSerialize(currentopts))
        except Exception as e:
            return self.error("Processing one or more of your inputs failed: " + str(e))

        templ = Template(filename='dyn/opts.tmpl', lookup=self.lookup)
        self.token = random.randint(0, 99999999)
        return templ.render(opts=self.config, pageid='SETTINGS', updated=True,
                            docroot=self.docroot, token=self.token)
Пример #8
0
    def clonescan(self, id):
        sf = SpiderFoot(self.config)
        dbh = SpiderFootDb(self.config)
        types = dbh.eventTypes()
        info = dbh.scanInstanceGet(id)
        scanconfig = dbh.scanConfigGet(id)
        scanname = info[0]
        scantarget = info[1]
        targetType = None

        if scanname == "" or scantarget == "" or len(scanconfig) == 0:
            return self.error("Something went wrong internally.")

        targetType = sf.targetType(scantarget)
        if targetType == None:
            # It must be a name, so wrap quotes around it
            scantarget = "&quot;" + scantarget + "&quot;"

        modlist = scanconfig['_modulesenabled'].split(',')

        templ = Template(filename='dyn/newscan.tmpl', lookup=self.lookup)
        return templ.render(pageid='NEWSCAN', types=types, docroot=self.docroot,
                            modules=self.config['__modules__'], selectedmods=modlist,
                            scanname=unicode(scanname, 'utf-8', errors='replace'), 
                            scantarget=unicode(scantarget, 'utf-8', errors='replace'))
Пример #9
0
    def scanexportjsonmulti(self, ids):
        dbh = SpiderFootDb(self.config)
        scaninfo = dict()

        for id in ids.split(','):
          scan_name = dbh.scanInstanceGet(id)[0]

          if scan_name not in scaninfo:
              scaninfo[scan_name] = []

          for row in dbh.scanResultEvent(id):
              lastseen = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(row[0]))
              event_data = str(row[1]).replace("<SFURL>", "").replace("</SFURL>", "")
              source_data = str(row[2])
              source_module = str(row[3])
              event_type = row[4]
              false_positive = row[13]

              if event_type == "ROOT":
                  continue

              scaninfo[scan_name].append({
                  "data": event_data,
                  "type": event_type,
                  "source_module": source_module,
                  "source_data": source_data,
                  "false_positive": false_positive,
                  "lastseen": lastseen
              })

        cherrypy.response.headers['Content-Disposition'] = "attachment; filename=SpiderFoot.json"
        cherrypy.response.headers['Content-Type'] = "application/json; charset=utf-8"
        cherrypy.response.headers['Pragma'] = "no-cache"

        return json.dumps(scaninfo)
Пример #10
0
    def scaninfo(self, id):
        dbh = SpiderFootDb(self.config)
        res = dbh.scanInstanceGet(id)
        if res == None:
            return self.error("Scan ID not found.")

        templ = Template(filename='dyn/scaninfo.tmpl', lookup=self.lookup)
        return templ.render(id=id, name=res[0], status=res[5], pageid='SCANLIST')
Пример #11
0
 def scaneventresultsunique(self, id, eventType, filterfp=False):
     dbh = SpiderFootDb(self.config)
     data = dbh.scanResultEventUnique(id, eventType, filterfp)
     retdata = []
     for row in data:
         escaped = cgi.escape(row[0])
         retdata.append([escaped, row[1], row[2]])
     return json.dumps(retdata, ensure_ascii=False)
Пример #12
0
 def scanlog(self, id):
     dbh = SpiderFootDb(self.config)
     data = dbh.scanLogs(id)
     retdata = []
     for row in data:
         generated = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(row[0]/1000))
         retdata.append([generated, row[1], row[2], cgi.escape(row[3])])
     return json.dumps(retdata)
Пример #13
0
 def scansummary(self, id):
     dbh = SpiderFootDb(self.config)
     data = dbh.scanResultSummary(id)
     retdata = []
     for row in data:
         lastseen = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(row[2]))
         retdata.append([row[0], row[1], lastseen, row[3], row[4]])
     return json.dumps(retdata)
Пример #14
0
 def __init__(self, config):
     self.defaultConfig = deepcopy(config)
     dbh = SpiderFootDb(config)
     # 'config' supplied will be the defaults, let's supplement them
     # now with any configuration which may have previously been
     # saved.
     sf = SpiderFoot(config)
     self.config = sf.configUnserialize(dbh.configGet(), config)
Пример #15
0
    def scanelementtypediscovery(self, id, eventType):
        keepGoing = True
        sf = SpiderFoot(self.config)
        dbh = SpiderFootDb(self.config)
        pc = dict()
        datamap = dict()

        # Get the events we will be tracing back from
        leafSet = dbh.scanResultEvent(id, eventType)

        # Get the first round of source IDs for the leafs
        nextIds = list()
        for row in leafSet:
            # these must be unique values!
            parentId = row[9]
            childId = row[8]
            datamap[childId] = row

            if pc.has_key(parentId):
                if childId not in pc[parentId]:
                    pc[parentId].append(childId)
            else:
                pc[parentId] = [ childId ]

            # parents of the leaf set
            if parentId not in nextIds:
                nextIds.append(parentId)

        while keepGoing:
            parentSet = dbh.scanElementSources(id, nextIds)
            nextIds = list()
            keepGoing = False

            for row in parentSet:
                parentId = row[9]
                childId = row[8]
                datamap[childId] = row
                #print childId + " = " + str(row)

                if pc.has_key(parentId):
                    if childId not in pc[parentId]:
                        pc[parentId].append(childId)
                else:
                    pc[parentId] = [ childId ]
                if parentId not in nextIds:
                    nextIds.append(parentId)

                # Prevent us from looping at root
                if parentId != "ROOT":
                    keepGoing = True

        datamap[parentId] = row

        #print pc
        retdata = dict()
        retdata['tree'] = sf.dataParentChildToTree(pc)
        retdata['data'] = datamap
        return json.dumps(retdata, ensure_ascii=False)
Пример #16
0
    def scanstatus(self, id):
        dbh = SpiderFootDb(self.config)
        data = dbh.scanInstanceGet(id)
        created = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(data[2]))
        started = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(data[3]))
        ended = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(data[4]))

        retdata = [data[0], data[1], created, started, ended, data[5]]
        return json.dumps(retdata)
Пример #17
0
    def scaninfo(self, id):
        dbh = SpiderFootDb(self.config)
        res = dbh.scanInstanceGet(id)
        if res is None:
            return self.error("Scan ID not found.")

        templ = Template(filename='dyn/scaninfo.tmpl', lookup=self.lookup, disable_unicode=True, input_encoding='utf-8')
        return templ.render(id=id, name=cgi.escape(res[0]), status=res[5], docroot=self.docroot,
                            pageid="SCANLIST")
Пример #18
0
 def scaneventresults(self, id, eventType):
     dbh = SpiderFootDb(self.config)
     data = dbh.scanResultEvent(id, eventType)
     retdata = []
     for row in data:
         lastseen = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(row[0]))
         escaped = cgi.escape(row[1])
         retdata.append([lastseen, escaped, row[2], row[3], row[5], row[6], row[7]])
     return json.dumps(retdata, ensure_ascii=False)
Пример #19
0
 def scanerrors(self, id, limit=None):
     dbh = SpiderFootDb(self.config)
     data = dbh.scanErrors(id, limit)
     retdata = []
     for row in data:
         generated = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(row[0] / 1000))
         retdata.append([generated, row[1],
                         cgi.escape(unicode(row[2], errors='replace'))])
     return json.dumps(retdata)
Пример #20
0
    def startscan(self, scanname, scantarget, modulelist, typelist):
        modopts = dict() # Not used yet as module options are set globally
        modlist = list()
        sf = SpiderFoot(self.config)
        dbh = SpiderFootDb(self.config)
        types = dbh.eventTypes()

        [scanname, scantarget] = self.cleanUserInput([scanname, scantarget])

        if scanname == "" or scantarget == "":
            return self.error("Form incomplete.")

        if typelist == "" and modulelist == "":
            return self.error("Form incomplete.")

        if modulelist != "":
            modlist = modulelist.replace('module_', '').split(',')
        else:
            typesx = typelist.replace('type_', '').split(',')
            # 1. Find all modules that produce the requested types
            modlist = sf.modulesProducing(typesx)
            newmods = deepcopy(modlist)
            newmodcpy = deepcopy(newmods)
            # 2. For each type those modules consume, get modules producing
            while len(newmodcpy) > 0:
                for etype in sf.eventsToModules(newmodcpy):
                    xmods = sf.modulesProducing([etype])
                    for mod in xmods:
                        if mod not in modlist:
                            modlist.append(mod)
                            newmods.append(mod)
                newmodcpy = deepcopy(newmods)
                newmods = list()

        # Add our mandatory storage module..
        if "sfp__stor_db" not in modlist:
            modlist.append("sfp__stor_db")
        modlist.sort()

        # For now we don't permit multiple simultaneous scans
        for thread in threading.enumerate():
            if thread.name.startswith("SF_"):
                templ = Template(filename='dyn/newscan.tmpl', lookup=self.lookup)
                return templ.render(modules=self.config['__modules__'], 
                    alreadyRunning=True, runningScan=thread.name[3:], 
                    types=types, pageid="NEWSCAN")

        # Start running a new scan
        self.scanner = SpiderFootScanner(scanname, scantarget.lower(), modlist, 
            self.config, modopts)
        t = threading.Thread(name="SF_" + scanname, target=self.scanner.startScan)
        t.start()

        templ = Template(filename='dyn/scaninfo.tmpl', lookup=self.lookup)
        return templ.render(id=self.scanner.myId, name=scanname, 
            status=self.scanner.status, pageid="SCANLIST")
Пример #21
0
    def eventtypes(self):
        dbh = SpiderFootDb(self.config)
        types = dbh.eventTypes()
        ret = list()

        for r in types:
            ret.append([r[1], r[0]])

        ret = sorted(ret, key=itemgetter(0))

        return json.dumps(ret)
Пример #22
0
    def scandelete(self, id, confirm=None):
        dbh = SpiderFootDb(self.config)
        res = dbh.scanInstanceGet(id)
        if res == None:
            return self.error("Scan ID not found.")

        if confirm != None:
            dbh.scanInstanceDelete(id)
            raise cherrypy.HTTPRedirect("/")
        else:
            templ = Template(filename='dyn/scandelete.tmpl', lookup=self.lookup)
            return templ.render(id=id, name=res[0])
Пример #23
0
 def scaneventresultexport(self, id, type, dialect="excel"):
     dbh = SpiderFootDb(self.config)
     data = dbh.scanResultEvent(id, type)
     fileobj = StringIO()
     parser = csv.writer(fileobj, dialect=dialect)
     parser.writerow(["Updated", "Type", "Module", "Source", "Data"])
     for row in data:
         lastseen = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(row[0]))
         parser.writerow([lastseen, str(row[4]), str(row[3]), str(row[2]), str(row[1])])
     cherrypy.response.headers['Content-Disposition'] = "attachment; filename=SpiderFoot.csv"
     cherrypy.response.headers['Content-Type'] = "application/csv"
     cherrypy.response.headers['Pragma'] = "no-cache"
     return fileobj.getvalue()
Пример #24
0
    def scandelete(self, id, confirm=None):
        dbh = SpiderFootDb(self.config)
        res = dbh.scanInstanceGet(id)
        if res is None:
            return self.error("Scan ID not found.")

        if confirm is not None:
            dbh.scanInstanceDelete(id)
            raise cherrypy.HTTPRedirect("/")
        else:
            templ = Template(filename='dyn/scandelete.tmpl', lookup=self.lookup)
            return templ.render(id=id, name=res[0], names=list(), ids=list(),
                                pageid="SCANLIST", docroot=self.docroot)
Пример #25
0
 def scaneventresultexport(self, id, type):
     dbh = SpiderFootDb(self.config)
     data = dbh.scanResultEvent(id, type)
     blob = "\"Updated\",\"Type\",\"Module\",\"Source\",\"Data\"\n"
     for row in data:
         lastseen = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(row[0]))
         escapedData = cgi.escape(row[1].replace("\n", "#LB#").replace("\r", "#LB#"))
         escapedSrc = cgi.escape(row[2].replace("\n", "#LB#").replace("\r", "#LB#"))
         blob = blob + "\"" + lastseen + "\",\"" + row[4] + "\",\""
         blob = blob + row[3] + "\",\"" + escapedSrc + "\",\"" + escapedData + "\"\n"
     cherrypy.response.headers['Content-Disposition'] = "attachment; filename=SpiderFoot.csv"
     cherrypy.response.headers['Content-Type'] = "application/csv"
     cherrypy.response.headers['Pragma'] = "no-cache"
     return blob
Пример #26
0
 def scanviz(self, id, gexf="0"):
     types = list()
     dbh = SpiderFootDb(self.config)
     sf = SpiderFoot(self.config)
     data = dbh.scanResultEvent(id, filterFp=True)
     scan = dbh.scanInstanceGet(id)
     root = scan[1]
     if gexf != "0":
         cherrypy.response.headers['Content-Disposition'] = "attachment; filename=SpiderFoot.gexf"
         cherrypy.response.headers['Content-Type'] = "application/gexf"
         cherrypy.response.headers['Pragma'] = "no-cache"
         return sf.buildGraphGexf([root], "SpiderFoot Export", data)
     else:
         return sf.buildGraphJson([root], data)
Пример #27
0
    def savesettings(self, allopts, token, configFile=None):
        if str(token) != str(self.token):
            return self.error("Invalid token (" + str(self.token) + ").")

        if configFile:  # configFile seems to get set even if a file isn't uploaded
            if configFile.file:
                contents = configFile.file.read()
                try:
                    tmp = dict()
                    for line in contents.split("\n"):
                        if "=" not in line:
                            continue
                        l = line.strip().split("=")
                        if len(l) == 1:
                            l[1] = ""
                        tmp[l[0]] = l[1]
                    allopts = json.dumps(tmp)
                except BaseException as e:
                    return self.error("Failed to parse input file. Was it generated from SpiderFoot? (" + str(e) + ")")

        try:
            dbh = SpiderFootDb(self.config)
            # Reset config to default
            if allopts == "RESET":
                dbh.configClear()  # Clear it in the DB
                self.config = deepcopy(self.defaultConfig)  # Clear in memory
            else:
                useropts = json.loads(allopts)
                cleanopts = dict()
                for opt in useropts.keys():
                    cleanopts[opt] = self.cleanUserInput([useropts[opt]])[0]

                currentopts = deepcopy(self.config)

                # Make a new config where the user options override
                # the current system config.
                sf = SpiderFoot(self.config)
                self.config = sf.configUnserialize(cleanopts, currentopts)
                dbh.configSet(sf.configSerialize(self.config))
        except Exception as e:
            return self.error("Processing one or more of your inputs failed: " + str(e))

        templ = Template(filename='dyn/opts.tmpl', lookup=self.lookup)
        self.token = random.randint(0, 99999999)
        return templ.render(opts=self.config, pageid='SETTINGS', updated=True,
                            docroot=self.docroot, token=self.token)
Пример #28
0
    def scanlist(self):
        dbh = SpiderFootDb(self.config)
        data = dbh.scanInstanceList()
        retdata = []
        for row in data:
            created = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(row[3]))
            if row[4] != 0:
                started = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(row[4]))
            else:
                started = "Not yet"

            if row[5] != 0:
                finished = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(row[5]))
            else:
                finished = "Not yet"
            retdata.append([row[0], row[1], row[2], created, started, finished, row[6], row[7]])
        return json.dumps(retdata)
Пример #29
0
    def scanelementtypediscovery(self, id, eventType):
        sf = SpiderFoot(self.config)
        dbh = SpiderFootDb(self.config)
        pc = dict()
        datamap = dict()

        # Get the events we will be tracing back from
        leafSet = dbh.scanResultEvent(id, eventType)
        [datamap, pc] = dbh.scanElementSourcesAll(id, leafSet)

        # Delete the ROOT key as it adds no value from a viz perspective
        del pc['ROOT']
        retdata = dict()
        retdata['tree'] = sf.dataParentChildToTree(pc)
        retdata['data'] = datamap

        return json.dumps(retdata, ensure_ascii=False)
Пример #30
0
    def clonescan(self, id):
        dbh = SpiderFootDb(self.config)
        types = dbh.eventTypes()
        info = dbh.scanInstanceGet(id)
        scanconfig = dbh.scanConfigGet(id)
        scanname = info[0]
        scantarget = info[1]
        targetType = None

        if scanname == "" or scantarget == "" or len(scanconfig) == 0:
            return self.error("Something went wrong internally.")

        modlist = scanconfig['_modulesenabled'].split(',')

        templ = Template(filename='dyn/newscan.tmpl', lookup=self.lookup)
        return templ.render(pageid='NEWSCAN', types=types, docroot=self.docroot,
                            modules=self.config['__modules__'], selectedmods=modlist,
                            scanname=scanname, scantarget=scantarget)
Пример #31
0
    def scaneventresultexportmulti(self, ids, dialect="excel"):
        """Get scan event result data in CSV format for multiple scans

        Args:
            ids (str): comma separated list of scan IDs
            dialect (str): TBD

        Returns:
            string: results in CSV format
        """

        dbh = SpiderFootDb(self.config)
        scaninfo = dict()
        data = list()
        for id in ids.split(','):
            scaninfo[id] = dbh.scanInstanceGet(id)
            data = data + dbh.scanResultEvent(id)

        fileobj = StringIO()
        parser = csv.writer(fileobj, dialect=dialect)
        parser.writerow([
            "Scan Name", "Updated", "Type", "Module", "Source", "F/P", "Data"
        ])
        for row in data:
            if row[4] == "ROOT":
                continue
            lastseen = time.strftime("%Y-%m-%d %H:%M:%S",
                                     time.localtime(row[0]))
            datafield = str(row[1]).replace("<SFURL>",
                                            "").replace("</SFURL>", "")
            parser.writerow([
                scaninfo[row[12]][0], lastseen,
                str(row[4]),
                str(row[3]),
                str(row[2]), row[13], datafield
            ])
        cherrypy.response.headers[
            'Content-Disposition'] = "attachment; filename=SpiderFoot.csv"
        cherrypy.response.headers['Content-Type'] = "application/csv"
        cherrypy.response.headers['Pragma'] = "no-cache"
        return fileobj.getvalue().encode("Utf-8")
Пример #32
0
    def rerunscanmulti(self, ids):
        # Snapshot the current configuration to be used by the scan
        cfg = deepcopy(self.config)
        modopts = dict()  # Not used yet as module options are set globally
        modlist = list()
        sf = SpiderFoot(cfg)
        dbh = SpiderFootDb(cfg)

        for id in ids.split(","):
            info = dbh.scanInstanceGet(id)
            scanconfig = dbh.scanConfigGet(id)
            scanname = info[0]
            scantarget = info[1]
            targetType = None

            if len(scanconfig) == 0:
                return self.error("Something went wrong internally.")

            modlist = scanconfig['_modulesenabled'].split(',')

            targetType = sf.targetType(scantarget)
            if targetType == None:
                # Should never be triggered for a re-run scan..
                return self.error("Invalid target type. Could not recognize it as " + \
                                  "an IP address, IP subnet, domain name or host name.")

            # Start running a new scan
            newId = sf.genScanInstanceGUID(scanname)
            t = SpiderFootScanner(scanname, scantarget.lower(), targetType,
                                  newId, modlist, cfg, modopts)
            t.start()

            # Wait until the scan has initialized
            while globalScanStatus.getStatus(newId) == None:
                print "[info] Waiting for the scan to initialize..."
                time.sleep(1)

        templ = Template(filename='dyn/scanlist.tmpl', lookup=self.lookup)
        return templ.render(rerunscans=True,
                            docroot=self.docroot,
                            pageid="SCANLIST")
Пример #33
0
    def test_scan_result_summary_invalid_type_should_raise(self):
        """
        Test scanResultSummary(self, instanceId, by="type")
        """
        sfdb = SpiderFootDb(self.default_options, False)

        invalid_types = [None, list(), dict()]
        for invalid_type in invalid_types:
            with self.subTest(invalid_type=invalid_type):
                with self.assertRaises(TypeError) as cm:
                    scan_results_summary = sfdb.scanResultSummary(invalid_type)

        instance_id = "example instance id"
        invalid_types = [None, list(), dict()]
        for invalid_type in invalid_types:
            with self.subTest(invalid_type=invalid_type):
                with self.assertRaises(TypeError) as cm:
                    scan_results_summary = sfdb.scanResultSummary(instance_id, None)

        with self.assertRaises(ValueError) as cm:
            scan_results_summary = sfdb.scanResultSummary(instance_id, "invalid filter type")
Пример #34
0
 def scaneventresultexport(self, id, type, dialect="excel"):
     dbh = SpiderFootDb(self.config)
     data = dbh.scanResultEvent(id, type)
     fileobj = StringIO()
     parser = csv.writer(fileobj, dialect=dialect)
     parser.writerow(["Updated", "Type", "Module", "Source", "Data"])
     for row in data:
         lastseen = time.strftime("%Y-%m-%d %H:%M:%S",
                                  time.localtime(row[0]))
         datafield = str(row[1]).replace("<SFURL>",
                                         "").replace("</SFURL>", "")
         parser.writerow(
             [lastseen,
              str(row[4]),
              str(row[3]),
              str(row[2]), datafield])
     cherrypy.response.headers[
         'Content-Disposition'] = "attachment; filename=SpiderFoot.csv"
     cherrypy.response.headers['Content-Type'] = "application/csv"
     cherrypy.response.headers['Pragma'] = "no-cache"
     return fileobj.getvalue()
Пример #35
0
    def test_scanEventStore_argument_sfEvent_with_empty_module_property_value_should_raise_ValueError(self):
        """
        Test scanEventStore(self, instanceId, sfEvent, truncateSize=0)
        """
        sfdb = SpiderFootDb(self.default_options, False)

        event_type = 'ROOT'
        event_data = 'example data'
        module = ''
        source_event = ''
        source_event = SpiderFootEvent(event_type, event_data, module, source_event)

        event_type = 'example event type'
        event_data = 'example event data'
        module = 'example module'
        event = SpiderFootEvent(event_type, event_data, module, source_event)

        instance_id = "example instance id"
        with self.assertRaises(ValueError) as cm:
            event.module = ''
            sfdb.scanEventStore(instance_id, event)
Пример #36
0
    def scandeletemulti(self, ids, confirm=None):
        dbh = SpiderFootDb(self.config)
        names = list()

        for id in ids.split(','):
            res = dbh.scanInstanceGet(id)
            names.append(unicode(res[0], 'utf-8', errors='replace'))
            if res is None:
                return self.error("Scan ID not found (" + id + ").")

            if res[5] in [ "RUNNING", "STARTING", "STARTED" ]:
                return self.error("You cannot delete running scans.")

        if confirm is not None:
            for id in ids.split(','):
                dbh.scanInstanceDelete(id)
            raise cherrypy.HTTPRedirect(self.docroot)
        else:
            templ = Template(filename='dyn/scandelete.tmpl', lookup=self.lookup)
            return templ.render(id=None, name=None, ids=ids.split(','), names=names, 
                                pageid="SCANLIST", docroot=self.docroot)
Пример #37
0
    def scaneventresultsunique(self, id, eventType, filterfp=False):
        """Unique event results for a scan

        Args:
            id (str): scan ID
            eventType (str): filter by event type
            filterfp: TBD
        """

        dbh = SpiderFootDb(self.config)
        retdata = []

        try:
            data = dbh.scanResultEventUnique(id, eventType, filterfp)
        except Exception:
            return json.dumps(retdata)

        for row in data:
            escaped = html.escape(row[0])
            retdata.append([escaped, row[1], row[2]])
        return json.dumps(retdata, ensure_ascii=False)
Пример #38
0
    def test_search_invalid_criteria_should_raise(self):
        """
        Test search(self, criteria, filterFp=False)
        """
        sfdb = SpiderFootDb(self.default_options, False)

        invalid_types = [None, "", list()]
        for invalid_type in invalid_types:
            with self.subTest(invalid_type=invalid_type):
                with self.assertRaises(TypeError) as cm:
                    search_results = sfdb.search(invalid_type, False)

        criteria = {
            'scan_id': None,
            'type': None,
            'value': None,
            'regex': None
        }

        with self.assertRaises(ValueError) as cm:
            search_results = sfdb.search(criteria, False)
Пример #39
0
    def scansummary(self, id, by):
        retdata = []

        dbh = SpiderFootDb(self.config)

        try:
            scandata = dbh.scanResultSummary(id, by)
        except:
            return json.dumps(retdata)

        try:
            statusdata = dbh.scanInstanceGet(id)
        except:
            return json.dumps(retdata)

        for row in scandata:
            if row[0] == "ROOT":
                continue
            lastseen = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(row[2]))
            retdata.append([row[0], row[1], lastseen, row[3], row[4], statusdata[5]])
        return json.dumps(retdata)
Пример #40
0
    def savesettings(self, allopts, token):
        if str(token) != str(self.token):
            return self.error("Invalid token (" + str(self.token) + ").")

        try:
            dbh = SpiderFootDb(self.config)
            # Reset config to default
            if allopts == "RESET":
                dbh.configClear()  # Clear it in the DB
                self.config = deepcopy(self.defaultConfig)  # Clear in memory
            else:
                useropts = json.loads(allopts)
                cleanopts = dict()
                for opt in useropts.keys():
                    cleanopts[opt] = self.cleanUserInput([useropts[opt]])[0]

                currentopts = deepcopy(self.config)

                # Make a new config where the user options override
                # the current system config.
                sf = SpiderFoot(self.config)
                self.config = sf.configUnserialize(cleanopts, currentopts)
                dbh.configSet(sf.configSerialize(currentopts))
        except Exception as e:
            return self.error(
                "Processing one or more of your inputs failed: " + str(e))

        templ = Template(filename='dyn/opts.tmpl', lookup=self.lookup)
        self.token = random.randint(0, 99999999)
        return templ.render(opts=self.config,
                            pageid='SETTINGS',
                            updated=True,
                            docroot=self.docroot,
                            token=self.token)
Пример #41
0
    def stopscan(self, id, cli=None):
        global globalScanStatus

        dbh = SpiderFootDb(self.config)
        scaninfo = dbh.scanInstanceGet(id)
        if scaninfo is None:
            if not cli:
                return self.error("Invalid scan ID.")
            else:
                return json.dumps(["ERROR", "Invalid scan ID."])

        if globalScanStatus.getStatus(id) is None:
            if not cli:
                return self.error("That scan is not actually running. A data consistency " + \
                                  "error for this scan probably exists. <a href='/scandelete?id=" + \
                                  id + "&confirm=1'>Click here to delete it.</a>")
            else:
                return json.dumps(["ERROR", "Scan doesn't appear to be running."])

        if globalScanStatus.getStatus(id) == "ABORTED":
            if not cli:
                return self.error("The scan is already aborted.")
            else:
                return json.dumps(["ERROR", "Scan already aborted."])


        if not globalScanStatus.getStatus(id) == "RUNNING":
            if not cli:
                return self.error("The running scan is currently in the state '" + \
                                  globalScanStatus.getStatus(id) + "', please try again later or restart " + \
                                  " SpiderFoot.")
            else:
                return json.dumps(["ERROR", "Scan in an invalid state for stopping."])

        globalScanStatus.setStatus(id, "ABORT-REQUESTED")
        if not cli:
            templ = Template(filename='dyn/scanlist.tmpl', lookup=self.lookup)
            return templ.render(pageid='SCANLIST', stoppedscan=True, docroot=self.docroot, errors=list())
        else:
            return json.dumps(["SUCCESS", ""])
Пример #42
0
    def scanexportjsonmulti(self, ids):
        dbh = SpiderFootDb(self.config)
        scaninfo = dict()

        for id in ids.split(','):
          scan = dbh.scanInstanceGet(id)

          if scan is None:
              continue

          scan_name = scan[0]

          if scan_name not in scaninfo:
              scaninfo[scan_name] = []

          for row in dbh.scanResultEvent(id):
              lastseen = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(row[0]))
              event_data = str(row[1]).replace("<SFURL>", "").replace("</SFURL>", "")
              source_data = str(row[2])
              source_module = str(row[3])
              event_type = row[4]
              false_positive = row[13]

              if event_type == "ROOT":
                  continue

              scaninfo[scan_name].append({
                  "data": event_data,
                  "type": event_type,
                  "source_module": source_module,
                  "source_data": source_data,
                  "false_positive": false_positive,
                  "lastseen": lastseen
              })

        cherrypy.response.headers['Content-Disposition'] = "attachment; filename=SpiderFoot.json"
        cherrypy.response.headers['Content-Type'] = "application/json; charset=utf-8"
        cherrypy.response.headers['Pragma'] = "no-cache"

        return json.dumps(scaninfo)
Пример #43
0
    def resultsetfp(self, id, resultids, fp):
        dbh = SpiderFootDb(self.config)
        if fp not in ["0", "1"]:
            return json.dumps(
                ["ERROR", "No FP flag set or not set correctly."])

        ids = json.loads(resultids)
        if not ids:
            return json.dumps(["ERROR", "No IDs supplied."])

        # Cannot set FPs if a scan is not completed
        status = dbh.scanInstanceGet(id)
        if status[5] not in ["ABORTED", "FINISHED", "ERROR-FAILED"]:
            return json.dumps(["WARNING", "Scan must be in a finished state when " + \
                               "setting False Positives."])

        # Make sure the user doesn't set something as non-FP when the
        # parent is set as an FP.
        if fp == "0":
            data = dbh.scanElementSourcesDirect(id, ids)
            for row in data:
                if str(row[14]) == "1":
                    return json.dumps(["WARNING",
                        "You cannot unset an element as False Positive " + \
                        "if a parent element is still False Positive."])

        # Set all the children as FPs too.. it's only logical afterall, right?
        childs = dbh.scanElementChildrenAll(id, ids)
        allIds = ids + childs

        ret = dbh.scanResultsUpdateFP(id, allIds, fp)
        if not ret:
            return json.dumps(["ERROR", "Exception encountered."])
        else:
            return json.dumps(["SUCCESS", ""])
Пример #44
0
    def savesettingsraw(self, allopts, token):
        if str(token) != str(self.token):
            return json.dumps(
                ["ERROR", "Invalid token (" + str(self.token) + ")."])

        try:
            dbh = SpiderFootDb(self.config)
            # Reset config to default
            if allopts == "RESET":
                dbh.configClear()  # Clear it in the DB
                self.config = deepcopy(self.defaultConfig)  # Clear in memory
            else:
                useropts = json.loads(allopts)
                cleanopts = dict()
                for opt in list(useropts.keys()):
                    cleanopts[opt] = self.cleanUserInput([useropts[opt]])[0]

                currentopts = deepcopy(self.config)

                # Make a new config where the user options override
                # the current system config.
                sf = SpiderFoot(self.config)
                self.config = sf.configUnserialize(cleanopts, currentopts)
                dbh.configSet(sf.configSerialize(self.config))
        except Exception as e:
            return json.dumps([
                "ERROR",
                "Processing one or more of your inputs failed: " + str(e)
            ])

        return json.dumps(["SUCCESS", ""])
Пример #45
0
    def stopscan(self, id, cli=None):
        """Stop a scan.

        Args:
            id (str): scan ID
            cli: TBD
        """

        dbh = SpiderFootDb(self.config)
        scaninfo = dbh.scanInstanceGet(id)

        if not scaninfo:
            if cli:
                return json.dumps(["ERROR", "Invalid scan ID."])

            return self.error("Invalid scan ID.")

        scanstatus = scaninfo[5]

        if scanstatus == "ABORTED":
            if cli:
                return json.dumps(["ERROR", "Scan already aborted."])

            return self.error("The scan is already aborted.")

        if not scanstatus == "RUNNING":
            if cli:
                return json.dumps(
                    ["ERROR", "Scan in an invalid state for stopping."])

            return self.error(
                "The running scan is currently in the state '%s', please try again later or restart SpiderFoot."
                % scanstatus)

        dbh.scanInstanceSet(id, status="ABORT-REQUESTED")

        if cli:
            return json.dumps(["SUCCESS", ""])

        raise cherrypy.HTTPRedirect("/")
Пример #46
0
    def __init__(self, config):
        self.defaultConfig = deepcopy(config)
        dbh = SpiderFootDb(self.defaultConfig)
        # 'config' supplied will be the defaults, let's supplement them
        # now with any configuration which may have previously been
        # saved.
        sf = SpiderFoot(self.defaultConfig)
        self.config = sf.configUnserialize(dbh.configGet(), self.defaultConfig)

        if self.config['__webaddr'] == "0.0.0.0":
            addr = "<IP of this host>"
        else:
            addr = self.config['__webaddr']

        self.docroot = self.config['__docroot'].rstrip('/')

        cherrypy.config.update({
            'error_page.404': self.error_page_404,
            'request.error_response': self.error_page
        })

        secure_headers = SecureHeaders()

        cherrypy.config.update({
            "tools.response_headers.on":
            True,
            "tools.response_headers.headers":
            secure_headers.cherrypy()
        })

        print("")
        print("")
        print("*************************************************************")
        print(" Use SpiderFoot by starting your web browser of choice and ")
        print(" browse to http://" + addr + ":" +
              str(self.config['__webport']) + self.docroot)
        print("*************************************************************")
        print("")
        print("")
Пример #47
0
    def scanerrors(self, id, limit=None):
        """Scan error data

        Args:
            id (str): scan ID
            limit: TBD
        """

        dbh = SpiderFootDb(self.config)
        retdata = []

        try:
            data = dbh.scanErrors(id, limit)
        except Exception:
            return json.dumps(retdata)

        for row in data:
            generated = time.strftime("%Y-%m-%d %H:%M:%S",
                                      time.localtime(row[0] / 1000))
            retdata.append([generated, row[1], html.escape(str(row[2]))])

        return json.dumps(retdata)
Пример #48
0
    def stopscanmulti(self, ids):
        global globalScanStatus  # running scans
        dbh = SpiderFootDb(self.config)
        error = list()

        for id in ids.split(","):
            errState = False
            scaninfo = dbh.scanInstanceGet(id)

            if scaninfo is None:
                return self.error("Invalid scan ID specified.")

            scanname = str(scaninfo[0])

            if globalScanStatus.getStatus(
                    id) == "FINISHED" or scaninfo[5] == "FINISHED":
                error.append("Scan '" + scanname + "' is in a finished state. <a href='/scandelete?id=" + \
                             id + "&confirm=1'>Maybe you want to delete it instead?</a>")
                errState = True

            if not errState and (globalScanStatus.getStatus(id) == "ABORTED"
                                 or scaninfo[5] == "ABORTED"):
                error.append("Scan '" + scanname + "' is already aborted.")
                errState = True

            if not errState and globalScanStatus.getStatus(id) is None:
                error.append("Scan '" + scanname + "' is not actually running. A data consistency " + \
                             "error for this scan probably exists. <a href='/scandelete?id=" + \
                             id + "&confirm=1'>Click here to delete it.</a>")
                errState = True

            if not errState:
                globalScanStatus.setStatus(id, "ABORT-REQUESTED")

        templ = Template(filename='dyn/scanlist.tmpl', lookup=self.lookup)
        return templ.render(pageid='SCANLIST',
                            stoppedscan=True,
                            errors=error,
                            docroot=self.docroot)
Пример #49
0
    def clonescan(self, id):
        """
        Clone an existing scan (pre-selected options in the newscan page)

        Args:
            id (str): scan ID to clone
        """

        sf = SpiderFoot(self.config)
        dbh = SpiderFootDb(self.config)
        types = dbh.eventTypes()
        info = dbh.scanInstanceGet(id)

        if not info:
            return self.error("Invalid scan ID.")

        scanconfig = dbh.scanConfigGet(id)
        scanname = info[0]
        scantarget = info[1]
        targetType = None

        if scanname == "" or scantarget == "" or len(scanconfig) == 0:
            return self.error("Something went wrong internally.")

        targetType = sf.targetType(scantarget)
        if targetType is None:
            # It must be a name, so wrap quotes around it
            scantarget = "&quot;" + scantarget + "&quot;"

        modlist = scanconfig['_modulesenabled'].split(',')

        templ = Template(filename='dyn/newscan.tmpl', lookup=self.lookup)
        return templ.render(pageid='NEWSCAN',
                            types=types,
                            docroot=self.docroot,
                            modules=self.config['__modules__'],
                            selectedmods=modlist,
                            scanname=str(scanname),
                            scantarget=str(scantarget))
Пример #50
0
    def clonescan(self, id):
        dbh = SpiderFootDb(self.config)
        types = dbh.eventTypes()
        info = dbh.scanInstanceGet(id)
        scanconfig = dbh.scanConfigGet(id)
        scanname = info[0]
        scantarget = info[1]
        targetType = None

        if scanname == "" or scantarget == "" or len(scanconfig) == 0:
            return self.error("Something went wrong internally.")

        modlist = scanconfig['_modulesenabled'].split(',')

        templ = Template(filename='dyn/newscan.tmpl', lookup=self.lookup)
        return templ.render(pageid='NEWSCAN',
                            types=types,
                            docroot=self.docroot,
                            modules=self.config['__modules__'],
                            selectedmods=modlist,
                            scanname=scanname,
                            scantarget=scantarget)
Пример #51
0
    def __init__(self, config):
        self.defaultConfig = deepcopy(config)
        dbh = SpiderFootDb(config)
        # 'config' supplied will be the defaults, let's supplement them
        # now with any configuration which may have previously been
        # saved.
        sf = SpiderFoot(config)
        self.config = sf.configUnserialize(dbh.configGet(), config)

        if self.config['__webaddr'] == "0.0.0.0":
            addr = "<IP of this host>"
        else:
            addr = self.config['__webaddr']

        print ""
        print ""
        print "*************************************************************"
        print " Use SpiderFoot by starting your web browser of choice and "
        print " browse to http://" + addr + ":" + str(self.config['__webport'])
        print "*************************************************************"
        print ""
        print ""
Пример #52
0
    def scanopts(self, id):
        ret = dict()
        dbh = SpiderFootDb(self.config)
        ret['config'] = dbh.scanConfigGet(id)
        ret['configdesc'] = dict()
        for key in ret['config'].keys():
            if ':' not in key:
                ret['configdesc'][key] = self.config['__globaloptdescs__'][key]
            else:
                [modName, modOpt] = key.split(':')
                if modName not in self.config['__modules__'].keys():
                    continue

                if modOpt not in self.config['__modules__'][modName][
                        'optdescs'].keys():
                    continue

                ret['configdesc'][key] = self.config['__modules__'][modName][
                    'optdescs'][modOpt]

        sf = SpiderFoot(self.config)
        meta = dbh.scanInstanceGet(id)
        if not meta:
            return json.dumps([])
        if meta[3] != 0:
            started = time.strftime("%Y-%m-%d %H:%M:%S",
                                    time.localtime(meta[3]))
        else:
            started = "Not yet"

        if meta[4] != 0:
            finished = time.strftime("%Y-%m-%d %H:%M:%S",
                                     time.localtime(meta[4]))
        else:
            finished = "Not yet"
        ret['meta'] = [meta[0], meta[1], meta[2], started, finished, meta[5]]

        return json.dumps(ret)
Пример #53
0
    def scanlist(self):
        dbh = SpiderFootDb(self.config)
        data = dbh.scanInstanceList()
        retdata = []
        for row in data:
            created = time.strftime("%Y-%m-%d %H:%M:%S",
                                    time.localtime(row[3]))
            if row[4] != 0:
                started = time.strftime("%Y-%m-%d %H:%M:%S",
                                        time.localtime(row[4]))
            else:
                started = "Not yet"

            if row[5] != 0:
                finished = time.strftime("%Y-%m-%d %H:%M:%S",
                                         time.localtime(row[5]))
            else:
                finished = "Not yet"
            retdata.append([
                row[0], row[1], row[2], created, started, finished, row[6],
                row[7]
            ])
        return json.dumps(retdata)
Пример #54
0
    def query(self, query):
        data = None
        dbh = SpiderFootDb(self.config)
        if not query.lower().startswith("select"):
            return json.dumps([
                "ERROR", "Non-SELECTs are unpredictable and not recommended."
            ])
        try:
            ret = dbh.dbh.execute(query)
            data = ret.fetchall()
        except BaseException as e:
            return json.dumps(["ERROR", str(e)])

        return json.dumps(data)
Пример #55
0
    def searchBase(self, id=None, eventType=None, value=None):
        regex = ""
        if [id, eventType, value].count('') == 2 or \
                        [id, eventType, value].count(None) == 2:
            return None

        if value.startswith("/") and value.endswith("/"):
            regex = value[1:len(value) - 1]
            value = ""

        value = value.replace('*', '%')
        if value in [None, ""] and regex in [None, ""]:
            value = "%"
            regex = ""

        dbh = SpiderFootDb(self.config)
        criteria = {
            'scan_id': None if id == '' else id,
            'type': None if eventType == '' else eventType,
            'value': None if value == '' else value,
            'regex': None if regex == '' else regex
        }

        data = dbh.search(criteria)
        retdata = []
        for row in data:
            lastseen = time.strftime("%Y-%m-%d %H:%M:%S",
                                     time.localtime(row[0]))
            escapeddata = cgi.escape(row[1])
            escapedsrc = cgi.escape(row[2])
            retdata.append([
                lastseen, escapeddata, escapedsrc, row[3], row[5], row[6],
                row[7], row[8], row[10], row[11], row[4], row[13], row[14]
            ])

        return retdata
Пример #56
0
    def scanelementtypediscovery(self, id, eventType):
        """scan element type discovery

        Args:
            id: TBD
            eventType (str): filter by event type
        """

        sf = SpiderFoot(self.config)
        dbh = SpiderFootDb(self.config)
        pc = dict()
        datamap = dict()

        # Get the events we will be tracing back from
        leafSet = dbh.scanResultEvent(id, eventType)
        [datamap, pc] = dbh.scanElementSourcesAll(id, leafSet)

        # Delete the ROOT key as it adds no value from a viz perspective
        del pc['ROOT']
        retdata = dict()
        retdata['tree'] = sf.dataParentChildToTree(pc)
        retdata['data'] = datamap

        return json.dumps(retdata, ensure_ascii=False)
Пример #57
0
    def scandelete(self, id, confirm=None, raw=False):
        dbh = SpiderFootDb(self.config)
        res = dbh.scanInstanceGet(id)
        if res is None:
            if not raw:
                return self.error("Scan ID not found.")
            else:
                return json.dumps(["ERROR", "Scan ID not found."])

        if confirm is not None:
            dbh.scanInstanceDelete(id)
            if not raw:
                raise cherrypy.HTTPRedirect("/")
            else:
                return json.dumps(["SUCCESS", ""])
        else:
            templ = Template(filename='dyn/scandelete.tmpl',
                             lookup=self.lookup)
            return templ.render(id=id,
                                name=str(res[0]),
                                names=list(),
                                ids=list(),
                                pageid="SCANLIST",
                                docroot=self.docroot)
Пример #58
0
    def query(self, query):
        data = None
        dbh = SpiderFootDb(self.config)

        cherrypy.response.headers['Content-Type'] = "application/json; charset=utf-8"

        if not query.lower().startswith("select"):
            return json.dumps(["ERROR", "Non-SELECTs are unpredictable and not recommended."])

        try:
            ret = dbh.dbh.execute(query)
            data = ret.fetchall()
        except BaseException as e:
            return json.dumps(["ERROR", str(e)])

        return json.dumps(data)
Пример #59
0
    def savesettings(self, allopts, token, configFile=None):
        if str(token) != str(self.token):
            return self.error("Invalid token (" + str(self.token) + ").")

        if configFile:  # configFile seems to get set even if a file isn't uploaded
            if configFile.file:
                contents = configFile.file.read()

                if type(contents) == bytes:
                    contents = contents.decode("utf-8")
                try:
                    tmp = dict()
                    for line in contents.split("\n"):
                        if "=" not in line:
                            continue
                        l = line.strip().split("=")
                        if len(l) == 1:
                            l[1] = ""
                        tmp[l[0]] = l[1]
                    allopts = json.dumps(tmp)
                except BaseException as e:
                    return self.error(
                        "Failed to parse input file. Was it generated from SpiderFoot? ("
                        + str(e) + ")")

        try:
            dbh = SpiderFootDb(self.config)
            # Reset config to default
            if allopts == "RESET":
                dbh.configClear()  # Clear it in the DB
                self.config = deepcopy(self.defaultConfig)  # Clear in memory
            else:
                useropts = json.loads(allopts)
                cleanopts = dict()
                for opt in list(useropts.keys()):
                    cleanopts[opt] = self.cleanUserInput([useropts[opt]])[0]

                currentopts = deepcopy(self.config)

                # Make a new config where the user options override
                # the current system config.
                sf = SpiderFoot(self.config)
                self.config = sf.configUnserialize(cleanopts, currentopts)
                dbh.configSet(sf.configSerialize(self.config))
        except Exception as e:
            return self.error(
                "Processing one or more of your inputs failed: " + str(e))

        templ = Template(filename='dyn/opts.tmpl', lookup=self.lookup)
        self.token = random.SystemRandom().randint(0, 99999999)
        return templ.render(opts=self.config,
                            pageid='SETTINGS',
                            updated=True,
                            docroot=self.docroot,
                            token=self.token)
Пример #60
0
    def test_config_set_invalid_optmap_should_raise(self):
        """
        Test configSet(self, optMap=dict())
        """
        sfdb = SpiderFootDb(self.default_options, False)

        invalid_types = [None, "", list()]
        for invalid_type in invalid_types:
            with self.subTest(invalid_type=invalid_type):
                with self.assertRaises(TypeError) as cm:
                    scan_result_event = sfdb.scanResultEventUnique("", invalid_type, None)
                    sfdb.configSet(invalid_type)

        with self.assertRaises(ValueError) as cm:
            sfdb.configSet(dict())