Commit 6a2e6123 authored by PidgeyL's avatar PidgeyL
Browse files

move the 'seen' functionality to its own plug-in

parent 7b8d8249
Loading
Loading
Loading
Loading
+0 −24
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ colCPEOTHER= db['cpeother']
colWHITELIST=   db['mgmt_whitelist']
colBLACKLIST=   db['mgmt_blacklist']
colUSERS=       db['mgmt_users']
colSEEN=        db['mgmt_seen']
colINFO=        db['info']
colVFEED=       db['vfeed']
colRANKING=     db['ranking']
@@ -133,29 +132,6 @@ def setAdmin(user, admin):
  else:
    colUSERS.update({'username': user}, {'$unset': {'master': ""}})

def createUserData(user):
  colSEEN.insert({"user": user, "seen_cves": []})

def seenCVEs(user):
  data = colSEEN.find_one({"user": user})
  if not data:
    createUserData(user)
    return []
  else:
    return data['seen_cves']

def addSeenCVEs(user, CVEs):
  if type(CVEs) == str: CVEs=[CVEs]
  if type(CVEs) == list:
    seen=list(set(CVEs)-set(seenCVEs(user)))
    if seen:
      colSEEN.update({"user": user}, {"$addToSet": {"seen_cves": { "$each": seen}}})

def removeSeenCVEs(user, CVEs):
  if type(CVEs) == str: CVEs=[CVEs]
  if type(CVEs) == list:
    colSEEN.update({"user": user}, {"$pullAll": {"seen_cves": CVEs}})

def isMasterAccount(user):
  return False if colUSERS.find({"username": user, "master": True}).count() == 0 else True

+46 −8
Original line number Diff line number Diff line
@@ -56,10 +56,9 @@ class PluginManager():
        print("[!] Failed to load module %s: "%x[0])
        print("[!]  -> %s"%e)

  def onOpenCVE(self, cve, user):
    for plugin in self.plugins.values(): # Read all plugins
      if plugin.isWebPlugin():           # Check if plugin is web plugin
        return plugin.onJsonCall(action, **args)
  def onCVEOpen(self, cve, **args):
    for plugin in self.getWebPlugins():
      plugin.onCVEOpen(cve, **args)

  def onCVEAction(self, cve, plugin, action, **args):
    if plugin.strip() in self.plugins.keys(): # Check if plugin exists
@@ -84,13 +83,12 @@ class PluginManager():
        plugins.append(plug)
    return plugins

  def getCVEActions(self, **args):
  def getCVEActions(self, cve, **args):
    actions = []
    for plugin in self.getWebPlugins():
      auth = plugin.requiresAuth
      try:
        for action in plugin.getCVEActions(**args):
          action['auth'] = auth
        for action in plugin.getCVEActions(cve, **args):
          action['auth'] = plugin.requiresAuth
          action['plugin'] = plugin.getUID()
          actions.append(action)
      except:
@@ -157,3 +155,43 @@ class PluginManager():
          entry['reason']=collection['n']
          result['data'].append(entry)
    return result

# Filters
  def getFilters(self, **args):
    filters = []
    for plugin in self.getWebPlugins():
      try:
        for filter_ in plugin.getFilters(**args):
          filter_['auth']   = plugin.requiresAuth
          filter_['plugin'] = plugin.getUID()
          filters.append(filter_)
      except Exception as e:
        print("[!] Plugin %s failed on fetching filters!"%plugin.getName())
    return filters

  def doFilter(self, filters, **args):
    plug_fils = {key[5:]: value for (key, value) in filters.items() if key.startswith('plug_')}
    filters_ = []
    for plugin in self.getWebPlugins():
      try:
        filter_ = plugin.doFilter(plug_fils, **args)
        if filter_:
          if   type(filter_) is dict: filters_.append(filter_)
          elif type(filter_) is list: filters_.extend(filter_)
      except Exception as e:
        print("[!] Plugin %s failed on applying filters!"%plugin.getName())
    return filters_

  def mark(self, cves, **args):
    for plugin in self.getWebPlugins():
      for cve in cves:
        try:
          marks = plugin.mark(cve['id'], **args)
          if marks and type(marks) == tuple and len(marks) == 2:
            if marks[0]: cve['icon']  = marks[0]
            if marks[1]: cve['color'] = marks[1]
            print(marks)
        except Exception as e:
          print(e)
          print("[!] Plugin %s failed on marking cves!"%plugin.getName())
    return cves
+14 −9
Original line number Diff line number Diff line
@@ -13,19 +13,24 @@ class Plugin():
  def setUID(self, uid):  self.uid = uid
  # Don't override
  def isWebPlugin(self):  return False
  # To override
  # To override without returns
  def loadSettings(self, reader): pass
  def onDatabaseUpdate(self):     pass
  # To override with returns
  def search(self, text):         pass


class WebPlugin(Plugin):
  # Don't override
  def isWebPlugin(self): return True
  # To override
  # To override with returns
  def getPage(self, **args):            return (None, None)
  def openSubpage(self, page, **args): return (None, None)
  def getCVEActions(self, **args):     return []
  # Functions based on user interaction
  def onCVEAction(self, action, **args): pass
  def getSubpage(self, page, **args):   return (None, None)
  def getCVEActions(self, cve, **args): return []
  def getFilters(self, **args):         return []
  def doFilter(self, filters, **args):  return []
  def cvePluginInfo(self, cve, **args): pass
  # To override without returns
  def onCVEAction(self, cve, action, **args): pass
  def onCVEOpen(self, cve, **args):           pass 
  def mark(self, cve, **args):                return (None, None)
+46 −104
Original line number Diff line number Diff line
@@ -110,13 +110,6 @@ def blacklist_mark(cve):
    return cve


def seen_mark(cve):
    if current_user.is_authenticated():
        seen=db.seenCVEs(current_user.get_id())
        for c in cve:
            if c["id"] in seen: cve[cve.index(c)]['seen'] = 'yes'


def compile(regexes):
  r=[]
  for rule in regexes:
@@ -160,11 +153,10 @@ def filterUpdateField(data):
    return "\n".join(returnvalue)


def filter_logic(blacklist, whitelist, unlisted, timeSelect, startDate, endDate,
                 timeTypeSelect, cvssSelect, cvss, rejectedSelect, hideSeen, limit, skip):
def filter_logic(f, limit, skip):
    query = []
    # retrieving lists
    if blacklist == "on":
    if f['blacklistSelect'] == "on":
        regexes = db.getRules('blacklist')
        if len(regexes) != 0:
            exp = "^(?!" + "|".join(regexes) + ")"
@@ -172,7 +164,7 @@ def filter_logic(blacklist, whitelist, unlisted, timeSelect, startDate, endDate,
                                  {'vulnerable_configuration': {'$exists': False}},
                                  {'vulnerable_configuration': []}
                                  ]})
    if whitelist == "hide":
    if f['whitelistSelect'] == "hide":
        regexes = db.getRules('whitelist')
        if len(regexes) != 0:
            exp = "^(?!" + "|".join(regexes) + ")"
@@ -180,46 +172,40 @@ def filter_logic(blacklist, whitelist, unlisted, timeSelect, startDate, endDate,
                                  {'vulnerable_configuration': {'$exists': False}},
                                  {'vulnerable_configuration': []}
                                  ]})
    if unlisted == "hide":
    if f['unlistedSelect'] == "hide":
        wlregexes = compile(db.getRules('whitelist'))
        blregexes = compile(db.getRules('blacklist'))
        query.append({'$or': [{'vulnerable_configuration': {'$in': wlregexes}},
                              {'vulnerable_configuration': {'$in': blregexes}}]})
    if rejectedSelect == "hide":
    if f['rejectedSelect'] == "hide":
        exp = "^(?!\*\* REJECT \*\*\s+DO NOT USE THIS CANDIDATE NUMBER.*)"
        query.append({'summary': re.compile(exp)})

    if current_user.is_authenticated():
      if hideSeen == "hide":
        query.append({'id': {"$nin":db.seenCVEs(current_user.get_id())}})
    # plugin filters
    query.extend(plugManager.doFilter(f, current_user=current_user))

    # cvss logic
    if cvssSelect != "all":
        if cvssSelect == "above":
            query.append({'cvss': {'$gt': float(cvss)}})
        if cvssSelect == "equals":
            query.append({'cvss': float(cvss)})
        if cvssSelect == "below":
            query.append({'cvss': {'$lt': float(cvss)}})
    if f['cvssSelect'] == "above":    query.append({'cvss': {'$gt': float(f['cvss'])}})
    elif f['cvssSelect'] == "equals": query.append({'cvss': float(f['cvss'])})
    elif f['cvssSelect'] == "below":  query.append({'cvss': {'$lt': float(f['cvss'])}})
    
    # date logic
    if timeSelect != "all":
        startDate = convertDateToDBFormat(startDate)
        endDate = convertDateToDBFormat(endDate)
        if timeSelect == "from":
            query.append({timeTypeSelect: {'$gt': startDate}})
        if timeSelect == "until":
            query.append({timeTypeSelect: {'$lt': endDate}})
        if timeSelect == "between":
            query.append({timeTypeSelect: {'$gt': startDate, '$lt': endDate}})
        if timeSelect == "outside":
            query.append({'$or': [{timeTypeSelect: {'$lt': startDate}}, {timeTypeSelect: {'$gt': endDate}}]})
    if f['timeSelect'] != "all":
        startDate = convertDateToDBFormat(f['startDate'])
        endDate = convertDateToDBFormat(f['endDate'])
        if f['timeSelect'] == "from":
            query.append({f['timeTypeSelect']: {'$gt': f['startDate']}})
        if f['timeSelect'] == "until":
            query.append({f['timeTypeSelect']: {'$lt': f['endDate']}})
        if f['timeSelect'] == "between":
            query.append({f['timeTypeSelect']: {'$gt': f['startDate'], '$lt': f['endDate']}})
        if f['timeSelect'] == "outside":
            query.append({'$or': [{f['timeTypeSelect']: {'$lt': f['startDate']}}, {f['timeTypeSelect']: {'$gt': f['endDate']}}]})
    cve=db.getCVEs(limit=limit, skip=skip, query=query)
    # marking relevant records
    if whitelist == "on":
        cve = whitelist_mark(cve)
    if blacklist == "mark":
        cve = blacklist_mark(cve)
    seen_mark(cve)
    if f['whitelistSelect'] == "on":   cve = whitelist_mark(cve)
    if f['blacklistSelect'] == "mark": cve = blacklist_mark(cve)
    plugManager.mark(cve, current_user=current_user)
    cve = list(cve)
    return cve

@@ -243,27 +229,14 @@ def markCPEs(cve):


def getFilterSettingsFromPost(r):
    blacklist = request.form.get('blacklistSelect')
    whitelist = request.form.get('whitelistSelect')
    unlisted = request.form.get('unlistedSelect')
    timeSelect = request.form.get('timeSelect')
    startDate = request.form.get('startDate')
    endDate = request.form.get('endDate')
    timeTypeSelect = request.form.get('timeTypeSelect')
    cvssSelect = request.form.get('cvssSelect')
    cvss = request.form.get('cvss')
    rejectedSelect = request.form.get('rejectedSelect')
    hideSeen = request.form.get('hideSeen')
    settings = {'blacklistSelect': blacklist, 'whitelistSelect': whitelist,
                'unlistedSelect': unlisted, 'timeSelect': timeSelect,
                'startDate': startDate, 'endDate': endDate,
                'timeTypeSelect': timeTypeSelect, 'cvssSelect': cvssSelect,
                'cvss': cvss, 'rejectedSelect': rejectedSelect, "hideSeen": hideSeen}
    filters = dict(request.form)
    filters = {x: filters[x][0] for x in filters.keys()}
    # retrieving data
    cve = filter_logic(blacklist, whitelist, unlisted, timeSelect, startDate, endDate,
                       timeTypeSelect, cvssSelect, cvss, rejectedSelect, hideSeen, pageLength, r)

    return(settings,cve)
    try:
      cve = filter_logic(filters, pageLength, r)
    except:
      cve = db.getCVEs(limit=pageLength, skip=r)
    return(filters,cve)

@login_manager.user_loader
def load_user(id):
@@ -273,25 +246,18 @@ def load_user(id):
@app.route('/')
def index():
    # get default page on HTTP get (navigating to page)
    blacklist = "on"
    whitelist = "on"
    unlisted = "show"
    timeSelect = "all"
    startDate = None
    endDate = None
    timeTypeSelect = "Modified"
    cvssSelect = "all"
    cvss = None
    rejectedSelect = "hide"
    hideSeen = "show"
    cve = filter_logic(blacklist, whitelist, unlisted, timeSelect, startDate, endDate,
                       timeTypeSelect, cvssSelect, cvss, rejectedSelect, hideSeen, pageLength, 0)
    return render_template('index.html', cve=cve, r=0, pageLength=pageLength)
    filters={'blacklistSelect': 'on', 'whitelistSelect': 'on', 
             'unlistedSelect': 'show', 'timeSelect': 'all', 
             'startDate': '', 'endDate': '', 'timeTypeSelect': 'Modified',
             'cvssSelect': 'all', 'cvss': '', 'rejectedSelect': 'hide'}
    
    cve = filter_logic(filters, pageLength, 0)
    return render_template('index.html', cve=cve, r=0, pageLength=pageLength, filters=plugManager.getFilters())

@app.route('/', methods=['POST'])
def filterPost():
    settings,cve = getFilterSettingsFromPost(0)
    return render_template('index.html', settings=settings, cve=cve, r=0, pageLength=pageLength)
    return render_template('index.html', settings=settings, cve=cve, r=0, pageLength=pageLength, filters=plugManager.getFilters())


@app.route('/r/<int:r>', methods=['POST'])
@@ -299,30 +265,7 @@ def filterLast(r):
    if not r:
        r = 0
    settings,cve = getFilterSettingsFromPost(r)
    return render_template('index.html', settings=settings, cve=cve, r=r, pageLength=pageLength)

@app.route('/r/<int:r>/seen', methods=['POST'])
def seen(r):
    if not r:
        r = 0
    seenlist=request.form.get('list').split(",")
    # retrieving data
    if current_user.is_authenticated():
        db.addSeenCVEs(current_user.get_id(), seenlist)
    settings,cve = getFilterSettingsFromPost(r)
    return render_template('index.html', settings=settings, cve=cve, r=r, pageLength=pageLength)


@app.route('/r/<int:r>/unseen', methods=['POST'])
def unseen(r):
    if not r:
        r = 0
    seenlist=request.form.get('list').split(",")
    # retrieving data
    if current_user.is_authenticated():
        db.removeSeenCVEs(current_user.get_id(), seenlist)
    settings, cve = getFilterSettingsFromPost(r)
    return render_template('index.html', settings=settings, cve=cve, r=r, pageLength=pageLength)
    return render_template('index.html', settings=settings, cve=cve, r=r, pageLength=pageLength, filters=plugManager.getFilters())

# Plugins
@app.route('/_get_plugins', methods=['GET'])
@@ -337,9 +280,9 @@ def get_plugins():
def get_cve_actions():
    cve = request.args.get('cve', type=str)
    if not current_user.is_authenticated(): # Don't show actions requiring auth if not authenticated
        actions = [x for x in plugManager.getCVEActions(current_user=current_user, cve=cve) if not x['auth']]
        actions = [x for x in plugManager.getCVEActions(cve, current_user=current_user) if not x['auth']]
    else:
        actions = plugManager.getCVEActions(current_user=current_user, cve=cve)
        actions = plugManager.getCVEActions(cve, current_user=current_user)
    return jsonify({"actions": actions})

@app.route('/plugin/<plugin>', methods=['GET'])
@@ -438,10 +381,9 @@ def cve(cveid):
    if cve is None:
        return render_template('error.html',status={'except':'cve-not-found','info':{'cve':cveid}})
    cve = markCPEs(cve)
    if current_user.is_authenticated():
        db.addSeenCVEs(current_user.get_id(), cveid)
    
    plugManager.onCVEOpen(cveid, current_user=current_user)
    pluginData = plugManager.cvePluginInfo(cveid, current_user=current_user)
    print(cveid, pluginData)
    return render_template('cve.html', cve=cve, plugins=pluginData)

@app.route('/browse/<vendor>')
@@ -502,7 +444,7 @@ def link(vFeedMap=None,field=None,value=None):
    # marking relevant records
    cve = whitelist_mark(cve)
    cve = blacklist_mark(cve)
    seen_mark(cve)
    plugManager.mark(cve, current_user=current_user)
    cve = list(cve)
    cvssList=[float(x['cvss']) for x in cve if 'cvss' in x]
    if cvssList:
+0 −3
Original line number Diff line number Diff line
@@ -4,9 +4,6 @@
.blacklisted{
    color: #555588;
}
table.table-striped tr.seen{
    color: #778899;
}
.table.table-striped tr.selected{
    background-color: #556677;
    color: #FFFFFF;
Loading