Skip to content

Commit

Permalink
Merge pull request #59 from adulau/master
Browse files Browse the repository at this point in the history
Many updates
  • Loading branch information
adulau committed Mar 23, 2015
2 parents e35cc86 + 7abd99c commit 103c1f4
Show file tree
Hide file tree
Showing 36 changed files with 1,320 additions and 202 deletions.
4 changes: 2 additions & 2 deletions bin/db_dump.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
import json
from bson import json_util

from lib import CVEs
import lib.CVEs as cves
from lib.Config import Configuration

# connect to db
Expand All @@ -40,7 +40,7 @@ def dumpallcveid():
vfeedlookup = args.v
capeclookup = args.c

l = CVEs.last(rankinglookup=rankinglookup, vfeedlookup=vfeedlookup, capeclookup=capeclookup)
l = cves.last(rankinglookup=rankinglookup, vfeedlookup=vfeedlookup, capeclookup=capeclookup)

for cveid in dumpallcveid():
item = l.getcve(cveid=cveid)
Expand Down
8 changes: 4 additions & 4 deletions bin/dump_last.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
import datetime
import argparse

import lib.CVEs
import lib.CVEs as cves

argParser = argparse.ArgumentParser(description='Dump last CVE entries in RSS/Atom format or in HTML tables')
argParser.add_argument('-f', type=str, help='Output format (rss1,rss2,atom,html)', default='rss1')
Expand All @@ -35,7 +35,7 @@
last = 10

ref = "http://adulau.github.com/cve-search/"
cves = CVEs.last(rankinglookup=args.r, namelookup=args.n, capeclookup=args.c)
cvelist = cves.last(rankinglookup=args.r, namelookup=args.n, capeclookup=args.c)

if not(args.f == "html"):
from feedformatter import Feed
Expand All @@ -50,7 +50,7 @@
print ("<style>.cve table { border-collapse: collapse; text-align: left; width: 100%; } .cve {font: normal 12px/150% Geneva, Arial, Helvetica, sans-serif; background: #fff; overflow: hidden; border: 1px solid #006699; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; }.cve table td, .cve table th { padding: 3px 10px; }.cve table tbody td { color: #00496B; border-left: 1px solid #E1EEF4;font-size: 12px;font-weight: normal; }.cve table tbody .alt td { background: #E1EEF4; color: #00496B; }.cve table tbody td:first-child { border-left: none; }.cve table tbody tr:last-child td { border-bottom: none; }.cve table tfoot td div { border-top: 1px solid #006699;background: #E1EEF4;} .cve table tfoot td { padding: 0; font-size: 12px } .cve table tfoot td div{ padding: 0px; }</style>")
print ("<title>Last " + str(args.l) + " CVE entries</title>")
print ("</head><body>")
for x in cves.get(limit=last):
for x in cvelist.get(limit=last):
if not(args.f == "html"):
if args.r:
if "ranking" not in x:
Expand Down Expand Up @@ -82,7 +82,7 @@
print ("<tr><td>Vulnerable configuration:</td></tr>")
print ("<tr><td><ul>")
for v in x['vulnerable_configuration']:
sys.stdout.write("<li>" + cves.getcpe(v) + "</li>")
sys.stdout.write("<li>" + cvelist.getcpe(v) + "</li>")
print ("</ul></td></tr>")
if args.r:
print ("<tr><td>Ranking:" + str(x['ranking']) + "</td></tr>")
Expand Down
152 changes: 152 additions & 0 deletions bin/search_irc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# Simple IRC bot to query for the last entries in the CVE database
#
# current command supported is:
#
# last <max>
# cvetweet <max>
# browse
# search <vendor>\<product>
# get <cve>
#
# You need to connect the IRC bot to the IRC Server you want to access it from.
#
# Software is free software released under the "Modified BSD license"
#
# Copyright (c) 2015 Pieter-Jan Moreels - pieterjan.moreels@gmail.com

# Imports
import os
import sys
runPath = os.path.dirname(os.path.realpath(__file__))
sys.path.append(os.path.join(runPath, ".."))

import argparse
import json
# BSON MongoDB include ugly stuff that needs to be processed for standard JSON
from bson import json_util

import irc.bot
import irc.strings

from lib.Query import lastentries, apigetcve, apibrowse, apisearch

argParser = argparse.ArgumentParser(description='IRC bot to query cve-search')
argParser.add_argument('-s', type=str, help='server ip', default='localhost')
argParser.add_argument('-p', type=int, help='server port)', default=6667)
argParser.add_argument('-n', type=str, help='nickname', default='cve-search')
argParser.add_argument('-w', type=str, help='password')
argParser.add_argument('-u', type=str, help='username', default='cve-search')
argParser.add_argument('-c', nargs="*", help='channel list', default=['cve-search'])
argParser.add_argument('-t', type=str, help='trigger prefix', default='.')
argParser.add_argument('-v', action='store_true', help='channel list', default=['cve-search'])
argParser.add_argument('-m', type=int, help='maximum query amount', default=20)
args = argParser.parse_args()

class IRCBot(irc.bot.SingleServerIRCBot):
def __init__(self, channel, nickname, server, port, password=None, username=None):
if not username:
username=nickname
irc.bot.SingleServerIRCBot.__init__(self, [(server, port)], nickname, username)
self.channel = channel

def on_nicknameinuse(self, c, e):
c.nick(c.get_nickname() + "_")

def on_welcome(self, c, e):
if args.v:
print("Server welcomed us")
for chan in self.channel:
if not chan.startswith('#'):chan=("#%s"%chan)
if args.v:
print("joining %s"%chan)
c.join(chan)

def on_privmsg(self, c, e):
self.do_command(e, e.arguments[0])

def on_pubmsg(self, c, e):
line = e.arguments[0]
if line.startswith(args.t):
self.do_command(e, line[len(args.t):])
return

def reply(self, e, reply):
c = self.connection
if e.target == c.nickname:
target=e.source.nick
else:
target=e.target
list = reply.split('\n')
for r in list:
c.privmsg(target, r)

def do_command(self, e, cmd):
words = cmd.split(' ')
if len(words)>=2:
cmd=words[0]
option=words[1]
else:
option=None

if cmd == "die":
self.die()
elif cmd == "last":
if option is None:
limit = 10
else:
limit = int(option)
if limit > args.m or limit < 1:
self.reply(e, "Request not in range 0-%d" % args.m)
self.reply(e, json.dumps(lastentries(limit=limit), sort_keys=True, indent=4, default=json_util.default))
elif cmd == "get":
if option is None:
self.reply(e, "A cve-id must be specified")
self.reply(e, apigetcve(cveid=option))
elif cmd == "browse":
self.reply(e, apibrowse(vendor=option))
elif cmd == "search":
self.reply(e, apisearch(query=option))
elif cmd == "cvetweet":
text = " "
if option is None:
limit = 10
else:
limit = int(option)
if limit > args.m or limit < 1:
return "Request not in range 0-%d" % args.m
for t in lastentries(limit=limit):
text = text + str(t['id']) + " , " + str(t['summary']) + " " + " , ".join(t['references']) + "\n"
self.reply(e, text)
elif cmd == "browse":
self.reply(e, apibrowse(vendor=option))

else:
self.reply(e, "Not understood: " + cmd)

import signal

# signal handlers
def sig_handler(sig, frame):
print('Caught signal: %s\nShutting down' % sig)
bot.die()

def main():
server = args.s
port = args.p
nick = args.n
password = args.w
user = args.u
chans = args.c
global bot
bot=IRCBot(chans, nick, server, port, password=password,username=user)
signal.signal(signal.SIGTERM, sig_handler)
signal.signal(signal.SIGINT, sig_handler)
if args.v:
print("Connecting to server")
bot.start()

if __name__ == "__main__":
main()
113 changes: 9 additions & 104 deletions bin/search_xmpp.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,13 @@
#
# Simple XMPP bot to query for the last entries in the CVE database
#
# current command supported is:
# current commands supported are:
#
# last <max>
# cvetweet <max>
# browse
# search <vendor>\<product>
# get <cve>
#
# You need to add the XMPP bot in your roster if you want to communicate
# with it.
Expand All @@ -26,10 +30,9 @@
from optparse import OptionParser
import sleekxmpp
import json
import requests
import urllib.parse

from lib.Config import Configuration
from lib.Query import lastentries, apigetcve, apibrowse, apisearch
# BSON MongoDB include ugly stuff that needs to be processed for standard JSON
from bson import json_util

Expand All @@ -54,64 +57,6 @@
helpmessage = helpmessage + "For more info about cve-search: http://adulau.github.com/cve-search/"


def lookupcpe(cpeid=None):
e = db.cpe.find_one({'id': cpeid})
if e is None:
return cpeid
if 'id' in e:
return e['title']


def findranking(cpe=None, loosy=True):
if cpe is None:
return False
r = db.ranking
result = False
if loosy:
for x in cpe.split(':'):
if x is not '':
i = r.find_one({'cpe': {'$regex': x}})
if i is None:
continue
if 'rank' in i:
result = i['rank']
else:
i = r.find_one({'cpe': {'$regex': cpe}})
print (cpe)
if i is None:
return result
if 'rank' in i:
result = i['rank']

return result


def lastentries(limit=5, namelookup=False):
entries = []
for item in collection.find({}).sort("Modified", -1).limit(limit):
if not namelookup and rankinglookup is not True:
entries.append(item)
else:
if "vulnerable_configuration" in item:
vulconf = []
ranking = []
for conf in item['vulnerable_configuration']:
if namelookup:
vulconf.append(lookupcpe(cpeid=conf))
else:
vulconf.append(conf)
if rankinglookup:
rank = findranking(cpe=conf)
if rank and rank not in ranking:
ranking.append(rank)

item['vulnerable_configuration'] = vulconf
if rankinglookup:
item['ranking'] = ranking
entries.append(item)
return entries


def cvesearch(query="last", option=None):
if query == "last":
if option is None:
Expand All @@ -124,11 +69,11 @@ def cvesearch(query="last", option=None):
elif query == "get":
if option is None:
return "A cve-id must be specified"
return apigetcve(cveid=option)
return apigetcve(opts.api,cveid=option)
elif query == "browse":
return apibrowse(vendor=option)
return apibrowse(opts.api, vendor=option)
elif query == "search":
return apisearch(query=option)
return apisearch(opts.api, query=option)
elif query == "cvetweet":
text = " "

Expand All @@ -146,46 +91,6 @@ def cvesearch(query="last", option=None):
else:
return False


def apigetcve(cveid=None):
if cveid is None:
return False
url = urllib.parse.urljoin(opts.api, "api/cve/"+cveid)
urltoget = urllib.parse.urljoin(url, cveid)
r = requests.get(urltoget)
if r.status_code is 200:
return r.text
else:
return False


def apibrowse(vendor=None):
url = urllib.parse.urljoin(opts.api, "api/browse")
if vendor is None:
r = requests.get(url)
else:
urlvendor = url + "/" + vendor
r = requests.get(urlvendor)

if r.status_code is 200:
return r.text
else:
return False


def apisearch(query=None):
if query is None:
return False
url = urllib.parse.urljoin(opts.api, "api/search/")
url = url+query

r = requests.get(url)
if r.status_code is 200:
return r.text
else:
return False


class CVEBot(sleekxmpp.ClientXMPP):

def __init__(self, jid, password):
Expand Down

0 comments on commit 103c1f4

Please sign in to comment.